Files
galaxy-game/user/docs/flows.md
T
2026-04-10 19:05:02 +02:00

164 lines
3.9 KiB
Markdown

# 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:
- `creatable`
- `existing`
- `blocked`
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_context` is required
- `registration_context` is create-only
- existing users ignore the supplied registration context
- blocked subjects return `blocked` rather than creating a user
- the current rollout sends temporary `preferred_language="en"` from
authsession and forwards the public confirm `time_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.get`
- `user.profile.update`
- `user.settings.update`
Internal REST routes:
- `GET /api/v1/internal/users/{user_id}/account`
- `POST /api/v1/internal/users/{user_id}/profile`
- `POST /api/v1/internal/users/{user_id}/settings`
Rules:
- gateway derives `user_id` from authenticated session context only
- success returns the shared account aggregate
- business errors return stable `code` and `message`
- timeout or upstream `503` stay 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_block` is active
- return current aggregate on no-op rename
### Settings update
`UpdateMySettings` changes only:
- `preferred_language`
- `time_zone`
Rules:
- validate BCP 47 and IANA semantics
- reject writes while `profile_update_block` is 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 Service` stores 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`, then `user_id desc`
- combine filters with `AND`
- `page_token` is opaque and filter-bound
## Domain Events
The shared auxiliary event stream contains post-commit state propagation for:
- `user.profile.changed`
- `user.settings.changed`
- `user.entitlement.changed`
- `user.sanction.changed`
- `user.limit.changed`
- `user.declared_country.changed`
Operation vocabularies:
- profile and settings:
- `initialized`
- `updated`
- entitlement:
- `initialized`
- `granted`
- `extended`
- `revoked`
- `expired_repaired`
- sanction:
- `applied`
- `removed`
- limit:
- `set`
- `removed`