feat(subscriptions): dry-run backfill preview — B4 preview (plan #708)
CI / lint (push) Successful in 3s
CI / backend-lint-and-test (push) Successful in 24s
CI / integration (push) Successful in 3m1s
CI / frontend-build (push) Successful in 5m13s

Owning the walk lets an operator gauge "is this source worth a backfill?" before
arming one. ingest_core.Ingester.preview walks the first few feed pages and
counts media NOT already in the seen/dead ledgers, downloading nothing
(read-only). download_backends.preview_source resolves the campaign id + runs it
(native-only, mirrors verify_source_credential / run_download); POST
/api/sources/{id}/preview returns {total_new, posts_scanned, has_more, sample[]}
(409 on auth/drift/unresolvable, 400 for gallery-dl platforms). PatreonClient
gains post_meta(post) for the sample's title/date.

UI: a Patreon-only Preview button (mdi-eye-outline) on SourceRow + SourceCard
opens PreviewDialog — self-fetches with loading / error / empty / result states
and a "Start backfill" shortcut. Store action previewSource.

Tests: preview counts new media without downloading + samples only posts with
new items; page_limit caps the walk + flags has_more.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 12:18:08 -04:00
parent cd43439401
commit e82c2ee57b
10 changed files with 368 additions and 2 deletions
+7
View File
@@ -107,6 +107,12 @@ export const useSourcesStore = defineStore('sources', () => {
return body
}
// Plan #708 B4: dry-run preview — count what a backfill WOULD download
// (native platforms), without downloading. Read-only, so no cache invalidate.
async function previewSource(id) {
return await api.post(`/api/sources/${id}/preview`)
}
function sourcesByArtistGrouped() {
// returns [{artist: {id,name,slug}, sources: [...]}, ...]
const arr = byArtist.value.get(null) ?? []
@@ -136,6 +142,7 @@ export const useSourcesStore = defineStore('sources', () => {
startBackfill,
stopBackfill,
recoverSource,
previewSource,
findOrCreateArtist, autocompleteArtist,
loadScheduleStatus,
sourcesByArtistGrouped,