No description
Find a file
DJP a9f4dcf71a Finish V2: serve dashboards, downscale covers, post-run Apify cost re-poll,
enable mp4 download, smart Stage 4 cache, default Apify live in prod

Closes the last gaps so the operator app is end-to-end usable in production.

Server:
- routes/reports.ts: GET /api/reports/:id/dashboard[/<file>] serves files
  out of the report's brief outputs/ tree (HTML bundle, dataset_v2.json,
  any covers referenced relatively). Auth-gated by team viewer role.
  Path-traversal guarded.
- index.ts: two new route patterns (with and without trailing path).

Client:
- routes/reports/detail.tsx: "Open dashboard" is a target=_blank anchor at
  /api/reports/:id/dashboard/, "Download" same URL with download attribute.
  No more dead SPA-internal link.

Pipeline polish (the four open items from the smoke test):
- stage_10_build.ts: covers are now downscaled via ffmpeg (240px / q=6)
  before base64 inlining. Hard ceiling per cover 60 KB; falls back to the
  original only if it already fits. Honours V3 brief's ≤3 MB HTML bundle.
- lib/apify_client.ts: post-run cost is re-polled with backoff (0/5/15/30s)
  instead of a single read. TIKTOK_COMMENTS reports $0 immediately and
  $5+ later — without this the soft cap can't fire on it.
- stage_2_pass1_scrape.ts: shouldDownloadVideos:true (and shouldDownloadCovers:true)
  by default so videoMeta.downloadAddr is populated for Stage 4 frame
  extraction. Disable with DISABLE_VIDEO_DOWNLOADS=true if the budget is
  tight.
- stage_4_pass2_enrich.ts: Stage 5 backfill candidates aren't in the
  transcripts/comments cache. New loadOrFetchActor() reads what's cached,
  identifies missing ids, fetches just those from Apify, and merges back
  into the cache. Backfill no longer drops every candidate.

Production defaults:
- .env.example: APIFY_LIVE_APPROVED=true (commented; operators can flip
  to false for dry-runs).
- cutover-in-place.sh: sets APIFY_LIVE_APPROVED=true if not already in .env
  after the migration step, so a fresh prod cutover doesn't accidentally
  dry-run.

62/62 unit tests pass; tsc + vite build green; bundle 269 kB.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 19:31:38 -04:00
v2 Finish V2: serve dashboards, downscale covers, post-run Apify cost re-poll, 2026-04-29 19:31:38 -04:00
.gitignore Stop .gitignore from swallowing src/routes/briefs/ 2026-04-29 18:44:08 -04:00
DEVELOPER_BRIEF_V2.md Add V2: multi-team social-reporting platform with manifest-gated linking 2026-04-29 17:39:07 -04:00
README.md README: document the cd /opt/social-reporting && git pull && cutover-in-place flow 2026-04-29 18:40:55 -04:00

Social Reporting

V2 lives in v2/. All commands run from there.

cd v2
docker compose -f docker-compose.v2.yml --env-file .env up -d --build
npm install
npm test                       # 62 unit tests
npm run pipe seed --report <brief-id>

For the full V2 spec see DEVELOPER_BRIEF_V2.md.

Deploying V2 over an existing V1 install

If V1 is already deployed at /opt/social-reporting, cut over in place:

ssh you@optical-dev.oliver.solutions
cd /opt/social-reporting
git pull origin main                          # pulls in v2/, removes V1 dirs
bash v2/deploy/cutover-in-place.sh            # stops V1, migrates secrets, starts V2

The script prompts before doing anything destructive, migrates APIFY/Anthropic/Azure secrets from V1's .env into a fresh v2/.env, swaps the Apache conf to V2's, and starts the V2 docker stack. It also prompts for the email that will be auto-promoted to super-admin on first SSO sign-in (BOOTSTRAP_SUPER_ADMIN_EMAIL).

The Azure-registered redirect URI https://optical-dev.oliver.solutions/social-reports/login.html is preserved by V2 (Vite base: /social-reports/, React Router basename, and an explicit /login.html route alias).

V1 archive

V1 source is preserved on the v1-archive branch (frozen at the last V1 commit) and is no longer kept on the deployed server. To roll back from V2 to V1, the rollback script will re-clone v1-archive if needed:

# On the server
export REPO_URL="https://x-token-auth:YOUR_TOKEN@bitbucket.org/zlalani/social-reporting-tool.git"
bash /opt/social-reporting-v2/v2/deploy/rollback-to-v1.sh

To inspect or check out V1 source locally:

git checkout v1-archive