151 lines
4.9 KiB
Markdown
151 lines
4.9 KiB
Markdown
# 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/<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:
|
|
|
|
```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/<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:
|
|
|
|
```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/<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)
|
|
|
|
```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/<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)
|
|
|
|
```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)
|