Commit Graph
3 Commits
Author SHA1 Message Date
bvandeusenandClaude Opus 5 173f4b00aa fix: the native path never reported tier-gated posts (milestone 387 step A1)
CI / lint (push) Successful in 4s
CI / extension-version (push) Successful in 4s
CI / frontend-build (push) Successful in 26s
CI / backend-lint-and-test (push) Successful in 55s
CI / integration (push) Successful in 2m4s
Build images / sign-extension (push) Successful in 11s
Build images / build-agent (push) Successful in 2m41s
Build images / build-web (push) Successful in 2m3s
Build images / smoke-web (push) Skipped
Build images / build-ml (push) Successful in 5m40s
Build images / promote (push) Skipped
`make_run_stats` has always declared `tier_gated_count`, and
DownloadDetailModal has always rendered it. gallery-dl populated it;
`ingest_core._result` did not — it built run_stats with six keys and let
the seventh default to 0, while the very same walk counted gated posts
into `gated_skipped` and spent the number on a log line.

So on Patreon, SubscribeStar and pixiv — the three platforms we now own —
the Downloads modal read "Tier-gated: 0" for a walk that skipped N
paywalled posts. A creator we've lost access to was indistinguishable
from a creator who stopped posting. Migrating Patreon off gallery-dl is
what dropped the signal.

Pass the count through, and tick it in the live-progress payload too, so
a long backfill on an inaccessible creator explains itself while it runs
rather than only at finalization. ActiveDownloadsPanel renders it only
when non-zero, coloured 'info' to match the severity FailingSourcesCard
already assigns tier_limited — this is not a failure.

Tests assert the run_stats key the UI actually reads rather than the
ingester's internal counter, so the guard tracks the property and not a
name. Falsification is structural: `make_run_stats` defaults the key to
0, so both assertions fail against the pre-fix call.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LNXXULQDjVZmbuNa2G9mD9
2026-09-09 12:34:08 -04:00
bvandeusenandClaude Opus 4.8 62cca64dce feat(downloads): live per-file progress on running events — #709
CI / lint (push) Successful in 2s
CI / frontend-build (push) Successful in 17s
CI / backend-lint-and-test (push) Successful in 25s
CI / integration (push) Failing after 3m1s
Now that we own the walk, surface live counts on the in-flight download in the
Downloads view. ingest_core.run takes an event_id and does a TIME-THROTTLED
write (~5s, decoupled from page boundaries so it ticks steadily regardless of
how big/slow a page is) of {downloaded, skipped, errors, quarantined, posts} to
the running download_event's metadata.live (jsonb_set; short session; status
guard so a finalized event isn't clobbered). download_backends threads
event_id from ctx; the /api/downloads list surfaces `live`; ActiveDownloadsPanel
renders it beside the elapsed timer. Native (Patreon) only — gallery-dl is an
opaque subprocess; the row only shows when `live` is present. Phase 3 overwrites
metadata with run_stats on finish, dropping `live`.

Test: _write_live_progress updates a running event's metadata.live and leaves a
finalized (status != running) event alone.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 15:48:31 -04:00
bvandeusenandClaude Opus 4.7 9e74c80e2f feat(downloads): front-and-center "active now" panel with live elapsed timers
New ActiveDownloadsPanel pinned at the top of the Downloads tab shows what's
running (pulsing dot + live mm:ss timer counting from started_at) and what's
queued, so the operator can see activity at a glance without the running
filter. Backed by store.loadActive() which fetches running + pending
independent of the feed filter; refreshed every 4s by the existing live poll.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 19:36:49 -04:00