# Vue d'ensemble EPTM Dashboard est une application de gestion des absences, notes, bulletins, avis (retenue / sanction) et notices pour l'École professionnelle technique et des métiers (EPTM Sion). Elle se synchronise avec **Escadaweb** (le système de notation cantonal) pour récupérer et pousser les données. ## À quoi sert l'application - **Visualiser** les absences, BN, notes d'examen, notices et fiches personnelles par apprenti ou par classe. - **Excuser ou modifier** les absences manuellement (les changements sont mis en file d'attente avant d'être renvoyés à Escada). - **Créer des avis** de retenue et de sanction au format PDF (templates AcroForm pré-remplis) — l'avis est aussi envoyé en notice vers Escada. - **Récupérer / pousser** les notices Escada (création, lecture, statut). - **Automatiser** les imports/exports via des tâches planifiées (cron) avec notifications Telegram. - **Envoyer par email** un récap d'absences (+ bulletin + notes) à l'apprenti, au formateur ou à une adresse libre. - **Tracer** qui a modifié quoi (audit log complet + champ `updated_by` sur chaque entité). - **Collecter du feedback** in-app via un widget chat (admin reçoit un email + dialogue de réponse). - **Gérer les droits utilisateur** : restriction d'accès par classe, self-service via identifiants Escada de l'utilisateur. ## Modèle de données simplifié ``` Apprenti ── Absence (statut : a_traiter, excusee, ...) ├── ApprentiFiche (adresse, entreprise, formateur, représentant │ légal, compensation des désavantages, majeur/mineur) ├── NotesBulletin (BN par semestre) ├── NotesMatu (Matu pro) ├── NotesExamen (notes d'examen) ├── ApprentiNotice (notices importées depuis Escada) └── Notice (notices locales, file de push vers Escada) EscadaPending : file d'attente des modifications d'absences locales à pousser vers Escada (action ∈ {"E", "N", "clear"}) Import / ImportBN / ImportMatu : trace des imports PDF effectués CronJob : tâches planifiées (push, sync, push+sync) — schedules daily_multi (plusieurs heures/jour) ou weekly FeedbackMessage : feedback in-app (bug / proposition) — statut new / in_progress / resolved + réponse admin ``` ## Architecture technique - **Frontend** : Reflex 0.9.2 (Python full-stack, Radix Themes, lucide-react icons) - **DB** : SQLite mode WAL, à `data/absences.db` - **Scraping Escada** : Playwright (sync API), dans `scripts/sync_esacada.py`, `scripts/push_to_escada.py`, `scripts/push_notices.py`, `scripts/pull_notices.py`, `scripts/fetch_user_classes.py` - **Parsing PDF** : `src/parser.py` (absences), `src/parser_bn.py` (bulletins), `src/parser_matu.py` (matu) - **Génération avis PDF** : `src/sanction_pdf.py`, `src/retenue_pdf.py` (templates AcroForm dans `data/templates/`) - **Conteneurisation** : Docker Compose, derrière nginx-proxy-manager (NPM, containerisé depuis mai 2026) - **Cron** : OS cron déclenche `scripts/cron_tick.py` toutes les minutes, qui consulte la table `CronJob` - **Emails** : SMTP (Brevo en prod), templates configurables depuis `/params` ## Pages disponibles | Page | Route | user | admin | |----------------------------|--------------|------|-------| | Tableau de bord | `/accueil` | ✅ | ✅ | | Classes | `/classe` | ✅* | ✅ | | Apprentis | `/fiche` | ✅* | ✅ | | Documentation | `/doc` | ✅ | ✅ | | Mon profil | `/profile` | ✅ | ✅ | | Escada (sync / push) | `/escada` | ❌ | ✅ | | Tâches planifiées | `/cron` | ❌ | ✅ | | Logs | `/logs` | ❌ | ✅ | | Utilisateurs | `/users` | ❌ | ✅ | | Paramètres | `/params` | ❌ | ✅ | | Feedback | `/feedback` | ❌ | ✅ | | Purger classe | `/purge` | ❌ | ✅ | ✅* : restriction par `allowed_classes` (l'utilisateur ne voit que ses classes autorisées). Si la liste est vide, un dialogue d'enrôlement obligatoire s'affiche à chaque navigation (cf. doc « Authentification »). ## Sidebar — version & profil - La **version** (dernier tag git ou contenu de `data/VERSION`) s'affiche au-dessus du widget profil. À mettre à jour manuellement après un nouveau tag : éditer `data/VERSION` puis `docker restart eptm-dashboard-app-1`. - Le **widget profil** ouvre un popover avec « Mon profil » + « Déconnexion ». - Le **bouton feedback** flotte en bas-droite de l'écran (FAB) : ouvre la modale chat pour signaler un bug ou proposer une idée.