3.5 KiB
NEDA Backend
NEDA is a real-time group voice communication backend designed for wearable devices (e.g., smartwatches).
It enables secure, low-latency push-to-talk audio communication within isolated groups.
This repository contains the FastAPI backend, realtime control layer, and database schema.
✨ Features
- Real-time push-to-talk voice groups
- Single active speaker per group
- Secure group isolation
- Role-based group permissions
- Admin-managed membership
- Redis-based realtime state
- LiveKit media integration
- Async PostgreSQL (SQLAlchemy)
- Alembic migrations
- WebSocket signaling layer
🧱 Architecture
NEDA follows a domain-oriented layered modular monolith architecture.
core/ shared infrastructure
db/ database & redis
domains/ business domains
integrations/ external services
alembic/ migrations
Domains:
- users
- groups
- realtime
- auth
- admin
This design keeps domain logic isolated and allows future service extraction.
🎙️ Realtime Model
- Audio media → LiveKit
- Signaling → WebSocket (FastAPI)
- State → Redis
- Persistence → PostgreSQL
Active speaker is stored in Redis:
speaker:{group_id} = user_id
Presence:
presence:{group_id} = set(user_ids)
👥 Roles
System role (User):
adminuser
Group role (GroupMember):
group_manager(exactly one per group)member
Only admins can:
- create groups
- assign group manager
- add/remove members
Group managers have realtime authority only (speaker control).
🗄️ Database
Core entities:
- User
- Group
- GroupMember
- Session
- GroupVoiceSession
- SpeakerHistory
Rules:
- soft delete for main entities
- single active group_manager per group
- unique membership (user, group)
🚀 Running with Docker
docker compose up --build
Services:
- API → http://localhost:8000
- Docs → http://localhost:8000/docs
- LiveKit → http://localhost:7880
- Postgres → 5432
- Redis → 6379
⚙️ Environment
.env
APP_NAME=NEDA
SECRET_KEY=change-me
POSTGRES_DB=neda
POSTGRES_USER=neda_user
POSTGRES_PASSWORD=neda_pass
DATABASE_URL=postgresql+asyncpg://neda_user:neda_pass@postgres:5432/neda
REDIS_URL=redis://redis:6379/0
LIVEKIT_API_KEY=neda_key
LIVEKIT_API_SECRET=neda_secret
LIVEKIT_HOST=http://livekit:7880
🧪 Development Setup
Create venv and install:
pip install -r requirements.txt
Run API:
uvicorn neda.main:app --reload
📜 Migrations (Alembic)
Init (first time):
alembic init alembic
Create migration:
alembic revision --autogenerate -m "init"
Apply:
alembic upgrade head
🔌 Realtime Flow
Request to speak:
- Client → WS
REQUEST_TALK - Backend → Redis
SET NX speaker:{group} - If granted → LiveKit publish token
- Others → subscribers
- Release → Redis delete
🧭 Project Structure
domains/
users/
groups/
realtime/
auth/
admin/
Each domain contains:
- models
- schemas
- repo
- service
- api
🧠 Design Principles
- realtime state outside DB
- single responsibility domains
- admin control plane
- Redis for locks/presence
- DB for long-term truth
- media separated from signaling
📡 Future Scaling
The architecture supports:
- realtime service extraction
- horizontal scaling
- sharded groups
- multi-tenant deployments