Skip to Content
Getting StartedArchitecture

Architecture

The Loop Health platform follows a monorepo architecture with shared packages, multiple apps, and a unified data layer.

System Diagram

┌─────────────────────────────────────────────────────────────────────────┐ │ Clients │ │ ┌──────────┐ ┌───────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ │ │ │ Consumer │ │ Luna AI │ │ Admin │ │Marketing │ │ Mobile │ │ │ │ App │ │ Chat │ │ CMS │ │ Site │ │ App │ │ │ └────┬─────┘ └─────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬────┘ │ └───────┼───────────────┼─────────────┼──────────────┼─────────────┼───────┘ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────────────────────┐ │ Authentication (Clerk) │ │ JWT verification · Role-based access · SSO tokens │ └───────┬───────────────┬─────────────┬─────────────┬───────────┬─────────┘ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────┐ ┌──────────────┐ ┌───────────┐ ┌─────────┐ │ Patient Graph │ │ Luna │ │ Payload CMS │ │ Call │ │Embeddings│ │ API │ │ Tools │ │REST+GraphQL │ │ Booking │ │ API │ │ (Hono) │ │ │ │ │ │ (Hono) │ │ (Hono) │ └────────┬────────┘ └────┬────┘ └──────┬───────┘ └─────┬─────┘ └────┬─────┘ │ │ │ ▼ ▼ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Shared Packages (@loop/*) │ │ core · shared · health-data · health-engine · biomarker-parser │ │ contraindications · guardrails · protocol-engine · rimo │ └───────┬──────────────────────────────────────────┬──────────────┘ │ │ ▼ ▼ ┌─────────────────────┐ ┌─────────────────────┐ │ Supabase PostgreSQL│ │ External Services │ │ ┌───────────────┐ │ │ ┌───────────────┐ │ │ │ patient_graph │ │ │ │ Rimo Health │ │ │ │ health │ │ │ │ Oura API │ │ │ │ payload │ │ │ │ Whoop API │ │ │ └───────────────┘ │ │ │ Dexcom API │ │ └─────────────────────┘ │ │ GetStream │ │ │ │ Trigger.dev │ │ └─────────────────────┘

Database Architecture

Loop Health uses a single Supabase PostgreSQL instance with three schemas:

patient_graph schema

Clinical health data managed by the Patient Graph API via Drizzle ORM.

TablePurpose
customer_profilesPatient demographics, conditions, medications
lab_resultsLab reports with biomarker readings
protocolsTreatment protocols with items and dosing
patient_eventsClinical timeline events
rbac_logsAudit trail for all data access
identity_mappingsCross-system identity resolution
subscriptionsMembership tier tracking
patient_treatmentsRimo Health treatment records
patient_prescriptionsPrescription tracking
conversation_historyCross-channel AI conversation logs
wearable_dataWearable device metrics
patient_wearable_readingsIndividual wearable readings
patient_wearable_daily_statsAggregated daily wearable statistics

health schema

Consumer app data managed via Drizzle ORM in my-loop-health.

TablePurpose
customersCustomer accounts
productsProduct catalog (synced from BigCommerce)
protocol_stacksUser-created protocol stacks
protocol_stack_itemsItems within protocol stacks
patient_cgm_connectionsCGM device connections
patient_glucose_readingsGlucose readings
patient_check_insWeekly health check-ins
followsUser follow relationships

payload schema

CMS content managed by Payload CMS ORM.

TablePurpose
usersCMS admin users
mediaUploaded files and images
peptidesPeptide compound catalog
stacksCurated protocol stacks
goalsHealth goal definitions
blog_postsBlog content
faqsFAQ articles
help_articlesHelp center content
coasCertificates of Analysis
research_papersResearch paper references

Authentication Flow

Client Request ┌──────────────┐ │ Clerk JWT │ Bearer token in Authorization header │ Verification │ └──────┬───────┘ ┌──────────────┐ │ Role │ Extracted from publicMetadata.adminRole │ Resolution │ Roles: admin, staff, support, provider, customer └──────┬───────┘ ┌──────────────┐ │ RBAC │ Permission matrix check │ Check │ resource × action × role └──────┬───────┘ ┌──────────────┐ │ Ownership │ For "ownOnly" permissions, │ Verification │ verify resource belongs to user └──────┬───────┘ ┌──────────────┐ │ Audit Log │ Record access in rbac_logs │ Entry │ └──────────────┘

RBAC Permission Matrix

ResourceAdminStaffProviderSupportCustomer
profilefullfullreadreadownOnly
lab_resultsfullfullreadreadownOnly
protocolsfullfullread/writereadownOnly
eventsfullfullreadreadownOnly
audit_logfullread

Data Flow: Lab Upload

1. User uploads PDF → POST /api/labs/upload 2. @loop/biomarker-parser extracts biomarkers via AI (Anthropic/OpenAI) 3. Raw biomarkers matched to canonical codes via @loop/health-data synonyms 4. Units normalized to standard units 5. Values classified against sex-specific reference ranges 6. Results stored in patient_graph.lab_results 7. @loop/health-engine computes health score 8. Patient event recorded in patient_graph.patient_events 9. Luna AI can access results via getLabResults tool

Data Flow: Wearable Sync

1. User connects device via OAuth (Oura/Whoop/Dexcom) 2. Tokens stored in patient_graph.wearable_data 3. Trigger.dev runs daily sync job (3 AM UTC) 4. Device API data fetched and normalized 5. Metrics stored: sleep, recovery, HRV, glucose, strain 6. @loop/health-score incorporates wearable data (40% weight) 7. Luna AI accesses via getWearableInsights tool

Data Flow: Luna AI Chat

1. User sends message → POST /api/chat 2. Emergency detection runs on user message 3. If userId exists, patient context loaded 4. AI model generates response (Anthropic Claude default) 5. Up to 5 tool calls executed (health data, labs, protocols, etc.) 6. Guardrails check response (compliance, business, safety) 7. Conversation stored in patient_graph.conversation_history 8. Clinical interactions logged for compliance 9. Streaming response returned to client

Monorepo Architecture

The platform uses Turborepo for build orchestration and pnpm workspaces for dependency management.

For detailed documentation on each application, see the Applications section.

Package Dependencies

@loop/core ← No internal deps (foundational) @loop/shared ← @loop/core @loop/database ← @loop/core @loop/health-data ← @loop/core (static data) @loop/contraindications ← @loop/core @loop/biomarker-parser ← @loop/core, @loop/health-data @loop/health-engine ← @loop/core, @loop/health-data, @loop/contraindications @loop/health-score ← @loop/core @loop/guardrails ← @loop/core, @loop/health-data, @loop/contraindications @loop/protocol-engine ← @loop/core @loop/hono ← @loop/core, @loop/shared @loop/patient-graph ← @loop/core, @loop/shared @loop/rimo ← @loop/core @loop/cms ← @loop/core, @loop/database, @loop/ai @loop/events ← @loop/shared @loop/auth ← (Clerk) @loop/stream ← @loop/core @loop/ai ← @loop/core

Build Order

Turborepo automatically determines the build order based on package.json dependencies. A typical build processes:

  1. @loop/tsconfig (no build needed)
  2. @loop/core@loop/shared@loop/database
  3. @loop/health-data@loop/biomarker-parser@loop/health-engine
  4. All remaining packages in parallel
  5. Apps (admin, my-loop-health, luna, etc.)