Commit Graph

1 Commits

Author SHA1 Message Date
mAi
75833082fc feat(db): mig 136 — additive procedural_events / sequencing_rules / legal_sources tables (Slice B.1, t-paliad-273 / m/paliad#93)
Some checks failed
Paliad CI gate / build (push) Has been cancelled
Paliad CI gate / test-go (push) Has been cancelled
Paliad CI gate / deploy (push) Has been cancelled
Creates the three new tables that split today's paliad.deadline_rules
into its three latent concepts, plus two nullable link columns on
paliad.deadlines for B.2 dual-write.

ADDITIVE ONLY. paliad.deadline_rules is untouched. deadlines.rule_id
stays in place — it remains the authoritative deadline → rule link
until B.3 cutover flips reads and B.4 drops the legacy table.

* paliad.legal_sources        — distinct citations (87 rows backfilled).
                                pretty_de/pretty_en deferred (Go
                                legalSourcePretty still computes them
                                on read; future slice backfills).
* paliad.procedural_events    — 153 rows from distinct submission_codes
                                + 78 synthetic-code rows for the
                                NULL-submission_code branch (m's pick
                                via paliadin 2026-05-26: mint
                                'null.<8hex>' codes so every rule row
                                has a procedural event, preserving the
                                NOT NULL FK on sequencing_rules).
* paliad.sequencing_rules     — 1:1 with deadline_rules (231 rows). id
                                inherited from deadline_rules.id so any
                                existing deadlines.rule_id FK resolves
                                transitively to the new sequencing_rule
                                during the dual-write window.
* paliad.deadlines.procedural_event_id, sequencing_rule_id (nullable,
                                backfilled by JOIN on the inherited id).

Audit-first pattern (mirrors mig 135): PRE pass counts what we're about
to backfill + refuses to run if multi-row submission_codes have crept
back in (B.0 found zero; the assertion guards against a future
re-archival or rule-editor bug). POST pass asserts the four
invariants — procedural_events count, sequencing_rules 1:1,
legal_sources distinct-citation match, FK integrity — and RAISE
EXCEPTIONs on any mismatch so the transaction rolls back cleanly.

Design deviations from §4.1 (documented in the migration header):
- procedural_events.event_kind is NULLABLE. 89 live rules have NULL
  event_type today (structural / parent-only rows in the proceeding
  tree). Tightening to NOT NULL with 'other' fallback would lose
  semantics; a later slice can do it after reclassification.
- legal_sources.pretty_de / pretty_en are NULLABLE. Materialising them
  requires the Go-side legalSourcePretty(); deferred to a Go-driven
  slice. Read path keeps computing them from the citation in the
  meantime.
- submission_drafts is NOT modified (instruction scope is explicit:
  tables + deadlines columns only).

Down migration: drops the two deadlines columns first, then
sequencing_rules → procedural_events → legal_sources in FK-safe
order. No data loss possible (deadline_rules is the source of truth
through B.3).

Test: internal/db/migration_136_test.go restates the four
invariants in Go so they survive PL/pgSQL refactors. Skipped without
TEST_DATABASE_URL.

Verified on live (read-only): 153 distinct codes + 78 distinct
synthetic-code candidates = 231 = deadline_rules row count. 87
distinct legal_sources. Zero 8-hex synthetic-code collisions in the
live UUIDs.

Hard-stop: B.2 dual-write requires explicit m greenlight before
RuleEditorService starts writing to the new tables. B.4 destructive
drop additionally requires m's downtime window + a
paliad.deadline_rules_pre_<N> snapshot in the same migration.
2026-05-26 15:12:12 +02:00