fix(discovery): add json tags to domain types

Without snake_case json tags, Go serializes fields as PascalCase (ID,
MarktName, etc.) — but the Svelte frontend reads snake_case. Every
row.id on the client was undefined, which made Svelte 5 see identical
'undefined' keys across the {#each queue as row (row.id)} loop and
throw each_key_duplicate.

Adds explicit snake_case tags to Bucket, DiscoveredMarket, and
RejectedDiscovery to match what the TypeScript types already expect.
This commit is contained in:
2026-04-18 09:11:44 +02:00
parent 8f1efe73f2
commit b6ace52ada

View File

@@ -9,47 +9,47 @@ import (
// Bucket is a scheduler row: one (land, region, year_month) tuple.
type Bucket struct {
ID uuid.UUID
Land string
Region string
YearMonth string // 'YYYY-MM'
LastQueriedAt *time.Time
LastError string
CreatedAt time.Time
ID uuid.UUID `json:"id"`
Land string `json:"land"`
Region string `json:"region"`
YearMonth string `json:"year_month"` // 'YYYY-MM'
LastQueriedAt *time.Time `json:"last_queried_at"`
LastError string `json:"last_error"`
CreatedAt time.Time `json:"created_at"`
}
// DiscoveredMarket is a queue entry awaiting admin review.
type DiscoveredMarket struct {
ID uuid.UUID
BucketID uuid.UUID
MarktName string
Stadt string
Bundesland string
Land string
StartDatum *time.Time
EndDatum *time.Time
Website string
Quellen []string
Extraktion string
Hinweis string
NameNormalized string
MatchedSeriesID *uuid.UUID
Status string // 'pending' | 'accepted' | 'rejected'
DiscoveredAt time.Time
ReviewedAt *time.Time
ReviewedBy *uuid.UUID
CreatedEditionID *uuid.UUID
ID uuid.UUID `json:"id"`
BucketID uuid.UUID `json:"bucket_id"`
MarktName string `json:"markt_name"`
Stadt string `json:"stadt"`
Bundesland string `json:"bundesland"`
Land string `json:"land"`
StartDatum *time.Time `json:"start_datum"`
EndDatum *time.Time `json:"end_datum"`
Website string `json:"website"`
Quellen []string `json:"quellen"`
Extraktion string `json:"extraktion"`
Hinweis string `json:"hinweis"`
NameNormalized string `json:"name_normalized"`
MatchedSeriesID *uuid.UUID `json:"matched_series_id"`
Status string `json:"status"` // 'pending' | 'accepted' | 'rejected'
DiscoveredAt time.Time `json:"discovered_at"`
ReviewedAt *time.Time `json:"reviewed_at"`
ReviewedBy *uuid.UUID `json:"reviewed_by"`
CreatedEditionID *uuid.UUID `json:"created_edition_id"`
}
// RejectedDiscovery stores a sticky rejection scoped to (normalized_name, city, year).
type RejectedDiscovery struct {
ID uuid.UUID
NameNormalized string
Stadt string
Year int
RejectedAt time.Time
RejectedBy *uuid.UUID
Reason string
ID uuid.UUID `json:"id"`
NameNormalized string `json:"name_normalized"`
Stadt string `json:"stadt"`
Year int `json:"year"`
RejectedAt time.Time `json:"rejected_at"`
RejectedBy *uuid.UUID `json:"rejected_by"`
Reason string `json:"reason"`
}
// Pass0Response is the parsed shape of the Mistral Pass 0 agent reply.