3.9 KiB
Main Flows and Boundaries
Auth / Session -> User
Auth / Session Service uses synchronous REST calls for user ownership
decisions during public auth.
Resolve by e-mail
POST /api/v1/internal/user-resolutions/by-email
Outcome vocabulary:
creatableexistingblocked
The decision is based on exact-after-trim e-mail matching plus the current block state for that subject.
Ensure by e-mail
POST /api/v1/internal/users/ensure-by-email
Rules:
registration_contextis requiredregistration_contextis create-only- existing users ignore the supplied registration context
- blocked subjects return
blockedrather than creating a user - the current rollout sends temporary
preferred_language="en"from authsession and forwards the public confirmtime_zone
Create side effects:
- generate opaque
user_id - generate default
player-*race name - store initial preferred language and time zone
- materialize the initial free entitlement snapshot
- publish initialization-style profile, settings, and entitlement events
Gateway -> User
Gateway owns the external authenticated gRPC contract and transcodes to this service's internal REST API.
External authenticated message types:
user.account.getuser.profile.updateuser.settings.update
Internal REST routes:
GET /api/v1/internal/users/{user_id}/accountPOST /api/v1/internal/users/{user_id}/profilePOST /api/v1/internal/users/{user_id}/settings
Rules:
- gateway derives
user_idfrom authenticated session context only - success returns the shared account aggregate
- business errors return stable
codeandmessage - timeout or upstream
503stay transport-level unavailable at gateway
Profile update
UpdateMyProfile changes only race_name.
Rules:
- preserve stored casing on success
- enforce canonical reservation uniqueness
- reject conflicts as
409 conflict - reject writes while
profile_update_blockis active - return current aggregate on no-op rename
Settings update
UpdateMySettings changes only:
preferred_languagetime_zone
Rules:
- validate BCP 47 and IANA semantics
- reject writes while
profile_update_blockis active - return the refreshed account aggregate
Lobby -> User
Game Lobby Service reads one synchronous eligibility snapshot through:
GET /api/v1/internal/users/{user_id}/eligibility
Rules:
- unknown users return
exists=false - current entitlement is expiry-repaired lazily
- active sanctions are filtered to the lobby-relevant set
- effective limits combine default catalog values plus active overrides
- markers are derived from sanctions, entitlement, and limits
Geo -> User
Geo Profile Service synchronizes the latest approved effective declared
country through:
POST /api/v1/internal/users/{user_id}/declared-country/sync
Rules:
- input must be uppercase ISO 3166-1 alpha-2
- syncing the stored value is a no-op
User Servicestores only the current effective value- geo owns review workflow and history
- successful updates publish
user.declared_country.changed
Admin Reads And Commands
Trusted admin callers use:
- exact reads by
user_id, e-mail, and race name - deterministic filtered listing
- explicit entitlement commands
- explicit sanction commands
- explicit limit commands
Listing rules:
- order by
created_at desc, thenuser_id desc - combine filters with
AND page_tokenis opaque and filter-bound
Domain Events
The shared auxiliary event stream contains post-commit state propagation for:
user.profile.changeduser.settings.changeduser.entitlement.changeduser.sanction.changeduser.limit.changeduser.declared_country.changed
Operation vocabularies:
- profile and settings:
initializedupdated
- entitlement:
initializedgrantedextendedrevokedexpired_repaired
- sanction:
appliedremoved
- limit:
setremoved