Analytics Dashboard Fully Functional

Converts the analytics dashboard from mocked UI theatre into real data. Every performance chart now aggregates from live deal activity; all 4 report generators produce real rows; PDF/Excel exports work; scheduled reports are cron-ready.

Converts the analytics dashboard from mocked UI theatre into real data. Every performance chart now aggregates from live deal activity; all 4 report generators produce real rows; PDF/Excel exports work; scheduled reports are cron-ready.

Foundation (Phase A)

  • Migration f7a8b9c0d1e2 creates analytics_snapshots — daily per-(workspace, campaign, channel) rollups with idempotent unique-key upsert
  • backend/services/analytics/snapshot_builder.py — aggregates scheduling deals + marketplace deals, writes buyer spend-side + seller revenue-side rows per deal
  • POST /analytics/admin/rollup — SA-only cron-compatible endpoint that rebuilds snapshots

Live performance endpoints (Phase B)

All 6 /performance/* endpoints now read from analytics_snapshots:

  • /performance, /performance/channels, /funnel, /heatmap, /gauges, /waterfall
  • No more random.uniform() mocks
  • All gated with require_roles(ADVERTISER, AGENCY_ADMIN, SUPER_ADMIN) (previously only /performance was gated — 5 leaked)
  • /performance response includes previous_period summary for real delta badges

Real report generators (Phase C)

  • 4 generators rewritten against snapshot data: campaign performance, cross-channel, attribution (with fallback), custom KPI
  • POST /reports/{id}/generate returns populated data and updates size_bytes, row_count
  • Attribution falls back to snapshot channel rollup when attribution_models is empty

Exports + scheduling (Phase D)

  • PDF via WeasyPrint + Jinja template backend/templates/analytics_report.html
  • Excel via openpyxl (added to requirements)
  • POST /analytics/reports/{id}/export accepts format=csv|pdf|xlsx
  • POST /admin/analytics/run-scheduled — SA endpoint that picks up daily/weekly/monthly reports due to run, generates them, emails recipients via existing email_service, advances next_run_at

Polish (Phase E)

  • Migration a9b0c1d2e3f4 adds formula_json JSONB to custom_kpis so the KPI formula builder round-trips cleanly
  • GET /analytics/attribution/channel-timeseries — real daily revenue per channel (replaces the fake 3-point synthesized series)
  • Attribution page uses real previous_period deltas (removes hardcoded previousValue * 0.85)

Verification (live)

  • Rollup wrote 34 snapshots from existing deals
  • Aggregated: 417,300 impressions, ₹24,640 spend
  • Advertiser /performance?dateFrom=2026-04-01&dateTo=2026-04-22 returns real numbers
  • PDF (%PDF-1.7 magic), XLSX (PK.. magic), CSV all produce valid bytes

Top-left brand text

Sidebar header changed from Advertise.net to Advertise.Network.

Honest caveats

  • Impressions/clicks derived from deal pricing + 2% CTR fallback — no real ad-platform telemetry yet. The source column on snapshots is designed to swap in Meta/Google/TikTok feeds without schema change.
  • Data is sparse (1 completed scheduling deal in test data) — numbers shown are real but small.

---

Want to see it in your own workspace?

Bring planning, discovery, delivery, and measurement into one platform.