๐Ÿ”ง How-to guide

WHITE LABEL DEPLOYMENT

How to onboard a new institutional client

Complete this guide to bring a new white label deployment from zero to live.

Version 1.0 | March 2026 | Reviewed by Dev the Dev
What this guide is for You are onboarding a new institutional client to the Medhavy white label platform. By the end of this guide, the client will have a live deployment at their subdomain with their branding, persona, content, and analytics configured. This guide assumes the Sprint 1 gaps (TD-001, TD-003, TD-008, theme config, pedagogy selector) have been resolved. If they have not, resolve them before beginning.

Prerequisites

Before you begin, confirm you have the following. Missing items will block specific steps โ€” the step will tell you which prerequisite it needs.

ItemSourceBlocks
Client Clerk organization ID (org_xxx) Created in Clerk dashboard. Client must be set up as a B2B organization. Step 1
Orama index ID and API key for this client Provisioned via Orama dashboard. One new index per client โ€” do not reuse. Step 2
Client brand assets: logo (PNG), favicon (ICO), primary and secondary hex colors Supplied by client. Step 3
Persona brief: tone, depth, example domain, disclaimer text See reference doc section 4 for valid values. Agree with client before writing system prompt. Step 4
Textbook content โ€” minimum 5 modules, fully through the pipeline Content pipeline must be complete before Step 5. See content pipeline how-to (separate doc). Step 5
Client subdomain confirmed: [client].medhavy.com Agreed with client. DNS entry created. Step 1

Deployment timeline

This is the realistic timeline for a new institutional client from signed agreement to live deployment. It assumes content work begins in parallel with infrastructure setup.

Day 1โ€“2
Steps 1โ€“3: Tenant registry, credentials, theme config. Infrastructure ready.
Day 3
Step 4: Persona written, tested against 20 representative queries, confirmed.
Day 1โ€“12
Content pipeline running in parallel: source gathering โ†’ generation โ†’ verification โ†’ visual assets โ†’ publishing. See content pipeline how-to.
Day 13
Step 5: Content indexed into Orama. Step 6: End-to-end QA.
Day 14
Step 7: Launch. First cohort onboarded.

Deployment steps

Step 1 of 7 ยท CRITICAL โ€” do this first
Register the tenant

Add the new client to tenants.json (or Edge Config KV if that migration is done). The hostname key must exactly match the client's deployment subdomain.

// tenants.json โ€” add this entry
{
  "[client].medhavy.com": {
    "orgId":           "org_[from_clerk]",
    "textbooks":       ["[content-identifier-v1]"],
    "oramaIndex":      "ORAMA_INDEX_[CLIENT]",        // env var NAME โ€” not value
    "oramaKey":        "ORAMA_KEY_[CLIENT]",           // env var NAME โ€” not value
    "persona":         "[agreed-persona-id]",
    "pedagogy": {
      "active":        ["[primary]", "[secondary]"],
      "bandwidthTest": false,
      "default":       "[primary]"
    },
    "badgeIssuer":     "[Full Institution Name]",
    "textbookOnly":    true
  }
}

Valid pedagogy.active values: direct-instruction ยท socratic ยท case-based ยท spaced-retrieval ยท project-based

Check the reference doc section 7 for default pedagogy values by institution type if the client has not specified a preference.

Done when: Hostname resolves to the correct Clerk org and returns the correct config object in local test. Deploy to staging before production.
Step 2 of 7 ยท CRITICAL โ€” before any external access
Set Orama credentials as environment variables

Never commit Orama keys to source. The tenant registry stores environment variable names, not values. The values go into the deployment environment only.

  1. Provision a new Orama index for this client in the Orama dashboard. Copy the index ID and API key.
  2. Add to the deployment environment (Vercel, or wherever Next.js is hosted):
    ORAMA_INDEX_[CLIENT]=[index-id-from-orama]
    ORAMA_KEY_[CLIENT]=[api-key-from-orama]
  3. Verify the environment variable names in the tenant registry (Step 1) exactly match the names you set here โ€” including case.
  4. Do not copy credentials between clients. Each client gets its own index and key pair.
Done when: AI pipeline returns results from the correct isolated Orama index. Verify by querying content that only exists in this client's textbook โ€” confirm the other client's index returns no results for the same query.
Step 3 of 7
Configure theme

Add the client's brand assets and theme config. No code changes โ€” this is all data.

  1. Place the client logo at /public/logos/[client]-logo.png
  2. Place the client favicon at /public/favicons/[client]-favicon.ico
  3. Add the theme config object to the theme config store:
    {
      domain:           "[client].medhavy.com",
      institutionName:  "[Full Institution Name]",
      platformName:     "[Institution] AI Learning Lab",
      primaryColor:     "[Brand hex]",
      secondaryColor:   "[Brand hex]",
      logoUrl:          "/logos/[client]-logo.png",
      faviconUrl:       "/favicons/[client]-favicon.ico",
      fontFamily:       "'Inter', sans-serif"          // change only if client specifies
    }
โš  Color contrast Check primary color against white text at WCAG AA (4.5:1 ratio minimum). Many brand colors fail this. If the client's primary color is too light, use it as a secondary and use a darker variant as primary.
Done when: Loading the client subdomain shows client logo, client colors, and correct platform name. No Medhavy branding visible unless client has opted to display it.
Step 4 of 7
Write and calibrate the persona system prompt

