Files
mercadodevida/work/artifacts/F-144/implementer.md
2026-08-22 12:40:23 +02:00

3.9 KiB

F-144 — Implementer evidence

What

F-144 build evidence: an additive schema migration 048_* adds the store/VAT/cost/shipping snapshot columns to orders_orders / orders_items, plus DB integration test reporting-snapshots.itest.ts. Backend-only, no API or user-facing behavior change (reporting routes are unchanged from F-143).

Design recap (architect-approved — see architect.md)

  • orders_orders.store_id uuid NOT NULL DEFAULT <default store> with guarded FK → pos_stores(id) + index (store_id, created_at). Column DEFAULT backfills existing rows and future inserts without a table rewrite and without app-layer changes to the order INSERT path. FK resolución por request se posterga a F-146.
  • orders_orders.shipping_cents integer NOT NULL DEFAULT 0 separa envío del total (sin sobreescritura: históricos → 0, total_cents intacto).
  • orders_items.cost_at_sale_cents bigint y orders_items.vat_rate text, nullable (snapshots → NULL hasta poblados; margen/IVA-por-tipo permanecen unavailable, nunca 0).
  • up() idempotente: ADD COLUMN IF NOT EXISTS (PG>=9.6) + DO $$ IF NOT EXISTS ... $$ guard para el FK (PG16 no admite ADD CONSTRAINT IF NOT EXISTS). down() reversible (índice/constraint/columnas).

Files

  • project/migrations/048_reporting_store_shipping_snapshots.js (created) — up/down idempotent/reversible. El FK usa DO $$ guard (convención 047/046) tras confirmar via psql que el bloque DO es SQL válido en PG16.15.
  • project/src/app/tests/reporting-snapshots.itest.ts (created) — recrea la DB (drop+recreate), migra 001→048, verifica schema vía information_schema/pg_constraint/pg_indexes, e inserta revertindo el CHECK de 047.

Tests

  • NEW reporting-snapshots.itest.ts (3, real PostgreSQL): AC1 (store_id col NOT NULL + DEFAULT + FK contype='f' + índice + INSERT backfill store_id=DEFAULT_STORE_ID), AC2 (shipping_cents NOT NULL DEFAULT 0 + backfill=0), AC3 (cost_at_sale_cents bigint nullable / vat_rate text nullable).
    • Adaptación: el INSERT usa INSERT INTO orders_orders (source) VALUES ('pos') en lugar de DEFAULT VALUES porque el CHECK de 047 (source='pos' OR user_id IS NOT NULL) rechaza una fila 100% NULL; store_id/shipping_cents siguen backfilliándose por el column DEFAULT → el intento de AC1/AC2 se verifica.

Verification

  • Migration 048 applies clean (dev + test DB): node-pg-migrate up --verbose → "Migrations complete!"; 048_reporting_store_shipping_snapshots (UP) log; columns/FK/index presentes en mercadodevida dev. (Raw psql confirmó el DO-block FK válido en PG16.15.)
  • TEST_DATABASE_URL=... npx vitest run src/app/tests/reporting-snapshots.itest.ts3 passed, 0 skipped, exit 0 (crea DB, migra 048, verifica todo).
  • npx tsc --noEmit0 errors (incluye el itest .ts; estricto, noUncheckedIndexedAccess).
  • node scripts/check-module-boundaries.mjs src0 NEW violations (única infracción R1 preexistente security.routes.ts → log-broadcaster, no introducida por F-144, fuera del diff).
  • ./scripts/verify.sh → green (F-144 in_progress, runtime-consistent; 270 features válidos).
  • Re-run up() idempotente → no-op (DDL IF NOT EXISTS + DO guard); down() revierte todo.

AC traceability

AC Estado Evidencia
AC1 store_id NOT NULL + DEFAULT + FK + idx + backfill itest col/is_nullable=NO/default+FK contype='f'+índice+INSERT backfill
AC2 shipping_cents NOT NULL DEFAULT 0 itest col + INSERT backfill=0
AC3 cost_at_sale/vat_rate nullable itest is_nullable=YES en orders_items
AC4 idempotent/reversible IF NOT EXISTS + DO guard; down() drops all (PG16 raw check válida DO-block)
AC5 itest DB 3/3 (dev + test DB fresh)
AC6 gates tsc 0; itest 3/3; 0 boundaries nuevas
AC7 no regressión orders_orders INSERT sin store_id explícito sigue válido (column DEFAULT)