feat(domain): add SourceRateLimited transcript source

429 from the caption endpoint means the IP is rate-limited (retry later),
not that the video has no captions. Distinguishing it from SourceNone is the
prerequisite for the runner's backoff/retry logic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-03 22:45:29 +02:00
co-authored by Claude Opus 4.8
parent 61d4d5bc4a
commit 27aa319f1d
6 changed files with 26 additions and 7 deletions
+15 -7
View File
@@ -79,12 +79,12 @@ templ flashBanner(code string) {
// #summary-list region; a non-HTMX request renders the whole page. flash carries
// a one-shot notification (e.g. "connected", "registered") surfaced on arrival
// after a POST→redirect.
templ ListPage(rows []store.SummaryRow, f Filter, flash string) {
templ ListPage(rows []store.SummaryRow, f Filter, flash string, hasConnected bool) {
@Layout("Tapir — Summaries") {
@flashBanner(flash)
@filterForm(f)
<div id="summary-list">
@summaryList(rows)
@summaryList(rows, hasConnected)
</div>
}
}
@@ -110,12 +110,20 @@ templ filterForm(f Filter) {
// summaryList is the swappable list fragment: one card per video (summarized or
// not). Cards reflow to a single column on mobile; an empty list shows a friendly
// first-run state instead of a blank table.
templ summaryList(rows []store.SummaryRow) {
templ summaryList(rows []store.SummaryRow, hasConnected bool) {
if len(rows) == 0 {
<div class="empty">
<strong>No videos yet</strong>
<span>Videos appear here as your subscriptions are processed run <code>tapir run</code> to fetch them. In manual mode, use the Summarize button to queue one.</span>
</div>
if hasConnected {
<div class="empty empty-connected">
<strong>Your YouTube account is connected!</strong>
<span>Run <code>tapir run</code> to discover your subscriptions. Videos will appear here once discovered. In manual mode, each new video gets a Summarize button.</span>
</div>
} else {
<div class="empty">
<strong>No videos yet</strong>
<span>Connect your YouTube account to get started.</span>
<p><a class="btn" href="/oauth/youtube/connect">Connect YouTube</a></p>
</div>
}
} else {
<ul class="cards">
for _, r := range rows {