Files
paliad/internal/db/migrations/161_composer_caption_parametric.down.sql
mAi b99b6d6fb5 feat(submissions): parametric caption.* keys — unify Rubrum across all render paths (t-paliad-358 A-S2)
Promotes the case caption (Rubrum) to ONE parametric set of resolver keys
(caption.*) consumed identically by every render path, so the wording no
longer diverges per path and reflects the forum.

New caption.* keys (addCaptionVars, submission_vars.go), each in bare +
_de + _en forms (bare resolves to the draft language):
  caption.heading · caption.claimant_designation · caption.defendant_designation
  caption.versus · caption.subject

Parametrised from data already in the bag — NO new schema:
  - designations reuse the proceeding-type role-label overrides (mig 137:
    upc.apl.unified→Berufungskläger, upc.rev.cfi→Antragsteller (Nichtigkeit),
    epa.opp.*→Einsprechende(r)/Patentinhaber(in)); else instance-derived
    appeal/cassation (project.instance_level); else civil default Klägerin/
    Beklagte // Claimant/Defendant.
  - heading + subject from jurisdiction + the dotted code's nature segment
    (inf→"In dem Rechtsstreit"/"Patentverletzung", null→"In der
    Patentnichtigkeitssache", UPC→"In der Sache"/"In the matter",
    opp→"Im Einspruchsverfahren").
Also exposes project.proceeding.jurisdiction.

All three render paths now reference the SAME keys:
  1. docx.BuildFallbackSkeleton (merge fallback) — heading/designations/versus/
     wegen-subject are {{caption.*}} placeholders.
  2. demo per-code template de.inf.lg.erwidg.docx (mWorkRepo) — regenerated via
     scripts/gen-demo-submission-template; caption wired to caption.*; closing
     drops the duplicate {{firm.name}} line (now carried by signature_block).
     Pushed to HL/mWorkRepo as mAi (commit 3682299).
  3. Composer caption seeds — mig 161 rewrites the caption section seed_md of
     all 4 bases (hlc-letterhead, neutral, lg-duesseldorf, upc-formal) to the
     parametric form (position-independent jsonb_agg patch; reversible down).

our_side is intentionally NOT a caption driver — the caption designates both
parties by procedural role regardless of which side we act for.

Tests: resolveCaption forum matrix (DE-LG/BPatG/UPC/role-label/instance-appeal/
EPA-opp), bare-resolves-to-lang, fallback skeleton renders caption.* keys.
mig 161 passes TestMigrations_DryRun. go vet ./... + bun build clean; all
touched packages green (the live approval/migration_136 failures are
pre-existing shared-DB env issues, unrelated).

LEXY-REVIEW FLAGS in the report — DE caption conventions are practitioner
convention, not in the youpc corpus; specific wordings flagged for sign-off.
2026-06-01 12:59:29 +02:00

56 lines
4.4 KiB
SQL

