-- mig 113 — t-paliad-222 / m/paliad#50 — auto-derived project codes.
--
-- Adds an opponent-code slug field on litigation projects. Used as
-- the middle segment when BuildProjectCode assembles an auto-derived
-- project code from the ancestor tree (e.g. EXMPL.OPNT.567.INF.CFI).
--
-- NULL = segment skipped silently. Existing litigation rows yield
-- codes without an opponent segment until the user fills the field.
-- No backfill from `title` — the litigation title is free-text
-- ("Siemens AG ./. Huawei", "Mandant vs Gegner") and any regex would
-- be brittle; the user enters the slug once at project creation /
-- next edit.
--
-- Slug shape: uppercase letters / digits / dashes, max 16 chars.
-- Constraint also gates on type='litigation' so a stray value on a
-- non-litigation row is rejected at the DB level (defence in depth;
-- the form already hides the field on other types).
--
-- Idempotent.

BEGIN;

ALTER TABLE paliad.projects
    ADD COLUMN IF NOT EXISTS opponent_code text;

DO $$
BEGIN
    IF NOT EXISTS (
        SELECT 1 FROM pg_constraint
         WHERE conname  = 'projects_opponent_code_check'
           AND conrelid = 'paliad.projects'::regclass
    ) THEN
        ALTER TABLE paliad.projects
            ADD CONSTRAINT projects_opponent_code_check
            CHECK (opponent_code IS NULL
                OR (opponent_code ~ '^[A-Z0-9-]{1,16}$'
                    AND type = 'litigation'));
    END IF;
END $$;

COMMENT ON COLUMN paliad.projects.opponent_code IS
    'Short slug for the opposing party on a litigation project '
    '(uppercase letters, digits, dashes, max 16 chars). Used as the '
    'middle segment when BuildProjectCode walks the ancestor tree to '
    'assemble a dotted project code — e.g. EXMPL.OPNT.567.INF.CFI '
    '(t-paliad-222 / m/paliad#50). NULL = segment skipped silently. '
    'Only meaningful on type=''litigation'' rows; the CHECK enforces '
    'that pairing.';

COMMIT;
