# SPEC.md — Private Friends Chat (Android + Web + Self-Hosted Backend)

## 0. Overview
Build a self-hosted chat system similar to a simplified WhatsApp/Discord/Signal experience for a small friend group.

- Target users: up to **10** initially, expandable to **25**.
- Clients: **Android app** + **Web app**.
- Backend: self-hosted, **Docker** deployable (Unraid 7.x or Debian).
- MVP focus: reliable messaging + media/files + voice notes + simple group chats.
- No censorship features. No rate limits.

## 1. Scope and Product Model

### 1.1 Conversations
- **Direct Messages (DM):** 1:1 chat.
- **Group Chats ("micro servers"):** WhatsApp-like group chats (NOT Discord servers/channels).
  - Max group size: **25 users**.
  - Group admin abilities:
    - ban/remove users from the group
    - delete messages inside the group

### 1.2 MVP Feature List
Must-have (v1):
- Text chat
- Voice notes
- File sharing (up to 1GB)
- Image sharing:
  - in-chat preview
  - full-screen view
- Reactions
- Message edit + delete
- Group mentions with special rules (see §4.5)
- Bots with verified bot accounts (see §6)
- Push notifications:
  - Android via self-hosted **UnifiedPush** distributor (e.g., ntfy-based)
  - Web via **WebPush**
  - Push preview shows up to **12 characters** of message content

Explicitly NOT required for v1:
- Read receipts (no "seen" status)
- Typing indicators
- Search (planned for v2)
- iOS client
- Roles/permissions beyond group admin

## 2. Platform Requirements

### 2.1 Android App
- Native **Kotlin/Java** implementation.
- WhatsApp-simple UI/UX:
  - chat list
  - conversation view
  - attachment picker + previews
  - voice note record/playback
  - group management (admin actions)
- Offline history available by default (see §5.2).

### 2.2 Web App
- React-based web app.
- Functional parity with Android for MVP where feasible:
  - DMs + group chats
  - sending/receiving messages
  - upload/download files and images
  - preview and full view for images
  - reactions, edit, delete
  - notifications via WebPush

## 3. Authentication & Accounts

### 3.1 Registration
- Users can create accounts with:
  - **Email**
  - **Username**
  - **Password** (max length **256** characters)
- Login supports:
  - email + password OR username + password

### 3.2 Admin Controls
Admin panel must support:
- Ban accounts
- Warn accounts (store warning reason and timestamp)
- Password reset workflow (admin-authorized OTP flow, §3.3)

### 3.3 Password Reset Flow (Admin-Authorized OTP)
- Admin initiates reset and generates a **32-character OTP**.
- User logs in by entering:
  - username/email as usual
  - OTP **in the password field**
- After successful OTP login:
  - user is forced to a password renewal page
  - if renewal is not completed, the account remains **locked**
- OTP is single-use and expires (default: **24h**, configurable).

### 3.4 2FA
- No 2FA in v1.

## 4. Messaging Rules

### 4.1 Message Types
- Text
- Image
- File
- Voice Note

### 4.2 Edit/Delete
- Sender can edit their own messages.
- Sender can delete their own messages.
- Group admin can delete messages within their groups.
- Deletion behavior:
  - Message is removed from normal client views (tombstone optional).
  - Server keeps audit record of deletion event (who/when/which message id).

### 4.3 Reactions
- Emoji-style reactions on messages.
- Multiple reactions allowed.
- Reaction add/remove events are synchronized across devices.

### 4.4 Delivery Semantics
- Reliability over performance:
  - server must confirm successful receipt and durable storage
  - clients retry sending if not confirmed
- No read receipts:
  - clients do not expose "seen/read" state
  - server may keep internal delivery state to ensure completeness (not user-visible)

### 4.5 Mentions (Group Chats Only)
- Mentions exist only in group chats.
- No `@all`.
- Only `@everyone` exists and works as:
  - notifies only users who have explicitly **opted-in** to receive mentions
- Per-user setting:
  - "Receive @everyone mentions" boolean (default: TBD, recommended default **off**).

## 5. Media, Files, Offline

### 5.1 Upload Limits and Chunking
- Max attachment size: **1GB** per message.
- Upload uses chunking:
  - chunk size: **50MB**
  - failed chunks must be re-sent until completion
  - server supports resumable uploads (upload session id + chunk indexes)
- Integrity:
  - each chunk has hash validation
  - final file has overall hash validation

### 5.2 Offline History
- Offline history is enabled by default:
  - messages are cached locally on device/browser storage
- Future (v2) option:
  - per-user setting to disable offline visibility (for users concerned about phone seizure)

### 5.3 "Disappearing Images" Policy
- UX: user can send images as "disappearing" (time/view based).
- Storage policy: images must be **permanently stored on the server** for legality / abuse reporting.
- Client behavior:
  - image becomes inaccessible in client UI after policy triggers (e.g., viewed once or after N minutes; exact rule configurable)
