Neda/Back/README.md

180 lines
3.6 KiB
Markdown

# NEDA Backend
NEDA is a FastAPI backend for real-time group voice communication.
It includes authentication, user/group management, WebSocket signaling, Redis for real-time state, and PostgreSQL for persistent data.
## Tech Stack
- FastAPI + Uvicorn
- SQLAlchemy (Async) + asyncpg
- PostgreSQL
- Redis
- Alembic
- LiveKit
## Project Structure
```text
core/ config, security, deps
alembic/ database migrations
db/ database/redis setup
domains/ domain modules (auth, users, admin, groups, realtime, notifications)
integrations/ external integrations (LiveKit)
scripts/ utility scripts (create_admin)
main.py FastAPI app entrypoint
```
## Active Routes
- `POST /auth/login`
- `GET /users/`
- `POST /admin/users`
- `POST /admin/users/{user_id}/logout`
- `POST /admin/users/{user_id}/reset-secret`
- `GET /admin/users`
- `GET /admin/groups`
- `POST /groups/`
- `GET /groups/my`
- `GET /groups/admin/all`
- `GET /groups/{group_id}/members`
- `POST /groups/{group_id}/invite`
- `DELETE /groups/{group_id}/members/{user_id}`
- `WS /ws/groups/{group_id}`
## Environment Variables
Create a `.env` file in the project root:
```env
APP_NAME=NEDA
DEBUG=False
SECRET_KEY=change-me
ACCESS_TOKEN_EXPIRE_MINUTES=30
ALGORITHM=HS256
SECRET_PASS_LENGTH=32
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
```
## Run With Docker
```bash
docker compose up --build -d
```
Services:
- API: `http://localhost:8000`
- Swagger Docs: `http://localhost:8000/docs`
- LiveKit: `http://localhost:7880`
- Postgres: `localhost:5432`
- Redis: `localhost:6379`
API logs:
```bash
docker compose logs -f api
```
## Create Admin (Inside Docker)
After services are up, create the initial admin user inside the API container:
```bash
docker compose exec api python -m scripts.create_admin
```
The script asks for `username` and optional `phone_number`, creates the user with `is_admin=True`, and prints the initial `secret`.
## Admin API Hardening
- `POST /admin/users` creates only non-admin users.
- Sending `is_admin` in the payload is not allowed and returns `422`.
- Admin creation is only allowed through the server-side script: `scripts/create_admin.py`.
Invalid payload example:
```json
{
"username": "new_user",
"phone_number": "09123456789",
"is_admin": true
}
```
Admin login:
- Endpoint: `POST /auth/login`
- Body:
```json
{
"username": "admin_username",
"secret": "printed_secret"
}
```
## Database Migrations (Alembic)
This project uses Alembic, and `env.py` reads `DATABASE_URL` from `.env`.
Apply migrations (inside Docker):
```bash
docker compose exec api alembic upgrade head
```
Create a new migration (autogenerate):
```bash
docker compose exec api alembic revision --autogenerate -m "your_message"
```
Check current DB revision:
```bash
docker compose exec api alembic current
```
Show migration history:
```bash
docker compose exec api alembic history
```
Important: run `alembic upgrade head` before starting the API in a new environment.
## Local Development (Without Docker)
```bash
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
```
Run migrations:
```bash
alembic upgrade head
```
Start API:
```bash
uvicorn main:app --reload
```
## Realtime Notes
- Presence is stored in Redis.
- Speaker lock is managed atomically in Redis.
- LiveKit tokens for listener/speaker roles are issued during the WebSocket flow.