Files
wyndham-ARR/database/006_report_channel_manifest.sql
2026-07-29 16:38:05 +08:00

167 lines
5.4 KiB
PL/PgSQL

-- Deterministic monthly-report worksheet manifest
-- PostgreSQL 15+
-- Target database: booking_test (connect to that database before running).
-- Additive migration; do not edit applied migrations 001-005 in place.
BEGIN;
CREATE TABLE finance.report_channel_manifest (
report_version_id bigint NOT NULL
REFERENCES finance.report_versions(id),
worksheet text NOT NULL CHECK (
btrim(worksheet) <> ''
AND char_length(worksheet) <= 31
),
worksheet_order integer NOT NULL CHECK (worksheet_order > 0),
row_count integer NOT NULL CHECK (row_count >= 0),
PRIMARY KEY (report_version_id, worksheet),
CONSTRAINT report_channel_manifest_order_unique
UNIQUE (report_version_id, worksheet_order)
);
COMMENT ON TABLE finance.report_channel_manifest IS
'Exact worksheet names, one-based order, and row counts for one immutable monthly-channel report artifact; empty worksheets are retained with row_count zero.';
CREATE OR REPLACE FUNCTION finance.validate_report_channel_manifest_parent()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF NOT EXISTS (
SELECT 1
FROM finance.report_versions AS report
WHERE report.id = NEW.report_version_id
AND report.report_kind = 'monthly_channel'
) THEN
RAISE EXCEPTION
'channel manifest must reference a monthly_channel report';
END IF;
RETURN NEW;
END;
$$;
CREATE TRIGGER report_channel_manifest_parent_guard
BEFORE INSERT OR UPDATE ON finance.report_channel_manifest
FOR EACH ROW
EXECUTE FUNCTION finance.validate_report_channel_manifest_parent();
-- Controlled backfill for the already-verified July 2026 monthly artifact in
-- booking_test. On a clean deployment this inserts zero rows. If another
-- current legacy monthly report exists, the guard below aborts the migration
-- so its sheet order can be inspected rather than guessed.
WITH verified_legacy_report AS (
SELECT report.id
FROM finance.report_versions AS report
JOIN booking.file_objects AS artifact
ON artifact.id = report.artifact_file_id
WHERE report.report_kind = 'monthly_channel'
AND report.period_start = DATE '2026-07-01'
AND report.period_end = DATE '2026-07-31'
AND report.as_of_date = DATE '2026-07-26'
AND report.company_scope = '*'
AND report.report_status = 'active'
AND report.is_current
AND artifact.file_kind = 'monthly_xlsx'
AND artifact.sha256 =
'592fee9b1e3e8290ed1e115d7eb213f09e780fa2bda08f6e270a34e7eaedd09f'
), manifest(worksheet, worksheet_order, row_count) AS (
VALUES
('LIANTAI-GROUP', 1, 195),
('LIANTAI-FIT', 2, 275),
('QBD', 3, 258),
('DY-AI-Easy-KB', 4, 74),
('FENGRUN', 5, 41),
('T- HANATOUR TD CO., L', 6, 24)
)
INSERT INTO finance.report_channel_manifest (
report_version_id, worksheet, worksheet_order, row_count
)
SELECT legacy.id, manifest.worksheet, manifest.worksheet_order, manifest.row_count
FROM verified_legacy_report AS legacy
CROSS JOIN manifest;
DO $$
BEGIN
IF EXISTS (
SELECT 1
FROM finance.report_versions AS report
WHERE report.report_kind = 'monthly_channel'
AND report.report_status = 'active'
AND report.is_current
AND NOT EXISTS (
SELECT 1
FROM finance.report_channel_manifest AS manifest
WHERE manifest.report_version_id = report.id
)
) THEN
RAISE EXCEPTION
'current legacy monthly report requires an inspected channel manifest';
END IF;
END;
$$;
CREATE OR REPLACE FUNCTION finance.protect_published_report_channel_manifest()
RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
target_report_version_id bigint;
BEGIN
target_report_version_id := CASE
WHEN TG_OP = 'DELETE' THEN OLD.report_version_id
ELSE NEW.report_version_id
END;
IF EXISTS (
SELECT 1
FROM finance.report_versions AS report
WHERE report.id = target_report_version_id
AND report.report_status IN ('active', 'superseded')
) THEN
RAISE EXCEPTION
'published monthly report channel manifest is immutable';
END IF;
RETURN CASE WHEN TG_OP = 'DELETE' THEN OLD ELSE NEW END;
END;
$$;
CREATE TRIGGER published_report_channel_manifest_guard
BEFORE INSERT OR UPDATE OR DELETE ON finance.report_channel_manifest
FOR EACH ROW
EXECUTE FUNCTION finance.protect_published_report_channel_manifest();
CREATE OR REPLACE FUNCTION finance.validate_monthly_report_channel_manifest()
RETURNS trigger
LANGUAGE plpgsql
AS $$
DECLARE
manifest_count integer;
first_order integer;
last_order integer;
BEGIN
IF NEW.report_kind = 'monthly_channel'
AND NEW.report_status = 'active'
AND NEW.is_current THEN
SELECT count(*), min(worksheet_order), max(worksheet_order)
INTO manifest_count, first_order, last_order
FROM finance.report_channel_manifest
WHERE report_version_id = NEW.id;
IF manifest_count = 0
OR first_order <> 1
OR last_order <> manifest_count THEN
RAISE EXCEPTION
'active monthly report requires a continuous channel manifest';
END IF;
END IF;
RETURN NEW;
END;
$$;
CREATE TRIGGER monthly_report_channel_manifest_guard
BEFORE INSERT OR UPDATE OF report_status, is_current
ON finance.report_versions
FOR EACH ROW
EXECUTE FUNCTION finance.validate_monthly_report_channel_manifest();
COMMIT;