# Infoscreen 2025

[![Docker](https://img.shields.io/badge/Docker-Multi--Service-blue?logo=docker)](https://www.docker.com/)
[![React](https://img.shields.io/badge/React-19.1.0-61DAFB?logo=react)](https://reactjs.org/)
[![Flask](https://img.shields.io/badge/Flask-REST_API-green?logo=flask)](https://flask.palletsprojects.com/)
[![MariaDB](https://img.shields.io/badge/MariaDB-11.2-003545?logo=mariadb)](https://mariadb.org/)
[![MQTT](https://img.shields.io/badge/MQTT-Eclipse_Mosquitto-purple)](https://mosquitto.org/)

Multi-service digital signage platform for educational institutions.

Core stack:
- Dashboard: React + Vite + Syncfusion
- API: Flask + SQLAlchemy + Alembic
- DB: MariaDB
- Messaging: MQTT (Mosquitto)
- Background jobs: Redis + RQ + Gotenberg

## Architecture (Short)

- Dashboard talks only to API (`/api/...` via Vite proxy in dev).
- API is the single writer to MariaDB.
- Listener consumes MQTT discovery/heartbeat/log/screenshot topics and updates API state.
- Scheduler expands recurring events, applies exceptions, and publishes active content to retained MQTT topics.
- Worker handles document conversions asynchronously.

## Quick Start

### Prerequisites
- Docker + Docker Compose
- Git

### Development

1. Clone
```bash
git clone https://github.com/RobbStarkAustria/infoscreen_2025.git
cd infoscreen_2025
```

2. Configure environment
```bash
cp .env.example .env
# edit values as needed
```

3. Start stack
```bash
make up
# or: docker compose up -d --build
```

4. Initialize DB (first run)
```bash
python server/initialize_database.py
```

5. Open services
- Dashboard: http://localhost:5173
- API: http://localhost:8000
- MariaDB: localhost:3306
- MQTT: localhost:1883 (WS: 9001)

## Holiday Calendar (Quick Usage)

Settings path:
- `Settings` -> `Academic Calendar` -> `Ferienkalender: Import/Anzeige`

Workflow summary:
1. Select target academic period (archived periods are read-only/not selectable).
2. Import CSV/TXT or add/edit holidays manually.
3. Validation is period-scoped (out-of-period ranges are blocked).
4. Duplicate/overlap policy:
   - exact duplicates: skipped/prevented
   - same normalized `name+region` overlaps (including adjacent ranges): merged
   - different-identity overlaps: conflict (manual blocked, import skipped with details)
5. Recurring events with `skip_holidays` are recalculated automatically after holiday changes.

## Common Commands

```bash
# Start/stop
make up
make down

# Logs
make logs
make logs-server

# Health
make health

# Build/push/deploy
make build
make push
make pull-prod
make up-prod
```

## Scheduler Runtime Flags

Scheduler runtime defaults can be tuned with environment variables:

- `POLL_INTERVAL_SECONDS` (default: `30`)
- `REFRESH_SECONDS` (default: `0`, disabled)

TV power coordination (server Phase 1, group-level intent only):

- `POWER_INTENT_PUBLISH_ENABLED` (default: `false`)
- `POWER_INTENT_HEARTBEAT_ENABLED` (default: `true`)
- `POWER_INTENT_EXPIRY_MULTIPLIER` (default: `3`)
- `POWER_INTENT_MIN_EXPIRY_SECONDS` (default: `90`)

Power intent topic contract for Phase 1:

- Topic: `infoscreen/groups/{group_id}/power/intent`
- QoS: `1`
- Retained: `true`
- Publish mode: transition publish + heartbeat republish each poll
- Schema version: `v1`
- Intent ID behavior: stable across unchanged heartbeat cycles; new UUID only on semantic transition (desired_state or reason change)
- Expiry rule: max(3 × poll_interval, 90 seconds)

Rollout strategy (Phase 1):

1. Keep `POWER_INTENT_PUBLISH_ENABLED=false` by default (disabled).
2. Enable in test environment first: set `POWER_INTENT_PUBLISH_ENABLED=true` on one canary group's scheduler instance.
3. Verify no unintended OFF between adjacent/overlapping events over 1–2 days.
4. Expand to 20% of production groups for 2 days (canary soak).
5. Monitor power-intent publish metrics (success rate, error rate, transition frequency) in scheduler logs.
6. Roll out to 100% once canary is stable (zero off-between-adjacent-events incidents).
7. Phase 2 (future): per-client override intents and state acknowledgments.

## Documentation Map

### Deployment
- [deployment-debian.md](deployment-debian.md)
- [deployment-ubuntu.md](deployment-ubuntu.md)
- [setup-deployment.sh](setup-deployment.sh)

### Backend & Database
- [DATABASE_GUIDE.md](DATABASE_GUIDE.md)
- [TECH-CHANGELOG.md](TECH-CHANGELOG.md)
- [server/alembic](server/alembic)

### Authentication & Authorization
- [AUTH_SYSTEM.md](AUTH_SYSTEM.md)
- [AUTH_QUICKREF.md](AUTH_QUICKREF.md)
- [userrole-management.md](userrole-management.md)
- [SUPERADMIN_SETUP.md](SUPERADMIN_SETUP.md)

### Monitoring, Screenshots, Health
- [CLIENT_MONITORING_IMPLEMENTATION_GUIDE.md](CLIENT_MONITORING_IMPLEMENTATION_GUIDE.md)
- [CLIENT_MONITORING_SPECIFICATION.md](CLIENT_MONITORING_SPECIFICATION.md)
- [SCREENSHOT_IMPLEMENTATION.md](SCREENSHOT_IMPLEMENTATION.md)

### MQTT & Payloads
- [MQTT_EVENT_PAYLOAD_GUIDE.md](MQTT_EVENT_PAYLOAD_GUIDE.md)
- [MQTT_PAYLOAD_MIGRATION_GUIDE.md](MQTT_PAYLOAD_MIGRATION_GUIDE.md)

### Events, Calendar, WebUntis
- [WEBUNTIS_EVENT_IMPLEMENTATION.md](WEBUNTIS_EVENT_IMPLEMENTATION.md)

### Historical Background
- [docs/archive/ACADEMIC_PERIODS_IMPLEMENTATION_SUMMARY.md](docs/archive/ACADEMIC_PERIODS_IMPLEMENTATION_SUMMARY.md)
- [docs/archive/ACADEMIC_PERIODS_CRUD_BUILD_PLAN.md](docs/archive/ACADEMIC_PERIODS_CRUD_BUILD_PLAN.md)
- [docs/archive/PHASE_3_CLIENT_MONITORING_IMPLEMENTATION.md](docs/archive/PHASE_3_CLIENT_MONITORING_IMPLEMENTATION.md)
- [docs/archive/CLEANUP_SUMMARY.md](docs/archive/CLEANUP_SUMMARY.md)

### Conversion / Media
- [pptx_conversion_guide.md](pptx_conversion_guide.md)
- [pptx_conversion_guide_gotenberg.md](pptx_conversion_guide_gotenberg.md)

### Frontend
- [FRONTEND_DESIGN_RULES.md](FRONTEND_DESIGN_RULES.md)
- [dashboard/README.md](dashboard/README.md)

### Project / Contributor Guidance
- [.github/copilot-instructions.md](.github/copilot-instructions.md)
- [AI-INSTRUCTIONS-MAINTENANCE.md](AI-INSTRUCTIONS-MAINTENANCE.md)
- [DEV-CHANGELOG.md](DEV-CHANGELOG.md)

## API Highlights

- Core resources: clients, groups, events, academic periods
- Holidays: `GET/POST /api/holidays`, `POST /api/holidays/upload`, `PUT/DELETE /api/holidays/<id>`
- Media: upload/download/stream + conversion status
- Auth: login/logout/change-password
- Monitoring: logs and monitoring overview endpoints

For full endpoint details, use source route files under `server/routes/` and the docs listed above.

## Project Structure (Top Level)

```text
infoscreen_2025/
├── dashboard/        # React frontend
├── server/           # Flask API + migrations + worker
├── listener/         # MQTT listener
├── scheduler/        # Event scheduler/publisher
├── models/           # Shared SQLAlchemy models
├── mosquitto/        # MQTT broker config
├── certs/            # TLS certs (prod)
└── docker-compose*.yml
```

## Contributing

1. Create branch
2. Implement change + tests
3. Update relevant docs
4. Open PR

Guidelines:
- Match existing architecture and naming conventions
- Keep frontend aligned with [FRONTEND_DESIGN_RULES.md](FRONTEND_DESIGN_RULES.md)
- Keep service/API behavior aligned with [.github/copilot-instructions.md](.github/copilot-instructions.md)

## License

MIT License. See [LICENSE](LICENSE).
