PRD §2.3 + §10. Implements the dual-write rule (load-bearing
complexity per PRD §10): project-backed scenarios mirror flag
toggles to paliad.projects.scenario_flags and filed event states
to paliad.deadlines, while kontextfrei scenarios continue writing
only to paliad.scenario_events. Visible affordances: page-header
Akte picker, enabled "Aus Akte" mode tab, Akte banner on the
project-backed canvas, cross-surface scenario-flag-changed
dispatch + listener for live peer-surface coherence.
Backend
- ScenarioBuilderService takes ProjectService + ScenarioFlagsService
deps so dual-write hits live tables.
- CreateScenarioFromProject seeds a scenario from a project: copies
proceeding_type_id + scenario_flags, normalises our_side to the
builder's binary claimant|defendant axis, surfaces existing
rule-bound deadlines as scenario_events (filed when completed,
planned otherwise).
- PatchProceeding on a project-backed top-level triplet dual-writes
scenario_flags to projects.scenario_flags via flagDeltaFromBuilder.
- PatchEvent transitioning to state='filed' on a project-backed
scenario upserts paliad.deadlines (status='completed', completed_
at, source='rule') inside the same tx as the scenario_events
UPDATE — canvas and project surfaces never diverge mid-flight.
- POST /api/builder/scenarios/from-project handler wires the entry
point.
Frontend
- builder-akte.ts: project list fetch + dropdown render, Akte
banner, createScenarioFromProject POST helper.
- builder.ts: mode branching — picking an Akte (search hit or
page-header pick) creates a project-backed scenario and loads it;
loaded scenarios reflect their origin_project_id on the picker +
banner; flag toggles on Akte-backed top-level triplets dispatch
scenario-flag-changed so the Verfahrensablauf strip / project
surfaces refresh; the builder listens to inbound scenario-flag-
changed and refetches its scenario when the changed project
matches origin_project_id.
- procedures.tsx: enable the previously-disabled Aus Akte tab.
- i18n + CSS: builder.akte.banner.prefix key (DE+EN); lime-tinted
banner styling.
Tests
- TestScenarioBuilderAkteDualWrite (live DB) pins the dual-write
contract: Akte flag toggle → projects.scenario_flags updated,
Akte filed event → deadlines row inserted; kontextfrei flag
toggle leaves projects.scenario_flags untouched, kontextfrei
filed event leaves deadlines untouched.
- Existing TestScenarioBuilderService passes against the new
signature (nil deps short-circuit dual-write paths).
Verification: go test ./... + go vet ./... + bun run build all
clean. Playwright smoke against the static dist build confirms
the Akte tab + picker render correctly, fetchAkteProjects fires
on mount, and the scenario-flag-changed CustomEvent dispatches +
receives without runtime errors.
t-paliad-347