feat: use postgres

This commit is contained in:
Ilia Denisov
2026-04-26 20:34:39 +02:00
committed by GitHub
parent 48b0056b49
commit fe829285a6
365 changed files with 29223 additions and 24049 deletions
+56
View File
@@ -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)