← Back to index | ← 07 Quiz app runtime | 08b Platform analytics →

The customer-facing analytics surface that Ilana uses today. Lives entirely in MMC's WordPress, sourced from a webhook + GA4. Pre-dates the CoachPilot platform analytics — the two coexist.


TL;DR

Ilana's primary analytics surface is wp-admin → MMC Marketing → Quiz Leads on mindfulmoneycoaching.online. It shows every prospect who's completed any Money Quiz format (Likert, Mirror, Game, Deal, Realm), their archetype scores, likelihood scoring (Hot/Warm/Cool/Cold), notes, campaigns, and tracking.

Plus the A/B Tests tab on the Landing Pages Dashboard, which surfaces GA4-backed per-variant conversion rates for the mq-likert vs mq-binary A/B split.

This is NOT in the CoachPilot dashboard. It predates it. The platform side (see 08b) has aggregate KPIs but not Ilana's per-prospect drilldown.


The data flow

Player completes a quiz (any format, any tenant with archetype_scores_webhook set)
                       │
                       ▼
   POST /api/quiz/results OR /api/deal/results in moneyquiz-app
                       │
                       │ fireArchetypeWebhook(brand, payload)
                       ▼
   POST <tenant_brand.archetype_scores_webhook>  (X-Deal-Secret header)
   For MMC: https://mindfulmoneycoaching.online/wp-json/sg-course/v1/archetype-scores
                       │
                       ▼
   archetype-scores.php receiver
   ├─ Authenticates (X-Deal-Secret OR logged-in user)
   ├─ Validates email + scores
   ├─ Sanitizes scores (legacy → production key mapping)
   ├─ C5: POSTs raw scores to gateway /calibrate (Likert path only via WP JS)
   ├─ Looks up WP user by email → snapshot to user_meta
   ├─ Dual-writes to legacy mq_prospects + mq_taken + mq_results tables
   ├─ Schedules transactional emails (prospect + coach)
   ├─ Stamps invite_token completion if present
   └─ Returns { stored: true | "pending", user_id, snapshot }
                       │
                       ▼
   Quiz Leads dashboard reads from mq_* tables
   ├─ Prospects tab: list + slide-out with likelihood + notes
   ├─ Campaigns tab: invite tokens + completion rates
   └─ Tracking tab: per-source funnel
                       │
                       │  separately:
                       ▼
   GA4 events fired client-side
   ├─ mq_variant_exposure  (on /money-quiz/ page load)
   └─ quiz_completed        (with mq_variant param)
                       │
                       ▼
   A/B Tests tab queries GA4 Data API → per-variant counts

Quiz Leads dashboard

Lives at wp-admin > MMC Marketing > Quiz Leads. Source files:

FileRole
page-quiz-leads.phpMenu registration + tab switch
quiz-leads-data.phpData loader + scoring helpers
quiz-leads-render.phpProspects tab HTML
quiz-leads-slideout.phpPer-prospect detail slide-out
quiz-leads-likelihood.phpHot / Warm / Cool / Cold scoring
quiz-leads-schema.phpCRM + campaign + invite schema
tab-campaigns.phpCampaigns tab
tab-tracking.phpTracking tab
quiz-leads.css / quiz-leads.jsUI assets
api/quiz-leads.phpREST endpoints (notes, likelihood updates, enrich, reply tracking)

Modular by design — adding a new tab or a new column doesn't require touching the rest.

Likelihood scoring

Each prospect gets a Hot / Warm / Cool / Cold tag derived from:

  • Their dominant archetype
  • Their secondary archetype
  • Whether they've interacted with email follow-ups
  • Whether they've booked a discovery call

Logic lives in quiz-leads-likelihood.php. Tweaking the formula is a WP code change.


A/B Tests tab

Lives at wp-admin > Landing Pages Dashboard > A/B Tests. Source: tab-mq-ab.php.

Queries the GA4 Data API for:

  • mq_variant_exposure count grouped by mq_variant (likert / binary)
  • quiz_completed count grouped by mq_variant

Surfaces:

  • Exposures × Completions × Completion rate per variant
  • Lookback: 1–90 days (configurable via ?days=)

Booking rate is NOT yet computed here because no booking event currently carries mq_variant. To add: fire a booking_completed event from page-book.php with the variant from cookie mmc_mq_fmt.

