Files
cg_api_secure-webshare/docs/OPERATIONAL_NOTES.md

138 lines
5.6 KiB
Markdown

# Operational Notes
This document covers runtime behaviors, limits, and maintenance considerations for operating a cg.cx instance.
---
## Telegram API Rate Limits
The bot does **not** implement explicit request throttling for Telegram API calls. It relies on Teloxide's default behavior and the Telegram Bot API flood-control semantics.
- **Forwarding / posting messages** — Subject to standard Bot API rate limits (roughly ~30 messages/second in groups, lower in smaller chats). Rapid approval of many submissions may trigger `RetryAfter` errors; the bot currently does not back off explicitly.
- **Banning / restricting members** — `banChatMember` and `restrictChatMember` have aggressive per-chat limits. Issuing many punishment commands in quick succession may result in temporary API rejections.
- **Message deletion** — `deleteMessage` is limited to ~300 deletions per chat per 24 hours for bots. The automatic service-message cleanup (see below) contributes to this budget.
**Operational recommendation:** If running in high-traffic groups, monitor bot logs for `RetryAfter` or `429` errors and consider spacing out bulk operations.
---
## System Message Deletion Limits
The bot automatically deletes service messages in groups and channels to reduce noise. In `handle_message_inner`, the following 17 message types are detected and deleted in non-private chats:
- `new_chat_members`
- `left_chat_member`
- `new_chat_title`
- `new_chat_photo`
- `delete_chat_photo`
- `group_chat_created`
- `supergroup_chat_created`
- `channel_chat_created`
- `migrate_to_chat_id`
- `migrate_from_chat_id`
- `pinned_message`
- `video_chat_scheduled`
- `video_chat_started`
- `video_chat_ended`
- `video_chat_participants_invited`
- `message_auto_delete_timer_changed`
- `proximity_alert_triggered`
**Limitations:**
- Some service messages (e.g., `channel_chat_created`) **cannot be deleted by bots** and will silently fail. The code handles this with `let _ = bot.delete_message(...).await;`.
- Deletion failures do not crash the bot or block subsequent message processing.
---
## Storage & Directories
Encrypted content is organized into the following directories (configured in `config/default.toml` under `[storage.paths]`):
| Directory | Purpose |
|-----------|---------|
| `data/media` | Image, video, and audio files (`image/*`, `video/*`, `audio/*`). |
| `data/documents` | All other file types (archives, binaries, etc.). |
| `data/text` | Plain text uploads (`text/*` MIME types). |
| `data/temp` | Temporary files during encryption and upload processing. |
| `data/logs` | Rolling log output from the bot and server. |
**Directory creation:** Both the bot and server call `storage.ensure_dirs().await` at startup, creating missing directories automatically.
---
## Rolling Log Files
Both the bot (`crates/cgcx-bot/src/main.rs`) and the server (`crates/cgcx-server/src/main.rs`) use `tracing-appender` for daily log rotation:
```rust
tracing_appender::rolling::Builder::new()
.rotation(tracing_appender::rolling::Rotation::DAILY)
.filename_prefix(log_prefix)
.max_log_files(config.logging.max_files)
.build(log_dir)
```
- **Rotation:** Daily.
- **Retention:** `max_files` (default: `7`).
- **Paths:**
- Bot: `data/logs/cgcx-bot.log` (or configured `logging.file_path`)
- Server: `data/logs/cgcx-server.log`
- **Format:** Plain text, ANSI colors disabled for file output.
- **Fallback:** If the rolling appender fails to initialize, the process falls back to console-only logging.
---
## SQLite WAL Mode
Every database connection is opened with:
```sql
PRAGMA journal_mode = WAL;
PRAGMA foreign_keys = ON;
PRAGMA busy_timeout = 5000;
```
**Implications:**
- **WAL (Write-Ahead Logging)** allows readers to proceed without blocking on writers, which is important because the bot and server may share the same SQLite file.
- A `busy_timeout` of 5000 ms reduces "database is locked" errors under concurrent load.
- WAL produces companion files (`db.sqlite-wal`, `db.sqlite-shm`) in the same directory as the database. These are safe to leave in place during normal operation and are automatically checkpointed by SQLite.
---
## Background Task Intervals
| Task | Interval | Description |
|------|----------|-------------|
| **Punishment expiration** | 60 seconds | Bot task that queries `punishments` for expired timed bans/mutes and lifts them. |
| **Orphan cleanup** | 24 hours | Server task that runs `FilePipeline::cleanup_orphans()` to remove files belonging to deleted/blacklisted content (only if `keep_content = false`). |
**Note:** The orphan sweeper skips its first tick on startup to avoid immediate load spikes.
---
## Frontend Chunk Size Warning
The frontend build uses Vite with its default configuration. During `npm run build`, Vite may emit warnings such as:
```
(!) Some chunks are larger than 500 kBs after minification.
```
- This is a **non-blocking** warning; the build completes successfully.
- The warning typically comes from large vendor dependencies (e.g., PDF.js, syntax highlighters).
- No custom `chunkSizeWarningLimit` is configured; the default Vite behavior is accepted.
---
## HTTP Rate Limiting (Server)
The Axum server uses `tower-governor` for per-IP rate limiting:
| Route Group | Config Key | Default | Burst |
|-------------|-----------|---------|-------|
| General API (`/api/health`, `/api/content/...`) | `rate_limiting.requests_per_minute` | 60 | 10 |
| Password verification (`POST /api/content/:cxid/verify-password`) | `rate_limiting.password_attempts_per_minute` | 4 | 3 |
- Exceeding the general limit returns `429 Too Many Requests`.
- The password endpoint has a separate, stricter limit to mitigate brute-force attacks.