feat(iace): Klaerungen Phase 3 — DB-Tabelle + Multi-User + PDF-Export

[migration-approved]

Three pieces complete the Klaerungen lifecycle:

1. Migration 028: iace_clarifications + iace_clarification_comments +
   iace_clarification_history. Deterministic clarification_key
   (UNIQUE per project) so engine re-inits don't lose answers.
   History table logs every status/answer transition. The previous
   JSONB-in-metadata storage is kept as read-only fallback for
   pre-migration projects until a one-shot upcopy script runs.

2. Multi-User-Workflow:
   - assigned_to field on every clarification (free-text user kuerzel
     for now; an FK to users can be added in a follow-up).
   - Comment thread per clarification (POST .../comment, GET
     .../detail returns the thread).
   - Status-history log written by UpsertClarification when the
     status or answer actually changes.
   - Frontend Modal: Zugewiesen-an + Bearbeiter fields, comment
     thread with inline post, collapsible history section.

3. PDF-Export via print-friendly HTML:
   - GET /clarifications.html returns a standalone A4-styled
     document with status badges, norm references, affected hazards
     and a signature row at the bottom. The Bediener opens the link
     and uses Strg-P / Cmd-P to save as PDF. No server-side PDF
     dependency added.
   - Frontend "PDF / Druck" button next to CSV export.

Backend:
- internal/iace/store_clarifications.go: UpsertClarification,
  ListClarificationsForProject, GetClarificationByKey,
  AddClarificationComment, ListClarificationComments,
  ListClarificationHistory.
- internal/api/handlers/iace_handler_clarifications.go:
  - AnswerClarification now writes the SQL row, falls back to legacy
    JSONB read on list.
  - PostClarificationComment, ListClarificationDetail,
    ExportClarificationsHTML added.

Migration must be applied manually on Mac Mini and prod via
psql -f /migrations/028_iace_clarifications.sql — pattern as in
scripts/apply_*_migration.sh.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-05-17 01:39:17 +02:00
parent b2b4d77877
commit c4be077c5d
6 changed files with 778 additions and 29 deletions
@@ -33,6 +33,7 @@ type Clarification struct {
Reasoning string `json:"reasoning,omitempty"`
AnsweredBy string `json:"answered_by,omitempty"`
AnsweredAt string `json:"answered_at,omitempty"`
AssignedTo string `json:"assigned_to,omitempty"`
}
// ClarificationAnswer is the persisted shape (one entry in
@@ -43,6 +44,7 @@ type ClarificationAnswer struct {
Reasoning string `json:"reasoning,omitempty"`
AnsweredBy string `json:"answered_by,omitempty"`
AnsweredAt string `json:"answered_at,omitempty"`
AssignedTo string `json:"assigned_to,omitempty"`
}
// BuildProjectClarifications walks the project's current hazards and returns
@@ -154,6 +156,7 @@ func BuildProjectClarifications(
b.Reasoning = ans.Reasoning
b.AnsweredBy = ans.AnsweredBy
b.AnsweredAt = ans.AnsweredAt
b.AssignedTo = ans.AssignedTo
}
// dedup hazard IDs (multiple patterns can target the same hazard)
b.AffectedHazardIDs = dedupUUIDs(b.AffectedHazardIDs)