A/B variant assignment

The mu-plugin mmc-mq-ab-variant.php runs early in the WP request lifecycle (before headers are sent):

if ($vid !== '') {
    $bit = crc32('mq_fmt:' . $vid) & 1;
    $fmt = $bit === 0 ? 'likert' : 'binary';
    $source = 'assigned_hash';
}

Deterministic 50/50 split keyed on sg_vid (CoachPilot gateway cookie) or mmc_vid (MMC site cookie). Falls back to mt_rand for truly fresh visitors. Cookie mmc_mq_fmt, 30-day TTL. URL override via ?fmt=likert|binary.

The template at theme/page-money-quiz.php reads the resolved variant from $GLOBALS['mmc_mq_variant'] and renders accordingly.


Legacy mq_* tables (active storage)

Despite the name, legacy_mq_* (or mq_* depending on WP prefix) is the live storage for ALL Money Quiz completions on MMC today. Schema:

TableRowsPurpose
mq_prospects~2,705One row per email. Includes WP_User_ID link when matched.
mq_takenone per sessionDate_Taken, Quiz_Length, Response_Format, Dominant, Secondary, Scores_JSON, Source
mq_resultsone per (session × trait)Score per Likert trait, mapped via Master_ID 1..112
mq_master112 rowsTrait definitions, Archetype mapping (STRIDE-4: 1=hero, 5=artist, 9=ruler, ...)

See reference_mmc_money_quiz_schema.md for the full schema + STRIDE-4 mapping + bridge contract.

Key facts:

  • WP DB prefix is zt4k9_wp7u_.
  • Date_Taken is VARCHAR — sort via STR_TO_DATE(...,'%d-%b-%y').
  • Email is NOT unique — repeats are intended (one person can take multiple times).
  • Score scale: even-Likert {0,2,4,6,8}, max per archetype = 112 (not 70).

The "legacy" label is a misnomer; this is the active production schema.


What's NOT in MMC's analytics

  • Sessions from other tenants: TSG/coachpilot Mirror+Game+Deal completions don't POST to MMC's webhook (intentional — they have no archetype_scores_webhook configured today). They live in the platform's assess_sessions table only.
  • Real-time funnel from quiz.tsg side: GA4 events from the Next.js app fire only client-side after page load + completion. The MMC dashboard only sees what GA4 sees.
  • Per-question drop-off: Not exposed in the dashboard today. The data is in GA4 events but no UI surfaces it.

Cross-tenant federation — deferred

A tenant other than MMC could configure archetype_scores_webhook = <their CRM> and receive the same payload shape. The contract is stable:

{
  "email": "...",
  "name": "...",
  "scores": { "hero": 0.4, "victim": 0.65, "martyr": 0.32, ... },
  "dominant": "victim",
  "secondary": "hero",
  "source": "money-mirror",
  "response_format": "qa",
  "quiz_length": "...",
  "urgency": "guide",
  "combos": [...],
  "played_at": "2026-05-19T08:00:00Z"
}

When TSG / coachpilot eventually want their own equivalent dashboard, the choices are:

  1. Port the WP Quiz Leads UI to a standalone Next.js page (significant work — ~1 week).
  2. Build a platform-native per-tenant Sessions view in CoachPilot dashboard, backed by assess_sessions. Mirror the Quiz Leads UX (Hot/Warm/Cool/Cold, slide-out, notes). See 08b.

The platform-native path is the more strategic choice — it scales across tenants without needing a WordPress dependency.


Open items

  • Mirror webhook smoke end-to-end: complete a real Mirror as ?tenant=mmc, verify Quiz Leads receives the row. Pre-condition met by D2 deploy; production smoke not yet recorded.
  • Likert variant tracking: mq_variant field already exists in mu-plugin; need to verify it's flowing through the receiver into mq_taken.Source for the A/B tab to correlate.
  • GA4 mq_variant propagation from non-Likert formats: D3 (deferred) — fire quiz_completed events from Mirror/Game/Deal/Realm completions with the same mq_variant parameter so the A/B Tests tab can see cross-format conversion.

Next

08b Platform analytics — CoachPilot dashboard /admin/analytics + planned Sessions tab.