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

41 lines
2.2 KiB
Markdown

# F-144 — Architecture decision record
## Context
REPORTING_ARCHITECTURE.md §5 lista los *snapshots* mínimos necesarios para
reportar ventas multi-tienda sin reescribir historia. `orders_orders` carece de
`store_id` (§5.1 riesgo #1), no separa envío de `total_cents` (§5.6) y
`orders_items` no guarda `cost_at_sale_cents`/`vat_rate` snapshots (§5.2, §5.9).
## Decision
Una migración idempotente `048_*` añade las columnas de *snapshot* como columnas
nuevas de tabla:
- `orders_orders.store_id uuid NOT NULL DEFAULT <default store>` con FK →
`pos_stores(id)` VALID. El default store (`00000000-0000-0000-0000-000000000001`)
está sembrado por `043_pos_basics` (ON CONFLICT), por lo que el backfill de
filas existentes y los inserts futuros sin store_id heredan el default sin un
`UPDATE` table-scan ni toque en el app-layer. La resolución explícita de tienda
por request se posterga a F-146 (writes app-layered).
- `orders_orders.shipping_cents integer NOT NULL DEFAULT 0` separa el envío del
total (nunca sobreescritura: filas históricas pasan a 0, `total_cents` intacto).
- `orders_items.cost_at_sale_cents bigint` y `orders_items.vat_rate text`, ambos
**nullable**: snapshots que quedan `NULL` hasta poblados (margen/IVA-por-tipo
permanecen `unavailable`, nunca 0 — §10/§4 F-143).
## Consequences
- Positivas: columna `DEFAULT` evita table rewrite y mantiene `PgOrderRepository`
(raw `INSERT INTO orders_orders (...)`) 100% compatible → cero regresión en
checkout/orders itests; el default store existe al subir la migración (043
precede a 048) → FK VALID siempre tiene un target válido.
- Nuevas limitaciones: `store_id` no se resuelve por request en F-144 (usa el
default); `cost_at_sale_cents`/`vat_rate` quedan NULL (población en F-146).
Ambas son explícitas en `dataAvailability` del reporting contract (F-143).
- Reversible: `down()` elimina índice/FK/columnas; idempotente vía `IF NOT
EXISTS`/`DO $$`.
## Evidence of design
- `orders_orders` esquema actual (16 columnas, sin store_id/shipping_cents) —
inspeccionado en `mercadodevida` dev DB.
- `pos_stores` default store sembrado por 043; `DEFAULT_STORE_ID` reutilizado desde
`src/modules/inventory/index.ts`.