docs: sync from backend cab0719 - align request budget validation

This commit is contained in:
Siavash Sameni
2026-05-31 14:46:59 +04:00
parent 773f5db454
commit 0bd3fe5598
25 changed files with 5976 additions and 48 deletions

View File

@@ -5,7 +5,7 @@ tags: [operations]
# Database Operations
Day-to-day operations for the two stateful services: **MongoDB 8.2** (primary data store) and **Redis 8** (cache, rate-limit counters, ephemeral session data).
Day-to-day operations for stateful services: **MongoDB 8.x** (primary runtime data store), **PostgreSQL 18** (migration target and conditional oracle quote store), and **Redis 8** (cache, rate-limit counters, ephemeral session data).
For schema details see [[Data Models]]. For backup procedures and disaster recovery see [[Backup & Recovery]].
@@ -177,9 +177,79 @@ Optional auto-seed on startup: set `AUTO_SEED_ON_START=true` in `.env`. The boot
---
## 2. Redis
## 2. PostgreSQL 18
### 2.1 Connection
### 2.1 Runtime role
Postgres is present in the current dev/integration stack, but MongoDB remains the primary runtime store. Use Postgres for:
- Drizzle migrations and schema verification.
- Mongo → Postgres backfill and reconciliation work.
- `payment_quotes` when `ORACLE_QUOTING_ENABLED=true` and a PG parent payment row exists.
Do **not** treat Postgres as the authoritative app database until the relevant domain has been wired through repository interfaces, backfilled, shadow-read, and cut over. See [[Postgres Runtime Cutover Status]].
### 2.2 Docker volume layout for Postgres 18
Postgres 18 Docker images expect the mount at `/var/lib/postgresql`, not directly at `/var/lib/postgresql/data`, because the image stores data under a major-version-specific directory such as `/var/lib/postgresql/18/docker`.
```yaml
postgres:
image: postgres:18-alpine
environment:
POSTGRES_DB: amanat_dev
POSTGRES_USER: amanat
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- /var/data/escrowDev/postgres_data:/var/lib/postgresql
```
For a disposable dev reset:
```bash
docker rm -f amanat-postgres 2>/dev/null || true
rm -rf /var/data/escrowDev/postgres_data
mkdir -p /var/data/escrowDev/postgres_data
```
### 2.3 Apply migrations
Run migrations only after the database is healthy and the DSN points at the intended non-production target:
```bash
PG_URL=postgres://amanat:...@postgres:5432/amanat_dev npx drizzle-kit migrate
```
The backend image contains migrations through `0008`. Application startup does not apply them automatically.
### 2.4 Backfill and verification
Backfills use `MIGRATION_PG_URL`, not `PG_URL`, and the scripts enforce a host allowlist. Run dry-run and verification before any dual-write/PG read flip:
```bash
MIGRATION_MONGO_URL=mongodb://mongodb:27017/marketplace \
MIGRATION_PG_URL=postgres://amanat:...@postgres:5432/amanat_dev \
node dist/db/backfill/run-backfill.js --dry-run
```
Verify row counts/checksums and inspect `pg_dualwrite_gaps` before enabling any cutover flag.
### 2.5 Backup
For dev/staging:
```bash
docker exec amanat-postgres pg_dump -U amanat -d amanat_dev --format=custom \
> backups/amanat_dev_pg_$(date +%F).dump
```
Before production cutover, use managed backups or self-hosted WAL archiving/PITR. A plain dev bind mount is not a production backup strategy.
---
## 3. Redis
### 3.1 Connection
Dev: `redis://redis:6379` (no password).
Prod: `redis://:<REDIS_PASSWORD>@redis:6379`. The compose command line is `redis-server --requirepass "$REDIS_PASSWORD"`.
@@ -193,7 +263,7 @@ docker exec -it nickapp-redis redis-cli -a "$REDIS_PASSWORD"
> KEYS * # prod-unsafe on large datasets, use SCAN
```
### 2.2 What we store
### 3.2 What we store
- **Rate-limit counters** for `express-rate-limit`
- **Session data** for refresh-token tracking and revocation lists
@@ -203,7 +273,7 @@ docker exec -it nickapp-redis redis-cli -a "$REDIS_PASSWORD"
Key prefixes follow `<service>:<entity>:<id>`. E.g. `payment:idem:<requestId>`, `auth:refresh:<userId>`.
### 2.3 Persistence
### 3.3 Persistence
Redis 8 defaults to **RDB snapshots** + optional **AOF**. Our compose uses the default config:
@@ -220,7 +290,7 @@ redis:
`appendfsync everysec` is the common compromise: at most 1 second of writes lost on crash, with negligible perf impact.
### 2.4 Eviction policy
### 3.4 Eviction policy
Default is `noeviction` — Redis refuses writes when memory is full. For our use (caches that can be regenerated), set:
@@ -233,7 +303,7 @@ docker exec nickapp-redis redis-cli -a "$REDIS_PASSWORD" \
Persist by adding to a custom `redis.conf` mounted at `/usr/local/etc/redis/redis.conf` (then change the compose `command:` to `["redis-server","/usr/local/etc/redis/redis.conf","--requirepass",...]`).
### 2.5 Backup
### 3.5 Backup
Redis backups are usually unnecessary (the data is regeneratable) but still cheap:
@@ -245,7 +315,7 @@ docker cp nickapp-redis:/data/dump.rdb ./backups/redis-$(date +%F).rdb
`BGSAVE` is non-blocking (forks). For AOF, copy `/data/appendonly.aof` too.
### 2.6 Cache flush
### 3.6 Cache flush
When deploying breaking changes to cached schemas:
@@ -261,7 +331,7 @@ docker exec nickapp-redis redis-cli -a "$REDIS_PASSWORD" \
> [!warning] `FLUSHALL` will sign out every user with an active refresh token and reset every rate-limit counter. Avoid in production unless that is what you want.
### 2.7 Monitoring
### 3.7 Monitoring
```bash
docker exec nickapp-redis redis-cli -a "$REDIS_PASSWORD" INFO stats
@@ -273,7 +343,7 @@ Watch `evicted_keys`, `keyspace_misses`, `rejected_connections` — see [[Monito
---
## 3. Maintenance windows
## 4. Maintenance windows
For both DBs, schedule a window when:
@@ -293,7 +363,7 @@ Suggested checklist:
---
## 4. Cross-links
## 5. Cross-links
- [[Backup & Recovery]] — formal backup/restore procedures, RTO/RPO targets, offsite storage.
- [[Monitoring]] — what metrics to watch (slow queries, evictions, replication lag).