124 lines
4.6 KiB
PL/PgSQL
124 lines
4.6 KiB
PL/PgSQL
-- Durable Booking Excel extraction drafts and item-level human review.
|
|
-- PostgreSQL 15+. Migrations 008-014 remain immutable.
|
|
|
|
BEGIN;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF current_database() <> 'booking_test' THEN
|
|
RAISE EXCEPTION
|
|
'ARR Booking review migration is allowed only in booking_test';
|
|
END IF;
|
|
IF to_regclass('booking.current_source_batch') IS NULL
|
|
OR to_regclass('booking.room_items') IS NULL
|
|
OR to_regclass('ingestion.artifacts') IS NULL THEN
|
|
RAISE EXCEPTION
|
|
'ARR migrations 008 through 014 must be applied first';
|
|
END IF;
|
|
IF to_regclass('booking.extraction_drafts') IS NOT NULL
|
|
OR to_regclass('booking.extraction_draft_items') IS NOT NULL THEN
|
|
RAISE EXCEPTION
|
|
'ARR Booking review migration is already applied';
|
|
END IF;
|
|
END;
|
|
$$;
|
|
|
|
CREATE TABLE booking.extraction_drafts (
|
|
draft_id text PRIMARY KEY CHECK (
|
|
draft_id ~ '^bookingdraft-[0-9a-f]{32}$'
|
|
),
|
|
source_artifact_id bigint NOT NULL UNIQUE
|
|
REFERENCES ingestion.artifacts(id),
|
|
draft_status text NOT NULL CHECK (
|
|
draft_status IN ('reviewing', 'activated', 'superseded')
|
|
),
|
|
processor_version text NOT NULL CHECK (btrim(processor_version) <> ''),
|
|
rule_set_sha256 character(64) NOT NULL CHECK (
|
|
rule_set_sha256 ~ '^[0-9a-f]{64}$'
|
|
),
|
|
source_sha256 character(64) NOT NULL CHECK (
|
|
source_sha256 ~ '^[0-9a-f]{64}$'
|
|
),
|
|
source_byte_size bigint NOT NULL CHECK (source_byte_size > 0),
|
|
source_rows integer NOT NULL CHECK (source_rows > 0),
|
|
worksheet_count integer NOT NULL CHECK (worksheet_count > 0),
|
|
distinct_group_codes integer NOT NULL CHECK (distinct_group_codes > 0),
|
|
extracted_items integer NOT NULL CHECK (extracted_items > 0),
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
activated_source_batch_id bigint UNIQUE
|
|
REFERENCES booking.source_batches(id),
|
|
activated_at timestamptz,
|
|
CONSTRAINT extraction_drafts_status_shape CHECK (
|
|
(
|
|
draft_status = 'reviewing'
|
|
AND activated_source_batch_id IS NULL
|
|
AND activated_at IS NULL
|
|
)
|
|
OR (
|
|
draft_status = 'activated'
|
|
AND activated_source_batch_id IS NOT NULL
|
|
AND activated_at IS NOT NULL
|
|
)
|
|
OR (
|
|
draft_status = 'superseded'
|
|
AND activated_source_batch_id IS NULL
|
|
AND activated_at IS NULL
|
|
)
|
|
)
|
|
);
|
|
|
|
CREATE INDEX extraction_drafts_status_created_idx
|
|
ON booking.extraction_drafts (draft_status, created_at DESC);
|
|
|
|
CREATE TABLE booking.extraction_draft_items (
|
|
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
draft_id text NOT NULL
|
|
REFERENCES booking.extraction_drafts(draft_id),
|
|
source_worksheet text NOT NULL CHECK (btrim(source_worksheet) <> ''),
|
|
source_row_no integer NOT NULL CHECK (source_row_no > 0),
|
|
item_no integer NOT NULL CHECK (item_no > 0),
|
|
group_code_raw text NOT NULL CHECK (btrim(group_code_raw) <> ''),
|
|
group_code_key text GENERATED ALWAYS AS (
|
|
upper(btrim(group_code_raw))
|
|
) STORED,
|
|
hotel_raw text NOT NULL CHECK (btrim(hotel_raw) <> ''),
|
|
room_type_raw text NOT NULL CHECK (btrim(room_type_raw) <> ''),
|
|
room_type_code text CHECK (
|
|
room_type_code IS NULL OR btrim(room_type_code) <> ''
|
|
),
|
|
quantity integer NOT NULL CHECK (quantity BETWEEN 1 AND 9999),
|
|
review_status text NOT NULL CHECK (
|
|
review_status IN ('confirmed', 'pending', 'deleted')
|
|
),
|
|
automatic boolean NOT NULL,
|
|
source_fragment text NOT NULL DEFAULT '',
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
CONSTRAINT extraction_draft_items_position_unique UNIQUE (
|
|
draft_id,
|
|
source_worksheet,
|
|
source_row_no,
|
|
item_no
|
|
),
|
|
CONSTRAINT extraction_draft_items_review_shape CHECK (
|
|
(review_status = 'confirmed' AND room_type_code IS NOT NULL)
|
|
OR (review_status = 'pending' AND room_type_code IS NULL)
|
|
OR review_status = 'deleted'
|
|
)
|
|
);
|
|
|
|
CREATE INDEX extraction_draft_items_draft_status_idx
|
|
ON booking.extraction_draft_items (draft_id, review_status, id);
|
|
|
|
CREATE INDEX extraction_draft_items_group_idx
|
|
ON booking.extraction_draft_items (draft_id, group_code_key);
|
|
|
|
COMMENT ON TABLE booking.extraction_drafts IS
|
|
'Private Booking Excel extraction drafts. A reviewing draft never changes the active accepted Booking source.';
|
|
|
|
COMMENT ON TABLE booking.extraction_draft_items IS
|
|
'Editable extracted room items. Pending items are excluded until confirmed; deleted items remain audit-visible.';
|
|
|
|
COMMIT;
|