# 08 · End-to-End Workflows This document traces the main user journeys through the system, tying together blueprints, models, utils, and the Graphify graph. --- ## 1. Content Upload → Playlist → Player ```mermaid flowchart LR U["Admin uploads media"] --> UF["/content/upload-media"] UF -->|image| IMG["optimize_image_to_fullhd"] UF -->|video| VID["validate via ffprobe"] UF -->|pdf| PDF["pdf2image @300dpi → page PNGs"] UF -->|pptx| PPT["LibreOffice → PDF → PNG slides"] UF -->|large file| BG["process_file_in_background (thread)"] UF --> DB[("Content row")] DB --> PLA["/content/playlist//add-content"] PLA --> PLC["playlist_content (position, duration, muted, edit_on_player_enabled)"] PLC --> VER["Playlist.increment_version() + cache.clear()"] VER --> API["/api/playlists/"] API --> P["Player fetches new playlist"] ``` **Key files:** `app/blueprints/content.py`, `app/utils/uploads.py`, `app/utils/pptx_converter.py`, `app/models/content.py`, `app/models/playlist.py`. --- ## 2. Playlist Synchronization (the "version" mechanism) Every playlist mutation bumps `Playlist.version`. Players detect changes by polling: ```mermaid sequenceDiagram participant U as Admin UI participant App participant DB as SQLite participant P as Player U->>App: reorder / mute / duration / add / remove App->>DB: mutate playlist_content App->>DB: playlist.increment_version() App->>App: cache.clear() loop while player runs P->>App: GET /api/playlist-version/ App-->>P: {version: N} alt version changed P->>App: GET /api/playlists/ App-->>P: new playlist payload end end ``` **Playlist payload items** include: `file_name`, `type`, `duration`, `position`, `url` (weblink or static file), `description`, `edit_on_player_enabled`, `muted`, `audio`. --- ## 3. On-Player Media Editing Pipeline ⭐ (heat 0.620) When a signage operator edits an image directly on the player device: ```mermaid flowchart TD A["Player posts edited image"] --> B["POST /api/player-edit-media (Bearer + multipart)"] B --> C{"Locate Content"} C -->|by filename| D["match filename"] C -->|edited_media regex| E["match edited_media//"] C -->|fallback| F["last PlayerEdit"] D/E/F --> G["Move original → edited_media//original_*"] G --> H["Save new version + side-car metadata JSON"] H --> I{"PlayerUser exists for user_code?"} I -- no --> J["auto-create PlayerUser"] I -- yes --> K["reuse"] J/K --> L["Create PlayerEdit (version, original_name, new_name...)"] L --> M["Repoint Content.filename → latest edit"] M --> N["Preserve original_filename"] N --> O["Playlist.increment_version() + cache.clear()"] O --> P["Player sees updated media on refresh"] ``` **Why this is a god node:** `PlayerEdit` (99 edges) and `PlayerUser` (74 edges) make this the most-connected data flow in the system. See `app/models/player_edit.py`, `app/models/player_user.py`, `app/blueprints/api.py`. --- ## 4. HTTPS Configuration (Caddy) ```mermaid flowchart TD A["Admin → /admin/https-config"] --> B["POST /admin/https-config/update"] B --> C["Validate + save HTTPSConfig (email, domain, ip, port)"] C --> D["CaddyConfigGenerator.generate_caddyfile()"] D --> E{"Mode"} E -->|HTTP| F[":80 reverse proxy"] E -->|domain| G["Let's Encrypt automatic HTTPS"] E -->|IP| H["Internal CA self-signed"] F/G/H --> I["write_caddyfile(/etc/caddy/Caddyfile)"] I --> J["POST http://caddy:2019/load (hot reload)"] J --> K["HTTPS live without restart"] ``` --- ## 5. User Management & Auditing ```mermaid flowchart TD A["Admin panel"] --> B["/admin/user/create"] A --> C["/admin/user//role"] A --> D["/admin/user//password"] A --> E["/admin/user//delete"] B/C/D/E --> L["log_action(level, message)"] L --> S[("server_log")] S --> F["dashboard / admin recent logs"] S --> G["/api/logs (limit, level, since)"] ``` **Roles:** `admin` (full), `user` (manage content/players), `viewer` (read-only dashboard). --- ## 6. Portal SSO (optional corporate gateway) ```mermaid sequenceDiagram participant B as Browser participant G as Umbrella nginx gateway participant A as DigiServer B->>G: request (authenticated by portal) G->>A: proxy + headers X-Auth-Username, X-Auth-Role A->>A: init_portal_sso before_request A->>A: _get_or_create_user(username, role) A-->>B: dashboard (auto logged-in) ``` --- ## 7. Media Housekeeping (Leftovers) Content not assigned to any playlist is flagged as "leftover": ```mermaid flowchart LR L["/admin/leftover-media"] --> T["grouped by type: image/video/pdf/pptx + sizes"] T --> D["/admin/delete-leftover-images|videos"] D --> X["delete file + edited_media archive + PlayerEdit rows"] ``` --- > Next: [09 · Legacy & Migrations](09-legacy-and-migrations.md)