# TECH-CHANGELOG This changelog documents technical and developer-relevant changes included in public releases. For development workspace changes, see DEV-CHANGELOG.md. Not all changes here are reflected in the user-facing changelog (`program-info.json`), and not all UI/feature changes are repeated here. Some changes (e.g., backend refactoring, API adjustments, infrastructure, developer tooling, or internal logic) may only appear in TECH-CHANGELOG.md. For UI/feature changes, see `dashboard/public/program-info.json`. --- ## 2025.1.0-alpha.12 (2025-11-27) Backend rework (post-release notes; no version bump): - ๐Ÿงฉ Dev Container hygiene: Remote Containers runs on UI (`remote.extensionKind`), removed in-container install to prevent reappearance loops; switched `postCreateCommand` to `npm ci` for reproducible dashboard installs; `postStartCommand` aliases made idempotent. - ๐Ÿ”„ Serialization: Consolidated snake_caseโ†’camelCase via `server/serializers.py` for all JSON outputs; ensured enums/UTC datetimes serialize consistently across routes. - ๐Ÿ•’ Time handling: Normalized naive timestamps to UTC in all back-end comparisons (events, scheduler, groups) and kept ISO strings without `Z` in API responses; frontend appends `Z`. - ๐Ÿ“ก Streaming: Stabilized range-capable endpoint (`/api/eventmedia/stream//`), clarified client handling; scheduler emits basic HEAD-probe metadata (`mime_type`, `size`, `accept_ranges`). - ๐Ÿ“… Recurrence/exceptions: Ensured EXDATE tokens (RFC 5545 UTC) align with occurrence start; detached-occurrence flow confirmed via `POST /api/events//occurrences//detach`. - ๐Ÿงฐ Routes cleanup: Applied `dict_to_camel_case()` before `jsonify()` uniformly; verified Session lifecycle consistency (open/commit/close) across blueprints. - ๐Ÿ”„ **API Naming Convention Standardization**: - Created `server/serializers.py` with `dict_to_camel_case()` and `dict_to_snake_case()` utilities for consistent JSON serialization - Events API refactored: `GET /api/events` and `GET /api/events/` now return camelCase JSON (`id`, `subject`, `startTime`, `endTime`, `type`, `groupId`, etc.) instead of PascalCase - Internal event dictionaries use snake_case keys, then converted to camelCase via `dict_to_camel_case()` before `jsonify()` - **Breaking**: External API consumers must update field names from PascalCase to camelCase - โฐ **UTC Time Handling**: - Standardized datetime handling: Database stores timestamps in UTC (naive timestamps normalized by backend) - API returns ISO strings without 'Z' suffix: `"2025-11-27T20:03:00"` - Frontend appends 'Z' to parse as UTC and displays in user's local timezone via `toLocaleTimeString('de-DE')` - All time comparisons use UTC; `date.toISOString()` sends UTC back to API - ๐Ÿ–ฅ๏ธ **Dashboard Major Redesign**: - Completely redesigned dashboard with card-based layout for Raumgruppen (room groups) - Global statistics summary card: total infoscreens, online/offline counts, warning groups - Filter buttons with dynamic counts: All, Online, Offline, Warnings - Active event display per group: shows currently playing content with type icon, title, date ("Heute"/"Morgen"/date), and time range - Health visualization: color-coded progress bars showing online/offline ratio per group - Expandable client details: shows last alive timestamps with human-readable format ("vor X Min.", "vor X Std.", "vor X Tagen") - Bulk restart functionality: restart all offline clients in a group - Manual refresh button with toast notifications - 15-second auto-refresh interval - "Nicht zugeordnet" group always appears last in sorted list - ๐ŸŽจ **Frontend Technical**: - Dashboard (`dashboard/src/dashboard.tsx`): Uses Syncfusion ButtonComponent, ToastComponent, and card CSS classes - Appointments page updated to map camelCase API responses to internal PascalCase for Syncfusion compatibility - Time formatting functions (`formatEventTime`, `formatEventDate`) handle UTC string parsing with 'Z' appending - TypeScript lint errors resolved: unused error variables removed, null safety checks added with optional chaining - ๐Ÿ“– **Documentation**: - Updated `.github/copilot-instructions.md` with comprehensive sections on: - API patterns: JSON serialization, datetime handling conventions - Frontend patterns: API response format, UTC time parsing - Dashboard page overview with features - Conventions & gotchas: datetime and JSON naming guidelines - Updated `README.md` with recent changes, API response format section, and dashboard page details Notes for integrators: - **Breaking change**: All Events API endpoints now return camelCase field names. Update client code accordingly. - Frontend must append 'Z' to API datetime strings before parsing: `const utcStr = dateStr.endsWith('Z') ? dateStr : dateStr + 'Z'; new Date(utcStr);` - Use `dict_to_camel_case()` from `server/serializers.py` for any new API endpoints returning JSON - Dev container: prefer `npm ci` and UI-only Remote Containers to avoid extension drift in-container. --- ### Component build metadata template (for traceability) Record component builds under the unified app version when releasing: ``` Component builds for this release - API: image tag `ghcr.io/robbstarkaustria/api:` (commit ``) - Dashboard: image tag `ghcr.io/robbstarkaustria/dashboard:` (commit ``) - Scheduler: image tag `ghcr.io/robbstarkaustria/scheduler:` (commit ``) - Listener: image tag `ghcr.io/robbstarkaustria/listener:` (commit ``) - Worker: image tag `ghcr.io/robbstarkaustria/worker:` (commit ``) ``` This is informational (build metadata) and does not change the user-facing version number. ## 2025.1.0-alpha.11 (2025-11-05) - ๐Ÿ—ƒ๏ธ Data model & API: - Added `muted` (Boolean) to `Event` with Alembic migration; create/update and GET endpoints now accept, persist, and return `muted` alongside `autoplay`, `loop`, and `volume` for video events. - Video event fields consolidated: `event_media_id`, `autoplay`, `loop`, `volume`, `muted`. - ๐Ÿ”— Streaming: - Added range-capable streaming endpoint: `GET /api/eventmedia/stream//` (supports byte-range requests 206 for seeking). - Scheduler: Performs a best-effort HEAD probe for video stream URLs and includes basic metadata in the emitted payload (`mime_type`, `size`, `accept_ranges`). Placeholders added for `duration`, `resolution`, `bitrate`, `qualities`, `thumbnails`, `checksum`. - ๐Ÿ–ฅ๏ธ Frontend/Dashboard: - Settings page refactored to nested tabs with controlled tab selection (`selectedItem`) to prevent sub-tab jumps. - Settings โ†’ Events โ†’ Videos: Added system-wide defaults with load/save via system settings keys: `video_autoplay`, `video_loop`, `video_volume`, `video_muted`. - Event modal (CustomEventModal): Exposes per-event video options including โ€œTon ausโ€ (`muted`) and initializes all video fields from system defaults when creating new events. - Academic Calendar (Settings): Merged โ€œSchulferien Importโ€ and โ€œListeโ€ into a single sub-tab โ€œ๐Ÿ“ฅ Import & Listeโ€. - ๐Ÿ“– Documentation: - Updated `README.md` and `.github/copilot-instructions.md` for video payload (incl. `muted`), streaming endpoint (206), nested Settings tabs, and video defaults keys; clarified client handling of `video` payloads. - Updated `dashboard/public/program-info.json` (user-facing changelog) and bumped version to `2025.1.0-alpha.11` with corresponding UI/UX notes. Notes for integrators: - Clients should parse `event_type` and handle the nested `video` payload, honoring `autoplay`, `loop`, `volume`, and `muted`. Use the streaming endpoint with HTTP Range for seeking. - System settings keys for video defaults: `video_autoplay`, `video_loop`, `video_volume`, `video_muted`. ## 2025.1.0-alpha.10 (2025-10-25) - No new developer-facing changes in this release. - UI/UX updates are documented in `dashboard/public/program-info.json`: - Event modal: Surfaced video options (Autoplay, Loop, Volume). - FileManager: Increased upload limits (Full-HD); client-side duration validation (max 10 minutes). ## 2025.1.0-alpha.9 (2025-10-19) - ๐Ÿ—“๏ธ Events/API: - Implemented new `webuntis` event type. Event creation now resolves the URL from the system setting `supplement_table_url`; returns 400 if unset. - Removed obsolete `webuntis-url` settings endpoints. Use `GET/POST /api/system-settings/supplement-table` for URL and enabled state (shared for WebUntis/Vertretungsplan). - Initialization defaults: dropped `webuntis_url`; updated `supplement_table_url` description to โ€œVertretungsplan / WebUntisโ€. - ๐Ÿšฆ Scheduler payloads: - Unified Website/WebUntis payload: both emit a nested `website` object `{ "type": "browser", "url": "โ€ฆ" }`; `event_type` remains either `website` or `webuntis` for dispatch. - Payloads now include a top-level `event_type` string for all events to aid client dispatch. - ๐Ÿ–ฅ๏ธ Frontend/Dashboard: - Program info updated to `2025.1.0-alpha.13` with release notes. - Settings โ†’ Events: WebUntis now uses the existing Supplement-Table URL; no separate WebUntis URL field. - Event modal: WebUntis type behaves like Website (no per-event URL input). - ๐Ÿ“– Documentation: - Added `MQTT_EVENT_PAYLOAD_GUIDE.md` (message structure, client best practices, versioning). - Added `WEBUNTIS_EVENT_IMPLEMENTATION.md` (design notes, admin setup, testing checklist). - Updated `.github/copilot-instructions.md` and `README.md` for the unified Website/WebUntis handling and settings usage. Notes for integrators: - If you previously integrated against `/api/system-settings/webuntis-url`, migrate to `/api/system-settings/supplement-table`. - Clients should now parse `event_type` and use the corresponding nested payload (`presentation`, `website`, โ€ฆ). `webuntis` and `website` should be handled identically (nested `website` payload). ## 2025.1.0-alpha.8 (2025-10-18) - ๐Ÿ› ๏ธ Backend: Seeded presentation defaults (`presentation_interval`, `presentation_page_progress`, `presentation_auto_progress`) in system settings; applied on event creation. - ๐Ÿ—ƒ๏ธ Data model: Added `page_progress` and `auto_progress` fields to `Event` (with Alembic migration). - ๐Ÿ—“๏ธ Scheduler: Now publishes only currently active events per group (at "now"); clears retained topics by publishing `[]` for groups with no active events; normalizes naive timestamps and compares times in UTC; presentation payloads include `page_progress` and `auto_progress`. - ๐Ÿ–ฅ๏ธ Dashboard: Settings โ†’ Events tab now includes Presentations defaults (interval, page-progress, auto-progress) with load/save via API; event modal applies defaults on create and persists per-event values on edit. - ๐Ÿ“– Docs: Updated README and Copilot instructions for new scheduler behavior, UTC handling, presentation defaults, and per-event flags. --- ## 2025.1.0-alpha.11 (2025-10-16) - โœจ Settings page: New tab layout (Syncfusion) with role-based visibility โ€“ Tabs: ๐Ÿ“… Academic Calendar, ๐Ÿ–ฅ๏ธ Display & Clients, ๐ŸŽฌ Media & Files, ๐Ÿ—“๏ธ Events, โš™๏ธ System. - ๐Ÿ› ๏ธ Settings (Technical): API calls now use relative /api paths via the Vite proxy (prevents CORS and double /api). - ๐Ÿ“– Docs: README updated for settings page (tabs) and system settings API. ## 2025.1.0-alpha.10 (2025-10-15) - ๐Ÿ” Auth: Login and user management implemented (role-based, persistent sessions). - ๐Ÿงฉ Frontend: Syncfusion SplitButtons integrated (react-splitbuttons) and Vite config updated for pre-bundling. - ๐Ÿ› Fix: Import error โ€˜@syncfusion/ej2-react-splitbuttonsโ€™ โ€“ instructions added to README (optimizeDeps + volume reset). ## 2025.1.0-alpha.9 (2025-10-14) - โœจ UI: Unified deletion workflow for appointments โ€“ all types (single, single instance, entire series) handled with custom dialogs. - ๐Ÿ”ง Frontend: Syncfusion RecurrenceAlert and DeleteAlert intercepted and replaced with custom dialogs (including final confirmation for series deletion). - ๐Ÿ“– Docs: README and Copilot instructions expanded for deletion workflow and dialog handling. ## 2025.1.0-alpha.8 (2025-10-11) - ๐ŸŽจ Theme: Migrated to Syncfusion Material 3; centralized CSS imports in main.tsx - ๐Ÿงน Cleanup: Tailwind CSS completely removed (packages, PostCSS, Stylelint, config files) - ๐Ÿงฉ Group management: "infoscreen_groups" migrated to Syncfusion components (Buttons, Dialogs, DropDownList, TextBox); improved spacing - ๐Ÿ”” Notifications: Unified toast/dialog wording; last alert usage replaced - ๐Ÿ“– Docs: README and Copilot instructions updated (Material 3, centralized styles, no Tailwind) ## 2025.1.0-alpha.7 (2025-09-21) - ๐Ÿงญ UI: Period selection (Syncfusion) next to group selection; compact layout - โœ… Display: Badge for existing holiday plan + counter โ€˜Holidays in viewโ€™ - ๐Ÿ› ๏ธ API: Endpoints for academic periods (list, active GET/POST, for_date) - ๐Ÿ“… Scheduler: By default, no scheduling during holidays; block display like all-day event; black text color - ๐Ÿ“ค Holidays: Upload from TXT/CSV (headless TXT uses columns 2โ€“4) - ๐Ÿ”ง UX: Switches in a row; dropdown widths optimized ## 2025.1.0-alpha.6 (2025-09-20) - ๐Ÿ—“๏ธ NEW: Academic periods system โ€“ support for school years, semesters, trimesters - ๐Ÿ—๏ธ DATABASE: New 'academic_periods' table for time-based organization - ๐Ÿ”— EXTENDED: Events and media can now optionally be linked to an academic period - ๐Ÿ“Š ARCHITECTURE: Fully backward-compatible implementation for gradual rollout - โš™๏ธ TOOLS: Automatic creation of standard school years for Austrian schools ## 2025.1.0-alpha.5 (2025-09-14) - Backend: Complete redesign of backend handling for group assignments of new clients and steps for changing group assignment. ## 2025.1.0-alpha.4 (2025-09-01) - Deployment: Base structure for deployment tested and optimized. - FIX: Program error when switching view on media page fixed. ## 2025.1.0-alpha.3 (2025-08-30) - NEW: Program info page with dynamic data, build info, and changelog. - NEW: Logout functionality implemented. - FIX: Sidebar width corrected in collapsed state. ## 2025.1.0-alpha.2 (2025-08-29) - INFO: Analysis and display of used open-source libraries. ## 2025.1.0-alpha.1 (2025-08-28) - Initial project setup and base structure.