The persona is the primary way the AI feels different to each institutional client's learners. Get this right before content goes in โ€” a miscalibrated persona is harder to fix after launch.

  1. Agree on persona parameters with the client (or decide using defaults from reference doc section 7):
    • Tone: authoritative ยท empathetic ยท inquisitive ยท structured
    • Depth: decision-support ยท conceptual ยท foundational ยท applied
    • Example domain: finance ยท policy ยท curriculum ยท clinical ยท general
  2. Write the system prompt for this persona. The prompt must:
    • State the institution name and the AI's name as the client specified
    • Specify tone and depth in behavioral terms, not adjectives ("When a learner asks a question, respond with a follow-up question before answering" not "be inquisitive")
    • Include the disclaimer: "Responses are sourced from [Institution]-verified materials only."
    • Include the textbookOnly instruction: if a question cannot be answered from the indexed textbook, respond exactly: "That topic isn't covered in the course materials. I can only help with content from this program."
    • Include the five pedagogy mode variants. The active mode is injected at Stage 1. The prompt must handle all five without needing to be rewritten per mode.
  3. Test the persona against 20 representative learner queries before marking this step done. Include:
    • 5 on-topic questions the textbook covers
    • 3 questions that push the textbook boundary
    • 3 questions entirely outside the textbook
    • 3 questions designed to test tone (emotional, confrontational, confused)
    • 3 questions designed to test depth (too advanced, too basic, exactly right)
    • 3 questions testing each pedagogy mode's behavior
Done when: All 20 test queries produce responses that match the agreed persona, textbook-only queries are refused correctly, and off-topic queries return the correct refusal message verbatim.
Step 5 of 7
Index content into Orama

Content must complete the full pipeline before this step: source gathering โ†’ Bookie generation โ†’ Popper verification โ†’ Figure Architect visuals โ†’ MDX formatting via Fumadocs. Do not index unverified content.

  1. Confirm all modules have passed Popper assertion scan and human expert review.
  2. Run the Textbook Auditor against the full module set. Resolve any flagged structural issues before indexing.
  3. Index the MDX content into the client's Orama index (the one provisioned in Step 2). Verify the index ID matches the environment variable set in Step 2.
  4. Run a test query against the indexed content via the API โ€” not the UI. Confirm search returns results from the correct modules.
  5. Run a cross-contamination check: query a term that only appears in another client's content. Confirm this client's index returns no results.
Done when: All modules indexed, Textbook Auditor passes, cross-contamination check passes.
Step 6 of 7
End-to-end QA

Run this on staging, not production. Fix all failures before proceeding to Step 7.

Pre-launch verification checklist

  • Subdomain resolves to correct deployment. No redirect to main Medhavy site.
  • Authentication scoped to correct Clerk org. A user from another org cannot access this deployment.
  • Logo, colors, and platform name display correctly on all main pages.
  • AI returns grounded responses for on-topic queries โ€” cites textbook content.
  • AI returns correct refusal message for off-topic queries. Verbatim, not paraphrased.
  • Pedagogy mode injection confirmed โ€” Stage 1 prompt contains active pedagogy mode from tenant config.
  • Bandit layer initializes with default approach (from tenant config) for new learners.
  • Analytics events fire correctly โ€” verify at least one ai_interaction event lands in Supabase.
  • Orama search returns results only from this client's index.
  • No hard-coded Orama credentials visible in browser network tab.
  • Credential / badge shows correct badgeIssuer name.
  • 20-query persona test passed (from Step 4). Document results.
Done when: All checklist items pass on staging. Document any items that required a fix so the issue does not recur on subsequent deployments.
Step 7 of 7
Launch and first cohort onboarding
  1. Promote staging to production. Confirm all environment variables are set in the production environment โ€” they do not carry over automatically.
  2. Run the QA checklist again on production. At minimum, verify authentication, one AI interaction, and one analytics event.
  3. Onboard the first learner cohort through the client's Clerk organization. Confirm learners can authenticate and access content.
  4. Monitor the Supabase analytics dashboard for the first 24 hours. Verify interaction events are logging correctly and bandit is updating.
  5. Document any deployment-specific decisions (custom persona choices, content edge cases, configuration overrides) in the client's deployment record. The goal is for the next deployment to cost 10% of this one. That only happens if decisions are written down.
Done when: First cohort authenticated, first AI interactions logged in Supabase, no errors in production logs for first 24 hours.

After launch

Adding content modules

New modules follow the same pipeline: source โ†’ Bookie โ†’ Popper โ†’ Figure Architect โ†’ Fumadocs โ†’ Orama index. The index for this client already exists โ€” you are adding to it, not replacing it. Run the Textbook Auditor on new modules before indexing. No other steps change.

Updating the persona

If the persona needs adjustment post-launch, update the system prompt in the persona config store. Re-run the 20-query test before pushing the change. Persona changes take effect immediately on next session โ€” existing sessions continue with the old prompt until they re-authenticate.

Changing pedagogy configuration

To add or remove approaches from pedagogy.active, update the tenant registry. The bandit will adapt within a few sessions. If you change the default approach, new learners will start with the new default โ€” existing learner bandit state is not affected.

What to document for the next deployment

After every deployment, add a one-page record to the client's internal folder covering: any configuration overrides from defaults, persona calibration decisions and test results, content edge cases found during QA, and any infrastructure issues encountered and their resolutions. This is not optional. It is how the second deployment costs 10% of the first.