Files
mercadodevida/legacy/specs-old/F-002-database-foundation/DESIGN.md
2026-08-17 22:23:10 +02:00

2.5 KiB

DESIGN — F-002 Database foundation with module-owned schemas

Affected modules

  • src/infrastructure/db (new): pool factory + migration runner entry.

Modules touched

  • src/infrastructure/db
  • project/migrations/ (new folder, SQL files)
  • project/docker-compose.yml (new)

Modules NOT touched

  • All business modules. No HTTP API change. No shared/ change.

New interfaces

  • src/infrastructure/db/pool.ts: createPoolFromEnv(): Pool (fail fast if DATABASE_URL missing), query(text, params) helper typed over pg.
  • npm scripts: db:up, db:down, db:status, docker:up, docker:down, test:integration.

API changes

  • None.

Database changes

  • Baseline migration 001_baseline.js (node-pg-migrate, pgm.sql):
    • CREATE EXTENSION IF NOT EXISTS citext;
    • CREATE EXTENSION IF NOT EXISTS pgcrypto;
    • CREATE TABLE app_meta (key text PRIMARY KEY, value text NOT NULL, updated_at timestamptz NOT NULL DEFAULT now());
    • Down: drop table, drop extensions.
  • Migration version tracking table owned by the migration tool.

Naming convention (documented rule)

<module>_<table>        e.g. catalog_products, inventory_stock, orders_orders
<module>_<table>_id_seq sequences owned by their table
  • A module never queries tables without its own prefix.
  • Migrations are immutable once merged; fixes ship as new migrations.

Events

  • None.

External integrations

  • Docker Compose: postgres:16-alpine (port 5432), redis:7-alpine (port 6379), named volumes.

Cache changes

  • None (Redis present but unused until cache ticket).

Security considerations

  • Compose credentials are dev-only and public by design; documented as such.
  • .env.example committed, real .env gitignored.
  • No secrets in migration files.

Toolchain decisions

  • Migration tool: node-pg-migrate (pure npm dependency, battle-tested, SQL-first via pgm.sql, supports up/down and dry-run). Rejected: hand-rolled runner (reinvention), Flyway/golang-migrate (foreign toolchains for a Node monolith).
  • Driver: pg (standard).
  • Env loading: Node 22 --env-file flag; no dotenv dependency.

Test strategy

  • Integration tests (*.itest.ts) run only when TEST_DATABASE_URL is set: describe.skipIf — explicit, no magic.
  • They verify: fresh up creates schema; second up is no-op; down reverts cleanly; app_meta usable via pool helper.

Migration strategy

  • Greenfield; compose starts empty volume, migrations run from zero.

Rollback strategy

  • db:down reverts last migration; compose volumes can be removed with docker compose down -v.