# Copilot instructions for infoscreen_2025 ## Purpose This file is a concise, high-signal brief for coding agents. It is not a changelog and not a full architecture handbook. ## TL;DR - Stack: Flask API + MariaDB, React/Vite dashboard, MQTT listener, scheduler, worker. - Main areas: - API logic in `server/` - Scheduler logic in `scheduler/` - UI logic in `dashboard/src/` - Keep changes minimal, match existing patterns, and update docs in the same commit when behavior changes. ## Fast file map - `scheduler/scheduler.py` - scheduler loop, MQTT event publishing, TV power intent publishing, crash auto-recovery, command expiry sweep - `scheduler/db_utils.py` - event formatting, power-intent helpers, crash recovery helpers, command expiry sweep - `listener/listener.py` - discovery/heartbeat/log/screenshot/service_failed MQTT consumption - `server/init_academic_periods.py` - idempotent academic-period seeding + auto-activation for current date - `server/initialize_database.py` - migration + bootstrap orchestration for local/manual setup - `server/routes/events.py` - event CRUD, recurrence handling, UTC normalization - `server/routes/eventmedia.py` - file manager, media upload/stream endpoints - `server/routes/groups.py` - group lifecycle, alive status, order persistence - `server/routes/system_settings.py` - system settings CRUD and supplement-table endpoint - `server/routes/clients.py` - client metadata, restart/shutdown/restart_app command issuing, command status, crashed/service_failed alert endpoints - `dashboard/src/settings.tsx` - settings UX and system-defaults integration - `dashboard/src/components/CustomEventModal.tsx` - event creation/editing UX - `dashboard/src/monitoring.tsx` - superadmin monitoring page - `TV_POWER_INTENT_SERVER_CONTRACT_V1.md` - Phase 1 TV power contract ## Service picture - API: `server/` on `:8000` (health: `/health`) - Dashboard: `dashboard/` (dev `:5173`, proxied API calls) - MQTT broker: Mosquitto (`mosquitto/config/mosquitto.conf`) - Listener: MQTT consumer that updates server-side state - Scheduler: publishes active events and group-level TV power intents - Nginx: routes `/api/*` and `/screenshots/*` to API, dashboard otherwise - Prod bootstrap: `docker-compose.prod.yml` server command runs migrations, defaults init, and academic-period init before Gunicorn start ## Non-negotiable conventions - Datetime: - Store/compare in UTC. - API returns ISO strings without `Z` in many routes. - Frontend must append `Z` before parsing if needed. - JSON naming: - Backend internals use snake_case. - API responses use camelCase (via `server/serializers.py`). - DB host in containers: `db` (not localhost). - Never put secrets in docs. ## MQTT contracts - Event list topic (retained): `infoscreen/events/{group_id}` - Group assignment topic (retained): `infoscreen/{uuid}/group_id` - Heartbeat topic: `infoscreen/{uuid}/heartbeat` - Logs topic family: `infoscreen/{uuid}/logs/{error|warn|info}` - Health topic: `infoscreen/{uuid}/health` - Dashboard screenshot topic: `infoscreen/{uuid}/dashboard` - Client command topic (QoS1, non-retained): `infoscreen/{uuid}/commands` (compat alias: `infoscreen/{uuid}/command`) - Client command ack topic (QoS1, non-retained): `infoscreen/{uuid}/commands/ack` (compat alias: `infoscreen/{uuid}/command/ack`) - Service-failed topic (retained, client→server): `infoscreen/{uuid}/service_failed` - TV power intent Phase 1 topic (retained, QoS1): `infoscreen/groups/{group_id}/power/intent` TV power intent Phase 1 rules: - Schema version is `"1.0"`. - Group-only scope in Phase 1. - Heartbeat publish keeps `intent_id`; semantic transition rotates `intent_id`. - Expiry rule: `expires_at = issued_at + max(3 x poll_interval_sec, 90s)`. - Canonical contract is `TV_POWER_INTENT_SERVER_CONTRACT_V1.md`. ## Backend patterns - Routes in `server/routes/*`, registered in `server/wsgi.py`. - Use one request-scoped DB session, commit on mutation, always close session. - Keep enum/datetime serialization JSON-safe. - Maintain UTC-safe comparisons in scheduler and routes. - Keep recurrence handling backend-driven and consistent with exceptions. - Academic periods bootstrap is idempotent and should auto-activate period covering `date.today()` when available. ## Frontend patterns - Use Syncfusion-based patterns already present in dashboard. - Keep API requests relative (`/api/...`) to use Vite proxy in dev. - Respect `FRONTEND_DESIGN_RULES.md` for component and styling conventions. - Keep role-gated UI behavior aligned with backend authorization. - Holiday status banner in dashboard should render from computed state and avoid stale message reuse in 3rd-party UI components. ## Environment variables (high-value) - Scheduler: `POLL_INTERVAL_SECONDS`, `REFRESH_SECONDS` - Power intent: `POWER_INTENT_PUBLISH_ENABLED`, `POWER_INTENT_HEARTBEAT_ENABLED`, `POWER_INTENT_EXPIRY_MULTIPLIER`, `POWER_INTENT_MIN_EXPIRY_SECONDS` - Monitoring: `PRIORITY_SCREENSHOT_TTL_SECONDS` - Crash recovery: `CRASH_RECOVERY_ENABLED`, `CRASH_RECOVERY_GRACE_SECONDS`, `CRASH_RECOVERY_LOCKOUT_MINUTES`, `CRASH_RECOVERY_COMMAND_EXPIRY_SECONDS` - Core: `DB_CONN`, `DB_USER`, `DB_PASSWORD`, `DB_HOST`, `DB_NAME`, `ENV` - MQTT auth/connectivity: `MQTT_BROKER_HOST`, `MQTT_BROKER_PORT`, `MQTT_USER`, `MQTT_PASSWORD` (listener/scheduler/server should use authenticated broker access) ## Edit guardrails - Do not edit generated assets in `dashboard/dist/`. - Do not change CI/build outputs unless explicitly intended. - Preserve existing API behavior unless task explicitly requires a change. - Prefer links to canonical docs instead of embedding long historical notes here. ## Documentation sync rule When services/MQTT/API/UTC/env behavior changes: 1. Update this file (concise deltas only). 2. Update canonical docs where details live. 3. Update changelogs separately (`TECH-CHANGELOG.md`, `DEV-CHANGELOG.md`, `dashboard/public/program-info.json` as appropriate). ## Canonical docs map - Repo entry: `README.md` - Instruction governance: `AI-INSTRUCTIONS-MAINTENANCE.md` - Technical release details: `TECH-CHANGELOG.md` - Workspace/development notes: `DEV-CHANGELOG.md` - MQTT payload details: `MQTT_EVENT_PAYLOAD_GUIDE.md` - TV power contract: `TV_POWER_INTENT_SERVER_CONTRACT_V1.md` - Frontend patterns: `FRONTEND_DESIGN_RULES.md` - Archived historical docs: `docs/archive/`