apiVersion: conventions/v1 version: 0.1.0 updated: "2026-06-29" name: database_patterns title: Database patterns scope: general status: active summary: Schema-is-the-contract (forward-only migrations), one connection singleton, per-service role isolation, pgBouncer transaction-mode constraints. v2 lilith database-architecture, evolved in v4. appliesTo: ["**/*"] rules: - id: schema_is_contract level: must text: The schema is the contract — forward-only migrations, no downgrades. No schema changes outside a migration. - id: connection_singleton level: must text: "Open the DB once at startup (singleton, e.g. openDb() in server.ts) and reuse via getDb(); no per-feature pools." - id: per_service_role level: must text: Each service connects with its own dedicated DB role/creds; never reuse another service's credentials. - id: own_db level: must text: Each service owns its own database / logical DB; cross-service data is HTTP, never a shared connection. - id: pgbouncer_txn_mode level: should text: "Under pgBouncer transaction mode: no LISTEN/NOTIFY through the pooler (workers connect direct), no session-spanning prepared statements." - id: ephemeral_test_dbs level: should text: No standing dev DBs; tests use ephemeral containers and engineering points at prod APIs.