Draft ยท v0.1
Technical Architecture
1. Stack
- Frontend + SSR: TanStack Start (React 19, Vite 7) on Cloudflare Workers.
- Backend: TanStack
createServerFnhandlers โ no separate API service. - Data + Auth + Storage: Lovable Cloud (managed Supabase).
- AI: Lovable AI Gateway (vision model for OCR/extraction, text model for insight synthesis).
- Observability (planned): structured server logs, no PHI, hashes only for prompts/completions.
2. Tenancy model
The unit of tenancy is a family. A family owns one or more children. Access to a child is granted via caregiver_access rows keyed on (child_id, user_id, role) . Every row-level security policy on child-scoped tables calls a SECURITY DEFINER function has_child_access(_user, _child, _min_role)to avoid recursive policy issues.
3. Data model (initial sketch)
families (id, name, created_by, created_at)
profiles (user_id PK/FK auth.users, display_name, created_at)
caregiver_roles (id, name enum: owner | co_parent | caregiver | viewer)
caregiver_access(id, child_id FK, user_id FK, role FK, invited_by, expires_at?)
children (id, family_id FK, given_name, dob, dx_tags[], created_at)
documents (id, child_id FK, uploader FK, storage_path, mime, sha256, status)
document_pages (id, document_id FK, page_number, text, embedding vector?)
timeline_events (id, child_id FK, event_date, kind, summary, source_doc_id?)
insights (id, child_id FK, source_doc_id FK, conclusion, why jsonb,
next_step, confidence, created_by_model, prompt_hash, created_at)
consents (id, granter_user_id, subject_child_id, grantee_user_id,
data_type, granted_at, revoked_at?)
audit_log (id, actor_user_id, action, target_table, target_id,
child_id, ip, ua, created_at)4. Service boundaries
- Public routes (marketing, docs) โ SSR, no auth.
- Authenticated routes โ under
_authenticated/, gated by managed layout. - Server functions โ all writes, all AI calls, all cross-child logic. RLS enforced as the calling user via
requireSupabaseAuth. - Admin operations (rare) โ dynamic import of the service-role client inside the handler, after a role check.
- No Edge Functions. No custom Node servers.
5. AI pipeline
upload
โ
โผ
[server fn] OCR page-by-page โโ vision model, min-necessary excerpts
โ
โผ
[server fn] structured extraction โโ strict JSON schema (Zod)
โ
โผ
[server fn] insight synthesis โโ prompt template versioned + hashed
โ
โผ
insights row { conclusion, why, next_step, confidence, prompt_hash }
โ
โผ
InsightCard refuses to render if any field is missingPrompts and completions are not stored raw. We persist a prompt_hash and the model id so we can reproduce behavior without keeping PHI in logs. The source-document citation lives in insights.why and links back to the exact document_pages row.
6. Integrations (future, not MVP)
- SMART on FHIR for Epic MyChart, Athena, Cerner โ per-user OAuth via App User Connectors.
- Calendars: Google, Apple (CalDAV), Microsoft โ appointment context for prep packets.
- School: IEP PDFs first; direct SIS connectors later where APIs exist.
- E-fax / secure email inbound for records intake from providers.
7. Authentication & 2FA
- Primary sign-in: email + password, plus Google OAuth via the Lovable broker.
- Two-factor authentication (required for all accounts): a second factor at every sign-in and before sensitive actions (adding a caregiver, exporting records, changing consent).
- Supported second factors:
- TOTP authenticator app (Authy, 1Password, Google Authenticator) โ the preferred factor, works offline.
- SMS one-time code โ delivered via a BAA-covered SMS provider; rate-limited and locked to the enrolled phone number.
- Email one-time code โ fallback when SMS is unavailable; delivered via a BAA-covered transactional email provider.
- Recovery codes โ one-time-use, generated at enrollment, shown once.
- SMS autofill on iOS / macOS Safari (Apple's SMS Passcodes AutoFill): the 2FA input uses
<input autocomplete="one-time-code" inputMode="numeric" />, and every SMS OTP message follows the domain-bound format Apple requires, e.g.:
The trailingYour Mariner Health code is 123456. @marinerhealth.app #123456@domain #codeline binds the code to our domain so iOS suggests it above the keyboard on the correct site only, matching the Apple docs. Android's Chrome/WebOTP API is supported by the same input attribute and message shape. - Session hardening: short-lived access tokens, rotating refresh tokens, idle timeout (15 min) with a re-auth prompt, and device sign-out from Account settings.
8. Environments
- Planning (now): no Cloud enabled, no data.
- Demo: Cloud enabled, synthetic data only, banner on every screen.
- Production: gated on BAA execution, penetration test, and a written HIPAA risk assessment.