Spec-Version: 1.0 (2026-05-19)
Audience: Internal engineers joining the Money Quiz / CoachPilot platform
Status: Living document — updated as the system evolves
Source of truth: this directory (10 Projects/MoneyQuiz/docs/)
What this document is
A complete, dated architecture reference for the Money Quiz product as it exists in production today. Covers:
- The three actors (CoachPilot platform, TSG tenant, MMC tenant) and how they share infrastructure.
- The five canonical quiz formats and where each is hosted.
- The tenancy model (
slug_prefixdiscriminator, override layers). - The configuration schema (8 JSONB columns +
tenant_brand+framework_definitions/*.json). - The PATCH → resolve → cache configuration flow.
- The scoring engine + Tier-2 calibration applied uniformly across all formats.
- The dual-analytics architecture (MMC WordPress Quiz Leads + CoachPilot platform
/admin/analytics). - Deployment, operations, security, and what's deferred.
What this document is not: marketing material, an aspirational design, or a one-off migration plan. Everything described here is live as of 2026-05-19.
Table of contents
| Section | Topic | When to read |
|---|---|---|
| 01 | System overview — three-actor model, network diagram, key concepts | First |
| 02 | Tenancy model — slug_prefix, override columns, theme provider | When designing per-tenant features |
| 03 | Format taxonomy — 5 canonical names, ids, slugs, URL composition | When adding a new format or alias |
| 04 | Configuration schema — framework_configs, tenant_brand, migrations | When changing what tenants can configure |
| 05 | Configuration flow — PATCH → snapshot → resolve → cache → consumer | When debugging stale configs |
| 06 | Scoring + calibration engine across all formats | When tuning rules or adding a new framework |
| 07 | Public quiz Next.js runtime — tenant-config.ts, theme + brand contexts | When changing public quiz routing or theming |
| 08a | MMC WordPress analytics (Quiz Leads + A/B) | When working on Ilana's customer-facing analytics |
| 08b | CoachPilot platform analytics + planned Sessions tab | When building new platform-side analytics |
| 09 | MMC WordPress ↔ CoachPilot gateway bridge | When adding new bridge integrations |
| 10 | Image taxonomy, kubectl recipes, registry, rollout patterns | Before every deploy |
| 11 | Runbooks: SG drop, kubeconfig refresh, snapshot restore, smoke | When the cluster is misbehaving |
| 12 | Clerk JWT, bearer tokens, RBAC, bridge secrets, audit log | When adding authenticated endpoints |
| 13 | Deferred work, Phase-4 Likert migration, analytics federation | When planning new initiatives |
| 📋 | ROADMAP.md — Prioritised forward-looking work + sequencing recommendation | When planning a sprint or deciding what to build next |
Executive summary
CoachPilot is a multi-tenant Swiss-coach SaaS platform hosted on Exoscale Zurich. The Money Quiz is one product within it — a 5-format archetype assessment shipped on top of CoachPilot's gateway, agent, dashboard, and database.
Three actors share one set of pods:
- CoachPilot runs the platform (
api.coachpilot.ch,app.coachpilot.ch). - TSG is a tenant whose quizzes are served directly by the platform at
quiz.thesynergygroup.ch. - MMC is a tenant whose quizzes are iframed inside
mindfulmoneycoaching.online. The Legacy Likert format runs as a WordPress page on MMC's own domain; the four newer formats (Mirror, Game, Deal, Realm) run in the Next.js app and are iframed in.
The five formats (canonical IDs and display names):
| ID | Display | Hosted in | Scoring path |
|---|---|---|---|
likert | Money Quiz | MMC WordPress (/money-quiz/) | WP PHP → gateway /calibrate → mq_* tables |
qa | Money Mirror | moneyquiz-app Next.js | TS analyseScores with calibration |
game | Money Game | moneyquiz-app Next.js | TS analyseScores with calibration |
deal | Money Deal | moneyquiz-app Next.js | Agent generate_results with calibration |
realm | Money Realm | moneyquiz-app Next.js (shares Deal engine) | Same as Deal |
Configuration is per-tenant rows in framework_configs (8 JSONB override columns) + tenant_brand (identity + brand JSONB + webhook URLs). Defaults live in framework_definitions/money_archetypes.json. The resolver merges defaults with overrides; the public quiz consumes the resolved view via GET /api/v1/assess/framework/{id}/resolved?client=<tenant>, cached for 30 seconds.
The slug_prefix field on tenant_brand is the discriminator that distinguishes platform-hosted (TSG: empty prefix → quiz.thesynergygroup.ch/<bare>) from tenant-hosted iframe (MMC: money- prefix → mindfulmoneycoaching.online/money-<slug>/).
Calibration (Tier-2 archetype-coupling rules, e.g. victim_martyr_cooccurrence) is applied uniformly across all five formats as of 2026-05-19:
- TS-side (
score-analyser.ts) for Mirror + Game. - Python-side in the agent (
scoring_calibration.py) for Deal + Realm. - Python-side in the gateway (
scoring_calibration.py+/calibrateendpoint) for the WP Likert receiver.
All three implementations are required to produce byte-identical outputs for the same rule set.
Analytics today are dual-pane:
- MMC WordPress owns the customer-facing analytics (Quiz Leads, A/B Tests). Every quiz completion across the 5 formats POSTs to MMC's
/sg-course/v1/archetype-scoresendpoint (when the tenant hasarchetype_scores_webhookconfigured). - CoachPilot dashboard has
/admin/analytics(aggregate KPIs across all tenants). A per-tenant Sessions page is on the deferred backlog.
Deployment is image-based via Exoscale SKS. Four production images:
synergygroup/coachpilot-gateway:<tag>— FastAPI gatewaysynergygroup/coachpilot-dashboard:<tag>— CoachPilot admin dashboard (alongsidemoneyquiz-adminwhich is the public quiz)synergygroup/moneyquiz-admin:<tag>— Public Money Quiz Next.js appsynergygroup/az-adaptive-assessment:<tag>— Adaptive assessment agent (Python, NATS)
MMC's WordPress theme + mu-plugins deploy independently via SFTP to Hostinger.
Conventions
- File paths use markdown links so they're clickable in VS Code:
[score-analyser.ts](../../moneyquiz-app/src/lib/score-analyser.ts). - Dates are absolute ISO format. "Today" is 2026-05-19 unless otherwise stated.
- Image tags follow the pattern
<base>:<phase>-<scope>-<YYYYMMDD>-<short-description>for the gateway/dashboard (e.g.p10e-mmc-20260519-d4-webhooks) and semver for moneyquiz-admin (e.g.v1.6.6). - Commit-style references use the format used in
git log: short codes (C5, D4, B5b) for phase identifiers tied to plans in~/.claude/plans/.
How to contribute
When you change the system in a way these docs describe:
- Update the relevant section file (
architecture/0X-*.md) with the new state and a dated note. - If the change crosses sections, update the executive summary above.
- If you add a new section or rename one, update this TOC + the dashboard sidebar (see Section 10).
- If you delete deprecated behavior, move the description to Section 13 under "Removed" with the date.
Each section file is capped at ~500 lines per CLAUDE.md. If a section grows beyond that, split it into 0X-topic.md + 0X-topic-detail.md.
Quick links to the most-asked questions
- "Where does configuration X live?" → 04 Config schema
- "Why is my edit not visible on the quiz?" → 05 Configuration flow (30s cache + dashboard preview)
- "How do I add a new tenant?" → 02 Tenancy model §Onboarding
- "Why is calibration not firing on format Y?" → 06 Scoring + calibration §Per-format coverage
- "The site is down, what do I do?" → 11 Operations §Incident runbooks
- "How does Ilana see her quiz completions?" → 08a MMC analytics
- "What does the
slug_prefixfield do?" → 02 Tenancy model §Per-tenant URLs - "Why is the public quiz themed Ilana even on TSG?" → 07 Quiz app runtime §TenantThemeProvider default palette