diff --git a/backend/app/services/download_service.py b/backend/app/services/download_service.py index 7139134..47cd4c0 100644 --- a/backend/app/services/download_service.py +++ b/backend/app/services/download_service.py @@ -515,6 +515,13 @@ class DownloadService: new_overrides = dict(src.config_overrides or {}) chunks = int(new_overrides.get("_backfill_chunks", 0)) + 1 new_overrides["_backfill_chunks"] = chunks + # plan #704 (#5): accumulate posts-processed across chunks so the badge + # shows live walk progress, not just the chunk count. Cleared on + # (re)start. (Slight over-count: each chunk re-walks the resumed page — + # fine for a progress indicator.) + new_overrides["_backfill_posts"] = int( + new_overrides.get("_backfill_posts", 0) + ) + int(getattr(dl_result, "posts_processed", 0) or 0) completed = ( dl_result.success diff --git a/backend/app/services/source_service.py b/backend/app/services/source_service.py index 67b2cf2..073b4d8 100644 --- a/backend/app/services/source_service.py +++ b/backend/app/services/source_service.py @@ -70,6 +70,9 @@ class SourceRecord: # plan #697: a running deep-walk that bypasses the Patreon seen-ledger # (recovery) vs. a normal backfill. Lets the badge label it "Recovering". backfill_bypass_seen: bool + # plan #704: cumulative posts processed across the walk's chunks — live + # progress for the badge. + backfill_posts: int def to_dict(self) -> dict: return { @@ -91,6 +94,7 @@ class SourceRecord: "backfill_state": self.backfill_state, "backfill_chunks": self.backfill_chunks, "backfill_bypass_seen": self.backfill_bypass_seen, + "backfill_posts": self.backfill_posts, } @@ -167,6 +171,7 @@ class SourceService: backfill_state=co.get("_backfill_state"), backfill_chunks=int(co.get("_backfill_chunks", 0)), backfill_bypass_seen=bool(co.get("_backfill_bypass_seen")), + backfill_posts=int(co.get("_backfill_posts", 0)), ) async def _row_to_record(self, source: Source) -> SourceRecord: @@ -317,7 +322,8 @@ class SourceService: raise LookupError(f"source id={source_id} not found") co = dict(source.config_overrides or {}) co["_backfill_state"] = "running" - for k in ("_backfill_cursor", "_backfill_cursor_stalls", "_backfill_chunks"): + for k in ("_backfill_cursor", "_backfill_cursor_stalls", "_backfill_chunks", + "_backfill_posts"): co.pop(k, None) source.config_overrides = co source.backfill_runs_remaining = BACKFILL_MAX_CHUNKS @@ -345,7 +351,8 @@ class SourceService: co = dict(source.config_overrides or {}) co["_backfill_state"] = "running" co["_backfill_bypass_seen"] = True - for k in ("_backfill_cursor", "_backfill_cursor_stalls", "_backfill_chunks"): + for k in ("_backfill_cursor", "_backfill_cursor_stalls", "_backfill_chunks", + "_backfill_posts"): co.pop(k, None) source.config_overrides = co source.backfill_runs_remaining = BACKFILL_MAX_CHUNKS @@ -362,7 +369,7 @@ class SourceService: raise LookupError(f"source id={source_id} not found") co = dict(source.config_overrides or {}) for k in ("_backfill_state", "_backfill_cursor", "_backfill_cursor_stalls", - "_backfill_chunks", "_backfill_bypass_seen"): + "_backfill_chunks", "_backfill_bypass_seen", "_backfill_posts"): co.pop(k, None) source.config_overrides = co source.backfill_runs_remaining = 0 diff --git a/frontend/src/components/subscriptions/SourceCard.vue b/frontend/src/components/subscriptions/SourceCard.vue index 4312d8f..c0c092f 100644 --- a/frontend/src/components/subscriptions/SourceCard.vue +++ b/frontend/src/components/subscriptions/SourceCard.vue @@ -28,7 +28,9 @@ v-else-if="source.backfill_state === 'running'" size="x-small" color="info" variant="tonal" label >{{ source.backfill_bypass_seen ? 'Recovering' : 'Backfilling' - }}{{ source.backfill_chunks ? ` (${source.backfill_chunks})` : '' }} + }}{{ source.backfill_posts + ? ` · ${source.backfill_posts} posts` + : (source.backfill_chunks ? ` (${source.backfill_chunks})` : '') }} {{ source.backfill_bypass_seen ? 'Recovering' : 'Backfilling' - }}{{ source.backfill_chunks ? ` (${source.backfill_chunks})` : '' }} + }}{{ source.backfill_posts + ? ` · ${source.backfill_posts} posts` + : (source.backfill_chunks ? ` (${source.backfill_chunks})` : '') }}