Offline-first civic emergency response platform with:
- a BLE mesh-enabled Flutter mobile app,
- a Node.js/TypeScript backend + PostgreSQL,
- a React admin dashboard,
- and an optional Python FastAPI QR-processing service.
This repository is a monorepo containing all components.
afm-work/
├── backend/ # Node.js + Express + PostgreSQL API
├── admin-dashboard/ # React + Vite operations/admin UI
├── mobile/ # Flutter app (BLE SOS, relay, onboarding)
├── python/ # FastAPI QR decode + forward helper service
├── docker-compose.yml # Local backend + postgres stack
└── WHITEPAPER.md # Full protocol and architecture details
- BLE SOS broadcast + mesh relay (mobile app)
- Offline queue + later sync to backend
- Onboarding + KYC-related flows
- SOS ingestion/ack lifecycle APIs
- Disaster reporting with image verification pipeline
- Admin APIs + dashboard views for events/users/reports
- Mobile: Flutter, Riverpod, BLE plugins, SQLite
- Backend: Node.js 22, TypeScript, Express, PostgreSQL, Zod, Vitest
- Dashboard: React 18, TypeScript, Vite
- Python service: FastAPI, OpenCV, NumPy, Uvicorn
- Docker + Docker Compose
- Node.js 18+ (Node 22 recommended for backend image parity)
- npm
- Flutter SDK (for mobile)
- Python 3.12 (for optional
python/service)
From repo root:
cd backend
cp .env.example .envUpdate at least these in backend/.env before starting:
BLE_ENCRYPTION_SECRETJWT_SECRETSERVER_SECRET(recommended)
Then run:
cd ..
docker compose up --buildServices:
- Backend:
http://localhost:3000 - Health:
http://localhost:3000/v1/health - Postgres:
localhost:5432
The compose backend command runs install + migration + dev server automatically.
cd backend
cp .env.example .env
npm ci
npm run migrate
npm run devUseful scripts:
npm run buildnpm startnpm testnpm run db:reset
cd admin-dashboard
npm install
npm run devDefault dashboard URL: http://localhost:5173
Dashboard access now requires a JWT in the browser. Open /login, paste an
admin token, and the UI stores it under ceal_token in localStorage.
Dashboard API base defaults to http://localhost:3000/v1.
Override with:
VITE_API_BASE_URL=http://localhost:3000/v1 npm run dev
Production URLs:
- Backend: `https://ceal.onrender.com`
- Admin dashboard: `https://ceal-peach.vercel.app`cd mobile
flutter pub get
flutter runFor local backend testing on LAN, update mobile/.env:
API_BASE_URL=http://<YOUR_LOCAL_IP>:3000/v1
BLE_ENCRYPTION_SECRET=<same-as-backend>
PYTHON_QR_BASE_URL=https://ceal-1.onrender.comHelper script:
cd mobile
./scripts/set_local_api.sh 3000 .envcd python
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
uvicorn app.app:app --host 0.0.0.0 --port 8001Default service health: http://localhost:8001/health
Run via Docker Compose:
docker compose up --build python-qrpython-qr reads its configuration from python/.env (via env_file in docker-compose.yml).
Important env vars:
TS_BACKEND_URL(full override, e.g.https://ceal.onrender.com/v1/onboarding/verify-aadhaar-qr)TS_BACKEND_BASE_URL(default:http://backend:3000)TS_BACKEND_PATH(default:/v1/onboarding/verify-aadhaar-qr)TS_BACKEND_AUTH_TOKEN(optional bearer token)PYTHON_SERVICE_SECRETPYTHON_REQUEST_TIMEOUT_SEC
All backend routes are under /v1:
/health/auth/onboarding/sos/users/disaster/admin
POST /v1/auth/token is gated by the X-Server-Secret header and is intended
for trusted internal/admin tooling only.
For protocol and lifecycle details, see WHITEPAPER.md.
Backend tests:
cd backend
npm test- Keep production secrets out of source control.
- Ensure mobile and backend
BLE_ENCRYPTION_SECRETvalues are aligned. - The backend currently validates env at startup; invalid or missing required vars will stop boot.
No explicit license file is currently present in this repository.