feat(store): TranscriptStatus read field + status setter/loader
Surfaces videos.transcript_status (migration 007) on SummaryRow and adds SetTranscriptStatus / GetTranscriptStatus / RateLimitedVideoIDs. SetTranscriptStatus is the single choke point for the rate-limit lifecycle: "rate_limited" stamps rate_limited_at = NOW(), every other status clears it, so the runner's backoff window and the UI badge read one consistent source. RateLimitedVideoIDs is the per-pass loader (mirrors SeenVideoIDs) the runner uses to skip still-throttled videos without re-hitting the caption endpoint. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,10 @@ type SummaryRow struct {
|
||||
// set by the web "Summarize" button and cleared by the next `tapir run`. Only
|
||||
// populated by ListVideos/GetVideoRow (summary-only reads leave it false).
|
||||
SummarizeRequested bool
|
||||
// TranscriptStatus mirrors videos.transcript_status (migration 007): "" (unset),
|
||||
// "none", "rate_limited", or "fetched". Drives the "Retrying later" list badge.
|
||||
// Only populated by ListVideos/GetVideoRow ("" on summary-only reads).
|
||||
TranscriptStatus string
|
||||
}
|
||||
|
||||
// selectSummary is the shared projection for both reads. videos is LEFT JOINed
|
||||
@@ -132,7 +136,8 @@ const selectVideo = `
|
||||
COALESCE(s.fallback_used, FALSE),
|
||||
COALESCE(s.created_at, v.seen_at),
|
||||
(s.id IS NOT NULL) AS summarized,
|
||||
v.summarize_requested
|
||||
v.summarize_requested,
|
||||
COALESCE(v.transcript_status, '')
|
||||
FROM videos v
|
||||
LEFT JOIN summaries s ON s.video_id = v.id AND s.user_id = v.user_id`
|
||||
|
||||
@@ -245,6 +250,7 @@ func scanVideoRow(rows pgx.Row) (SummaryRow, error) {
|
||||
&row.CreatedAt,
|
||||
&row.Summarized,
|
||||
&row.SummarizeRequested,
|
||||
&row.TranscriptStatus,
|
||||
); err != nil {
|
||||
return SummaryRow{}, fmt.Errorf("store: scan video: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user