← Back to index | ← 08a MMC analytics | 09 MMC bridge →
The platform-side analytics surface in the CoachPilot dashboard. Today: aggregate KPIs across all tenants. Planned: per-tenant Sessions drilldown.
What exists today
/[locale]/admin/analytics/page.tsx
Live route in dashboard/src/app/[locale]/admin/analytics/page.tsx. Calls assess.getAnalytics(period) which hits the gateway.
Surfaces:
| Surface | Shape | Source |
|---|---|---|
| Total sessions | int | COUNT(*) FROM assess_sessions WHERE completed_at >= NOW() - period |
| Completion rate | float % | SUM(quiz_complete) / SUM(quiz_started) over period |
| Avg turns | float | Median turn count per session |
| Archetype breakdown | {hero: 23, artist: 18, ...} | GROUP BY primary_id |
| Game modes | {qa: 80, game: 12, deal: 6, ...} | GROUP BY format |
| Drop-off | {intro: 100, q1: 92, q2: 84, ...} | Per-step retention |
| AI cost USD | float | Aggregated from token usage rows |
| Cost breakdown | {reflection: 0.12, micro_insight: 0.08, ...} | Per-purpose AI cost |
Period selector: 7d / 30d / 90d.
assess_sessions table
The source data lives in Postgres:
CREATE TABLE assess_sessions (
session_id VARCHAR(64) PRIMARY KEY,
tenant_id VARCHAR(64) NOT NULL,
framework_id VARCHAR(64) NOT NULL,
format VARCHAR(32), -- qa, game, deal, realm, likert
user_email VARCHAR(255),
user_name VARCHAR(255),
scores JSONB, -- calibrated scores
primary_id VARCHAR(64),
secondary_id VARCHAR(64),
completed_at TIMESTAMPTZ DEFAULT NOW(),
metadata JSONB DEFAULT '{}'
);
Populated by:
- Agent
generate_resultswrites via NATS publish + a subscriber that persists. /api/quiz/resultswrites via the gateway.- WP Likert writes through the bridge (via gateway POST).
Note: MMC Legacy Likert sessions currently live in WP mq_* tables (see 08a), NOT here. Phase 4 will ETL them.
What does NOT exist yet
Per-tenant Sessions drilldown
There is NO route today like /[locale]/coach/quiz-sessions/?tenant=mmc that shows individual session rows with filters/drilldown. The placeholder at /[locale]/sessions/page.tsx is a coaching-session CALENDAR page with hardcoded mock data — unrelated to quiz sessions.
Per-tenant scoping in /admin/analytics
The current admin analytics page doesn't scope to a tenant — it returns platform-wide aggregates. To see per-tenant breakdown, the gateway would need a ?client=<tenant> filter on assess.getAnalytics. Not implemented.
Drop-off heatmaps
The "drop-off" KPI is a coarse percentage. A per-step heatmap (visit → start → q1 → q2 → ... → completion → email open → booking) is on the deferred list. Was Phase 6 of the v3 plan — not built.
Cross-tenant cohort analysis
E.g. "show me Hero × Magician combinations across all tenants" — no UI today. Would be a useful research tool.
What Ilana CAN do today via CoachPilot
If she has admin access to app.coachpilot.ch:
- See aggregate quiz session counts across the platform.
- See archetype distribution.
- See AI cost (mostly platform-level concern).
- Edit her tenant's
framework_configsoverrides (Voice, Scoring, Modes, Landing, Communications, Results, Providers, Personas). - Edit her
tenant_brand(coach details, brand colours, webhook URLs).
If she doesn't have admin access (the more likely customer scenario):
- Nothing on the CoachPilot side. She uses MMC WordPress Quiz Leads instead.
What Ilana CANNOT do today via CoachPilot
- See "every prospect who's taken any of my quizzes" — that's in MMC WordPress.
- See "Jane Doe's full quiz history including the Money Quiz from 2024" — same.
- Tag a prospect Hot/Warm/Cool/Cold — same.
- Run a campaign — same.
The federation question
Two paths to a unified per-tenant analytics view:
Path A — Build it in CoachPilot dashboard
A new route /[locale]/coach/quiz-sessions/?tenant=<id> that:
- Queries
assess_sessions WHERE tenant_id = <id>for new-format sessions. - Joins (or federates a query against) the MMC bridge for Legacy Likert sessions.
- Mirrors the Quiz Leads UX: filter by date/format/email/archetype combo, slide-out for per-prospect detail, Hot/Warm/Cool/Cold scoring, notes.
Estimated: ~2 days. Largely UI work; the data is already in Postgres / accessible via bridge.
Path B — Federate FROM MMC
Extend the existing Quiz Leads UI to also pull non-MMC tenants' sessions via gateway. Less work but couples the multi-tenant story to MMC's WordPress, which is bad architecture long-term.
Recommendation
Path A, when there's a non-MMC tenant who actually wants this dashboard. Until then, the platform-side is operationally adequate (per-tenant edits via the Brand + Framework editors).
Per-tenant analytics webhook (new)
D4 added tenant_brand.analytics_webhook for tenants who want raw event streaming to their own analytics. Distinct from archetype_scores_webhook (CRM-shaped completion events) — this is for higher-volume telemetry like quiz_started, question_answered, variant_exposure.
Today nothing fires events to this URL yet. D3 (deferred) is the work to start firing per-event POSTs. Schema is in place for future activation.
Privacy considerations
The platform assess_sessions table stores user_email and user_name directly. This is fine for first-party (the coach receiving their own client data). For cross-tenant analytics (planned /admin/analytics), we hash these on retrieval for non-tenant admins.
The analytics_webhook payloads should be ANONYMISED (no PII) — the distinction vs archetype_scores_webhook (which DOES include PII because it's a tenant-owned CRM receiver).
Implementation note: when D3 lands, fire two parallel payload shapes:
- CRM payload: full PII, only to
archetype_scores_webhookfor tenants that opt in. - Analytics payload: hashed user identifier + anonymised session data, to
analytics_webhook.
Open items
- Build per-tenant Sessions drilldown (Path A above).
- Scope
/admin/analyticsper-tenant (add?client=<id>filter). - Drop-off heatmap per format per tenant.
- D3: start firing
quiz_completed+variant_exposureevents toanalytics_webhook.
Next
→ 09 MMC bridge — WordPress ↔ CoachPilot gateway integration.