docs: replace ASCII art diagrams with Mermaid (renders natively in Gitea)

This commit is contained in:
2026-05-17 12:03:49 +01:00
parent da0898f52a
commit 2a674c6bcd

View File

@@ -35,45 +35,46 @@ Admin users can view all users' downloads, see server status, cache statistics,
### High-Level Architecture ### High-Level Architecture
``` ```mermaid
┌─────────────────────────────────────────────────────┐ flowchart TB
Browser (SPA) │ subgraph Browser["Browser (SPA)"]
┌──────────┐ ┌──────────┐ ┌───────────────────┐ │ login["Login Form"]
Login │ │Dashboard │ │ Status Panel │ │ dash["Dashboard Cards"]
Form │ │ Cards │ │ (Admin only) │ │ status["Status Panel\n(Admin only)"]
└────┬─────┘ └────┬─────┘ └───────┬───────────┘ │ end
│ │ │ │ │
└───────┼──────────────┼────────────────┼──────────────┘ subgraph Server["Express Server (:3001)"]
│ POST /login │ GET /user- │ GET /status auth_r["Auth Routes\n/api/auth"]
│ │ downloads │ dash_r["Dashboard Routes\n/api/dashboard"]
▼ ▼ ▼ emby_r["Emby Routes\n/api/emby"]
┌─────────────────────────────────────────────────────┐ static_f["Static Files\npublic/"]
│ Express Server (:3001) │
┌────────┐ ┌──────────┐ ┌────────┐ ┌────────────┐ │ subgraph Utils["Utilities Layer"]
Auth │ │Dashboard │ │ Emby │ │ Static │ │ poller["Poller"]
│ Routes │ │ Routes │ │ Routes │ │ Files │ │ cache["Cache"]
└────┬───┘ └────┬─────┘ └────┬───┘ └────────────┘ │ config["Config"]
│ │ │ │ │ qbt["qBittorrent"]
┌────┴──────────┴────────────┴──────────────────┐ │ end
│ │ Utilities Layer │ │ end
│ │ ┌────────┐ ┌────────┐ ┌──────┐ ┌──────────┐ │ │
│ Poller │ │ Cache │ │Config│ │qBittorrent│ │ │ subgraph Ext["External Services"]
└───┬────┘ └────────┘ └──────┘ └──────────┘ │ │ sab["SABnzbd\n(Usenet)"]
└──────┼────────────────────────────────────────┘ │ sonarr["Sonarr\n(TV)"]
└─────────┼────────────────────────────────────────────┘ radarr["Radarr\n(Movies)"]
│ HTTP/API calls qbittorrent["qBittorrent\n(Torrent)"]
emby["Emby / Jellyfin\n(Auth + User DB)"]
┌──────────────────────────────────────────────────────┐ end
│ External Services │
┌──────────┐ ┌────────┐ ┌────────┐ ┌────────────┐ │ login -->|"POST /login"| auth_r
│ SABnzbd │ │ Sonarr │ │ Radarr │ │qBittorrent │ │ dash -->|"GET /stream SSE\nGET /user-downloads"| dash_r
│ (Usenet) │ │ (TV) │ │(Movie) │ │ (Torrent) │ │ status -->|"GET /status"| dash_r
│ └──────────┘ └────────┘ └────────┘ └────────────┘ │
┌──────────────────────────────────────────────┐ │ auth_r -->|"authenticate"| emby
│ │ Emby / Jellyfin │ │ emby_r -->|"proxy"| emby
(Authentication + User DB) │ │ dash_r --> Utils
└──────────────────────────────────────────────┘ │ poller -->|"HTTP/API calls"| sab & sonarr & radarr
└──────────────────────────────────────────────────────┘ qbt -->|"HTTP/API calls"| qbittorrent
static_f -.->|"serve"| Browser
``` ```
--- ---
@@ -361,22 +362,21 @@ The core logic in `dashboard.js` matches raw download client data to *arr servic
For each download item (SABnzbd slot or qBittorrent torrent): For each download item (SABnzbd slot or qBittorrent torrent):
``` ```mermaid
1. Try Sonarr QUEUE match (by title substring) flowchart TD
→ resolve series via seriesMap (embedded in queue record) Start(["Download item"]) --> SQ{"Sonarr QUEUE\nmatch (title)"}
extract user tag → check tag matches requesting user SQ -->|yes| SQR["Resolve series via seriesMap\nextract user tag → check match"]
SQ -->|no| RQ{"Radarr QUEUE\nmatch (title)"}
RQ -->|yes| RQR["Resolve movie via moviesMap\nextract user tag → check match"]
RQ -->|no| SH{"Sonarr HISTORY\nmatch (title)"}
SH -->|yes| SHR["Resolve series via seriesId\nextract user tag → check match"]
SH -->|no| RH{"Radarr HISTORY\nmatch (title)"}
RH -->|yes| RHR["Resolve movie via movieId\nextract user tag → check match"]
RH -->|no| Skip(["Skip — unmatched"])
2. Try Radarr QUEUE match (by title substring) SQR & RQR & SHR & RHR --> Tagged{"Tag matches\nrequesting user?"}
→ resolve movie via moviesMap (embedded in queue record) Tagged -->|yes| Include(["Include in response"])
→ extract user tag → check tag matches requesting user Tagged -->|no| Skip
3. Try Sonarr HISTORY match (by title substring)
→ resolve series via seriesMap (from queue) using seriesId
→ extract user tag → check tag matches requesting user
4. Try Radarr HISTORY match (by title substring)
→ resolve movie via moviesMap (from queue) using movieId
→ extract user tag → check tag matches requesting user
``` ```
### Title Matching ### Title Matching
@@ -593,18 +593,25 @@ The frontend is a **vanilla JavaScript SPA** with no build step. All logic resid
### UI States ### UI States
``` ```mermaid
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ stateDiagram-v2
Splash Screen│────▶│ Login Form │────▶│ Dashboard │ [*] --> SplashScreen : Page load
│ (on load) │ │ (if no │ │ (after auth) │ SplashScreen --> LoginForm : No session
│ │ │ session) │ │ │ SplashScreen --> Dashboard : Valid session
└──────────────┘ └──────────────┘ └──────────────┘ LoginForm --> Dashboard : Auth success
Dashboard --> LoginForm : Logout
┌─────┴─────┐
│ Status │ state Dashboard {
│ Panel │ [*] --> ActiveDownloads
│ (admin) │ ActiveDownloads --> ActiveDownloads : SSE update
└───────────┘
state StatusPanel {
[*] --> Closed
Closed --> Open : Click Status (admin)
Open --> Closed : Click close
Open --> Open : 5s refresh
}
}
``` ```
### Key Frontend Functions ### Key Frontend Functions