feat: user service
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
# Runbook
|
||||
|
||||
## Startup Checklist
|
||||
|
||||
Before starting `userservice`, verify:
|
||||
|
||||
- `USERSERVICE_REDIS_ADDR` points to the intended Redis instance
|
||||
- internal HTTP bind address is free
|
||||
- optional admin metrics listener does not collide with another process
|
||||
- domain-events stream settings match the environment that consumes them
|
||||
|
||||
Expected startup behavior:
|
||||
|
||||
- configuration is loaded and validated first
|
||||
- Redis-backed stores and publishers are constructed
|
||||
- startup fails fast on Redis misconfiguration or connectivity failure
|
||||
|
||||
## Health And Readiness
|
||||
|
||||
`userservice` does not expose public health endpoints.
|
||||
|
||||
Operational readiness is typically checked through one trusted internal route,
|
||||
for example:
|
||||
|
||||
- `GET /api/v1/internal/users/{user_id}/exists`
|
||||
|
||||
with a guaranteed-missing `user_id`. A healthy process returns `200` with
|
||||
`{"exists":false}`.
|
||||
|
||||
If admin metrics are enabled, `/metrics` on the admin listener is the
|
||||
additional process-level operational endpoint.
|
||||
|
||||
## Common Failure Modes
|
||||
|
||||
### Redis unavailable
|
||||
|
||||
Symptoms:
|
||||
|
||||
- process fails during startup
|
||||
- internal API returns `503 service_unavailable`
|
||||
- domain events stop being published
|
||||
|
||||
Checks:
|
||||
|
||||
- connectivity to `USERSERVICE_REDIS_ADDR`
|
||||
- Redis ACL credentials
|
||||
- Redis DB number
|
||||
- TLS setting mismatch
|
||||
|
||||
### Invalid registration context
|
||||
|
||||
Symptoms:
|
||||
|
||||
- `ensure-by-email` returns `400 invalid_request`
|
||||
|
||||
Checks:
|
||||
|
||||
- `preferred_language` is a valid BCP 47 tag
|
||||
- `time_zone` is a valid IANA time-zone name
|
||||
|
||||
### race_name conflict
|
||||
|
||||
Symptoms:
|
||||
|
||||
- profile update returns `409 conflict`
|
||||
|
||||
Checks:
|
||||
|
||||
- desired race name is not already reserved under canonical uniqueness rules
|
||||
- user is not currently blocked by `profile_update_block`
|
||||
|
||||
### declared-country sync rejected
|
||||
|
||||
Symptoms:
|
||||
|
||||
- geo sync returns `400 invalid_request`
|
||||
|
||||
Checks:
|
||||
|
||||
- country code is uppercase ISO 3166-1 alpha-2
|
||||
- trusted caller is using the intended internal route
|
||||
|
||||
## Safe Rollout Notes
|
||||
|
||||
- Keep `Auth / Session Service` and `User Service` aligned on the current
|
||||
`registration_context` shape.
|
||||
- During the current rollout, treat authsession-provided
|
||||
`preferred_language="en"` as the active create-path contract.
|
||||
- Gateway direct `user.*` self-service routing depends on the internal REST
|
||||
routes staying stable.
|
||||
- Do not roll out billing-driven entitlement mutations assuming another
|
||||
service owns current entitlement state. `User Service` remains the source of
|
||||
truth for current entitlement.
|
||||
|
||||
## Debugging Data Mismatches
|
||||
|
||||
When a caller reports mismatched user state:
|
||||
|
||||
1. Read the current account aggregate through the trusted internal route.
|
||||
2. Confirm whether the discrepancy is in source-of-truth state or in a
|
||||
downstream projection.
|
||||
3. If the issue concerns declared-country workflow history, switch to `Geo
|
||||
Profile Service`; `User Service` stores only the current effective value.
|
||||
4. If the issue concerns authenticated edge transport, verify the same user
|
||||
through gateway `user.account.get` to distinguish transport problems from
|
||||
source-of-truth problems.
|
||||
Reference in New Issue
Block a user