@startuml component !theme plain title sofarr — Component Diagram skinparam componentStyle rectangle skinparam packageStyle frame package "Browser" as browser { [index.html] as html [app.js] as appjs [style.css] as css html ..> appjs : loads html ..> css : loads } package "Express Server" as server { package "Middleware" { [CORS] as cors [cookie-parser] as cp [express.json] as ej [express.static] as es } package "Routes" as routes { [auth.js\n/api/auth] as auth [dashboard.js\n/api/dashboard] as dashboard [emby.js\n/api/emby] as emby_route [sabnzbd.js\n/api/sabnzbd] as sab_route [sonarr.js\n/api/sonarr] as sonarr_route [radarr.js\n/api/radarr] as radarr_route } package "Utilities" as utils { [poller.js] as poller [cache.js\nMemoryCache] as cache [config.js] as config [qbittorrent.js\nQBittorrentClient] as qbt [logger.js] as logger } [index.js\nEntry Point] as entry entry --> cors entry --> cp entry --> ej entry --> es entry --> auth entry --> dashboard entry --> emby_route entry --> sab_route entry --> sonarr_route entry --> radarr_route entry --> poller : startPoller() dashboard --> cache : read poll:* keys dashboard --> poller : pollAllServices()\n(on-demand mode) dashboard --> config : getSonarrInstances()\ngetRadarrInstances() dashboard --> qbt : mapTorrentToDownload() poller --> cache : set poll:* keys poller --> config : get all instances poller --> qbt : getTorrents() poller --> logger qbt --> config : getQbittorrentInstances() qbt --> logger } cloud "External Services" as external { [Emby / Jellyfin] as emby [SABnzbd] as sab [Sonarr] as sonarr [Radarr] as radarr [qBittorrent] as qbit } auth --> emby : authenticate\nuser profile dashboard ..> emby : /user-summary\n(live fetch) emby_route --> emby sab_route --> sab sonarr_route --> sonarr radarr_route --> radarr poller --> sab : queue + history poller --> sonarr : tags + queue + history poller --> radarr : tags + queue + history qbt --> qbit : login + torrents/info appjs --> auth : POST /login\nGET /me appjs --> dashboard : GET /user-downloads\nGET /status es --> html : serve static @enduml