Your Passport to Better Healthcare
A patient-held iOS app that helps you build, carry, and share your complete health history — so you never have to repeat yourself to a new doctor.
Disclaimer: This app is for informational purposes only. It does not provide medical advice, diagnosis, or treatment. Always consult a qualified healthcare professional.
Navigating the healthcare system — especially in Quebec — is fragmented and frustrating:
- Patients repeat their history at every visit. When you see a new specialist, you start from scratch: listing medications, allergies, past surgeries, and family history from memory. Details get lost.
- Wait times are long; preparation is key. Quebec has some of the longest specialist wait times in Canada. When you finally get your appointment, you need to make every minute count — but most patients walk in without an organized summary of their health.
- Paper records are scattered. Prescriptions pile up in drawers. Discharge summaries get lost. There's no single, patient-controlled document that travels with you.
- Drug safety falls through the cracks. Patients often don't know if a new medication conflicts with an existing one or triggers a known allergy. Pharmacists catch some issues, but not all — and not before the prescription is written.
Sage puts a structured, AI-powered health passport in your pocket. You talk to it like you'd talk to a doctor — in plain language — and it organizes everything into a clean, shareable profile.
- Chat with Sage — Describe your health history naturally. Sage extracts conditions, medications, allergies, procedures, family history, injuries, and appointments, then saves them to your on-device profile.
- Scan prescriptions — Photograph a prescription label or doctor's note. Sage reads it with AI vision (OCR) and adds the medication to your profile automatically.
- Stay safe — When you add a medication, Sage checks for:
- Drug-drug interactions against your existing medications (via OpenFDA adverse events)
- Allergy contraindications against your recorded allergies (via OpenFDA drug labels)
- FDA warnings for the individual drug
- Duplicate detection so the same entry isn't added twice
- Track appointments — Log upcoming and past specialist visits with doctor name, location, date/time. Upcoming appointments sort to the top.
- Export and share — Generate a PDF health passport or a 24-hour shareable link with QR code. Hand it to any doctor, ER nurse, or specialist to bring them up to speed in seconds.
- Privacy-first — All health data lives exclusively on your device in SQLite. Nothing is stored on any server. The only data that leaves your phone is chat messages sent to Claude for processing (and the opt-in share link).
- Conversational — No forms to fill out. Just talk. Sage asks follow-up questions to get the details right.
- Clinically useful — Drug interaction checking, allergy contraindication alerts, and structured data export are features designed for real patient safety.
| Feature | Description |
|---|---|
| AI Chat | Conversational health history intake powered by Claude. Asks follow-up questions, confirms details before saving. |
| Prescription OCR | Camera-based scanning of prescription labels and documents. AI extracts medication name, dose, frequency. |
| Drug Safety Alerts | Checks new medications against existing drugs (interactions), allergies (contraindications), and FDA warnings. |
| Duplicate Detection | Prevents the same condition, medication, or appointment from being added twice. |
| Appointments | Track upcoming and past specialist visits. Auto-categorized by date. |
| Health Passport | Organized profile view with conditions, medications, allergies, procedures, family history, injuries, and appointments. |
| PDF Export | Clean, printable health passport with all profile data and optional QR code for the shareable link. |
| Shareable Link | 24-hour temporary URL that renders a self-contained HTML passport page (stored in Upstash Redis). |
| Dark/Light Mode | Full theme support persisted across sessions. |
| Onboarding | Guided setup with blood type dropdown, numeric height/weight inputs with unit toggles (cm/ft, kg/lbs). |
| Mobile | React Native + Expo (iOS, managed workflow) |
| Language | TypeScript |
| Local Storage | SQLite (expo-sqlite) — 8 tables: profile, conditions, medications, allergies, procedures, family_history, injuries, appointments |
| Backend | Vercel serverless edge functions (stateless API proxy) |
| AI | Anthropic Claude API (vision + text) |
| Drug Safety | OpenFDA Drug Label API + Drug Adverse Event API |
| Sharing | Upstash Redis (24hr TTL snapshots) |
expo-print + expo-sharing |
|
| Camera | expo-camera (base64 capture) |
Mobile App (Expo) Vercel Backend
┌─────────────────────┐ ┌─────────────────────┐
│ SQLite (on-device) │ │ api/chat.ts │
│ ├── profile │ chat + image │ ├── Claude API │
│ ├── conditions │ ───────────────> │ └── returns JSON │
│ ├── medications │ │ {reply, action}│
│ ├── allergies │ <─────────────── │ │
│ ├── procedures │ │ api/share.ts │
│ ├── family_history │ share profile │ ├── POST: store │
│ ├── injuries │ ───────────────> │ │ in Redis (24h) │
│ └── appointments │ │ └── GET: render │
│ │ <─────────────── │ HTML passport │
│ OpenFDA API │ └─────────────────────┘
│ ├── Drug warnings │
│ ├── Interactions │
│ └── Allergy checks │
└─────────────────────┘
Data flow: User message (+ full profile as context) -> lib/claude.ts -> POST /api/chat -> Claude -> structured JSON response with reply + action -> app applies action to SQLite -> profile refreshes.
Privacy: Health data never leaves the device except through the opt-in share flow. The Vercel backend is a stateless proxy — it forwards messages to Claude and returns the response. No health data is logged or stored server-side.
├── app/ # Expo Router screens
│ ├── splash.tsx # Animated splash -> profile check -> route
│ ├── onboarding.tsx # Disclaimer + profile form (name, DOB, blood type, height, weight)
│ ├── camera.tsx # Full-screen camera for prescription scanning
│ ├── (tabs)/
│ │ ├── index.tsx # Chat screen (AI conversation + action handling)
│ │ ├── profile.tsx # Health passport view (upcoming/past appointments, all sections)
│ │ └── export.tsx # PDF export + shareable link generation
│ └── _layout.tsx # ThemeProvider > SQLiteProvider > Stack
├── api/
│ ├── chat.ts # Vercel edge function — Claude API proxy
│ └── share.ts # Vercel edge function — Redis snapshot store + HTML renderer
├── lib/
│ ├── claude.ts # sendMessage + parseClaudeResponse (handles JSON, markdown, prose)
│ ├── openfda.ts # queryDrugWarnings, checkDrugInteractions, checkAllergyContraindications
│ ├── pdf.ts # buildPassportHtml — generates styled HTML for PDF export
│ ├── share.ts # postSnapshot — client-side share link creation
│ └── db/
│ ├── schema.ts # CREATE TABLE statements (8 tables)
│ ├── queries.ts # Generic addEntry/removeEntry/updateEntry + getFullProfile
│ └── init.ts # Database open + migrations
├── components/
│ ├── ChatMessage.tsx # Markdown-rendered chat bubble (user/assistant)
│ ├── TypingIndicator.tsx # Animated typing dots (3-dot bounce)
│ ├── ProfileSection.tsx # Card with title, count badge, item list
│ ├── SageHeader.tsx # App header with logo + theme toggle
│ ├── SageMascot.tsx # Mascot illustration
│ ├── SageLoadingScreen.tsx # Loading state
│ └── DisclaimerBanner.tsx # Required disclaimer component
├── constants/
│ ├── colors.ts # LightColors, DarkColors, ThemeColors type
│ └── theme.ts # Spacing, Radius, FontSize, FontWeight
├── context/
│ └── ThemeContext.tsx # Light/dark mode (persisted via expo-secure-store)
├── hooks/
│ └── useProfile.ts # Fetches FullProfile from SQLite, exposes refresh()
└── types/
└── index.ts # All TypeScript interfaces (Profile, Medication, Appointment, etc.)
- Node.js 18+
- Xcode (for iOS Simulator)
- Anthropic API key
- Vercel account (free tier works)
# Install dependencies (--legacy-peer-deps required due to react peer conflict)
npm install --legacy-peer-deps
# Set environment variables
cp .env.example .env
# Edit .env: set EXPO_PUBLIC_API_URL to your Vercel deployment URL
# Deploy the Vercel backend
vercel deploy
# Set ANTHROPIC_API_KEY in Vercel dashboard (Project > Settings > Environment Variables)
# Start the app
./node_modules/.bin/expo start --ios
npx expowill fail — always use the local binary. Camera features require a physical device.
| Variable | Where | Description |
|---|---|---|
ANTHROPIC_API_KEY |
Vercel dashboard only | Claude API key — never in the mobile app |
EXPO_PUBLIC_API_URL |
App .env |
URL of your deployed Vercel function |
KV_REST_API_URL |
Vercel dashboard only | Upstash Redis URL (for shareable links) |
KV_REST_API_TOKEN |
Vercel dashboard only | Upstash Redis token |
npm install -g eas-cli
eas login
eas build:configure
eas build --platform ios --profile production
eas submit --platform ios- All health data is stored locally on your device in SQLite — nothing is sent to any server by default
- Chat messages are sent to Claude via the Vercel proxy for AI processing — no data is logged or stored
- The shareable link feature is opt-in only and snapshots expire after 24 hours
- No analytics, no tracking, no user accounts
Built in 48 hours for the CBC Hackathon (April 2026) by a 2-person team from McGill University. This is a prototype — not intended for real medical use.
