Files
digiserver-v2/docs/08-workflows.md
T

4.9 KiB

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

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/<id>/add-content"]
    PLA --> PLC["playlist_content (position, duration, muted, edit_on_player_enabled)"]
    PLC --> VER["Playlist.increment_version() + cache.clear()"]
    VER --> API["/api/playlists/<id>"]
    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:

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/<player_id>
        App-->>P: {version: N}
        alt version changed
            P->>App: GET /api/playlists/<player_id>
            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:

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/<id>/"]
    C -->|fallback| F["last PlayerEdit"]
    D/E/F --> G["Move original → edited_media/<content_id>/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)

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

flowchart TD
    A["Admin panel"] --> B["/admin/user/create"]
    A --> C["/admin/user/<id>/role"]
    A --> D["/admin/user/<id>/password"]
    A --> E["/admin/user/<id>/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)

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":

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