feat: store finding as structured title/fix/sources, not flat message

Migration 0002 replaces finding.message with title/fix/sources (a
Postgres text[]). A finding needs to render into the dossier the way it
looked at the moment it was raised — referencing the current rules/*.yaml
by rule_id+version isn't safe once that file is edited for a later
version, since old wording isn't kept around as a separate live file.
Added as a new migration rather than editing 0001, since that's already
applied on the test server.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
noroot
2026-08-27 14:39:14 +02:00
parent e0218337e7
commit 72005fc326
5 changed files with 42 additions and 16 deletions

View File

@@ -128,7 +128,7 @@ func TestFindingCRUDAndSupersedes(t *testing.T) {
t.Fatalf("CreateSubmission: %v", err)
}
old, err := s.CreateFinding(ctx, sub.ID, nil, "WK-004", 1, "hoch", "alte Fassung")
old, err := s.CreateFinding(ctx, sub.ID, nil, "WK-004", 1, "hoch", "alte Fassung", "alte Korrektur", []string{"§ 5a Abs. 4 UWG"})
if err != nil {
t.Fatalf("CreateFinding (old): %v", err)
}
@@ -140,11 +140,14 @@ func TestFindingCRUDAndSupersedes(t *testing.T) {
if len(current) != 1 || current[0].ID != old.ID {
t.Fatalf("expected exactly the old finding before any correction, got %+v", current)
}
if len(current[0].Sources) != 1 || current[0].Sources[0] != "§ 5a Abs. 4 UWG" {
t.Fatalf("Sources = %v, want [§ 5a Abs. 4 UWG]", current[0].Sources)
}
// Korrektur: neue Zeile, die die alte per supersedes ersetzt.
_, err = s.Pool.Exec(ctx, `
INSERT INTO finding (submission_id, rule_id, rule_version, severity, message, supersedes)
VALUES ($1, 'WK-004', 2, 'hoch', 'korrigierte Fassung', $2)
INSERT INTO finding (submission_id, rule_id, rule_version, severity, title, fix, sources, supersedes)
VALUES ($1, 'WK-004', 2, 'hoch', 'korrigierte Fassung', 'neue Korrektur', '{}', $2)
`, sub.ID, old.ID)
if err != nil {
t.Fatalf("insert superseding finding: %v", err)
@@ -157,7 +160,7 @@ func TestFindingCRUDAndSupersedes(t *testing.T) {
if len(current) != 1 {
t.Fatalf("expected exactly one current finding after a correction, got %d: %+v", len(current), current)
}
if current[0].Message != "korrigierte Fassung" {
if current[0].Title != "korrigierte Fassung" {
t.Fatalf("expected the corrected finding to be current, got %+v", current[0])
}
}