No description
Find a file
DJP 1d2801d3c3 Wire reports end-to-end: trigger, track, poll, view
Closes the gap between "brief exists" and "report ships". The Phase A
placeholders for Home and Reports/detail are now real, and the brief detail
page can actually start a pipeline run.

Server (no schema changes — reports table already existed):
- db/reports.ts: createReport, getReport, getReportWithBrief, listReportsForTeam,
  updateReportStatus, finishReport, logCostEvent (atomically updates the
  reports row's running totals), listCostEvents.
- routes/reports.ts: GET /api/reports (active team), GET /api/reports/:id
  (with cost_events), POST /api/briefs/:id/run that
    1. authorises (editor+ on the brief's team),
    2. creates a reports row (status=pending),
    3. spawns the pipeline as a detached child running
       `tsx pipeline/cli.ts all --report <brief_id> --run-id <reports.id>`,
    4. returns the new report id.
  Singleton flag prevents two concurrent runs (mirrors V1).

Pipeline:
- cli.ts: new --run-id flag. New `all` command drives every stage in order
  via a withStage() helper that updates reports.status / current_stage at
  each step. Cost callbacks now ALSO write to cost_events when run-id is
  set, tagged with the current stage. main()'s catch handler calls
  finishReport(runId, 'failed', err.message) so the UI doesn't poll forever
  on a crash.

Client:
- api/reports.ts: useRecentReports, useReport (auto-polls every 3s while
  status is non-terminal), useRunPipeline.
- routes/home.tsx: real recent-reports list — status pill, brief client +
  business question, cost split, relative time.
- routes/reports/detail.tsx: full run page — header with status pill,
  10-step pipeline progress with current-stage pulse, error block on
  failure, three-tile cost summary (total / apify / claude), cost-event
  log (most recent first, scrollable, sticky header), "Open dashboard"
  + "Download HTML bundle" actions when the run completes.
- routes/briefs/detail.tsx: Run pipeline button is now functional for
  editors+, with a confirm dialog (warns about Apify/Claude spend),
  navigates to the new /reports/:id on success, surfaces 409 if another
  run is in flight.

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

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 19:18:57 -04:00
v2 Wire reports end-to-end: trigger, track, poll, view 2026-04-29 19:18:57 -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