feat: use postgres
This commit is contained in:
@@ -445,10 +445,66 @@ as:
|
||||
Transport failures, timeouts, and upstream `503` remain transport-level
|
||||
gateway `UNAVAILABLE`, not business results.
|
||||
|
||||
## Storage
|
||||
|
||||
`User Service` is split between two backends per
|
||||
[`../ARCHITECTURE.md §Persistence Backends`](../ARCHITECTURE.md):
|
||||
|
||||
- PostgreSQL is the source of truth for table-shaped business state. The
|
||||
`user` schema (provisioned externally) holds `accounts`,
|
||||
`blocked_emails`, `entitlement_records`, `entitlement_snapshots`,
|
||||
`sanction_records`, `sanction_active`, `limit_records`, `limit_active`.
|
||||
Embedded migrations in
|
||||
[`internal/adapters/postgres/migrations`](internal/adapters/postgres/migrations)
|
||||
apply at process start; a non-zero exit is fatal.
|
||||
- Redis hosts the two stream publishers — the auxiliary domain-events
|
||||
stream and the trusted user-lifecycle stream described below. No
|
||||
durable user state lives on Redis after Stage 3 of `PG_PLAN.md`.
|
||||
|
||||
Schema decisions and the reasoning behind keeping `entitlement_snapshots`
|
||||
denormalised, expressing eligibility flags as SQL predicates instead of
|
||||
materialised columns, and sharing one `*redis.Client` between the two
|
||||
publishers are recorded in
|
||||
[`docs/postgres-migration.md`](docs/postgres-migration.md).
|
||||
|
||||
### Configuration
|
||||
|
||||
PostgreSQL knobs (consumed via `pkg/postgres`):
|
||||
|
||||
- `USERSERVICE_POSTGRES_PRIMARY_DSN` (required)
|
||||
- `USERSERVICE_POSTGRES_REPLICA_DSNS` (optional; comma-separated)
|
||||
- `USERSERVICE_POSTGRES_OPERATION_TIMEOUT` (default `1s`)
|
||||
- `USERSERVICE_POSTGRES_MAX_OPEN_CONNS` (default `25`)
|
||||
- `USERSERVICE_POSTGRES_MAX_IDLE_CONNS` (default `5`)
|
||||
- `USERSERVICE_POSTGRES_CONN_MAX_LIFETIME` (default `30m`)
|
||||
|
||||
Redis knobs (consumed via `pkg/redisconn`):
|
||||
|
||||
- `USERSERVICE_REDIS_MASTER_ADDR` (required)
|
||||
- `USERSERVICE_REDIS_REPLICA_ADDRS` (optional; comma-separated)
|
||||
- `USERSERVICE_REDIS_PASSWORD` (required; mandatory by architectural rule)
|
||||
- `USERSERVICE_REDIS_DB` (default `0`)
|
||||
- `USERSERVICE_REDIS_OPERATION_TIMEOUT` (default `250ms`)
|
||||
|
||||
Stream-shape knobs:
|
||||
|
||||
- `USERSERVICE_REDIS_DOMAIN_EVENTS_STREAM` (default `user:domain_events`)
|
||||
- `USERSERVICE_REDIS_DOMAIN_EVENTS_STREAM_MAX_LEN` (default `1024`)
|
||||
- `USERSERVICE_REDIS_LIFECYCLE_EVENTS_STREAM` (default
|
||||
`user:lifecycle_events`)
|
||||
- `USERSERVICE_REDIS_LIFECYCLE_EVENTS_STREAM_MAX_LEN` (default `1024`)
|
||||
|
||||
The deprecated variables `USERSERVICE_REDIS_ADDR`,
|
||||
`USERSERVICE_REDIS_USERNAME`, `USERSERVICE_REDIS_TLS_ENABLED`, and
|
||||
`USERSERVICE_REDIS_KEYSPACE_PREFIX` are retired; setting any of them now
|
||||
fails service start with a clear error message pointing back to
|
||||
`ARCHITECTURE.md §Persistence Backends`.
|
||||
|
||||
## References
|
||||
|
||||
- [Internal REST contract](openapi.yaml)
|
||||
- [Service docs index](docs/README.md)
|
||||
- [PostgreSQL migration decisions](docs/postgres-migration.md)
|
||||
- [Stage 21 decisions](docs/stage21-user-name-display-name.md)
|
||||
- [Stage 22 decisions](docs/stage22-permanent-block-delete-user.md)
|
||||
- [System architecture](../ARCHITECTURE.md)
|
||||
|
||||
Reference in New Issue
Block a user