מידע · תיאום · החלטה · הצלת חיים
From the medic's voice to a printed form in the trauma team's hands — without typing a single word.
In a mass casualty incident (אר"ן / MCI) — a building collapse, a multi-vehicle crash, a mass-attack scene — a single field medic may triage dozens of casualties in minutes. Today that happens on paper and over a crackling radio: handwritten tags, verbal handoffs, numbers lost in the noise. The command center has no live picture. Hospitals learn what's coming when the ambulance doors open.
Every minute spent writing is a minute not spent treating. Every garbled radio call is a vital sign that never reaches the trauma bay.
DOMINO turns a medic's spoken report into structured, shared, life-saving data — instantly.
A medic holds a push-to-talk button and speaks a casualty report in natural Hebrew. DOMINO transcribes it, an LLM parses it into structured fields, the medic confirms with a glance, and the casualty appears live on the command center's board. The command center routes them to a hospital with an ETA. That hospital — and only that hospital — sees its inbound casualties and prints a fully-filled Form 101 over the original scanned document.
One Casualty object is the single source of truth. The board, the routing screen, and the printed form are all just views of it.
| Role | What they do | |
|---|---|---|
| 🎙️ | Field medic (חובש) — Android tablet, gloved, landscape | Push-to-talk dictation → review → commit. 11-column triage board, color-coded body chart for injuries & interventions, per-casualty voice updates. |
| 🗺️ | Command center (חמ"ל) — web | Live board of every casualty, assign hospital + ETA, stamp evacuation & escort, full append-only incident log. |
| 🏥 | Hospital (בית חולים) — web | Sees only its own inbound casualties (server-side filtered), arrival-clock ETA, one tap → printed Form 101 over the scanned original. |
A medic can also run all three roles on a single tablet via the topbar role switcher — the demo-safe fallback.
The hard part isn't the UI; it's reliably turning «פצוע ראשון, גבר כבן שלושים, פגיעת רסיסים בבטן, בהכרה, דופק 118, לחץ דם 90 על 60…» into clean fields — in the field, in Hebrew, sometimes with no signal, and never writing anything the medic didn't confirm.
flowchart LR
A[🎙️ Medic speaks<br/>natural Hebrew] --> B[Record-first<br/>16 kHz mono WAV]
B --> C{Network?}
C -->|online| D[Groq Whisper v3<br/>server transcription<br/>~sub-second]
C -->|offline| E[On-device<br/>Android STT]
D --> F[Claude Sonnet 4.6<br/>structured parse]
E --> F
F -->|API down| G[On-device<br/>regex fallback]
F --> H[📝 Review sheet<br/>editable · low-confidence amber]
G --> H
H -->|medic confirms| I[(✅ Casualty<br/>+ raw transcript<br/>+ audio + log)]
- Record-first — the recorder captures a WAV regardless of whether on-device STT is available, so the voice flow never stalls on a missing language pack.
- Server transcription via Groq's free Whisper v3 (Hebrew, synchronous, sub-second) — with automatic fallback to the device transcript if Groq is unreachable.
- Structured parsing by Claude Sonnet 4.6 into a typed casualty patch; a pure-Dart regex parser covers the canonical reports with zero network for a fully offline demo path.
- Human-in-the-loop, always — nothing is written without the medic's confirmation in the review sheet. Low-confidence fields are flagged amber; an amber banner warns when the parse came from the regex fallback rather than the LLM.
- Provenance is preserved — every voice commit stores the raw transcript, the audio path, and the STT engine used, in an append-only timestamped log.
DOMINO doesn't generate a new form — it fills the real, official scanned IDF casualty form (טופס 101) as a PDF overlay, so what the trauma team receives looks exactly like the document they already know.
- Text, check-marks, and injury marks drawn at calibrated coordinates over the scanned page.
- Hebrew rendered through the bundled Heebo TTF (standard PDF fonts have no Hebrew glyphs).
- Correct handling of the scan's landscape-stored-in-portrait rotation, verified against rendered output.
- One casualty → one form, or «כל הטפסים» → a merged PDF, one page per casualty. Print or share.
- 🔴 Live multi-device sync over Cloud Firestore — a medic's commit lands on the command center board in real time, offline-queued when the signal drops.
- 🔒 Strict data isolation — hospitals query
evac.hospital == myIdserver-side; they never see another hospital's casualties. - 🧠 Graceful degradation everywhere — Groq → device STT, Claude → regex, online → offline queue. The demo never blocks.
- 🩸 Built for gloved field use — touch targets ≥48 dp, ≥16 pt body text, landscape tablet board with no horizontal scroll.
- 🧩 Unified body chart — one color-coded body map drives both injury regions and CAT/FC/CG interventions (tap a zone → picker).
- 🌐 RTL-native Hebrew throughout, with numbers and clock times rendered LTR inside RTL text. Every user-facing string is centralized.
- 🗂️ Multi-event management — open or join an incident by a shareable 5-character code; each event is fully isolated.
┌──────────────┐ voice / touch ┌──────────────┐ live sync ┌──────────────┐
│ Field medic │ ─────────────────► │ Firestore │ ◄───────────► │ Command (חמ"ל)│
│ (tablet) │ Casualty patch │ (or Fake │ streams │ + Hospital │
└──────┬───────┘ │ in-memory) │ └──────┬───────┘
│ Groq Whisper + Claude ▲ │ Form 101
▼ │ single source of truth ▼ PDF overlay
review → confirm ───────────────────► Casualty ◄─────────────── Heebo TTF render
SyncServiceis an interface with two implementations:FirestoreSyncService(live default, web-persistent) and an in-memoryFakeSyncServiceseeded with the demo canon — the app silently falls back to Fake if Firebase init fails, so it always runs.- State via Riverpod (session, sync providers, incident actions).
- One
Casualtymodel with JSON (de)serialization; an append-only, timestamped log with the raw transcript on every voice entry.
| Layer | Tech |
|---|---|
| App | Flutter (web + Android), Dart, Riverpod |
| Backend / sync | Cloud Firestore + anonymous Firebase Auth |
| Transcription | Groq Whisper-large-v3 (server) · speech_to_text (on-device) · whisper.cpp GGML (debug compare) |
| Parsing | Claude Sonnet 4.6 (structured) · pure-Dart regex fallback |
Syncfusion PDF + printing + share_plus, Heebo TTF |
|
| Audio | record (16 kHz mono WAV) + path_provider |
| 🥈 Hackathon placement | 2nd place |
| Lines of Dart | ~11,500 |
| Passing tests | 85 (flutter analyze → 0 issues) |
| Roles | 3 — field · command · hospital |
| Transcription latency (Groq) | sub-second |
| Demo runtime, end-to-end | ~90 seconds |
The Flutter SDK lives at
~/flutterand is not on PATH — export it first.
export PATH="$HOME/flutter/bin:$PATH"
flutter pub get
flutter run -d chrome # web — command center / hospital, fast iteration
flutter test # 85 unit & widget tests
flutter analyze # keep at zero issuesLive voice parsing (optional — the app runs fully offline on the regex path without these):
# .env — baked in via --dart-define on the tablet build scripts
GROQ_API_KEY=... # free Groq key → server-side Hebrew Whisper
ANTHROPIC_BASE_URL=... # local proxy or API base → Claude structured parsingThe signed domino-release.apk is sideload-ready for the field tablet. See docs/SETUP.md for the full environment, Firebase config, and demo-day routine.
lib/
├── models/ Casualty · Incident · enums (all Hebrew labels live here)
├── services/ sync · STT · Groq transcribe · Claude/regex parsers · PDF · voice flow
├── state/ Riverpod — session · sync providers · incident actions
├── screens/ login · event list · field board · חמ"ל · hospital · Form 101 · calibration
├── widgets/ board table · body map · dictation & review sheets · stats · cells
└── theme.dart RTL tokens, Heebo
docs/ ARCHITECTURE · VOICE_PIPELINE · FORM101_EXPORT · UI_SPEC · DECISIONS · DEMO · SETUP
assets/ form101.pdf · form101_map.json · parser_prompt.txt · Heebo fonts · branding
The living docs are the source of truth — start with ROADMAP.md and CLAUDE.md.
These are non-negotiable, and they're what make DOMINO trustworthy in the field:
- One
Casualtyis the single source of truth — the board and Form 101 are views of it. - Nothing from dictation is written without medic confirmation.
- The log is append-only and timestamped; voice commits store the raw transcript.
- Empty fields are first-class — render «—», export blanks, never invent a value.
- Hebrew RTL +
he_ILeverywhere; numbers and times render LTR inside RTL text.