-- +goose Up CREATE TABLE procurement_requests ( id TEXT PRIMARY KEY NOT NULL CHECK (length(id) = 36), creator_subject TEXT NOT NULL, freight_order_item_id TEXT NOT NULL REFERENCES freight_order_items(id) ON UPDATE RESTRICT ON DELETE RESTRICT, source_revision INTEGER NOT NULL CHECK (source_revision >= 1), source_sha256 TEXT NOT NULL CHECK ( length(source_sha256) = 64 AND source_sha256 NOT GLOB '*[^0-9a-f]*' ), title TEXT NOT NULL CHECK (length(CAST(title AS BLOB)) <= 2048), product_spec TEXT NOT NULL CHECK (length(CAST(product_spec AS BLOB)) <= 1024), sku TEXT NOT NULL CHECK (length(CAST(sku AS BLOB)) <= 512), quantity INTEGER CHECK (quantity IS NULL OR quantity > 0), source_purchase_status TEXT CHECK ( source_purchase_status IS NULL OR length(CAST(source_purchase_status AS BLOB)) <= 128 ), source_is_canceled INTEGER CHECK ( source_is_canceled IS NULL OR source_is_canceled IN (0, 1) ), procurement_confirmed_by_user_id TEXT NOT NULL REFERENCES users(id) ON UPDATE RESTRICT ON DELETE RESTRICT, procurement_confirmed_at TEXT NOT NULL, status TEXT NOT NULL CHECK ( status IN ( 'BLOCKED', 'NEEDS_IMAGE', 'READY', 'TASK_CREATED', 'SOURCE_CHANGED' ) ), blocking_code TEXT CHECK ( blocking_code IS NULL OR blocking_code IN ( 'SOURCE_CANCELED', 'TITLE_REQUIRED', 'SKU_REQUIRED', 'QUANTITY_REQUIRED', 'SOURCE_CHANGED' ) ), reference_asset_id TEXT UNIQUE REFERENCES assets(id) ON UPDATE RESTRICT ON DELETE RESTRICT, purchase_task_id TEXT UNIQUE REFERENCES purchase_tasks(id) ON UPDATE RESTRICT ON DELETE RESTRICT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE (freight_order_item_id, source_revision), CHECK ( (status = 'BLOCKED' AND blocking_code IS NOT NULL AND reference_asset_id IS NULL AND purchase_task_id IS NULL) OR (status = 'NEEDS_IMAGE' AND blocking_code IS NULL AND reference_asset_id IS NULL AND purchase_task_id IS NULL) OR (status = 'READY' AND blocking_code IS NULL AND reference_asset_id IS NOT NULL AND purchase_task_id IS NULL) OR (status = 'TASK_CREATED' AND blocking_code IS NULL AND reference_asset_id IS NOT NULL AND purchase_task_id IS NOT NULL) OR (status = 'SOURCE_CHANGED' AND blocking_code = 'SOURCE_CHANGED' AND purchase_task_id IS NULL) ) ); CREATE INDEX procurement_requests_creator_updated_idx ON procurement_requests (creator_subject, updated_at DESC, id DESC); CREATE INDEX procurement_requests_item_created_idx ON procurement_requests ( freight_order_item_id, source_revision DESC, id DESC ); CREATE TABLE purchase_task_sources ( task_id TEXT PRIMARY KEY NOT NULL REFERENCES purchase_tasks(id) ON UPDATE RESTRICT ON DELETE RESTRICT, procurement_request_id TEXT NOT NULL UNIQUE REFERENCES procurement_requests(id) ON UPDATE RESTRICT ON DELETE RESTRICT, freight_order_item_id TEXT NOT NULL REFERENCES freight_order_items(id) ON UPDATE RESTRICT ON DELETE RESTRICT, source_revision INTEGER NOT NULL CHECK (source_revision >= 1), source_sha256 TEXT NOT NULL CHECK ( length(source_sha256) = 64 AND source_sha256 NOT GLOB '*[^0-9a-f]*' ), created_at TEXT NOT NULL ); -- +goose Down CREATE TEMP TABLE procurement_v13_down_guard ( allowed INTEGER NOT NULL CHECK (allowed = 1) ); INSERT INTO procurement_v13_down_guard (allowed) SELECT CASE WHEN EXISTS (SELECT 1 FROM procurement_requests) OR EXISTS (SELECT 1 FROM purchase_task_sources) THEN 0 ELSE 1 END; DROP TABLE procurement_v13_down_guard; DROP TABLE purchase_task_sources; DROP INDEX procurement_requests_item_created_idx; DROP INDEX procurement_requests_creator_updated_idx; DROP TABLE procurement_requests;