SnapAid lets users assess and document injuries in real time — capture a photo, answer guided triage questions, and receive an AI-generated care plan in seconds.
- Overview
- Features
- How It Works
- Tech Stack
- Architecture
- Project Structure
- Getting Started
- Environment Variables
- API Reference
- Database Schema
- Roadmap
SnapAid is a cross-platform mobile application that guides users through structured injury self-reporting. The app collects a photo of the injury, walks the user through a short triage questionnaire, and instantly generates a care report — including a care level classification (Home Care / See a Doctor / Urgent), first-aid steps, and warning signs to watch for.
Reports are stored in Supabase, exportable as PDFs, and shareable with a doctor directly from the app. An optional AI layer powered by a local LLM rewrites reports in natural language and enables a contextual chat session per report.
⚠️ Disclaimer: SnapAid is an informational tool and does not provide medical diagnoses. Always consult a qualified healthcare professional for medical decisions.
| Feature | Description |
|---|---|
| 📸 Injury Photo Capture | Consent-gated in-app camera capture with upload to Supabase Storage |
| 📝 Guided Triage Questionnaire | Multi-step form covering pain level, bleeding, mobility, and time elapsed |
| 🤖 AI Report Generation | Heuristic-based report with optional LLM rewrite for natural language output |
| 🏥 Care Level Classification | Three-tier system: Home Care · See a Doctor · Urgent |
| 💬 AI Chat Per Report | Contextual Q&A powered by LLM — scoped to each specific injury report |
| 📄 PDF Export | Shareable single or bulk PDF reports with first-aid steps and warning signs |
| 👨⚕️ Doctor Invite System | Invite a doctor via email to review a report; invite tracked in database |
| 🕓 Report History | Full archive with search, filter by care level, bulk delete, and bulk export |
| 👤 User Profiles | Avatar upload, region, notification preferences |
| 🌙 Dark / Light Mode | Full theme support with persistent user preference |
| 🩺 Doctor Dashboard (Preview) | Clinician-side UI for reviewing reports with tabbed detail and response form |
User Opens App
│
▼
Auth Gate (Supabase)
│
├── New User ──► Register ──► Profile Created
│
└── Existing ──► Main App
│
▼
┌─────────────┐
│ Home Tab │ ← Recent reports + Quick Start
└─────────────┘
│
"Start New Report"
│
▼
┌─── Step 1: Photo ────┐
│ Camera capture or │
│ skip (optional) │
└──────────┬───────────┘
│
▼
┌─── Step 2: Questions ┐
│ Pain / Bleeding / │
│ Mobility / Time │
└──────────┬───────────┘
│
▼
┌─── Step 3: Results ──┐
│ Care Level + Report │
│ (+ optional AI │
│ rewrite via LLM) │
└──────────┬───────────┘
│
┌────────┴────────┐
▼ ▼
Save to DB Share PDF
(Supabase)
Frontend
- Flutter / Dart — cross-platform mobile UI
- camera — in-app injury photo capture
- image_picker — gallery-based avatar selection
- pdf + printing — report generation and export/share
Backend (AI Sidecar)
- FastAPI — Python web framework
- Uvicorn — ASGI server
- OpenAI-compatible LLM — report rewriting and contextual chat (tested with Ollama /
qwen3-vl:2b) - SMTP — doctor invite email delivery
Database & Auth
- Supabase — PostgreSQL, user authentication, and object storage
- Auth via
supabase_flutter(email/password) - Tables:
injury_reports,profiles,doctor_invites,support_docs - Storage buckets:
injury-images,profile-avatars
- Auth via
┌─────────────────────────────────────────┐
│ Flutter App │
│ │
│ ┌──────────┐ ┌────────────────────┐ │
│ │ Screens │→ │ Services │ │
│ │ (UI) │ │ AuthService │ │
│ │ │ │ ReportRepository │ │
│ │ │ │ AiClient │ │
│ │ │ │ ReportPdfService │ │
│ └──────────┘ └────────┬───────────┘ │
└───────────────────────── │ ─────────────┘
│
┌────────────┴────────────┐
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ Supabase │ │ FastAPI Backend │
│ • Auth │ │ /rewrite_report │
│ • PostgreSQL │ │ /chat_about_ │
│ • Storage │ │ report │
└─────────────────┘ │ /send_doctor_ │
│ invite_email │
└────────┬──────────┘
│
▼
┌─────────────────┐
│ LLM Endpoint │
│ (Ollama/OpenAI │
│ compatible) │
└─────────────────┘
Pattern: Feature-screen UI with a service/repository layer. Stateful widgets call singleton services (AuthService, ReportRepository, AiClient) directly. Supabase is the source of truth; FastAPI acts as a lightweight AI orchestration sidecar.
snapaid/
├── lib/
│ ├── main.dart # App entrypoint, auth gate, shell nav
│ ├── supabase_config.dart # Supabase connection constants
│ ├── models/
│ │ ├── injury_report.dart # Core report domain model + care-level mapping
│ │ ├── new_injury_state.dart # Transient wizard state (photo → questions)
│ │ ├── doctor_invite.dart # Doctor invite model
│ │ └── user.dart # User profile model
│ ├── services/
│ │ ├── auth_service.dart # Supabase auth + profile management
│ │ ├── report_repository.dart # Data access + heuristic report generation
│ │ ├── ai_client.dart # FastAPI AI backend HTTP client
│ │ └── report_pdf_service.dart # PDF formatting and export
│ ├── screens/
│ │ ├── home_screen.dart # Dashboard + recent reports
│ │ ├── history_screen.dart # Archive with search/filter/export
│ │ ├── new_injury_photo_screen.dart # Step 1: Photo capture
│ │ ├── new_injury_questions_screen.dart # Step 2: Triage questionnaire
│ │ ├── new_injury_summary_screen.dart # Step 3: AI report output
│ │ ├── report_detail_screen.dart # Full report + doctor invite + chat
│ │ ├── profile_screen.dart # User profile hub
│ │ ├── doctor_dashboard_screen.dart # Clinician report list (preview)
│ │ └── ...
│ ├── theme/
│ │ ├── snap_theme.dart # Design tokens + light/dark ThemeData
│ │ └── theme_controller.dart # Runtime theme toggle
│ └── widgets/
│ ├── injury_report_card.dart # Reusable report list item
│ └── primary_button.dart # Reusable CTA button
├── backend/
│ ├── main.py # FastAPI AI + email backend
│ └── requirements.txt
├── pubspec.yaml
└── run.sh # One-command local dev startup
- Flutter SDK
>=3.0.0 - Python
>=3.11 - A Supabase project
- An OpenAI-compatible LLM endpoint (e.g. Ollama running locally)
git clone https://github.com/Vihaan-Singhal1/SnapAid.git
cd SnapAidIn lib/supabase_config.dart, replace the placeholder values with your Supabase project credentials:
const supabaseUrl = 'YOUR_SUPABASE_URL';
const supabaseAnonKey = 'YOUR_SUPABASE_ANON_KEY';Copy the example env file and fill in your values:
cp .env.example .envflutter pub getcd backend
pip install -r requirements.txt
uvicorn main:app --reload --port 8000Or from the project root:
./run.shflutter runCreate a .env file in the project root based on .env.example:
| Variable | Description | Default |
|---|---|---|
LLM_API_URL |
OpenAI-compatible chat completions endpoint | http://localhost:11434/v1/chat/completions |
LLM_MODEL |
Model name for rewrite/chat | qwen3-vl:2b |
SMTP_HOST |
SMTP server for doctor invite emails | — |
SMTP_PORT |
SMTP port | 587 |
SMTP_USER |
Sender email address | — |
SMTP_PASSWORD |
SMTP password | — |
Rewrites a locally-generated injury report into natural, medically-cautious language.
{
"report_text": "string",
"care_level": "home_possible | see_doctor | urgent"
}Contextual Q&A about a specific report. LLM is strictly scoped to avoid diagnosis.
{
"report_context": "string",
"messages": [{ "role": "user", "content": "string" }]
}Sends a doctor an invitation email to review a patient's report.
{
"doctor_email": "string",
"patient_name": "string",
"report_id": "string"
}Accepts a doctor's diagnosis/prescription response. Full persistence planned for v2.
profiles
id uuid PK (FK → auth.users)
name text
region text
avatar_url text
notifications bool
injury_reports
id uuid PK
user_id uuid FK → profiles
title text
summary text
care_level text -- 'home_possible' | 'see_doctor' | 'urgent'
first_aid_steps text
warning_signs text
photo_url text
created_at timestamptz
doctor_invites
id uuid PK
user_id uuid
report_id uuid
doctor_email text
status text
note text
created_at timestamptz
Storage Buckets
injury-images→user_{id}/injury_{timestamp}.jpgprofile-avatars→ user profile pictures
- True computer vision pipeline — on-device or cloud wound classification model
- Doctor portal backend persistence — full save/load for diagnoses and prescriptions
- Push notifications — alert patients when a doctor responds
- Secure credential management via
--dart-definebuild-time injection - App Store / Play Store deployment
- Report sharing via link — shareable read-only web view
- Multi-language support
Built with ❤️ using Flutter · Supabase · FastAPI