- panneau d'édition des absences : P1-5 dans la colonne gauche, P6-10
à droite (au lieu d'un grid à 2 colonnes en flux ligne par ligne).
Sur mobile, les deux colonnes s'empilent.
- tables BN et Notes d'examen : ajout d'un min-width forcé pour
qu'elles débordent de la largeur d'un écran mobile, wrapper
overflow-x:auto fonctionnel pour le swipe horizontal.
- exclu les tables de la règle CSS .content-area * { min-width: 0 }
pour éviter la casse caractère par caractère du contenu cellule.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- création de compte par admin envoie un email avec lien de définition (7j),
bouton "Reset mdp" pour renvoyer un lien (24h). Plus aucun admin ne peut
modifier directement le mdp d'un user (tout passe par les liens email).
- nouvelle page /password-set publique (validation token, formulaire, hash
bcrypt) au style aligné sur /login, avec emails multipart texte+HTML.
- nouvelle page /profile (changement mdp avec ancien, reset 2FA, avatar,
infos), accessible via dropdown sur le widget user en bas de sidebar.
- restriction d'accès par utilisateur : champ allowed_classes dans auth.yaml,
multi-select dans la page Users, filtrage cross-page (KPIs, sanctions,
classes, apprentis, navigations cross-page, génération PDF avis).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- importer.py : nouvelle logique pour les 4 cas d'absence × pending :
* abs en PDF + pending modify : pending wins (sans force) / override (force)
* abs en PDF + pas en DB + pending action=clear : respecte la suppression
locale (sans force) / recrée l'abs (force)
* orpheline (DB sans PDF) sans pending : supprimée + comptée + détaillée
* orpheline avec pending : conservée (sans force) / supprimée (force)
- importer.py : query orpheline par classe + fenêtre de dates du PDF
(couvre les abs locales avec import_id=None)
- run_imports.py : remonte orphelines + pending_skipped dans res_abs
- notifier.py : niveau detailed inclut absences supprimées par classe
+ détail des orphelines (max 5 par classe)
- escada.py : sépare cache disque (toutes classes pour matching Matu)
vs liste UI (filtrée MP/MI/Formation)
- escada.py : timeout polling import passe de 60s à 15min
- escada.py : retire mode test push, fix bouton Actualiser bloqué sans
classe sélectionnée
- cron.py : reset last_run_at à l'activation d'un job pour relance
immédiate au prochain tick
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>