social-reporting-tool/v2
DJP 8e25914939 Run page liveness: heartbeat banner + fix Apify $0 + Stage 4 budget cap
Three bugs surfaced by the Dove2 demo run on prod and addressed together
because they all conspire to make the run page look dead:

1. Apify cost events were never persisted. Stage 2 imported onApifyCost
   and registered an empty no-op callback inside its run loop, silently
   overwriting the CLI's DB-writing handler set in cli.ts:logCost(). The
   APIFY total stuck at $0.00 even though Stage 2 had spent $5+ in real
   billing. Removed the override; the CLI's callback now wins.

2. Stage 4 inherited Stage 2's Pass-1 soft cap and skipped every actor.
   resetBudget() sets a hard ceiling (95% of brief.budget_usd) and
   setSoftCap() sets the Pass-1 cap (50%). Stage 2 fills the soft cap,
   but Stage 4 never released it — every TIKTOK_TRANSCRIPTS / COMMENTS /
   PROFILE call returned "budget reached — skipping" and the manifest
   gate failed at 0% coverage. Stage 4 now calls setSoftCap(null) at
   entry so it stays bounded only by the hard ceiling.

3. Even between cost events the run page had no liveness signal. Apify
   actors run 1-3 minutes per scrape with no DB writes in flight, so the
   UI looked frozen. Added a best-effort heartbeat: apify_client writes
   .state/live_activity.json on every Apify status poll (every 5s),
   GET /reports/:id includes it on the response, and the run page shows
   a live banner with the current activity, elapsed time, last
   heartbeat age (flags as suspicious past 90s), and running Apify
   spend.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 21:12:53 -04:00
..
db Lower default engagement floor 10×; richer Stage 3 diagnostic 2026-04-29 20:28:23 -04:00
deploy deploy: chown briefs/ to uid 1000 so container can write per-report dirs 2026-04-29 20:06:56 -04:00
examples Demo brief JSON file: same content as the inline operator-app demo 2026-04-29 20:37:42 -04:00
operator-app Run page liveness: heartbeat banner + fix Apify $0 + Stage 4 budget cap 2026-04-29 21:12:53 -04:00
pipeline Run page liveness: heartbeat banner + fix Apify $0 + Stage 4 budget cap 2026-04-29 21:12:53 -04:00
server Run page liveness: heartbeat banner + fix Apify $0 + Stage 4 budget cap 2026-04-29 21:12:53 -04:00
templates Per-report dashboard SPA (V3 §10a) — 9 interactive views 2026-04-29 20:06:12 -04:00
.env.example Finish V2: serve dashboards, downscale covers, post-run Apify cost re-poll, 2026-04-29 19:31:38 -04:00
.gitignore Add V2: multi-team social-reporting platform with manifest-gated linking 2026-04-29 17:39:07 -04:00
docker-compose.v2.dev.yml Drop db-v2 host port binding in prod; add port pre-flight to cutover script 2026-04-29 18:49:44 -04:00
docker-compose.v2.prod.yml Drop db-v2 host port binding in prod; add port pre-flight to cutover script 2026-04-29 18:49:44 -04:00
docker-compose.v2.yml Bake VITE_AZURE_* into the SPA at docker build time; sweep V1 leftovers in cutover 2026-04-29 19:00:15 -04:00
Dockerfile.v2 Per-report dashboard SPA (V3 §10a) — 9 interactive views 2026-04-29 20:06:12 -04:00
package-lock.json Per-report dashboard SPA (V3 §10a) — 9 interactive views 2026-04-29 20:06:12 -04:00
package.json Per-report dashboard SPA (V3 §10a) — 9 interactive views 2026-04-29 20:06:12 -04:00
tsconfig.base.json Add V2: multi-team social-reporting platform with manifest-gated linking 2026-04-29 17:39:07 -04:00
tsconfig.json Add V2: multi-team social-reporting platform with manifest-gated linking 2026-04-29 17:39:07 -04:00
vitest.config.ts Add V2: multi-team social-reporting platform with manifest-gated linking 2026-04-29 17:39:07 -04:00