74 lines
3.7 KiB
Markdown
74 lines
3.7 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Chad is a real-time voice/video chat server (think Discord-like) built with Fastify, Socket.IO, and mediasoup for WebRTC media handling. It uses SQLite via Prisma ORM and Lucia for session-based authentication. The client is a Tauri desktop app (separate repo).
|
|
|
|
## Commands
|
|
|
|
- **Start server:** `yarn start` (runs `ts-node --transpile-only server.ts`)
|
|
- **Deploy DB (migrate + seed + generate):** `yarn db:deploy`
|
|
- **Generate Prisma client after schema changes:** `npx prisma generate`
|
|
- **Create a migration:** `npx prisma migrate dev --name <name>`
|
|
- **Lint:** `npx eslint .`
|
|
- **Package manager:** Yarn 4 (corepack). Do not use npm.
|
|
|
|
## Architecture
|
|
|
|
### Entry Point & Plugin System
|
|
|
|
`server.ts` creates a Fastify instance and uses `@fastify/autoload` to auto-register everything in `plugins/` and `routes/` (prefixed under `/chad`). Plugins use `fastify-plugin` (`fp`) with named dependencies to control load order.
|
|
|
|
### Plugin Load Order (dependency chain)
|
|
|
|
1. `plugins/auth.ts` — Adds `req.user` / `req.session` via Lucia cookie validation on every request (preHandler hook)
|
|
2. `plugins/mediasoup-worker.ts` — Creates a mediasoup Worker, decorates `fastify.mediasoupWorker`
|
|
3. `plugins/mediasoup-router.ts` — Creates a mediasoup Router (depends on worker), decorates `fastify.mediasoupRouter`. Configures supported audio/video codecs (Opus, VP8, VP9, H.264, AV1)
|
|
4. `plugins/socket.ts` — Creates Socket.IO server at `/chad/ws` (depends on worker + router), decorates `fastify.io`. Registers socket handlers on `fastify.ready()`
|
|
|
|
### Socket Handlers (`socket/`)
|
|
|
|
- `socket/webrtc.ts` — Main WebRTC signaling: join/leave, transport creation, producer/consumer lifecycle, audio level observation, active speaker detection
|
|
- `socket/channel.ts` — Channel-based socket logic (in development on `channels` branch)
|
|
|
|
Both handlers authenticate by looking up `socket.handshake.auth.userId` against the DB.
|
|
|
|
### REST Routes (`routes/`)
|
|
|
|
All routes are prefixed with `/chad` via autoload config.
|
|
|
|
- `routes/auth.ts` — `/register`, `/login`, `/logout`, `/me`
|
|
- `routes/user.ts` — `/preferences` (GET/PATCH), `/profile` (PATCH). Profile changes broadcast to connected socket peers via `clientChanged` event.
|
|
|
|
### Type System (`types/socket.ts`)
|
|
|
|
Fully typed Socket.IO events: `ClientToServerEvents`, `ServerToClientEvents`, `SocketData`. The `SomeSocket` union type covers both live `Socket` and `RemoteSocket` (from `fetchSockets()`).
|
|
|
|
### Database
|
|
|
|
- SQLite with Prisma 7 + `@prisma/adapter-better-sqlite3`
|
|
- Schema at `prisma/schema.prisma`, generated client at `prisma/generated/client/`
|
|
- Models: `User`, `Session` (Lucia), `UserPreferences`, `Channel`
|
|
- Seed creates a persistent "Default" channel
|
|
- Config in `prisma.config.ts` using `dotenv` for `DATABASE_URL`
|
|
|
|
### Key Patterns
|
|
|
|
- Request validation uses Zod schemas defined inline in route handlers
|
|
- DTOs in `dto/` define Prisma select objects with `satisfies Prisma.*Select` for type-safe projections
|
|
- `utils/socket-to-client.ts` maps socket data to the `ChadClient` interface sent to clients
|
|
- ESLint uses `@antfu/eslint-config` (flat config) with `no-console` and `n/prefer-global/process` disabled
|
|
|
|
### Environment Variables
|
|
|
|
- `PORT` — Server port (default: 4000, Docker: 80)
|
|
- `DATABASE_URL` — SQLite path (e.g., `file:../data/database.db`)
|
|
- `ANNOUNCED_ADDRESS` — Public IP for WebRTC ICE candidates (default: `127.0.0.1`)
|
|
- `CORS_ORIGIN` — Socket.IO CORS origin (default: `*`)
|
|
|
|
### Docker
|
|
|
|
`Dockerfile` requires python3 and build-essential for mediasoup native compilation. Runs `yarn db:deploy && yarn start`.
|