A full-stack peer-support platform connecting veterans with trusted "buddy" volunteers via real-time SOS alerts, AI-assisted empathetic communication, geospatial buddy matching, and mood-driven wellness check-ins.
- Overview
- Feature Matrix
- System Architecture
- Tech Stack
- Database Schema
- API Reference
- Getting Started
- Project Structure
- Architectural Decisions
- Author
Komrade is a crisis-aware peer support network built specifically for veterans. It pairs veterans with vetted "buddy" volunteers who can be reached in moments of distress. The system combines real-time WebSocket event delivery, geospatial proximity matching, AI-rewritten empathetic responses (with hard-wired crisis interception), and a voice-to-text interface — all backed by a dual-database architecture (PostgreSQL for relational state, MongoDB for AI conversation history).
| Dimension | Value |
|---|---|
| Backend | FastAPI 0.115+ (Python 3.11+) |
| Auth | JWT HS256, 7-day expiry |
| User roles | veteran, buddy, admin |
| AI providers | Google Gemini 1.5 Flash · Ollama (llama3.1) |
| Real-time | Persistent WebSocket per user |
| STT | ElevenLabs Scribe v1 |
| Databases | PostgreSQL (relational state) + MongoDB (AI chat history) |
- Veterans invite buddies by email; buddies accept or decline
- Configurable trust level per link (1–5 scale)
- Veteran-initiated block at any time
- Buddy inbox for incoming SOS alerts with response + ETA fields
- Manual SOS or auto-trigger on low-mood check-in
- Auto-selects up to 5 buddies ranked by: availability + trust level + proximity (haversine)
- Escalation: if no acceptance within 60 seconds, alert fan-out expands
- Cooldown: 60-second minimum between SOS blasts (prevents alert fatigue)
- Safety fallback: if no online nearby buddy exists, falls back to all accepted buddies regardless of location or presence
- SOS lifecycle:
OPEN → ESCALATED → CLOSED
- Daily mood score (1–10) with optional tags, free-text note, and "wants company" flag
- Auto-triggers SOS on critically low mood scores
- Dashboard shows last 7 check-ins with trend visualization
- Users compose messages; the backend rewrites them via Gemini or Ollama into empathetic, personalised responses
- Crisis keyword interception: suicide/self-harm terms short-circuit directly to the 988 Lifeline response — no AI call is made
- Full conversation history persisted to MongoDB (
komrade.translations) - Dual-provider abstraction: switch between
geminiandollamavia env var
- Browser records audio (WebM/WAV)
- Sent to ElevenLabs Scribe v1 for transcription
- Transcript auto-fills the chat input field
- Persistent WebSocket per authenticated user
- Server-push events:
sos.created,sos.recipient_updated,sos.closed - WS manager is a module-level singleton enabling fire-and-forget broadcasts from HTTP handlers
- Status:
AVAILABLE,BUSY,OFFLINE - Configurable quiet-hour windows (e.g. 22:00–07:00) — buddies are excluded from SOS targeting during their window
- Lat/lng push from client; haversine-ranked buddy selection
- Leaflet map page renders buddy positions visually
┌──────────────────────────────────────────────────────────────────┐
│ Browser (React 18 + TypeScript) │
│ │
│ React Router v6 · Leaflet Map · WebSocket client │
│ JWT stored in localStorage · Typed API client (fetch) │
└────────────────────┬──────────────────────────┬──────────────────┘
│ HTTP /api/* │ WS /ws
▼ ▼
┌──────────────────────────────────────────────────────────────────┐
│ FastAPI (Uvicorn ASGI) │
│ │
│ Routers: auth · buddies · checkins · sos · presence │
│ settings · translate · stt · ws · health │
│ │
│ Services: ai_service · buddy_service · sos_service │
│ geo_service · auth_service │
│ │
│ WS Manager (singleton) ← broadcasts SOS events to all clients │
└────────┬───────────────────────────────────┬─────────────────────┘
│ SQLAlchemy (asyncpg) │ Motor (async)
▼ ▼
┌─────────────────┐ ┌────────────────────┐
│ PostgreSQL 15+ │ │ MongoDB │
│ 8 tables │ │ translations coll │
│ Alembic migs │ │ AI chat history │
└─────────────────┘ └────────────────────┘
│
▼ httpx (async)
┌────────────────────────────────────┐
│ AI Providers │
│ • Google Gemini 1.5 Flash │
│ • Ollama (llama3.1 — local LLM) │
│ • ElevenLabs Scribe (STT) │
└────────────────────────────────────┘
| Component | Technology |
|---|---|
| Web framework | FastAPI 0.115+ |
| ASGI server | Uvicorn 0.32+ (uvloop, httptools, watchfiles) |
| ORM | SQLAlchemy 2.0 (async, declarative mapped columns) |
| Migrations | Alembic 1.13+ |
| Primary database | PostgreSQL (port 5433) |
| Secondary database | MongoDB via Motor 3.6+ (async driver) |
| Validation | Pydantic v2 + pydantic-settings |
| Auth | python-jose (JWT HS256) + passlib/bcrypt |
| AI — Gemini | google-genai 1.0+ |
| AI — Ollama | httpx async calls to local Ollama REST API |
| STT | ElevenLabs API (Scribe v1) |
| HTTP client | httpx 0.27+ |
| Testing | pytest 8+ · pytest-asyncio · httpx TestClient |
| Component | Technology |
|---|---|
| Language | TypeScript 5.6 |
| UI framework | React 18.3 |
| Bundler | Vite 5.4 |
| Routing | React Router v6 |
| Maps | Leaflet 1.9 + react-leaflet 4.2 |
| Real-time | Native WebSocket API via api/ws.ts event bus |
| Testing | Vitest 2.1 + @testing-library/react + jsdom |
users ──┬── buddy_links ────────────────── users (buddy)
│ └── trust_level (1–5)
│
├── buddy_presence (AVAILABLE | BUSY | OFFLINE)
│
├── mood_checkins
│ └── auto-trigger SOS on low score
│
├── sos_alerts ──── sos_recipients (NOTIFIED | ACCEPTED | DECLINED)
│ └── trigger_type: MANUAL | MOOD
│ └── status: OPEN | ESCALATED | CLOSED
│
├── user_settings (quiet_hours, share_location, sos_radius_km)
│
└── reports (reporter_id → reported_user_id)
Stores every AI conversation turn: user_message, ai_response, safety_flag, provider, timestamp
| Method | Route | Auth | Description |
|---|---|---|---|
POST |
/auth/register |
Public | Create user account |
POST |
/auth/login |
Public | Authenticate, return JWT |
GET |
/buddies |
Veteran | List buddy links |
POST |
/buddies/invite |
Veteran | Send buddy invitation |
PATCH |
/buddies/:id |
Veteran | Accept / block buddy |
GET |
/buddies/nearby |
All | Haversine-ranked nearby buddies |
POST |
/checkins |
Veteran | Submit mood check-in |
GET |
/checkins |
Veteran | Last 7 check-ins |
POST |
/sos |
Veteran | Fire SOS alert |
GET |
/sos |
All | SOS history |
PATCH |
/sos/:id/respond |
Buddy | Accept/decline with ETA |
POST |
/presence |
All | Update availability status |
POST |
/location |
All | Push lat/lng |
POST |
/translate |
All | AI-rewrite message (Gemini/Ollama) |
GET |
/translate/history |
All | AI chat history from MongoDB |
POST |
/stt/elevenlabs |
All | Transcribe audio (multipart/form-data) |
GET |
/ws |
All | WebSocket upgrade — persistent event stream |
GET |
/health |
Public | Service health check |
- Python 3.11+
- PostgreSQL 15+ (running on port 5433)
- MongoDB 6+ (running on port 27017)
- Node.js 20+
- Ollama (optional — for local AI) or a Gemini API key
git clone https://github.com/SriRammSS/komrade.git
cd komrade/backend
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtCreate backend/.env:
DATABASE_URL=postgresql://postgres:<password>@localhost:5433/komrade
JWT_SECRET=<generate-with: openssl rand -hex 32>
JWT_ALGORITHM=HS256
JWT_EXPIRE_MINUTES=10080
# AI — choose one
AI_PROVIDER=gemini
GEMINI_API_KEY=<your-key>
GEMINI_MODEL=gemini-1.5-flash
# Or local
# AI_PROVIDER=ollama
# OLLAMA_BASE_URL=http://localhost:11434
# OLLAMA_MODEL=llama3.1
ELEVENLABS_API_KEY=<your-key>
MONGO_URI=mongodb://localhost:27017cd backend
alembic upgrade head
uvicorn app.main:app --reload --port 8000cd frontend
npm install
npm run dev # → http://localhost:5173komrade/
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI app — router registration
│ │ ├── api/ # Thin HTTP controllers
│ │ │ └── auth, buddies, checkins, sos, presence, settings, ws, health
│ │ ├── routers/ # translate, stt, ai_test
│ │ ├── services/ # Business logic
│ │ │ └── ai_service, buddy_service, sos_service, geo_service
│ │ ├── models/ # SQLAlchemy ORM models
│ │ ├── schemas/ # Pydantic request/response schemas
│ │ └── core/
│ │ ├── config.py # pydantic-settings
│ │ ├── security.py # JWT creation/verification
│ │ ├── ws_manager.py # WebSocket singleton
│ │ └── sos_policies.py # Cooldown, radius, escalation constants
│ ├── alembic/ # Database migrations
│ ├── tests/ # pytest suite (14 test modules)
│ └── requirements.txt
│
└── frontend/
└── src/
├── pages/ # Dashboard, Buddies, BuddyInbox, BuddyMap,
│ # SosHistory, Translation, Profile, Settings
├── components/ # MoodCheckinForm, SOSAlertCard, BuddyList,
│ # PresenceControl, LocationUpdate, BrandLogo
├── api/ # Typed fetch wrapper + per-domain modules
└── state/ # authStore (JWT localStorage) + realtime hooks
| Decision | Rationale |
|---|---|
| Dual AI provider | A single generate_structured() abstraction dispatches to Gemini or Ollama, validates the JSON response against a schema, and retries once with a correction prompt — AI backend is swappable without touching business logic |
| Crisis keyword interception | Hardcoded before any AI call — safety-critical path never depends on model availability or latency; 988 response is always immediate and deterministic |
| SOS safety fallback | If no online nearby buddy exists, the engine falls back to all accepted buddies regardless of presence or location — safety takes priority over precision |
| WebSocket singleton | ws_manager is a module-level object shared across all FastAPI routes, enabling loop.create_task(broadcast(...)) fire-and-forget from synchronous HTTP handlers |
| MongoDB for AI history | Chat history has a document-centric, variable-length schema (messages with arbitrary citation blobs). MongoDB's flexible document model fits this better than a relational table |
| Quiet-hour filtering | Buddy availability windows are applied at SOS targeting time, not at notification delivery — ensures buddies are not woken during configured rest hours |
Sri Ramm Sekar Sasirekha