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

108 lines
5.4 KiB
Markdown

# 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/`