Files
eifeldc/README.md
root cacd2b04a7
Some checks failed
CI / Rust Format (push) Has been cancelled
CI / Clippy (push) Has been cancelled
CI / Test Server (push) Has been cancelled
CI / Frontend Check (push) Has been cancelled
CI / Tauri Client Check (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Build Tauri (Linux) (push) Has been cancelled
feat: comprehensive project improvements
- Fix 14 Clippy warnings across server and bot-sdk
- Add 67 unit tests (32 bot-sdk, 34 server, 1 doctest)
- Add Prometheus metrics endpoint (/api/metrics)
- Add structured JSON logging (EIFELDC_LOG_FORMAT=json)
- Add release workflow (Docker push + GitHub Release + Tauri builds)
- Add rate limiting middleware (EIFELDC_RATE_LIMIT)
- Add CORS restriction (EIFELDC_CORS_ORIGINS)
- Add session token expiry (EIFELDC_SESSION_TTL)
- Add input validation (username/password/homeserver length limits)
- Add upload size limit (EIFELDC_MAX_UPLOAD_MB)
- Upgrade Tauri client from v1 to v2
- Add session store with SQLite persistence
- Add proper error types and cleanup across all crates
- Format all code with cargo fmt
- Update CI pipeline with fmt, clippy, test, frontend, and Tauri checks
- Add README with full API reference and setup guide
2026-04-29 13:08:01 +02:00

300 lines
9.2 KiB
Markdown

# EifelDC
Discord-like Matrix chat platform built with Rust, Svelte, and Tauri.
## Architecture
| Component | Crate | Description |
|---|---|---|
| **Server** | `eifeldc-server` | Axum web server, Matrix SDK, LiveKit voice, SQLite sessions |
| **Bot SDK** | `eifeldc-bot-sdk` | SDK for building Matrix bots |
| **Client** | `eifeldc-client` | Tauri desktop app |
| **Frontend** | — | Svelte + TypeScript UI |
## Prerequisites
- Rust 1.82+ (stable)
- Node.js 20+
- A running Matrix Synapse homeserver
- LiveKit server (for voice)
## Quick Start
### Build Server & Bot SDK
```bash
cargo build --release -p eifeldc-server -p eifeldc-bot-sdk
```
### Build Frontend
```bash
cd client/src-ui
npm ci
npm run build
```
### Build Tauri Desktop App
Requires system dependencies:
```bash
# Ubuntu/Debian
sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev librsvg2-dev libssl-dev
```
```bash
cargo build --release -p eifeldc-client
```
### Run the Server
```bash
cargo run -p eifeldc-server
```
The server starts on `http://0.0.0.0:3000` and serves the frontend from `client/src-ui/dist`.
## Environment Variables
| Variable | Default | Description |
|---|---|---|
| `EIFELDC_DB` | `eifeldc.db` | SQLite database path for session storage |
| `EIFELDC_STATIC_DIR` | `client/src-ui/dist` | Path to frontend static files |
| `LIVEKIT_API_KEY` | `devkey` | LiveKit API key |
| `LIVEKIT_API_SECRET` | `devsecret` | LiveKit API secret |
| `LIVEKIT_URL` | `ws://localhost:7880` | LiveKit server URL |
| `RUST_LOG` | — | Logging filter (e.g. `eifeldc_server=info`) |
| `EIFELDC_LOG_FORMAT` | `pretty` | Log format: `pretty` or `json` |
| `EIFELDC_CORS_ORIGINS` | `*` | Comma-separated allowed origins (e.g. `https://app.example.org,https://dev.example.org`) |
| `EIFELDC_SESSION_TTL` | — | Session TTL in seconds (no expiry if unset) |
| `EIFELDC_RATE_LIMIT` | `60` | Max requests per minute per client |
| `EIFELDC_MAX_UPLOAD_MB` | `50` | Max upload size in MB |
## Docker Deployment
```bash
# Configure environment
cp infra/.env.example infra/.env
# Edit infra/.env with your domain and secrets
# Setup infrastructure (generates secrets, configs, certs)
bash infra/scripts/setup.sh your.domain.com
# Or manually:
cd infra
docker compose up -d
```
Services: EifelDC server, Synapse, PostgreSQL, LiveKit, coturn, nginx.
### Useful Commands
```bash
make docker-build # Build Docker image
make docker-up # Start containers
make docker-down # Stop containers
make docker-logs # Follow EifelDC logs
make health # Run healthcheck
make backup # Backup data
```
## API Reference
All endpoints are under `/api`. Public endpoints require no auth. Protected endpoints require a `Bearer` token in the `Authorization` header.
### Authentication
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | `/api/login` | No | Login with Matrix credentials |
| POST | `/api/register` | No | Register a new Matrix user |
| GET | `/api/current-user` | No | Get current user ID from token |
| POST | `/api/logout` | Yes | Logout and invalidate session |
**Login Request:**
```json
{ "homeserver": "https://matrix.example.org", "username": "alice", "password": "secret" }
```
**Login Response:**
```json
{ "success": true, "user_id": "@alice:example.org", "token": "uuid-token", "error": null }
```
### Rooms
| Method | Endpoint | Description |
|---|---|---|
| GET | `/api/rooms` | List joined rooms |
| POST | `/api/rooms/create` | Create a new room |
| POST | `/api/rooms/join` | Join a room by ID or alias |
| POST | `/api/rooms/{room_id}/leave` | Leave a room |
| GET | `/api/rooms/{room_id}/members` | List room members |
| POST | `/api/rooms/{room_id}/name` | Set room name |
| POST | `/api/rooms/{room_id}/topic` | Set room topic |
| POST | `/api/rooms/{room_id}/avatar` | Set room avatar (multipart) |
| GET | `/api/rooms/unread` | Get unread notification counts |
| POST | `/api/rooms/{room_id}/read` | Mark room as read |
### Messages
| Method | Endpoint | Description |
|---|---|---|
| GET | `/api/rooms/{room_id}/messages` | Get room messages |
| POST | `/api/rooms/{room_id}/send` | Send a message |
| POST | `/api/rooms/{room_id}/edit` | Edit a message |
| POST | `/api/rooms/{room_id}/delete/{event_id}` | Delete a message |
| POST | `/api/rooms/{room_id}/react` | React to a message |
| POST | `/api/rooms/{room_id}/typing` | Set typing notification |
| POST | `/api/rooms/{room_id}/upload` | Upload a file (multipart) |
### Threads
| Method | Endpoint | Description |
|---|---|---|
| GET | `/api/rooms/{room_id}/threads` | List threads in a room |
| GET | `/api/rooms/{room_id}/threads/{thread_id}` | Get thread messages |
| POST | `/api/rooms/{room_id}/threads/{thread_id}/reply` | Reply in a thread |
| POST | `/api/rooms/{room_id}/reply` | Reply to a message |
### Voice (LiveKit)
| Method | Endpoint | Description |
|---|---|---|
| POST | `/api/voice/join` | Join a voice channel |
| POST | `/api/voice/leave` | Leave voice channel |
| POST | `/api/voice/toggle-mute` | Toggle mute |
| POST | `/api/voice/toggle-deafen` | Toggle deafen |
| GET | `/api/voice/participants` | Get voice participants |
### Presence
| Method | Endpoint | Description |
|---|---|---|
| POST | `/api/presence/set` | Set presence status |
| GET | `/api/presence/{user_id}` | Get user presence |
### Profile
| Method | Endpoint | Description |
|---|---|---|
| GET | `/api/profile/me` | Get own profile |
| GET | `/api/profile/{user_id}` | Get user profile |
| POST | `/api/profile/displayname` | Set display name |
| POST | `/api/profile/avatar` | Upload avatar (multipart) |
### Emoji & Roles
| Method | Endpoint | Description |
|---|---|---|
| GET | `/api/rooms/{room_id}/emoji` | Get custom emoji |
| POST | `/api/rooms/{room_id}/emoji/upload` | Upload custom emoji |
| GET | `/api/rooms/{room_id}/roles` | Get room roles |
| POST | `/api/rooms/{room_id}/roles/assign` | Assign role to user |
| POST | `/api/rooms/{room_id}/roles/remove` | Remove role from user |
| GET | `/api/rooms/{room_id}/permissions/{user_id}` | Get user permissions |
### Media & WebSocket
| Method | Endpoint | Description |
|---|---|---|
| GET | `/api/media/{mxc_path}` | Proxy Matrix media |
| GET | `/api/metrics` | Prometheus metrics endpoint |
| GET | `/api/ws?token={token}` | WebSocket for real-time events |
### WebSocket Events
### Monitoring
**Prometheus Metrics** are exposed at `/api/metrics`:
| Metric | Type | Description |
|---|---|---|
| `eifeldc_http_requests_total` | Counter | Total HTTP requests |
| `eifeldc_active_sessions` | Gauge | Active user sessions |
| `eifeldc_active_websockets` | Gauge | Active WebSocket connections |
| `eifeldc_messages_sent_total` | Counter | Total messages sent |
| `eifeldc_rooms_joined_total` | Counter | Total room join operations |
| `eifeldc_uploads_total` | Counter | Total file uploads |
| `eifeldc_voice_participants` | Gauge | Current voice participants |
**Structured Logging** — set `EIFELDC_LOG_FORMAT=json` for JSON output:
```json
{"timestamp":"2026-04-29T10:00:00Z","level":"INFO","target":"eifeldc_server::routes::auth","fields":{"message":"LiveKit URL: ws://localhost:7880"}}
```
Use `RUST_LOG` for filtering: `RUST_LOG=eifeldc_server=debug,tower_http=info`
### WebSocket Events
```json
{ "type": "message", "room_id": "...", "event_id": "...", "sender": "...", "body": "...", "timestamp": 0 }
{ "type": "message_edited", "room_id": "...", "event_id": "...", "new_body": "..." }
{ "type": "message_deleted", "room_id": "...", "redacts": "..." }
{ "type": "reaction", "room_id": "...", "event_id": "...", "key": "👍", "sender": "..." }
{ "type": "room_joined", "room_id": "...", "name": "..." }
{ "type": "room_left", "room_id": "..." }
{ "type": "presence", "user_id": "...", "status": "online|idle|offline", "status_msg": "..." }
{ "type": "typing", "room_id": "...", "user_id": "...", "typing": true }
{ "type": "voice_state_update", "room_id": "...", "user_id": "...", "muted": false, "deafened": false }
{ "type": "voice_user_joined", "room_id": "...", "user_id": "..." }
{ "type": "voice_user_left", "room_id": "...", "user_id": "..." }
{ "type": "thread_reply", "room_id": "...", "root_event_id": "...", "event_id": "...", "sender": "...", "body": "...", "timestamp": 0 }
```
## Bot SDK
```rust
use std::sync::Arc;
use eifeldc_bot_sdk::{BotClient, BotEvent, CommandContext};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut bot = BotClient::new("https://matrix.example.org")
.with_auth("botuser", "botpassword");
bot.on_event(|event| {
match event {
BotEvent::Message { room_id, sender, body, .. } => {
println!("{} in {}: {}", sender, room_id, body);
}
_ => {}
}
});
bot.on_command("hello", Arc::new(|ctx: CommandContext| {
println!("Hello command from {} in {}!", ctx.sender, ctx.room_id);
}));
bot.start().await?;
Ok(())
}
```
## Development
```bash
# Check compilation
cargo check -p eifeldc-server -p eifeldc-bot-sdk
# Run linter
cargo clippy -p eifeldc-server -p eifeldc-bot-sdk -- -D warnings
# Check formatting
cargo fmt --all -- --check
# Run tests
cargo test -p eifeldc-server -p eifeldc-bot-sdk
# Build frontend
cd client/src-ui && npm ci && npm run build
# Run dev server
cargo run -p eifeldc-server
```
## License
All rights reserved.