68 lines
3.4 KiB
JavaScript
68 lines
3.4 KiB
JavaScript
/**
|
|
* F-144 — Reporting snapshots: store_id, shipping_cents, cost & VAT line snapshots
|
|
*
|
|
* Adds the snapshot columns needed to report multi-store sales without
|
|
* rewriting history (REPORTING_ARCHITECTURE.md §5 "store/VAT/cost/shipping"):
|
|
* - orders_orders.store_id -> uuid NOT NULL, FK -> pos_stores, default store.
|
|
* - orders_orders.shipping_cents -> integer NOT NULL DEFAULT 0 (shipping split out).
|
|
* - orders_items.cost_at_sale_cents -> bigint (nullable; NULL until backfilled).
|
|
* - orders_items.vat_rate -> text (nullable snapshot of the VAT key).
|
|
*
|
|
* store_id gets a column DEFAULT of the well-known default store (seeded by
|
|
* migration 043_pos_basics), so both pre-existing rows and new inserts that
|
|
* don't specify a store inherit the default — no full table rewrite, no
|
|
* app-layer change to the order INSERT path. The FK is created with a `DO $$`
|
|
* guard (same idiom as 047/046) because PG16 does not support
|
|
* `ADD CONSTRAINT IF NOT EXISTS`; the guard makes `up` safely re-runnable.
|
|
*
|
|
* Idempotent: columns/index use `IF NOT EXISTS`; the FK is guarded by
|
|
* `DO $$ IF NOT EXISTS ... $$`. Reversible: down() drops everything.
|
|
*
|
|
* @param {import('node-pg-migrate').MigrationBuilder} pgm
|
|
*/
|
|
|
|
// Must match the default-store UUID seeded in 043_pos_basics and exported as
|
|
// DEFAULT_STORE_ID by src/modules/inventory/index.ts.
|
|
const DEFAULT_STORE_ID = '00000000-0000-0000-0000-000000000001';
|
|
|
|
export const up = (pgm) => {
|
|
// ── orders_orders.store_id (NOT NULL + default store; no table rewrite) ──
|
|
// `ADD COLUMN IF NOT EXISTS` is supported (PG>=9.6); existing rows, if any,
|
|
// are backfilled by the DEFAULT, satisfying NOT NULL.
|
|
pgm.sql(`ALTER TABLE orders_orders ADD COLUMN IF NOT EXISTS store_id uuid NOT NULL DEFAULT '${DEFAULT_STORE_ID}'::uuid`);
|
|
|
|
// ── orders_orders.shipping_cents (shipping split out of totals) ─────────
|
|
pgm.sql(`ALTER TABLE orders_orders ADD COLUMN IF NOT EXISTS shipping_cents integer NOT NULL DEFAULT 0`);
|
|
|
|
// ── orders_items line snapshots (nullable — no history rewrite) ──────────
|
|
pgm.sql(`ALTER TABLE orders_items ADD COLUMN IF NOT EXISTS cost_at_sale_cents bigint`);
|
|
pgm.sql(`ALTER TABLE orders_items ADD COLUMN IF NOT EXISTS vat_rate text`);
|
|
|
|
// ── FK to pos_stores (guarded, idempotent; note the ';' after REFERENCES) ──
|
|
pgm.sql(`
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1 FROM pg_constraint
|
|
WHERE conname = 'orders_orders_store_id_fkey'
|
|
) THEN
|
|
ALTER TABLE orders_orders
|
|
ADD CONSTRAINT orders_orders_store_id_fkey
|
|
FOREIGN KEY (store_id) REFERENCES pos_stores(id);
|
|
END IF;
|
|
END $$
|
|
`);
|
|
|
|
// ── supporting index for multi-store + date-range reporting queries ──────
|
|
pgm.sql(`CREATE INDEX IF NOT EXISTS orders_orders_store_id_created_at_idx ON orders_orders (store_id, created_at)`);
|
|
};
|
|
|
|
export const down = (pgm) => {
|
|
pgm.sql(`DROP INDEX IF EXISTS orders_orders_store_id_created_at_idx`);
|
|
pgm.sql(`ALTER TABLE orders_orders DROP CONSTRAINT IF EXISTS orders_orders_store_id_fkey`);
|
|
pgm.sql(`ALTER TABLE orders_items DROP COLUMN IF EXISTS vat_rate`);
|
|
pgm.sql(`ALTER TABLE orders_items DROP COLUMN IF EXISTS cost_at_sale_cents`);
|
|
pgm.sql(`ALTER TABLE orders_orders DROP COLUMN IF EXISTS shipping_cents`);
|
|
pgm.sql(`ALTER TABLE orders_orders DROP COLUMN IF EXISTS store_id`);
|
|
};
|