Files
2026-08-27 11:38:45 +01:00

51 lines
2.1 KiB
Markdown

# User to Support Chat
Real-time support chat in Rust. Users start conversations, supporters reply from a dashboard. Everything lives in RAM, nothing persists, and it all resets every 20 minutes. Like a café where everyone gets kicked out when the clock strikes. Lovely.
Anonymous by default, ephemeral by design.
## What It Does
![user-gif](./docs/images/user-to-support-chat.gif)
- Users create sessions anonymously (UUIDs, not usernames)
- Supporters browse active chats and reply in real time
- WebSockets for typing indicators and live message pushes
- Rate limiting: 60 messages per IP per 20-minute window
- Auto-reset: clears all sessions, messages, and rate limits every 20 minutes
## Tech Stack
| Thing | Choice | Why |
|---|---|---|
| Language | Rust 1.96 | Single binary. No runtime. Panic = abort. |
| Framework | Axum | WebSocket support, typed routes, tokio-powered. |
| State | DashMap | Concurrent, lock-free, perfect for in-memory sessions. |
| Frontend | HTMX + vanilla JS | Less JavaScript, more HTML swaps. No bundlers. |
| Deployment | Bare metal + systemd | No Docker. No Podman. Just a binary and a `.service` file. |
## Running It
The `justfile` handles everything, but you'll need to [install](https://just.systems/man/en/installation.html) it on your machine.
```bash
just build # clippy + fmt + release
just run # dev mode with hot reload
just deploy # rsync to server + restart systemd
just logs # tail remote journalctl
```
Server binds on `0.0.0.0:3111`. Landing page at `/`, user view at `/user`, supporter dashboard at `/supporter`.
## Key Behaviors
- Sessions are created via POST to `/api/session/create` — returns JSON with UUID
- Messages sent via HTMX forms to `/send/:session_id` or `/supporter/send/:session_id`
- WebSocket connects to `/ws/user/:session_id` (user) or `/ws/supporter/:supporter_id`
- Reset countdown shown in navbar, auto-refreshes every second
- Typing indicators broadcast via WebSocket using prefixes like `typing:user:start:<session_id>`
---
**For production use, you'd want a database, auth, TLS, and probably less drama.**