Solution
How Disaster Compass is architected and implemented — a rules-based, transparent action planner.
System architecture
Three layers, cleanly separated: a React presentation layer, a pure decision engine, and an in-memory state and data layer.
Presentation layer
A React single-page app rendered with TanStack Start (SSR) and routed by file-based TanStack Router. Styling is Tailwind CSS with shadcn/ui (Radix) primitives.
React + TypeScript
Typed, component-driven UI.
TanStack Start + Router
File-based routes under src/routes with SSR and scroll restoration.
Tailwind + shadcn/ui
Utility styling over accessible Radix primitives.
Leaflet map
Renders routes, shelters, and hazard layers over North Creek.
Decision engine
Pure, deterministic functions turn signals into action. No black box: the same inputs always produce the same output, and every score is explained inline.
decideAction (lib/actions.ts)
Maps disaster + household profile to a single go / stay / wait action with a reason.
scoreRoute (lib/scoring.ts)
Scores routes from 100 using named terms — flood, bridge, blocked-road, distance/time penalties and elevation, shelter-fit, accessibility bonuses.
getBestRoute
Selects the highest-scoring non-rejected route, with a safe fallback.
Recovery checklist (lib/recovery.ts)
Builds the phase-aware post-event checklist.
State & data
Root-level React context holds the golden-path flow so decisions survive navigation. The demo runs on in-memory seed data — no live APIs, no database.
ScenarioContext
Disaster selection, route choice, volunteer approval, recovery progress — provided above all routes.
PhaseContext
Tracks the active lifecycle phase (Prepare / Respond / Recover) and resident vs community mode.
Seed data (data/seed.ts)
Households, shelters, routes, and blocked roads for the fictional town of North Creek.
TanStack Query
Caching layer ready for any async data fetching.
Implementation principles
Transparent by construction
Every recommendation shows its inputs, weights, and rejected alternatives. Trust is earned in the UI, not asserted.
Deterministic & testable
The engine is pure functions with unit tests (e.g. recovery.test.ts) — reproducible and easy to verify.
Lifecycle-shaped
Code is organized around Prepare, Respond, and Recover so the product mirrors how emergencies actually unfold.
