-- mig 094 — tighten paliad.projects.client_number + matter_number CHECK -- from 7-digit to 6-digit. The "7-Ziffern" rule in mig 018 was wrong; -- HLC's real Client/Matter format is 6 digits each (m's correction, -- 2026-05-17). The constraints carry the legacy 'projekte_*_check' -- name from before the table was renamed (mig 021), so the ALTER -- TABLE DROP / ADD has to use those names verbatim. -- -- Existing rows: only test data (2 client_numbers, 1 matter_number), -- all 7-digit. They violate the new pattern, so we NULL them out -- before tightening — preserving the project rows themselves, just -- clearing the wrong-shaped billing identifiers. The rows are -- snapshotted in projects_pre_094 first so the down migration can -- restore them byte-identically. -- -- audit_reason wrapper at top: the trigger on paliad.projects logs -- every row-level UPDATE; the message persists in the audit table as -- the permanent record of why those test values were cleared. SELECT set_config( 'paliad.audit_reason', 'mig 094: clear test 7-digit client_number/matter_number values before tightening CHECK to 6-digit (HLC real format correction, 2026-05-17)', true); -- ============================================================================= -- 1. Backup snapshot. Full row copy of every paliad.projects row that -- has either field populated. Idempotent via CREATE TABLE IF NOT -- EXISTS — re-running the migration after an aborted run re-uses -- the existing snapshot. -- ============================================================================= CREATE TABLE IF NOT EXISTS paliad.projects_pre_094 AS SELECT *, now() AS snapshotted_at FROM paliad.projects WHERE client_number IS NOT NULL OR matter_number IS NOT NULL; COMMENT ON TABLE paliad.projects_pre_094 IS 'Snapshot of paliad.projects rows that had a client_number or ' 'matter_number set before mig 094 tightened the CHECK from ' '7-digit to 6-digit. The 094 UPDATE NULL-ed those values out ' 'because they were leftover 7-digit test data. Persists as the ' 'permanent audit anchor; the down migration restores from it.'; -- ============================================================================= -- 2. Clear the 7-digit test values. Only rows that already violate -- the new pattern are touched — anything that happens to already -- be 6 digits (none today, but the WHERE keeps the migration -- re-runnable after future inserts) is left alone. -- ============================================================================= UPDATE paliad.projects SET client_number = NULL WHERE client_number IS NOT NULL AND client_number !~ '^[0-9]{6}$'; UPDATE paliad.projects SET matter_number = NULL WHERE matter_number IS NOT NULL AND matter_number !~ '^[0-9]{6}$'; -- ============================================================================= -- 3. Replace the legacy 7-digit CHECKs with 6-digit ones. The -- constraint names carry the pre-rename `projekte_*` prefix from -- mig 018; keep them stable so external audit tools that scan -- pg_constraint by name don't drift. -- ============================================================================= ALTER TABLE paliad.projects DROP CONSTRAINT projekte_client_number_check, DROP CONSTRAINT projekte_matter_number_check; ALTER TABLE paliad.projects ADD CONSTRAINT projekte_client_number_check CHECK (client_number IS NULL OR client_number ~ '^[0-9]{6}$'), ADD CONSTRAINT projekte_matter_number_check CHECK (matter_number IS NULL OR matter_number ~ '^[0-9]{6}$'); -- ============================================================================= -- 4. Hard assertions. Any row that survived the UPDATE+ALTER must -- satisfy the new pattern; the count of cleared test rows must -- match the snapshot. -- ============================================================================= DO $$ DECLARE n_violations int; BEGIN SELECT count(*) INTO n_violations FROM paliad.projects WHERE (client_number IS NOT NULL AND client_number !~ '^[0-9]{6}$') OR (matter_number IS NOT NULL AND matter_number !~ '^[0-9]{6}$'); IF n_violations > 0 THEN RAISE EXCEPTION 'mig 094: % rows still violate the 6-digit pattern after UPDATE — should be 0', n_violations; END IF; RAISE NOTICE 'mig 094: 6-digit CHECKs in place, all rows compliant'; END $$;