246 lines
3.5 KiB
Markdown
246 lines
3.5 KiB
Markdown
# 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):
|
|
|
|
- `admin`
|
|
- `user`
|
|
|
|
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
|
|
|
|
```bash
|
|
docker compose up --build
|
|
````
|
|
|
|
Services:
|
|
|
|
* API → [http://localhost:8000](http://localhost:8000)
|
|
* Docs → [http://localhost:8000/docs](http://localhost:8000/docs)
|
|
* LiveKit → [http://localhost:7880](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:
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
Run API:
|
|
|
|
```bash
|
|
uvicorn neda.main:app --reload
|
|
```
|
|
|
|
---
|
|
|
|
# 📜 Migrations (Alembic)
|
|
|
|
Init (first time):
|
|
|
|
```bash
|
|
alembic init alembic
|
|
```
|
|
|
|
Create migration:
|
|
|
|
```bash
|
|
alembic revision --autogenerate -m "init"
|
|
```
|
|
|
|
Apply:
|
|
|
|
```bash
|
|
alembic upgrade head
|
|
```
|
|
|
|
---
|
|
|
|
# 🔌 Realtime Flow
|
|
|
|
Request to speak:
|
|
|
|
1. Client → WS `REQUEST_TALK`
|
|
2. Backend → Redis `SET NX speaker:{group}`
|
|
3. If granted → LiveKit publish token
|
|
4. Others → subscribers
|
|
5. 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
|
|
|