Create/Get for submission (including the one legitimate status transition — submission is not append-only, unlike the other three), Create/GetLatest for extraction and evidence_package, Create for finding plus ListCurrentFindings which applies the anti-join documented in the migration (a finding referenced by another row's `supersedes` is not "current"). Tested against real Postgres, including that the append-only trigger still rejects UPDATE on evidence_package via this new code path, and that ListCurrentFindings actually hides a finding once a correction supersedes it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
67 lines
2.1 KiB
Go
67 lines
2.1 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Submission ist ein eingereichter Beitrag.
|
|
type Submission struct {
|
|
ID string
|
|
Platform string
|
|
PostType string
|
|
Caption string
|
|
Status string
|
|
CreatedAt time.Time
|
|
UpdatedAt time.Time
|
|
}
|
|
|
|
// CreateSubmission legt einen neuen Beitrag an (Status "draft").
|
|
func (s *Store) CreateSubmission(ctx context.Context, platform, postType, caption string) (Submission, error) {
|
|
var sub Submission
|
|
err := s.Pool.QueryRow(ctx, `
|
|
INSERT INTO submission (platform, post_type, caption)
|
|
VALUES ($1, $2, $3)
|
|
RETURNING id, platform, post_type, caption, status, created_at, updated_at
|
|
`, platform, postType, caption).Scan(
|
|
&sub.ID, &sub.Platform, &sub.PostType, &sub.Caption, &sub.Status, &sub.CreatedAt, &sub.UpdatedAt,
|
|
)
|
|
if err != nil {
|
|
return Submission{}, fmt.Errorf("store: create submission: %w", err)
|
|
}
|
|
return sub, nil
|
|
}
|
|
|
|
// GetSubmission liest einen Beitrag anhand seiner ID.
|
|
func (s *Store) GetSubmission(ctx context.Context, id string) (Submission, error) {
|
|
var sub Submission
|
|
err := s.Pool.QueryRow(ctx, `
|
|
SELECT id, platform, post_type, caption, status, created_at, updated_at
|
|
FROM submission WHERE id = $1
|
|
`, id).Scan(
|
|
&sub.ID, &sub.Platform, &sub.PostType, &sub.Caption, &sub.Status, &sub.CreatedAt, &sub.UpdatedAt,
|
|
)
|
|
if err != nil {
|
|
return Submission{}, fmt.Errorf("store: get submission: %w", err)
|
|
}
|
|
return sub, nil
|
|
}
|
|
|
|
// SetSubmissionStatus setzt den Status eines Beitrags (submission ist,
|
|
// anders als extraction/finding/evidence_package, NICHT append-only —
|
|
// der Lebenszyklus draft → checked → published → archived ist eine
|
|
// normale Zustandsänderung, kein Beweis-Eintrag).
|
|
func (s *Store) SetSubmissionStatus(ctx context.Context, id, status string) error {
|
|
tag, err := s.Pool.Exec(ctx, `
|
|
UPDATE submission SET status = $2, updated_at = now() WHERE id = $1
|
|
`, id, status)
|
|
if err != nil {
|
|
return fmt.Errorf("store: set submission status: %w", err)
|
|
}
|
|
if tag.RowsAffected() == 0 {
|
|
return fmt.Errorf("store: set submission status: submission %s nicht gefunden", id)
|
|
}
|
|
return nil
|
|
}
|