groupchat/server/README.md

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, default 0.0.0.0:3001
  • RUST_LOG: log level, default info
  • DATABASE_URL: SQLite connection string, default sqlite:chat.db?mode=rwc
  • JWT_SECRET: JWT signing secret
  • OPENROUTER_API_KEY: required
  • SEARCH_PROVIDER: tavily or brave
  • TAVILY_API_KEY: required when SEARCH_PROVIDER=tavily
  • BRAVE_API_KEY: required when SEARCH_PROVIDER=brave
  • STATIC_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_room
  • typing
  • send_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.