- Server behavior:
  - server retains the image and related metadata
  - access to retained disappearing media is restricted to admin tooling

## 6. Bots

### 6.1 Bot Accounts
- Bots use separate accounts flagged as `BOT`.
- Bot accounts must be "verified" (admin approval).
- Bot identity is distinct from human users in UI.

### 6.2 Bot Integration Model
- Bots are "subscribable" integrations.
- MVP integrations:
  - Twitch "stream went live" notifications
  - Modrinth "new update released" notifications
- Bot delivery:
  - bots can post messages into selected group chats (where enabled)
- Recommended implementation approach:
  - backend-managed integration connectors + admin panel to configure tokens/webhooks
  - bot posts are created by server with bot account attribution

## 7. Security & Encryption

### 7.1 V1 Encryption Mode (Development/Test Phase)
- V1 prioritizes simplicity and testability:
  - **Server can decrypt all messages** (no true E2EE in v1).
- Transport security:
  - HTTPS/TLS required for all API connections.

### 7.2 V1 → V2 Future Direction
- Goal for later: E2EE-capable design.
- Requirement already set for v1:
  - When "developer reading" is disabled, the developer must **not** be able to read **old messages**.
- Therefore, design must support a future migration where:
  - message history can be re-encrypted (or replaced with client-side encrypted messages)
  - and server-held plaintext becomes inaccessible

(Implementation details are v2; v1 must not block this migration.)

## 8. Push Notifications

### 8.1 Android
- Use **UnifiedPush** with a self-hosted distributor (e.g., ntfy-based).
- Must support:
  - device registration tokens
  - per-device subscriptions
  - multi-device notifications

### 8.2 Web
- Use **WebPush**.

### 8.3 Notification Content
- Push preview includes up to **12 characters** of message content.
- If message is media-only or encrypted in future:
  - use fallback preview like "New message" / "Image" / "File" / "Voice note" (configurable).

## 9. Backend Deployment & Ops

### 9.1 Deployment
- Must run in Docker containers.
- Must support:
  - Unraid 7.x shares (volume mounts)
  - Debian-based bare metal without a dedicated data drive
- Minimal setup requirement:
  - only required setup is creating/setting the **admin account**
  - everything else runs with sensible defaults

### 9.2 Domains & TLS
- Domain options: `metl-group.de`, `metl-group.com` with project subdomain.
- Certificates are provided externally via FRPS + certbot.
- Backend must load TLS certs from a configured directory:
  - e.g. `/config/certs/` (final path configurable via env vars)

### 9.3 Certificate Auto-Reload
- Every **5 minutes**, scan the cert directory for updated cert/key files.
- If files changed, reload TLS without full service downtime:
  - preferred: hot reload of TLS context
  - acceptable: restart only the TLS listener process/container with minimal disruption

## 10. Data Storage

### 10.1 Database
Allowed:
- SQLite (preferred if admin panel is integrated)
- OR MySQL + phpMyAdmin

MVP recommendation for simplicity:
- choose **SQLite** unless multi-instance scaling requires MySQL later.

### 10.2 File Storage
- Store attachments locally on server disk (volume mounted).
- Server has sufficient storage + 2TB NVMe cache available.
- Directory layout must be deterministic and configurable.

### 10.3 Backups
- Local backups once per day.
- Rotation:
  - keep 7 daily backups
  - keep 1 monthly backup until next monthly completes
- Backups must include:
  - database
  - attachment storage
  - config (excluding secrets if user chooses)

## 11. Admin Panel (Built-in)
Must be included without external setup and provide:
- Admin account creation / management
- User list, ban/warn/reset password
- Group list and moderation controls
- Bot/integration configuration UI
- Logs view (errors, auth events, moderation actions, bot events, upload events)
- Metrics dashboard:
  - message throughput (msg/min)
  - upload/download throughput
  - active users
  - online devices (if tracked)

## 12. Non-Functional Requirements
- Best effort availability (no HA requirement).
- Data integrity is critical:
  - chunked uploads must be reliable
  - durable message storage required before server ACK
- No rate limiting.
- No censoring.

## 13. Tech Stack Preferences
- Backend: no strict preference (Python/Java acceptable; C components optional for performance where needed).
- Android: Kotlin/Java.
- Web: React.

## 14. Acceptance Criteria (MVP)
- User can register/login with email+password and username+password.
- DMs work with:
  - send/receive text
  - reactions
  - edit/delete
  - image preview + full view
  - voice notes record/playback
  - file upload/download up to 1GB with 50MB chunks and retry
- Group chats up to 25 users:
  - group admin can remove users and delete messages
  - `@everyone` notifies only opted-in users
- Push notifications:
  - Android via UnifiedPush distributor
  - Web via WebPush
  - preview includes up to 12 chars
- Admin panel:
  - ban/warn users
  - generate 32-char OTP reset and user can complete reset
  - view logs and throughput metrics
- TLS:
  - certificate directory configured
  - auto-scan every 5 minutes and reload certs when updated
