Rapprochement des formateurs de classe virtuelle OGDPC
Version métier : voir Rapprochement des formateurs de classe virtuelle OGDPC.
⚠️ Orpheline à date (2026-04-23) — la commande existe dans le code mais n’a aucun schedule GitLab actif ni job CI. À planifier prochainement (cf. section Déclenchement).
Description
Section intitulée « Description »Commande qui rapproche les noms d’intervenants déclarés côté OGDPC (colonne intervenant du CSV ogdpc_sessions_latest.csv) avec les utilisateurs ROLE_TRAINER affectés aux VirtualClass futures. En cas de divergence, elle réaffecte les trainers de la VirtualClass. Le matching exact s’appuie sur une normalisation (uppercase + NFD sans accents) ; le fallback utilise Gemini pour gérer typos, inversions prénom/nom et abréviations.
Déclenchement
Section intitulée « Déclenchement »Planification GitLab : aucune à ce jour. La commande scheduled:ogdpc-reconcile-virtual-class-trainers n’est pas référencée dans ci-jobs/.scheduled-ci.yml et aucun schedule GitLab (2026-04-23) ne l’invoque.
TODO(review) : brancher cette commande sur un schedule GitLab (ex. description
Reconcile virtual class trainers against ANDPC, cron0 3 * * *Europe/Paris après le rapprochement des dates). Il faudra :
- Ajouter un job
ogdpc_reconcile_trainersdansci-jobs/.scheduled-ci.yml(stageogdpc_extractréutilisable), avecif: '$CI_PIPELINE_SOURCE == "schedule" && $SCHEDULE_TYPE == "ogdpc_reconcile_trainers"'.- Créer le schedule côté GitLab > Build > Pipeline schedules avec la variable
SCHEDULE_TYPE=ogdpc_reconcile_trainers.- Mettre à jour cette page et la home internal-api pour refléter la planification effective.
Commande (exécution manuelle en attendant) :
docker exec $APP_NAME php bin/console scheduled:ogdpc-reconcile-virtual-class-trainersOptions :
--bucket=<name>(défauterevo-lms)--csv-key=<key>(défautdpc-extract/ogdpc_sessions_latest.csv)--local-csv=/path.csv--no-report-upload
Fonctionnement
Section intitulée « Fonctionnement »- Charger le CSV depuis MinIO (ou
--local-csv). Parsing BOM-aware, séparateur;. Échec I/O ⇒Command::FAILURE(via$io->error, pas d’exception). - Indexer les lignes CSV par clé
"<reference>|<sessionNumber>"en ne gardant queformat === 'Classe virtuelle'. - Pré-charger les trainers :
SELECT u FROM User u WHERE u.roles LIKE '%"ROLE_TRAINER"%'. ConstruittrainerIndex[normalizeName("LASTNAME FIRSTNAME")] = User. - Charger les VC futures :
VirtualClassRepository::getFutureVirtualClasses(). - Pour chaque
VirtualClass:- Remonter à
SessionDate → Versionpour obtenirreferenceetinternalId(numéro de session). - Lookup CSV par clé ; absent ⇒
not_in_csvdans le rapport, skip. - Colonne
intervenantvide ⇒ skip silencieux. - Pour chaque nom CSV (split sur
,) :trainerIndex[normalizeName(csvName)]→ match exact ; sinonfindUserWithGemini()envoie à Gemini le nom CSV + la liste des noms DB et retourne le nom choisi ouNONE.- Utilisateur introuvable ⇒ ligne
unresolved_userdans le rapport.
- Compare le set d’IDs résolus avec le set actuel (
$vc->getTrainers()). Différent ⇒removeTrainer/addTrainerpour aligner.
- Remonter à
flush()si au moins un fix.- Rapport : CSV
reference;session_number;type;descriptionavectype ∈ {fixed, error, not_in_csv, unresolved_user}, uploadé surdpc-extract/reports/virtual-class-trainer-reconcile_*.csv+ alias_latest. - Exit :
FAILUREsi au moins ununresolved_user, sinonSUCCESS.
Entités impactées
Section intitulée « Entités impactées »- User — lecture seule (liste des trainers via
roles LIKE '%ROLE_TRAINER%'). - VirtualClass — écriture de la collection
trainers(ajout/retrait). - SessionDate — lecture (pour remonter à
Version). - Version — lecture (
reference).
TODO(review) : pages
modele-de-donnees/user,virtual-class,session-date,versionabsentes — à créer parentity-documenter.
Gestion des erreurs
Section intitulée « Gestion des erreurs »- Contrairement à
ReconcileSessionDateCommand, aucuneScheduledCommandExceptionn’est levée : les erreurs I/O MinIO produisent unCommand::FAILURE(via$io->error+return) plutôt qu’une exception remontée dans Sentry.
TODO(review) : harmoniser avec
ReconcileSessionDateCommanden levantScheduledCommandException(ou en ajoutant manuellement unSentry\captureException()) pour que les échecs MinIO soient capturés dans Sentry au lieu de rester dans le log GitLab.
unresolved_userfait basculer l’exit enFAILURE(job CI échoue) — comportement voulu pour attirer l’attention sur les écarts de nommage à corriger côté DB ou côté OGDPC.- Gemini indisponible : seul le matching exact est tenté ; les noms non triviaux tombent en
unresolved_user.
Dépendances externes
Section intitulée « Dépendances externes »- MinIO / S3 : input
erevo-lms/dpc-extract/ogdpc_sessions_latest.csv, outputerevo-lms/dpc-extract/reports/virtual-class-trainer-reconcile_*.csv. - Gemini API (
App\Service\GeminiClient) — clef$GEMINI_API_KEY. Fallback de matching fuzzy. - MariaDB : Users, VirtualClasses, SessionDates, Versions.
Observabilité
Section intitulée « Observabilité »- Logs : sortie console lors d’une exécution manuelle (
docker exec). Une fois planifiée, logs dansGitLab > Build > Pipelines. - Rapport CSV :
dpc-extract/reports/virtual-class-trainer-reconcile_latest.csvsur MinIO. - Alerting : Sentry capture les exceptions PHP (voir TODO ci-dessus concernant les erreurs MinIO non-exception).
Références code
Section intitulée « Références code »- Commande :
src/Command/Scheduled/ReconcileVirtualClassTrainerCommand.php - Job CI : aucun (à créer)
- Services :
App\Service\GeminiClient,Aws\S3\S3Client - Repository :
App\Repository\VirtualClassRepository::getFutureVirtualClasses()