# Digital Signage CMS — Project Overview ## Concept Multi-tenant digital signage platform. Customers upload content (images, video) via a web portal, create playlists, and Raspberry Pi players pull and display content in fullscreen kiosk mode. ## Architecture ``` ┌─────────────────────────────┐ ┌──────────────────────────────┐ │ Customer Portal (Web) │ │ Raspberry Pi Player │ │ │ │ │ │ ┌───────────────────────┐ │ │ ┌────────────────────────┐ │ │ │ Login (auth per │ │ │ │ Registration script │ │ │ │ customer/tenant) │ │ │ │ P: POST /api/register │ │ │ ├───────────────────────┤ │ │ │ → gets device token │ │ │ │ Dashboard │ │ │ ├────────────────────────┤ │ │ │ - My Screens │ │ │ │ Polling script │ │ │ │ - Content Library │ │ │ │ GET /api/playlist/:id │ │ │ │ - Playlists │ │ │ │ → returns content URLs │ │ │ │ - Upload │ │ │ ├────────────────────────┤ │ │ ├───────────────────────┤ │ │ │ Chromium kiosk │ │ │ │ Admin (ITPP) │ │ │ │ --kiosk --no-sandbox │ │ │ │ - All tenants │ │ │ └────────────────────────┘ │ │ │ - Device management │ │ └──────────────────────────────┘ │ └───────────────────────┘ │ └─────────────────────────────┘ │ ▼ ┌─────────────────┐ │ API + Storage │ │ │ │ FastAPI backend │ │ SQLite/S3 │ │ per tenant │ └─────────────────┘ ``` ## Multi-Tenant Architecture ### Tenant Hierarchy ``` Signage CMS (Platform) ├── Tenant: Joe's Diner │ ├── User: alice@joesdiner.com (admin) │ ├── Device: Main Lobby Pi │ │ ├── Serial: 10000000a1b2c3d4 │ │ ├── Status: Online │ │ └── Playlist: Main Menu Loop │ ├── Device: Menu Board Pi │ │ ├── Serial: 10000000e5f6g7h8 │ │ ├── Status: Online │ │ └── Playlist: Daily Specials │ ├── Device: Waiting Room Pi │ │ ├── Serial: 10000000i9j0k1l2 │ │ ├── Status: Offline │ │ └── Playlist: Promo Rotation │ └── Content: 8 items (4 images, 4 videos) │ ├── Tenant: Main Street Gym │ ├── User: owner@mainstreetgym.com │ └── Device: Front Desk Pi │ └── Tenant: Third Coast Dental ├── User: frontdesk@thirdcoast.com ├── Device: Waiting Room Pi ├── Device: Exam Room Pi └── Device: Hallway Pi ``` ### Key Design Points - **One customer = one tenant = unlimited devices** - Each device registers independently with a unique code + serial - Devices belong to a tenant, not directly to a user - Multiple users can manage the same tenant (owner + staff accounts) - Content libraries are per-tenant (shared across all their devices) - Playlists can be assigned to one or multiple devices - A device can only play ONE playlist at a time ### Pi Registration Flow ``` 1. Customer gets Pi with a unique registration code (printed or emailed) 2. Pi boots → runs registration script 3. Script calls POST /api/register with code + Pi serial number 4. Server registers device under that tenant 5. Pi receives device_id + auth token 6. Pi starts polling GET /api/playlist/:device_id every 60s 7. CMS pushes updates → Pi picks up new playlist on next poll ``` ### Registration Script (on Pi) ```bash #!/bin/bash # register-pi.sh REG_CODE="$1" PI_SERIAL=$(cat /proc/cpuinfo | grep Serial | awk '{print $3}') API="https://signage.itpropartner.com/api" curl -X POST "$API/register" \ -H "Content-Type: application/json" \ -d "{\"code\":\"$REG_CODE\",\"serial\":\"$PI_SERIAL\"}" ``` ## MVP Scope (Phase 1) | Feature | Status | |---------|--------| | Customer login | To build | | Content upload (images + video) | To build | | Simple playlist (ordered) | To build | | Pi kiosk player script | To build | | Multi-tenant (tenant isolation) | To build | | Cloudflare proxy | Future | | Scheduling | Future | | Shuffled/random play | Future | | 4K detection via EDID | To research | ## Stack - **Backend:** FastAPI + SQLite (same pattern as ops portal) - **Frontend:** Dark theme, mobile-responsive (PWA-ready) - **Player:** Raspberry Pi 3/4/5, Chromium kiosk, auto-updating - **Storage:** Local filesystem → S3 in future - **Auth:** JWT per tenant, admin override ## Status 📝 **Project created — MVP design underway**