Files
infoscreen/.github/copilot-instructions.md
Olaf 4d652f0554 feat: 2026.1.0-alpha.16 – dashboard banner refactor, period auto-activation, text & docs
Dashboard (dashboard/src/dashboard.tsx, settings.tsx, apiAcademicPeriods.ts):
- Refactor loadHolidayStatus to useCallback with stable empty-deps reference;
  removes location.pathname dependency that caused overlapping API calls at mount
  and left the banner unresolved via request-sequence cancellation
- Add key prop derived from severity:text to Syncfusion MessageComponent to force
  remount on state change, fixing stale banner that ignored React prop/children updates
- Correct German transliterated text to proper Umlauts throughout visible UI strings
  (fuer -> für, oe -> ö, ae -> ä etc. across dashboard and settings views)

Backend (server/init_academic_periods.py):
- Refactor to idempotent two-phase flow: seed default periods only when table is
  empty; on every run activate exactly the non-archived period covering date.today()
- Enforces single-active invariant by deactivating all periods before promoting match
- Emits explicit warning when no period covers current date instead of doing nothing

Deployment (docker-compose.prod.yml):
- Add init_academic_periods.py to server startup chain after migrations and defaults;
  eliminates manual post-deploy step to set an active academic period

Release docs:
- program-info.json: bump to 2026.1.0-alpha.16; fix JSON parse error caused by
  typographic curly quotes in the new changelog entry
- TECH-CHANGELOG.md: detailed alpha.16 section with root-cause motivation for both
  dashboard refactoring decisions (unstable callback ref + Syncfusion stale render)
- DEV-CHANGELOG.md: document dashboard refactor, Syncfusion key fix, Umlaut changes,
  and program-info JSON regression and fix
- README.md: add Latest Release Highlights section for alpha.16
- .github/copilot-instructions.md: sync file map, prod bootstrap note, backend and
  frontend pattern additions for academic period init and Syncfusion remount pattern
2026-04-02 14:16:53 +00:00

5.4 KiB

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
  • scheduler/db_utils.py - event formatting and power-intent helper logic
  • listener/listener.py - discovery/heartbeat/log/screenshot 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
  • 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
  • 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
  • Core: DB_CONN, DB_USER, DB_PASSWORD, DB_HOST, DB_NAME, ENV

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/