-- Revert t-paliad-358 A-S2: restore each base's original (pre-parametric)
-- caption seed_md from migrations 146 / 150, verbatim. One UPDATE per slug
-- because the originals differed per base.
-- hlc-letterhead (mig 146): heading + parties with "vertreten durch" + court.
UPDATE paliad.submission_bases AS b
SET section_spec = jsonb_set(b.section_spec, '{defaults}', (
SELECT jsonb_agg(
CASE WHEN elem->>'section_key' = 'caption'
THEN elem || jsonb_build_object(
'seed_md_de', E'In der Sache\n\n**{{parties.claimant.0.name}}**\nvertreten durch {{parties.claimant.0.representative}}\n\n— Klägerin —\n\ngegen\n\n**{{parties.defendant.0.name}}**\nvertreten durch {{parties.defendant.0.representative}}\n\n— Beklagte —\n\nAktenzeichen: {{project.case_number}}\n{{project.court}}',
'seed_md_en', E'In the matter\n\n**{{parties.claimant.0.name}}**\nrepresented by {{parties.claimant.0.representative}}\n\n— Claimant —\n\nv.\n\n**{{parties.defendant.0.name}}**\nrepresented by {{parties.defendant.0.representative}}\n\n— Defendant —\n\nCase number: {{project.case_number}}\n{{project.court}}')
ELSE elem END
ORDER BY ord)
FROM jsonb_array_elements(b.section_spec->'defaults') WITH ORDINALITY AS d(elem, ord)))
WHERE b.slug = 'hlc-letterhead' AND b.section_spec ? 'defaults';
-- neutral (mig 146): heading + parties (no representative) + Aktenzeichen, no court.
UPDATE paliad.submission_bases AS b
SET section_spec = jsonb_set(b.section_spec, '{defaults}', (
SELECT jsonb_agg(
CASE WHEN elem->>'section_key' = 'caption'
THEN elem || jsonb_build_object(
'seed_md_de', E'In der Sache\n\n**{{parties.claimant.0.name}}**\n— Klägerin —\n\ngegen\n\n**{{parties.defendant.0.name}}**\n— Beklagte —\n\nAktenzeichen: {{project.case_number}}',
'seed_md_en', E'In the matter\n\n**{{parties.claimant.0.name}}**\n— Claimant —\n\nv.\n\n**{{parties.defendant.0.name}}**\n— Defendant —\n\nCase number: {{project.case_number}}')
ELSE elem END
ORDER BY ord)
FROM jsonb_array_elements(b.section_spec->'defaults') WITH ORDINALITY AS d(elem, ord)))
WHERE b.slug = 'neutral' AND b.section_spec ? 'defaults';
-- lg-duesseldorf (mig 150): heading + parties (no representative) + court.
UPDATE paliad.submission_bases AS b
SET section_spec = jsonb_set(b.section_spec, '{defaults}', (
SELECT jsonb_agg(
CASE WHEN elem->>'section_key' = 'caption'
THEN elem || jsonb_build_object(
'seed_md_de', E'In der Sache\n\n**{{parties.claimant.0.name}}**\n— Klägerin —\n\ngegen\n\n**{{parties.defendant.0.name}}**\n— Beklagte —\n\nAktenzeichen: {{project.case_number}}\n{{project.court}}',
'seed_md_en', E'In the matter\n\n**{{parties.claimant.0.name}}**\n— Claimant —\n\nv.\n\n**{{parties.defendant.0.name}}**\n— Defendant —\n\nCase number: {{project.case_number}}\n{{project.court}}')
ELSE elem END
ORDER BY ord)
FROM jsonb_array_elements(b.section_spec->'defaults') WITH ORDINALITY AS d(elem, ord)))
WHERE b.slug = 'lg-duesseldorf' AND b.section_spec ? 'defaults';
-- upc-formal (mig 150): UPC heading + parties with "represented by" + UPC case number + patent.
UPDATE paliad.submission_bases AS b
SET section_spec = jsonb_set(b.section_spec, '{defaults}', (
SELECT jsonb_agg(
CASE WHEN elem->>'section_key' = 'caption'
THEN elem || jsonb_build_object(
'seed_md_de', E'# In the matter\n\n**{{parties.claimant.0.name}}**\nrepresented by {{parties.claimant.0.representative}}\n— Claimant —\n\nv.\n\n**{{parties.defendant.0.name}}**\nrepresented by {{parties.defendant.0.representative}}\n— Defendant —\n\nUPC-Aktenzeichen: {{project.case_number}}\nStreitpatent: {{project.patent_number_upc}}',
'seed_md_en', E'# In the matter\n\n**{{parties.claimant.0.name}}**\nrepresented by {{parties.claimant.0.representative}}\n— Claimant —\n\nv.\n\n**{{parties.defendant.0.name}}**\nrepresented by {{parties.defendant.0.representative}}\n— Defendant —\n\nUPC case number: {{project.case_number}}\nPatent in suit: {{project.patent_number_upc}}')
ELSE elem END
ORDER BY ord)
FROM jsonb_array_elements(b.section_spec->'defaults') WITH ORDINALITY AS d(elem, ord)))
WHERE b.slug = 'upc-formal' AND b.section_spec ? 'defaults';