Skip to content

feat(users): include email in /users/search response (#42) - #43

Merged
amrtgaber merged 1 commit into
mainfrom
feat/search-include-email
May 27, 2026
Merged

feat(users): include email in /users/search response (#42)#43
amrtgaber merged 1 commit into
mainfrom
feat/search-include-email

Conversation

@amrtgaber

Copy link
Copy Markdown
Contributor

Closes #42.

Summary

Consumer pickers (e.g. the admin owner-grant flow in hera-streamer-invitational-2026-web#142) currently render a raw UUID as the fallback label when a matched user has no `display_name` — common for Steam-OAuth users who haven't customized their profile. This makes the picker functionally unusable for that population.

Adds `email: str | None` to `UserSearchResult`. Consumer-side code can now render `display_name ?? email` and never bottom out at the UUID. `email` is null for Steam-OAuth users pre-tos-gate, matching the existing nullability on `/auth/me`'s `UserRead`.

Privacy posture

The endpoint is authenticated AND the search query already matches against email as an input key — meaning a caller who didn't already know the email couldn't have found that user via the email-substring branch anyway. Returning email doesn't expand the caller's knowledge surface. The two callers that have a legitimate reason to type-ahead users (admin picker in hera-streamer-invitational-2026-web, profile pages) both benefit; nothing else changes.

If you want a more conservative posture later (e.g. gate behind a query param or admin role), this PR keeps the field unconditional and we can add the gate as a follow-up. Per the issue's consumer recommendation, defaulting to unconditional.

Test plan

  • `uv run pytest tests/test_users_search.py` — 16/16. Renamed the "email never in response" test to assert email IS in response with the right value (Alice has both populated). New test confirms Steam-OAuth users come back with `email: null` (not missing key — explicit null so consumers can detect the no-email state).
  • `uv run pytest` — full suite 125 passed.
  • `uv run ruff check . && uv run ruff format --check .` — clean.

Consumer-side follow-up

After this merges, downstream consumers can regenerate their TS types and remove the raw-UUID fallback from their picker code. The relevant consumer issue is hera-streamer-invitational-2026-web#142.

Consumer pickers (e.g. the admin owner-grant flow in
hera-streamer-invitational-2026-web) currently render a raw UUID as the
fallback label when a matched user has no display_name set — common for
Steam-OAuth users who haven't customized their profile. This makes the
picker functionally unusable for that population.

Adding email to UserSearchResult lets consumer-side code render
``display_name ?? email`` and never bottom out at the UUID. The endpoint
is authenticated and the search query already matches against email as
an input key, so returning email doesn't expand the caller's existing
knowledge surface — they already had to know (or guess) it to find the
user via email-match.

email is null for Steam-OAuth users pre-tos-gate, matching the existing
nullability on /auth/me's UserRead.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add email to GET /users/search response so consumer pickers can fall back to a readable label

1 participant