feat(events): add webuntis event, unify website payload, bump UI to alpha.13

- Add `webuntis` event type; event creation resolves URL from system `supplement_table_url`
- Consolidate settings: remove separate webuntis-url endpoints; use GET/POST /api/system-settings/supplement-table
- Scheduler: emit top-level `event_type` and unified `website` payload (`{ "type":"browser","url":"..." }`) for website/webuntis
- Preserve presentation payloads (page_progress/auto_progress) — presentation messages remain backwards-compatible
- Update defaults (`init_defaults.py`) and remove duplicate webuntis setting
- Docs & metadata: bump program-info to 2025.1.0-alpha.13; update README, copilot-instructions, DEV- and TECH-CHANGELOGs; add MQTT_EVENT_PAYLOAD_GUIDE.md and WEBUNTIS_EVENT_IMPLEMENTATION.md
This commit is contained in:
RobbStarkAustria
2025-10-19 11:35:41 +00:00
parent c9cc535fc6
commit e6c19c189f
12 changed files with 788 additions and 11 deletions

View File

@@ -6,7 +6,7 @@ Your database has been successfully initialized! Here's what you need to know:
### ✅ Current Status
- **Database**: MariaDB 11.2 running in Docker container `infoscreen-db`
- **Schema**: Up to date (Alembic revision: `b5a6c3d4e7f8`)
- **Schema**: Up to date (check with `alembic current` in `server/`)
- **Default Data**: Admin user and client group created
- **Academic Periods**: Austrian school years 2024/25 (active), 2025/26, 2026/27
@@ -82,8 +82,70 @@ session.close()
- **`conversions`** - File conversion jobs (PPT → PDF)
- **`academic_periods`** - School year/semester management
- **`school_holidays`** - Holiday calendar
- **`event_exceptions`** - Overrides and skips for recurring events (per occurrence)
- **`system_settings`** - Keyvalue store for global settings
- **`alembic_version`** - Migration tracking
### Key details and relationships
- Users (`users`)
- Fields: `username` (unique), `password_hash`, `role` (enum: user|editor|admin|superadmin), `is_active`
- Client groups (`client_groups`)
- Fields: `name` (unique), `description`, `is_active`
- Clients (`clients`)
- Fields: `uuid` (PK), network/device metadata, `group_id` (FK→client_groups, default 1), `last_alive` (updated on heartbeat), `is_active`
- Academic periods (`academic_periods`)
- Fields: `name` (unique), optional `display_name`, `start_date`, `end_date`, `period_type` (enum: schuljahr|semester|trimester), `is_active` (at most one should be active)
- Indexes: `is_active`, dates
- Event media (`event_media`)
- Fields: `media_type` (enum, see below), `url`, optional `file_path`, optional `message_content`, optional `academic_period_id`
- Used by events of types: presentation, video, website, message, other
- Events (`events`)
- Core: `group_id` (FK), optional `academic_period_id` (FK), `title`, optional `description`, `start`, `end`, `event_type` (enum), optional `event_media_id` (FK)
- Presentation/video extras: `autoplay`, `loop`, `volume`, `slideshow_interval`, `page_progress`, `auto_progress`
- Recurrence: `recurrence_rule` (RFC 5545 RRULE), `recurrence_end`, `skip_holidays` (bool)
- Audit/state: `created_by` (FK→users), `updated_by` (FK→users), `is_active`
- Indexes: `start`, `end`, `recurrence_rule`, `recurrence_end`
- Relationships: `event_media`, `academic_period`, `exceptions` (one-to-many to `event_exceptions` with cascade delete)
- Event exceptions (`event_exceptions`)
- Purpose: track per-occurrence skips or overrides for a recurring master event
- Fields: `event_id` (FK→events, ondelete CASCADE), `exception_date` (Date), `is_skipped`, optional overrides (`title`, `description`, `start`, `end`)
- School holidays (`school_holidays`)
- Unique: (`name`, `start_date`, `end_date`, `region`)
- Used in combination with `events.skip_holidays`
- Conversions (`conversions`)
- Purpose: track PPT/PPTX/ODP → PDF processing
- Fields: `source_event_media_id` (FK→event_media, ondelete CASCADE), `target_format`, `target_path`, `status` (enum), `file_hash`, timestamps, `error_message`
- Indexes: (`source_event_media_id`, `target_format`), (`status`, `target_format`)
- Unique: (`source_event_media_id`, `target_format`, `file_hash`) — idempotency per content
- System settings (`system_settings`)
- Keyvalue store: `key` (PK), `value`, optional `description`, `updated_at`
- Notable keys used by the app: `presentation_interval`, `presentation_page_progress`, `presentation_auto_progress`
### Enums (reference)
- UserRole: `user`, `editor`, `admin`, `superadmin`
- AcademicPeriodType: `schuljahr`, `semester`, `trimester`
- EventType: `presentation`, `website`, `video`, `message`, `other`, `webuntis`
- MediaType: `pdf`, `ppt`, `pptx`, `odp`, `mp4`, `avi`, `mkv`, `mov`, `wmv`, `flv`, `webm`, `mpg`, `mpeg`, `ogv`, `jpg`, `jpeg`, `png`, `gif`, `bmp`, `tiff`, `svg`, `html`, `website`
- ConversionStatus: `pending`, `processing`, `ready`, `failed`
### Timezones, recurrence, and holidays
- All timestamps are stored/compared as timezone-aware UTC. Any naive datetimes are normalized to UTC before comparisons.
- Recurrence is represented on events via `recurrence_rule` (RFC 5545 RRULE) and `recurrence_end`. Do not pre-expand series in the DB.
- Per-occurrence exclusions/overrides are stored in `event_exceptions`. The API also emits EXDATE tokens matching occurrence start times (UTC) so the frontend can exclude instances natively.
- When `skip_holidays` is true, occurrences that fall on school holidays are excluded via corresponding `event_exceptions`.
### Environment Variables:
```bash
DB_CONN=mysql+pymysql://infoscreen_admin:KqtpM7wmNdM1DamFKs@db/infoscreen_by_taa