3.0 KiB
3.0 KiB
F-144 — Diseño técnico
Enfoque
Una única migrations 048_reporting_store_shipping_snapshots.js (node-pg-migrate,
estilo 043_pos_basics/047_*) idempotente y reversible. No hay migración de
datos costosa: store_id usa column DEFAULT del default store (sembrado por
043), por lo que filas existentes e inserts sin store_id heredan el default sin
table rewrite ni toque en el app-layer.
Columnas nuevas
| Tabla | Columna | Tipo | Nullable | Default | Restricción |
|---|---|---|---|---|---|
| orders_orders | store_id | uuid | NOT NULL | '00000000-0000-0000-0000-000000000001'::uuid |
FK → pos_stores(id) |
| orders_orders | shipping_cents | integer | NOT NULL | 0 | CHECK (>=0) |
| orders_items | cost_at_sale_cents | bigint | YES (snapshot) | — | — |
| orders_items | vat_rate | text | YES (snapshot) | — | — |
Índice: orders_orders_store_id_created_at_idx ON orders_orders(store_id, created_at)
(por el patrón de reporting §7: consultas por tienda + rango de fechas).
Idempotencia + reversibilidad
- Toda la DDL:
ADD COLUMN IF NOT EXISTS/DO $$ IF NOT EXISTSsobrepg_constraint. Re-ejecutar es no-op. down():DROP INDEX,DROP CONSTRAINT,DROP COLUMNpor cada nueva columna (orden inverso de dependencias).
Por qué DEFAULT (no NOT NULL sin default + UPDATE)
store_ides una columna nueva: no hay histórico que "reescribir". UnDEFAULTconstante backfilla silenciosamente y evita unUPDATEtable-scan sobre tabla potencialmente grande — alineado con §11 "no añadir índices duplicados indiscriminadamente" y con no-rewrite-history.- El app inserta pedidos vía
PgOrderRepository(raw SQLINSERT INTO orders_orders (...)). Con columnDEFAULT, ese INSERT sigue funcionando (la column no aparece en la lista) → cero regresión en checkout/orders.itest. La resolución explícita de tienda (writes app-layered) se deja a F-146.
Test
- itest
reporting-snapshots.itest.ts(mirrorinventory.itest.ts):recreateDatabase(url)+runMigrations(url,'up')(aplica 048 contramercadodevida_test) +createPool, condescribe.skipIf(!hasDb). - Asocia columnas/nullabilidad/default/FK/índice vía
information_schema/pg_constraint/pg_indexes, e insertaINSERT INTO orders_orders DEFAULT VALUES RETURNING store_id, shipping_cents→store_id = DEFAULT_STORE_ID,shipping_cents = 0. - Harness:
TEST_DATABASE_URL=postgres://mdv:mdv_dev_only@localhost:5432/mercadodevida_test(verificado:orders.itest.tsrecrea+migra+tests en ~450ms con elmdvsuperuser).
Verificación esperada
npx tsc --noEmit→ 0 errores.TEST_DATABASE_URL=... npx vitest run src/app/tests/reporting-snapshots.itest.ts→ 3/3.TEST_DATABASE_URL=... npx vitest run→ 1 archivo itest nuevo + regresión (orders/catalog/checkout/sales itests) verde, 0 fallos.node scripts/check-module-boundaries.mjs src→ 0 violaciones nuevas (F-144 añade 1 migration .js + 1 .ts en tests; sin imports inter-módulo).