3.8 KiB
GroupChat2 Server
The server is a Rust/Axum application that provides authentication, room and message APIs, WebSocket chat delivery, AI response orchestration, file uploads, and SQLite-backed persistence for GroupChat2.
Stack
- Rust 2021
- Axum and Tokio
- SQLx with SQLite
- JWT auth and Argon2 password hashing
- OpenRouter for AI completions
- Tavily or Brave for web search tools
Responsibilities
- Register and authenticate users
- Support Nostr challenge/verify login
- Manage rooms, members, invites, and profile updates
- Persist messages, hashes, room settings, and AI metadata
- Broadcast real-time events over WebSockets
- Stream AI responses and tool usage events to connected clients
- Store uploaded avatars and chat images
- Serve built frontend assets in production
Requirements
- Rust toolchain with
cargo - A valid
OPENROUTER_API_KEY - A search provider configured through either Tavily or Brave
Environment
Copy .env.example to .env and fill in the values you need.
cp .env.example .env
Important variables:
BIND_ADDR: server bind address, default0.0.0.0:3001RUST_LOG: log level, defaultinfoDATABASE_URL: SQLite connection string, defaultsqlite:chat.db?mode=rwcJWT_SECRET: JWT signing secretOPENROUTER_API_KEY: requiredSEARCH_PROVIDER:tavilyorbraveTAVILY_API_KEY: required whenSEARCH_PROVIDER=tavilyBRAVE_API_KEY: required whenSEARCH_PROVIDER=braveSTATIC_DIR: optional path to built client assets for production serving
Commands
Run the backend directly:
cargo run
Build a release binary:
cargo build --release
From the repo root, production build/run is also available through:
./prod.sh
Startup Behavior
On startup the server:
- loads environment variables from
.env - validates required AI/search configuration
- creates a timestamped backup of the SQLite database if it already exists
- keeps the 10 most recent backups
- opens the SQLite database
- applies SQL migrations embedded in the binary
API Surface
Main routes exposed by the server:
/api/auth/register/api/auth/login/api/auth/me/api/auth/profile/api/auth/avatar/api/auth/nostr/challenge/api/auth/nostr/verify/api/rooms/api/rooms/:room_id/api/rooms/:room_id/messages/api/rooms/:room_id/join/api/rooms/:room_id/clear/api/messages/hash/:hash/api/models/api/invites/api/invites/:token/accept/api/invites/nostr/api/upload/ws/uploads/*
Real-Time Flow
WebSocket clients connect to /ws with a JWT token in the query string.
Client messages include:
join_roomtypingsend_message
Server events include:
- new messages
- AI typing notifications
- AI stream chunks and stream end markers
- AI tool usage updates
- user typing notifications
- room deleted and room cleared events
Storage Layout
server/
|- migrations/ SQL schema and incremental changes
|- src/ handlers, middleware, models, services
|- uploads/ avatars and chat images
|- backups/ automatic database backups
|- chat.db SQLite database
Uploaded file behavior:
- avatars are stored under
uploads/avatars/ - chat images are stored under
uploads/chat-images/ - avatar uploads are limited to 2 MB
- chat image uploads are limited to 5 MB
AI Behavior
When a user mentions the assistant or the room is configured to always respond, the server:
- loads recent room history
- includes image context for human-uploaded images when available
- calls OpenRouter in streaming mode
- executes tool calls for search or page fetches
- broadcasts streaming output to the room
- stores the final AI response with usage metadata
For frontend behavior and local browser setup, see the Client README.