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.
| Table | Purpose |
|---|---|
customer_profiles | Patient demographics, conditions, medications |
lab_results | Lab reports with biomarker readings |
protocols | Treatment protocols with items and dosing |
patient_events | Clinical timeline events |
rbac_logs | Audit trail for all data access |
identity_mappings | Cross-system identity resolution |
subscriptions | Membership tier tracking |
patient_treatments | Rimo Health treatment records |
patient_prescriptions | Prescription tracking |
conversation_history | Cross-channel AI conversation logs |
wearable_data | Wearable device metrics |
patient_wearable_readings | Individual wearable readings |
patient_wearable_daily_stats | Aggregated daily wearable statistics |
health schema
Consumer app data managed via Drizzle ORM in my-loop-health.
| Table | Purpose |
|---|---|
customers | Customer accounts |
products | Product catalog (synced from BigCommerce) |
protocol_stacks | User-created protocol stacks |
protocol_stack_items | Items within protocol stacks |
patient_cgm_connections | CGM device connections |
patient_glucose_readings | Glucose readings |
patient_check_ins | Weekly health check-ins |
follows | User follow relationships |
payload schema
CMS content managed by Payload CMS ORM.
| Table | Purpose |
|---|---|
users | CMS admin users |
media | Uploaded files and images |
peptides | Peptide compound catalog |
stacks | Curated protocol stacks |
goals | Health goal definitions |
blog_posts | Blog content |
faqs | FAQ articles |
help_articles | Help center content |
coas | Certificates of Analysis |
research_papers | Research 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
| Resource | Admin | Staff | Provider | Support | Customer |
|---|---|---|---|---|---|
profile | full | full | read | read | ownOnly |
lab_results | full | full | read | read | ownOnly |
protocols | full | full | read/write | read | ownOnly |
events | full | full | read | read | ownOnly |
audit_log | full | read | — | — | — |
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 toolData 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 toolData 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 clientMonorepo 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/coreBuild Order
Turborepo automatically determines the build order based on package.json dependencies. A typical build processes:
@loop/tsconfig(no build needed)@loop/core→@loop/shared→@loop/database@loop/health-data→@loop/biomarker-parser→@loop/health-engine- All remaining packages in parallel
- Apps (
admin,my-loop-health,luna, etc.)