eptm_dashboard/data/docs/10-faq.md
2026-05-12 15:30:28 +02:00

7.1 KiB

FAQ / Dépannage

Synchronisation Escada

« Import timeout — vérifiez les logs (> 15 min) »

Le subprocess Playwright n'a pas répondu dans le temps imparti. Causes possibles :

  • Escadaweb répond très lentement (en pic de charge)
  • Captcha / re-login imposé par Escada
  • Container Docker en surcharge

Que faire :

  1. Aller dans /logs et chercher le dernier [sync] actif
  2. Si Playwright est bloqué sur un écran de login : lancer un Actualiser des classes (re-login)
  3. Si gros volume de classes : lancer la sync en plusieurs lots de 5-6 classes

« Aucune classe récupérée »

Le scraping Playwright a échoué — souvent token de session expiré.

Que faire : recliquer sur « Actualiser » (force un re-login propre).

« Le push échoue toujours sur le même apprenti »

Possibles causes :

  • L'apprenti existe en local mais pas (ou plus) sur Escada → le pending est obsolète, à supprimer
  • Le nom diffère entre local et Escada (ex : prénom composé partiel)
  • La page Escada de cet apprenti est verrouillée par un autre éditeur (lock pessimiste Escada)

Que faire :

  1. Vérifier les logs pour le message d'erreur exact
  2. Si l'apprenti n'existe plus : supprimer le pending manuellement en DB
  3. Sinon : retenter plus tard

« L'option 'Forcer la réimportation complète' est en rouge — c'est dangereux ? »

Pas dangereux mais destructif :

  • Tous les pendings concernés sont écrasés (les modifs locales pas encore poussées sont perdues)
  • Tous les statuts d'absences sont remis à ce qu'Escada dit

À utiliser uniquement quand on veut sciemment reprendre l'état complet d'Escada.

Tâches planifiées (cron)

« J'ai créé une tâche, elle ne se déclenche pas »

Vérifier dans l'ordre :

  1. La tâche est-elle activée ? (toggle vert)

  2. Les heures choisies sont-elles dans le bon fuseau horaire ? (l'app fonctionne en Europe/Zurich)

  3. La crontab du host appelle-t-elle bien cron_tick.py ?

    crontab -l | grep cron_tick
    # Doit avoir : * * * * * docker exec eptm-dashboard-app-1 python scripts/cron_tick.py
    
  4. Regarder le log d'exécution : ls /logs/cron/ et tail sur le dernier fichier.

« J'avais un job 'toutes les X minutes', il a disparu »

L'ancien mode interval a été remplacé par daily_multi. Au boot du container, les jobs interval sont automatiquement migrés en daily_multi (l'intervalle est déroulé sur 24 h depuis minuit). Idem pour les anciens jobs daily (HH:MM) → convertis en daily_multi avec une seule heure.

Si tu veux modifier un de ces jobs : ouvre-le, tu verras la grille 24 cases avec les heures qui étaient configurées.

« La tâche ne notifie pas sur Telegram »

  • notify_on doit être always, success ou failure (pas never)
  • Le bot_token et chat_id doivent être valides → tester via le bouton « Tester Telegram »

Édition d'absences

« Le bouton 'Absent toute la journée' est grisé »

Affichage « Absent toute la journée (Données chronoplan manquantes) » → aucun horaire n'est configuré pour cette classe et ce jour de la semaine.

Que faire : admin → /params → Horaires de classe, sélectionner la classe, cocher les périodes du jour concerné, enregistrer.

« Quel est le type de jour affiché en badge ? »

Théorie / Pratique / Matu — défini par classe et par jour dans /params → Horaires de classe. Sert d'indication contextuelle dans le panneau d'édition.

Authentification

« Mon utilisateur n'a accès à aucune classe »

À sa première connexion, un dialog s'ouvre pour configurer l'accès. Il doit fournir :

  • son email Escada (identifiant Keycloak)
  • son mot de passe Escada
  • un code TOTP courant

Un script Playwright tourne en arrière-plan (visible dans /logs avec préfixe [fetch_classes:<username>]) et remplit automatiquement allowed_classes dans auth.yaml.

Si le dialog est fermé (« Plus tard »), il réapparaîtra au prochain login.

« J'ai perdu mon téléphone avec mon code 2FA »

Un admin peut réinitialiser le 2FA via /users : bouton « Réinitialiser 2FA ». Au prochain login, l'utilisateur reverra le QR code.

« Comment révoquer l'accès d'un user »

Admin → /users → bouton « Réinitialiser les droits » : efface allowed_classes + identifiants Escada. À sa prochaine connexion, le popup d'enrôlement réapparaîtra (s'il ne le reconfigure pas, il n'aura accès à rien).

Données

« Les BN affichent des trous (cellules vides) »

C'est normal : un apprenti peut avoir commencé sa formation au S2 ou S3 → les premiers semestres restent vides. L'extraction depuis le PDF Escada respecte ces trous. Toutes les notes (pas juste les moyennes) sont stockées et affichées.

« Les notes Matu n'apparaissent pas »

Pré-requis : l'apprenti est dans une classe MP / MI correspondante. Le matching se fait via la classe MP1, MP2, etc. La sync Matu cherche le PDF correspondant si la case 'BN' est cochée.

« L'adresse sur les avis sanction/retenue est fausse »

Depuis mai 2026, l'app n'utilise plus l'adresse de l'entreprise. Elle prend :

  • l'adresse du représentant légal si l'apprenti est mineur (majeur=False)
  • l'adresse perso de l'apprenti sinon

Vérifier que les champs ApprentiFiche.resp_legal_* et ApprentiFiche.adresse/code_postal/localite sont bien remplis (sync option « Données apprentis »).

Performance

« L'app rame quand je change de classe avec beaucoup d'apprentis »

Le _reload reconstruit les tableaux HTML BN / Notes pour chaque apprenti — peut prendre quelques secondes pour 25+ apprentis. Un skeleton s'affiche pendant le chargement pour donner du feedback visuel.

« L'app est bloquée pour les autres users quand je lance la synchro de mes classes »

C'était un bug : le subprocess Playwright bloquait l'event loop. Corrigé en passant à @rx.event(background=True) + asyncio.create_subprocess_exec. Si ça revient, vérifier que fetch_my_classes est bien décoré background=True dans profile.py.

Conteneur Docker

« Le conteneur consomme 100 % CPU à l'idle »

Bug historique lié au hot-reload qui détectait les fichiers WAL/SHM de SQLite comme des modifications source. Corrigé via REFLEX_HOT_RELOAD_EXCLUDE_PATHS=/app/data dans le docker-compose.

« La version dans le sidebar ne change pas après un nouveau tag git »

data/VERSION doit être mis à jour manuellement (le .git du container dev n'est pas synchronisé avec celui du hôte). Édite le fichier, puis :

docker restart eptm-dashboard-app-1

« Comment redémarrer proprement »

cd /opt/eptm-dashboard
docker compose -f docker-compose.dev.yml restart app

« Comment voir les logs du serveur Reflex »

docker logs -f eptm-dashboard-app-1

SSL / Accès depuis le web

« Mon navigateur affiche un avertissement sécurité sur dev.dashboard.eptm-automation.ch »

Vérifier le certificat affiché : si l'émetteur est « Fortinet CA » (et non Let's Encrypt), c'est ton firewall qui fait du SSL inspection / IPS — pas un problème du serveur. À demander à l'IT pour whitelister le domaine.