/** * Commercial bounded context, first slice: products (sellable catalog * items) — Master Prompt §6.3, eden.md §2 §1.1. MVP scope only: the shape * below ports the legacy `products` table's core identity/pricing/flag * columns faithfully (product_code sequence, the 5 fixed price tiers, * impl_unit_price), but deliberately leaves out service_type/metered/ * tariff_rates/ixc_product_code — those are legacy telecom-billing * specifics that belong to a later phase, not invented here. `product_type` * is free text for now (no CHECK) since the enum of types isn't finalized; * tightening it to a CHECK/lookup table is future work once Quotes needs * to branch behavior on it. * * Quotes/pricing-tier selection logic is explicitly out of scope here — * this migration only stores the data, it computes nothing. */ exports.shorthands = undefined; exports.up = (pgm) => { pgm.sql(` CREATE SEQUENCE products_product_code_seq START 1; CREATE TABLE products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), created_by UUID REFERENCES users(id), product_code INTEGER NOT NULL UNIQUE DEFAULT nextval('products_product_code_seq'), name TEXT NOT NULL, description TEXT, product_type TEXT NOT NULL, product_group TEXT, product_subgroup TEXT, brand TEXT, unit TEXT NOT NULL DEFAULT 'unidade', active BOOLEAN NOT NULL DEFAULT true, discontinued BOOLEAN NOT NULL DEFAULT false, tracks_stock BOOLEAN NOT NULL DEFAULT false, tracks_serial BOOLEAN NOT NULL DEFAULT false, tracks_asset_tag BOOLEAN NOT NULL DEFAULT false, tracks_mac BOOLEAN NOT NULL DEFAULT false, price_0 NUMERIC(12,2), price_12 NUMERIC(12,2), price_24 NUMERIC(12,2), price_36 NUMERIC(12,2), price_48 NUMERIC(12,2), impl_unit_price NUMERIC(12,2) NOT NULL DEFAULT 0 ); COMMENT ON TABLE products IS 'Catálogo de produtos vendáveis — eden.md §2 §1.1, Master Prompt §6.3. product_code é a sequência legada (distinta do UUID); price_0/12/24/36/48 são as 5 faixas fixas de preço por período de fidelidade, não uma tabela relacionada. Leitura aberta a qualquer autenticado (catálogo precisa ser navegável por qualquer vendedor); escrita restrita à permissão products:edit.'; COMMENT ON COLUMN products.impl_unit_price IS 'Valor de implantação por unidade, multiplicado pela quantidade do item na oferta (fase futura — Quotes). NUMERIC sempre, nunca float.'; CREATE TRIGGER trg_products_updated_at BEFORE UPDATE ON products FOR EACH ROW EXECUTE FUNCTION set_updated_at(); CREATE INDEX idx_products_active ON products(active); ALTER SEQUENCE products_product_code_seq OWNED BY products.product_code; `); }; exports.down = (pgm) => { pgm.sql(` DROP TABLE IF EXISTS products; DROP SEQUENCE IF EXISTS products_product_code_seq; `); };