Beacon is an emergency supply optimizer for hospitals. Nurses can log inventory changes from a focused form or an ElevenLabs voice assistant, while the visualization tools show hospital inventory, transfer routes, volunteer supply requests, and regional analytics.
- Backend: Express, TypeScript, Firebase Admin SDK, Firestore
- Frontend: React, Vite, Tailwind CSS
- Maps: Mapbox via
react-map-gl - Voice: ElevenLabs Conversational AI widget
- Data: Firestore collections for hospitals, inventory, items, users, requests, and logs
backend/
server.ts Express app and API route registration
routes/ HTTP endpoints
services/ Firestore and business logic
models/ Shared backend types
scripts/ Firestore seed scripts
frontend/
src/components/ App screens and shared UI
src/lib/ API and session helpers
src/index.css Global theme and font setup
docs/
ELEVENLABS_SETUP.md ElevenLabs tool and webhook setup
- Node.js and npm
- Firebase project with Firestore in Native mode
- Firebase Admin service account credentials
- Mapbox token for the visualizer map
- ElevenLabs Conversational AI agent for voice updates
ngrokif testing ElevenLabs webhooks locally
Create backend and frontend env files:
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.envBackend values:
PORT=5050
FIREBASE_PROJECT_ID=your-project-id
FIREBASE_CLIENT_EMAIL=firebase-adminsdk@your-project-id.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
VOICE_WEBHOOK_SECRET=replace-with-a-random-secretFrontend values:
VITE_API_BASE=http://localhost:5050
VITE_MAPBOX_TOKEN=your-mapbox-token
VITE_ELEVENLABS_AGENT_ID=your-elevenlabs-agent-idThe Firebase web app values in frontend/.env are only needed for frontend Firebase features. The main app data currently flows through the backend API.
From the repo root:
npm --prefix backend install
npm --prefix frontend installRun the seed scripts from backend/ after backend/.env is configured:
cd backend
npx tsx scripts/seed-hospitals.ts
npx tsx scripts/seed-users.tsseed-hospitals.ts creates global items, five Chicago-area hospitals, and hospital inventory entries. seed-users.ts creates one nurse per seeded hospital.
Start the backend API:
npm --prefix backend run devThe API listens on:
http://localhost:5050
Start the frontend:
npm --prefix frontend run devOpen the Vite URL printed in the terminal, usually:
http://localhost:5173
Start an ngrok tunnel to the backend:
ngrok http 5050Use the HTTPS ngrok URL for ElevenLabs tools:
POST https://your-ngrok-domain/api/voice/webhooks/action
POST https://your-ngrok-domain/api/voice/webhooks/get
Every ElevenLabs webhook tool must send:
x-beacon-secret: <VOICE_WEBHOOK_SECRET>
Preferred voice update tool:
{
"hospitalId": "{{hospitalId}}",
"nurseId": "{{nurseId}}",
"entryId": "inventory entry id from inventoryList",
"action": "used",
"quantity": 5
}Action behavior:
used: decreasesavailableCountonlyremoved: decreases bothcountandavailableCountadded: increases bothcountandavailableCount
See docs/ELEVENLABS_SETUP.md for the full agent prompt, dynamic variables, and tool schemas.
- Nurse signs in by selecting a hospital and nurse profile.
- Nurse selects an item category and item.
- Nurse chooses an action:
Used: available stock decreases, total stock stays the same.Removed: available stock and total stock both decrease.Added: available stock and total stock both increase.
- Backend validates nurse access, updates Firestore, recalculates status, and writes an inventory log.
- If the item drops below threshold, the backend can create an automatic transfer request.
- Frontend passes
hospitalId,nurseId, andinventoryListto the ElevenLabs widget. - ElevenLabs maps spoken item names to
entryIdfrominventoryList. - ElevenLabs calls
/api/voice/webhooks/actionfor inventory changes or/api/voice/webhooks/getfor stock questions. - Backend applies the same inventory rules as the nurse form and logs the change to Firestore.
- The visualization map loads hydrated hospitals and active transfer requests.
- Hospital pins reflect current inventory-derived status.
- Active transfers draw routes between hospitals using Mapbox Directions.
- The mission panel shows transfer and shortage suggestions in a compact list.
- Requests are listed in a flat table.
- Admin or visualization users can assign donors and progress requests.
- Nurses can volunteer their own hospital for unassigned requests when appropriate.
- The analytics view loads summary, hospitals, inventory, and requests.
- It calculates network health, at-risk nodes, active transfers, and category health.
- The facility table lists area, score, and status for each hospital.
Common local endpoints:
GET /api/health
GET /api/hospitals
GET /api/hospitals?hydrate=true
GET /api/hospitals/:hospitalId
PATCH /api/hospitals/:hospitalId/inventory/:entryId
GET /api/items
GET /api/users
GET /api/requests
POST /api/requests
POST /api/voice/webhooks/action
POST /api/voice/webhooks/get
Inventory PATCH supports:
{
"change": -5,
"adjustmentType": "available",
"nurseId": "nurse-user-id",
"source": "MANUAL_FORM",
"message": "Used 5 isolation gowns"
}adjustmentType can be:
available: updateavailableCountonlystock: update bothcountandavailableCount
Backend typecheck:
npm --prefix backend run buildFrontend production build:
npm --prefix frontend run buildFrontend lint:
npm --prefix frontend run lint- Seed hospitals and users.
- Start backend and frontend.
- Sign in as a nurse.
- Submit a
used,removed, oraddedinventory update. - Open the visualization tool from the user menu.
- Review transfer routes, volunteer supply requests, inventory, and regional analytics.
- Optionally connect ElevenLabs through ngrok and test hands-free updates.
Built for Uncommon Hacks.