Skip to content

TalBenAmii/DOMINO

Repository files navigation

🁢 DOMINO

Decision-Oriented Medical Information & Network Operations

מידע · תיאום · החלטה · הצלת חיים

From the medic's voice to a printed form in the trauma team's hands — without typing a single word.


2nd Place Flutter Firebase Claude Groq Whisper

Hebrew RTL Tests analyze Lines


🚑 The problem

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.


💡 The solution

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.


🎬 End-to-end in three roles

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 voice pipeline — the heart of DOMINO

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)]
Loading
  • 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.

📄 Form 101 — the printed payoff

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.

✨ Highlights

  • 🔴 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 == myId server-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.

🏗️ Architecture

┌──────────────┐   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
  • SyncService is an interface with two implementations: FirestoreSyncService (live default, web-persistent) and an in-memory FakeSyncService seeded 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 Casualty model with JSON (de)serialization; an append-only, timestamped log with the raw transcript on every voice entry.

Tech stack

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
PDF Syncfusion PDF + printing + share_plus, Heebo TTF
Audio record (16 kHz mono WAV) + path_provider

📊 By the numbers

🥈 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

🚀 Getting started

The Flutter SDK lives at ~/flutter and 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 issues

Live 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 parsing

The 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.


📁 Project structure

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.


🛡️ Design invariants

These are non-negotiable, and they're what make DOMINO trustworthy in the field:

  1. One Casualty is the single source of truth — the board and Form 101 are views of it.
  2. Nothing from dictation is written without medic confirmation.
  3. The log is append-only and timestamped; voice commits store the raw transcript.
  4. Empty fields are first-class — render «—», export blanks, never invent a value.
  5. Hebrew RTL + he_IL everywhere; numbers and times render LTR inside RTL text.

🥈 Built in a hackathon. Designed for the worst day on the job.

מהקול של החובש ועד נייר ביד הצוות בטראומה — בלי להקליד מילה.

DOMINO · a hackathon project · Flutter · Firebase · Claude · Groq Whisper

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors