What this document is
This is a reference document. It describes the Medhavy white label system as it currently exists β stack, configuration schema, analytics payload, pipeline stages, and known gaps. It is not a deployment guide and not a pedagogical explanation. Use it to look things up, not to learn how to deploy or to understand why the architecture is designed as it is. Those are separate documents.
1. Platform stack
Current as of March 2026. Live deployments: Science, Physics. White label slots: available.
| Layer | Technology | Notes |
| Frontend framework | Next.js | App router. Per-deployment layout via hostname resolution. |
| Authentication | Clerk (B2B org pattern) | Each institutional client = one Clerk Organization. Learners scoped to org. |
| Session tokens | JWT, 24-hour expiry | Hub verifies on every page load β see gap AI-003. |
| Search / retrieval | Orama (semantic) | One isolated index per deployment. No cross-tenant data. |
| AI pipeline | OpenAI | Two-stage: analyze-context β chat. See pipeline section. |
| Analytics storage | Supabase | Webhook receiver bypasses 16KB Clerk ceiling. See gap TD-008. |
| Hub / registry | hub.medhavy.com | Authentication Β· registry Β· analytics Β· access control Β· dashboard. |
| Content format | MDX via Fumadocs | Indexed into Orama at publish time. |
| Styling | Tailwind + CSS variables | Theme injected at root layout via next-themes. Per-tenant config object. |
2. System architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MEDHAVI HUB (hub.medhavy.com) β
β Authentication Β· Registry Β· Analytics Β· Access Control Β· Dashboard β
β Stack: Next.js Β· Clerk Β· JWT (24hr sessions) β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββΌβββββββββββββββ
βΌ βΌ βΌ
[deployment-A] [deployment-B] [deployment-N]
(Live: Science) (Live: Physics) (White Label Slot)
β β β
ββββββββββββββββΌβββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββββββββββ
β AI CHAT PIPELINE (Per Deployment) β
β Stage 1: /api/analyze-context β
β β question + page context + history β
β β keywords + tags + follow-ups + plan β
β β active pedagogy mode injected here β
β Stage 2: /api/chat β
β β Orama semantic search (isolated index) β
β β Sources + pedagogy prompt injected β
β β SSE stream: sources β tokens β done β
β Rule: Not in textbook β "Not in textbook." β
ββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββββββββββ
β BANDIT LAYER (Pedagogical selection) β
β Tracks: approach β outcome β update β
β Selects from: Direct Β· Socratic Β· Case Β· β
β Retrieval Β· Project β
β Updates: per learner, per session, per topicβ
ββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββΌβββββββββββββββββββββββββββββββ
β PERSONA LAYER (Swappable per client) β
β Tone Β· Depth Β· Examples Β· Disclaimer β
β Stored in tenant registry β not in code β
ββββββββββββββββββββββββββββββββββββββββββββββββ
3. Tenant registry schema
β Gap TD-001 β not yet implemented
The tenant registry currently lives in Clerk organization metadata, which has a 16KB ceiling and no structured lookup. The schema below represents the target state. The minimum viable implementation is tenants.json or an Edge Config KV store. See the gap matrix in section 6.
Each key is the institutional deployment hostname. All fields are required unless marked optional.
{
"[client].medhavy.com": {
"orgId": "org_clienta_2026", // Clerk organization ID
"textbooks": ["ai-literacy-v1"], // array of textbook identifiers
"oramaIndex": "[ENV: ORAMA_INDEX_X]", // env var name β not the key value
"oramaKey": "[ENV: ORAMA_KEY_X]", // env var name β not the key value
"persona": "corporate-advisor", // persona identifier β see section 4
"pedagogy": {
"active": ["case-based", "project-based"], // approaches bandit tests
"bandwidthTest": false, // true = test all five
"default": "direct-instruction" // fallback if bandit uninit
},
"badgeIssuer": "[Institution Name]", // appears on credential
"textbookOnly": true // AI restricted to textbook content
}
}
Field reference
| Field | Type | Required | Notes |
| orgId |
string |
Required |
Clerk organization ID. All API routes filter by this value. |
| textbooks |
string[] |
Required |
Array of textbook identifiers. Must match Orama index content. |
| oramaIndex |
string |
Required |
Name of the environment variable holding the Orama index ID β not the ID itself. See gap TD-003. |
| oramaKey |
string |
Required |
Name of the environment variable holding the Orama API key β not the key itself. See gap TD-003. |
| persona |
string |
Required |
Persona identifier. Must match an entry in the persona config store. See section 4. |
| pedagogy.active |
string[] |
Required |
Valid values: direct-instruction Β· socratic Β· case-based Β· spaced-retrieval Β· project-based |
| pedagogy.bandwidthTest |
boolean |
Optional |
If true, bandit tests all five approaches regardless of active array. Default: false. |
| pedagogy.default |
string |
Required |
Fallback approach used before the bandit has enough data to select. Must be in active array. |
| badgeIssuer |
string |
Required |
Institution name as it appears on issued credentials. |
| textbookOnly |
boolean |
Required |
If true, AI responds "Not in textbook." to any question outside indexed content. Always true for white label deployments. |
4. Theme configuration schema
Theme config is injected at root layout via next-themes and Tailwind CSS variables. No code changes required per deployment β all values are data.
const clientTheme = {
institutionName: "[Institution Full Name]",
platformName: "[Institution] AI Learning Lab",
primaryColor: "[Brand hex β 6-digit]",
secondaryColor: "[Brand hex β 6-digit]",
logoUrl: "/logos/[client]-logo.png",
faviconUrl: "/favicons/[client]-favicon.ico",
fontFamily: "'Inter', sans-serif",
domain: "[client].medhavy.com",
persona: {
name: "[Institution] AI Advisor",
tone: "authoritative | empathetic | inquisitive | structured",
depth: "decision-support | conceptual | foundational | applied",
examples: "finance | policy | curriculum | clinical | general",
disclaimer: "Responses sourced from [Institution]-verified materials only.",
textbookOnly: true
}
};
Valid persona tone values
| Value | Behavior | Typical deployment |
authoritative | Direct, concise, decision-oriented. Minimal hedging. | Executive education, professional associations |
empathetic | Encouraging, patient, checks understanding frequently. | K-12 networks |
inquisitive | Responds to answers with questions. Resists giving direct answers. | Think tanks, policy organizations |
structured | Framework-forward. Names the model before applying it. | Curriculum organizations |
Valid persona depth values
| Value | Behavior |
decision-support | Orients responses toward actionable decisions. ROI-framing. |
conceptual | Prioritizes understanding over application. Policy and research contexts. |
foundational | Assumes minimal prior knowledge. Defines before using. |
applied | Ties every concept to a concrete task or output. |
5. Analytics payload schema
β Gap TD-008 β Supabase sync not yet live
The payload below is the target schema for the Supabase webhook receiver at POST /api/analytics/ingest. This endpoint does not yet exist. See gap matrix.
POST /api/analytics/ingest
{
"orgId": "org_clienta_2026", // required β Clerk org
"userId": "[anonymized-hash]", // required β never raw PII
"event": "ai_interaction", // event type
"pedagogy": "case-based", // active approach at time of event
"chapter": "module-3-application", // textbook chapter identifier
"query": "[learner question text]", // stored for grounding audit only
"response": "grounded", // enum: grounded | not_in_textbook
"mouseTrace": {
"path": [...], // coordinate array
"dwellMs": 4200 // milliseconds on section
},
"bandyUpdate": {
"approach": "case-based",
"outcome": "positive" // enum: positive | neutral | negative
},
"timestamp": "2026-04-01T14:23:00Z"
}
Event type reference
| event value | Description | Required fields |
ai_interaction | Learner submitted a query to the AI tutor | all |
chapter_open | Learner opened a textbook chapter | orgId, userId, chapter, timestamp |
chapter_complete | Learner marked chapter complete or scrolled to end | orgId, userId, chapter, timestamp |
session_start | New authenticated session began | orgId, userId, timestamp |
bandyUpdate.outcome values
| Value | Condition |
positive | Learner continued engagement after response β follow-up question, chapter progression |
neutral | Session ended without clear positive or negative signal |
negative | Learner disengaged, repeated same question, or explicitly indicated confusion |
6. Technical gap priority matrix
CRITICAL and HIGH gaps must be resolved before any external institutional deployment. BACKLOG items are not blockers at pilot scale.
| ID | Description | Priority | Minimum viable fix | Sprint |
| TD-001 |
Tenant registry lives in Clerk org metadata. No structured lookup. Blocks multi-tenant routing. |
CRITICAL |
Implement tenants.json or Edge Config KV. Map hostname β Orama credentials + persona + pedagogy + content manifest. |
Sprint 1 |
| TD-003 |
Orama credentials hard-coded in source. Security and multi-tenant blocker. |
CRITICAL |
Migrate all Orama keys to environment variables, one env var pair per tenant. Registry references env var names, not values. |
Sprint 1 |
| TD-008 |
All analytics stored in Clerk org metadata. 16KB ceiling hit at moderate interaction volume. |
HIGH |
Supabase webhook receiver at /api/analytics/ingest. See payload schema in section 5. |
Sprint 1 |
| Theme config |
Branding changes require code edits. Every new client needs a developer. |
HIGH |
CSS variable injection at root layout from tenant config object. See theme schema in section 4. |
Sprint 1 |
| Pedagogy selector |
Bandit approach selection not wired to Stage 1 system prompt. Pedagogy config exists in registry but has no effect on AI behavior. |
HIGH |
Inject active pedagogy mode from tenant config into Stage 1 context analysis prompt. Five prompt variants required β one per approach. |
Sprint 1 |
| TD-005 |
TEXTBOOK_ONLY not enforced in Science deployment. New deployments should use Template/Physics logic. |
NOT A BLOCKER |
New white label deployments built on Template/Physics branch. Science deployment isolated from white label rollout. |
Backlog |
| AI-003 |
Hub verifies JWT on every page load. Performance cost at scale. |
LOW |
Session caching. Defer until after first pilot β not a correctness issue, a performance issue. |
Sprint 2 |
| TD-009 |
User iteration not synced on delete events. Stale data risk. |
LOW |
Defer. Not triggered at pilot scale. |
Sprint 3 |
7. Supported deployment types
This table defines expected configuration defaults by institution type. All values are overridable per tenant.
| Institution type |
Default pedagogy.active |
Default persona.tone |
Default persona.depth |
| Business school executive education |
case-based, project-based |
authoritative |
decision-support |
| Think tank / policy organization |
socratic, case-based |
inquisitive |
conceptual |
| Curriculum organization |
direct-instruction, project-based |
structured |
applied |
| Private K-12 network |
spaced-retrieval, project-based |
empathetic |
foundational |
| Professional association |
direct-instruction, spaced-retrieval |
authoritative |
foundational |