Disaster Monitor is a local-first disaster-monitoring MVP. It combines a Next.js map, a FastAPI backend, bounded source-backed reporting, and optional local Qwen models.
Assistant requests enter a bounded agent runtime. Current facts come from normalized trusted-source evidence; model output cannot create providers, countries, URLs, or facts. See docs/agent-runtime.md.
- Next.js/OpenLayers map with a default-visible, source-backed Active Incidents sidebar plus an assistant UI with session-local conversation state.
- FastAPI health, readiness, active-incidents, assistant, and operations endpoints.
- Optional local Qwen text and vision adapters.
- Deterministic request normalization, event selection, evidence reconciliation, and source-attributed reports.
- USGS, GDACS, NASA EONET wildfire, NASA COOLR landslide, CEMS GFM, and Smithsonian/USGS volcanic-eruption event adapters.
- Optional ReliefWeb supplementary situation reports when configured.
- Optional PostgreSQL/PostGIS history, snapshots, workers, freshness, reviews, and backup tooling.
- Bounded multimodal observations, contextual event media, triage, decision support, specialist coordination, and governed analytical ordering.
- Backend, frontend, adapter, integration, evaluation, and Playwright tests.
Unsupported combinations and missing configuration are reported explicitly. See current-disaster-reporting.md, multimodal-awareness.md, and capability-status.md.
Live weather, geocoding, automatic imagery retrieval, broad news aggregation, hosted models, paid map services, production identity/TLS, cloud deployment, and consequential analytics remain deferred. External datasets, human evaluations, and pilot evidence remain release gates.
apps/api/ FastAPI application and Python tests
apps/web/ Next.js application, OpenLayers map, and frontend tests
docs/ Architecture and other documentation
scripts/ Deterministic system-test server and optional smoke helpers
compose.yaml Production-like local API/web/scheduler/worker/PostGIS orchestration
- Python 3.12+
uv0.6+- Node.js 24 and npm 11+
- Ollama for real model requests (optional for tests)
- Docker Desktop if using Compose (optional)
Install Ollama from ollama.com, start it, and pull the configured model:
ollama serve
ollama pull qwen3:1.7b
ollama listThe backend defaults to http://localhost:11434 and qwen3:1.7b. Copy apps/api/.env.example to apps/api/.env to override the model, timeout, or allowed origins. No API key is required.
Start the backend:
uv sync --project apps/api
uv run --project apps/api uvicorn disaster_monitor.main:app --reload --host 127.0.0.1 --port 8001Start the frontend:
cd apps/web
npm ci
Copy-Item .env.example .env.local
npm run devUseful checks:
Invoke-RestMethod http://localhost:8001/api/v1/health
Invoke-RestMethod http://localhost:8001/api/v1/ready
Invoke-RestMethod 'http://localhost:8001/api/v1/incidents?time_window_days=7&limit_per_disaster=10'The incidents endpoint queries the registered worldwide event-discovery providers directly; it does not call Qwen. Its defaults are a 7-day window and at most 10 records per disaster. Each of the six hazards has a separate coverage state so an upstream failure, unavailable provider, or successful empty result cannot be mistaken for proof that no disaster occurred. Map features are drawn only from source-backed point, track, or area geometry returned by the endpoint.
With Docker Desktop running and Ollama running on the host:
docker compose up --buildThen open http://localhost:3000. The API container uses host.docker.internal to
reach Ollama. Compose also starts PostgreSQL/PostGIS, migration, scheduler, and worker
services with durable volumes. See
docs/operations/runbook.md.
Backend checks:
uv sync --project apps/api
uv run --directory apps/api ruff format --check src tests
uv run --directory apps/api ruff check src tests
uv run --directory apps/api mypy
uv run --directory apps/api pytest -qFrontend checks:
cd apps/web
npm ci
npm run format:check
npm run lint
npm run typecheck
npm test
npm run buildThe deterministic system test starts a fake-model FastAPI server and a Next.js dev server, so it does not need Ollama:
cd apps/web
npm run test:systemPlaywright may need its browser installed once:
npx playwright install chromiumThe optional live-provider smoke test is excluded from normal CI. It submits two natural-language named-country examples for every supported hazard, one worldwide question per hazard, and an all-hazard Active Incidents request while printing provider failures and coverage states:
uv run --project apps/api python scripts/live_disaster_smoke.pyIt was not run during the default offline verification.
After Ollama is running and ollama pull qwen3:1.7b completes:
uv run --project apps/api python scripts/real_qwen_smoke.pyThe readiness response must report both ollama_available: true and model_available: true. This smoke test is manual and excluded from CI because the local model runtime is not guaranteed.
- A
503assistant response means Ollama is not reachable or the configured model is not installed. Checkollama serve,ollama list,OLLAMA_BASE_URL, andOLLAMA_MODEL. - A frontend network error usually means the API is not running on port 8001 or
NEXT_PUBLIC_API_BASE_URLis incorrect. - OpenStreetMap tiles are external map tiles, not a disaster-data provider. If tiles are unavailable, the assistant and API tests still work.
- If Playwright cannot start, install Chromium with the command above and make sure both Node.js and
uvare onPATH.
Add future capabilities by introducing a focused application port only when the capability is used. Keep provider calls in infrastructure adapters, translate them into application DTOs, and inject the adapter from infrastructure/composition.py. The frontend should receive typed transport data through a feature API client rather than calling providers from React components.
See docs/architecture.md for the current dependency direction.