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

@@ -71,15 +71,15 @@ func TestFindingIsAppendOnly(t *testing.T) {
var findingID string
err = s.Pool.QueryRow(ctx, `
INSERT INTO finding (submission_id, rule_id, rule_version, severity, message)
VALUES ($1, 'WK-004', 3, 'hoch', 'Testfeststellung')
INSERT INTO finding (submission_id, rule_id, rule_version, severity, title, fix, sources)
VALUES ($1, 'WK-004', 3, 'hoch', 'Testfeststellung', 'Testkorrektur', '{}')
RETURNING id
`, submissionID).Scan(&findingID)
if err != nil {
t.Fatalf("insert finding: %v", err)
}
_, err = s.Pool.Exec(ctx, `UPDATE finding SET message = 'geändert' WHERE id = $1`, findingID)
_, err = s.Pool.Exec(ctx, `UPDATE finding SET title = 'geändert' WHERE id = $1`, findingID)
if err == nil {
t.Fatal("expected UPDATE on finding to be rejected, but it succeeded")
}