feat(store): expose provider_video_id on SummaryRow

Read-only addition (column + field + scan) so the web layer can build a
video embed URL. No write-path or restructuring.
This commit is contained in:
2026-06-03 15:10:29 +02:00
parent b2d1909b13
commit 897a21a1d6
+16 -13
View File
@@ -25,19 +25,20 @@ var ErrNotFound = errors.New("store: summary not found")
// not part of the Stage-0 store slice yet. When that table is migrated, swap the // not part of the Stage-0 store slice yet. When that table is migrated, swap the
// JOIN source — callers already fall back gracefully on an empty Channel. // JOIN source — callers already fall back gracefully on an empty Channel.
type SummaryRow struct { type SummaryRow struct {
VideoID string VideoID string
Title string // videos.title; empty when no videos row ProviderVideoID string // videos.provider_video_id; empty when no videos row
Channel string // videos.provider for now; empty when no videos row Title string // videos.title; empty when no videos row
URL string // videos.url; empty when no videos row Channel string // videos.provider for now; empty when no videos row
PublishedAt time.Time // videos.published_at; zero when absent URL string // videos.url; empty when no videos row
Summary string PublishedAt time.Time // videos.published_at; zero when absent
Highlights []string Summary string
Takeaways []string Highlights []string
AIProvider string Takeaways []string
AIModel string AIProvider string
FallbackUsed bool AIModel string
CreatedAt time.Time FallbackUsed bool
Actions []string // current active actions for this video; nil when none CreatedAt time.Time
Actions []string // current active actions for this video; nil when none
} }
// selectSummary is the shared projection for both reads. videos is LEFT JOINed // selectSummary is the shared projection for both reads. videos is LEFT JOINed
@@ -45,6 +46,7 @@ type SummaryRow struct {
// crosses users and a missing videos row yields nulls, not a dropped summary. // crosses users and a missing videos row yields nulls, not a dropped summary.
const selectSummary = ` const selectSummary = `
SELECT s.video_id, SELECT s.video_id,
COALESCE(v.provider_video_id, ''),
COALESCE(v.title, ''), COALESCE(v.title, ''),
COALESCE(v.provider, ''), COALESCE(v.provider, ''),
COALESCE(v.url, ''), COALESCE(v.url, ''),
@@ -135,6 +137,7 @@ func scanSummaryRow(rows pgx.Row) (SummaryRow, error) {
) )
if err := rows.Scan( if err := rows.Scan(
&row.VideoID, &row.VideoID,
&row.ProviderVideoID,
&row.Title, &row.Title,
&row.Channel, &row.Channel,
&row.URL, &row.URL,