feat(t-paliad-265): projection engine + HTTP handlers for per-card choices

m/paliad#96 — slice A engine + slice B engine wired together (per
m's Q4 bundling decision in §11 of the design doc).

Engine (internal/services/fristenrechner.go):
- CalcOptions gains PerCardAppellant map, SkipRules set, IncludeCCRFor
  set. All three keyed by paliad.deadline_rules.submission_code (same
  key AnchorOverrides uses).
- UIDeadline gains AppellantContext (per-decision pick that propagates
  to descendants via parent_id chain) + ChoicesOffered (passes the
  jsonb through to the frontend so the caret renders).
- Calculate honours all three:
  * IncludeCCRFor non-empty → append with_ccr to flag set before gate
    evaluation (v1 simplification documented in CalcOptions comment;
    correct for single-CCR-entry-point proceedings).
  * SkipRules suppression via submission_code match AND parent_id
    cascade (descendants suppress too — one-pass walk in sequence_order).
  * AppellantContext: each rule with its own per-card pick stamps its
    UUID; descendants inherit via parent_id lookup; "" = no override.

HTTP:
- /api/projects/{id}/event-choices GET / PUT / DELETE — full CRUD
  with visibility gate, audit-logged via paliad.system_audit_log.
- POST /api/tools/fristenrechner accepts either projectId (server
  pulls choices from project_event_choices) OR inline perCardChoices
  (unbound /tools/verfahrensablauf surface). Inline wins when both.

Services wiring:
- EventChoiceService instantiated in cmd/server/main.go; threaded into
  handlers.dbServices.eventChoice.
This commit is contained in:
mAi
2026-05-25 16:45:21 +02:00
parent dc47ea7f43
commit bf60fc1400
6 changed files with 275 additions and 9 deletions

View File

@@ -218,6 +218,8 @@ func main() {
// is captured into __meta of every export and printed in the
// embedded README.
Export: services.NewExportService(pool, branding.Name),
// t-paliad-265 / m/paliad#96 — per-event-card optional choices.
EventChoice: services.NewEventChoiceService(pool, projectSvc, users),
}
// t-paliad-246 Slice A — Backup Mode runner. Wired only when