Feedback 360 — guide technique
Pour les mainteneurs des campagnes, affectations et réponses. Les éléments d'implémentation décrivent le code legacy ; la disponibilité dépend de la configuration du tenant. Voir Fonctionnel pour les parcours et Configuration pour les responsabilités. La capture relie la synthèse de campagne au cycle décrit.
Architecture
L'implémentation tracée est dans smartmobility-legacy : Symfony, Twig, jQuery/Ajax et Doctrine. Les chemins suivants sont relatifs à ce dépôt sauf indication contraire.
Configuration manager → FeedbackInterview + Assessment
→ FeedbackInterviewUser (personne évaluée)
→ ManagerReviewersService
→ FeedbackInterviewReviewer + AssessmentUser (contribution)
Questionnaire collaborateur → AssessmentAnswer / AssessmentQuestionItemAnswer
→ complétion du reviewer et de l'AssessmentUser
→ consultation entreprise / feedback reçu
| Source | Responsabilité |
|---|---|
config/routes.yaml | Monte les bundles à /feedback et /plateforme/feedback. |
src/Company/FeedbackBundle/Resources/config/routing.yml | Routes campagne, participants, contributeurs, consultation et relances. |
src/Company/FeedbackBundle/Controller/DefaultController.php | Configuration, populations, écritures, consultation et emails planifiés. |
src/Company/FeedbackBundle/Service/ManagerReviewersService.php | Déduplication, création AssessmentUser, nettoyage des désactivés et notifications. |
src/Customer/FeedbackBundle/Controller/DefaultController.php | Listes personnelles, questionnaire affecté, réponses et complétion. |
src/Main/ConfigBundle/Entity/FeedbackInterview{,User,Reviewer}.php | Campagne, participant évalué, contribution. |
src/Main/ConfigBundle/Resources/config/doctrine/FeedbackInterview*.orm.yml | Champs, relations et cascades ORM. |
src/Command/FeedBack/{AddReviewerManagerCommand,SendMailReviewerCommand}.php | Commandes explicites d'affectation et d'envoi. |
Modèle et cycle de vie
FeedbackInterview référence Setting, School propriétaire, Assessment, dates et participants. Les constantes définissent les statuts brouillon/publiée et types employee/manager. Les onglets Terminées/Non débuté sont des regroupements calculés, pas des statuts persistés supplémentaires.
FeedbackInterviewUser lie campagne, User évalué, School délégataire optionnelle, date de modification et canAdd. FeedbackInterviewReviewer lie campagne, participant, User contributeur et AssessmentUser, avec done et updated. AssessmentAnswer référence l'AssessmentUser ; AssessmentQuestionItemAnswer porte les éléments de choix.
Les mappings déclarent false pour canAdd et addManager. Les nouveaux participants copient le canAdd de campagne avant d'éventuelles modifications individuelles. Les collections parentes et la relation reviewer/AssessmentUser déclarent des cascades. Ne supposez ni suppression logique ni récupération garantie des réponses après retrait d'un membre.
Création et affectation
newAction()persiste un brouillon, un nom par défaut, l'heure courante, School et Setting, puis redirige. La navigation/feedback/newécrit en base.updateAction()analyse les dates avecd/m/Y H:i, en ajoutant 00:00/23:59 dans le fuseau du serveur. Il écrit nom, description et statut. Le bouton de publication transmet la valeur du sélecteur, sans machine d'état distincte.assessmentAction()lie une trame.interviewIndicatorsAction()filtre les choix par tenant et type360; cette restriction du sélecteur n'est pas à elle seule un invariant du endpoint d'écriture.updateusersAction()remplace les participants : les absents sont retirés, une sélection vide retire tous. Les nouveaux copientcanAddet peuvent recevoir le manager direct siaddManagerest actif.- Pour les campagnes managers, les utilisateurs actifs rattachés à chaque School sont ajoutés avec
addReviewers(..., true); les contributeurs désactivés sont retirés. Le retrait de tout contributeur actif ayant changé de manager n'est pas établi. addReviewers()vérifie le couple participant/contributeur, crée AssessmentUser et reviewer, puis flush par lots de dix et en fin. Une contrainte unique en base n'a pas été établie.
Ce chemin ne garantit pas une synchronisation continue. La commande d'ajout existe, sans planification de déploiement vérifiée.
Vérifié dans le code : partials/typeSelect.html.twig marque Manager actif initialement, sans persister automatiquement ce type. updateusersAction() contient aussi une garde de date de fin renvoyant Impossible to add new collaborator ; la comparaison DateTime/chaîne n’a pas été validée pour tous les runtimes.
Les modèles de notification masquent Conditions par display: none. À la création, Non est initialisé et les deux options itemDone valent managers, alors qu’en modification elles valent 1/0. Les emplacements nécessitent send_targeted_email. Aucun contrôle Conditions n’était visible dans l’éditeur observé. Résoudre ces différences avant de construire une extension de notification conditionnelle.
Contrats HTTP
Contrats internes legacy, pas une API publique garantie. Le YAML ne restreint pas les verbes des actions listées ; POST désigne la méthode du client inspecté, pas une restriction exclusive côté serveur. Identifiants fictifs uniquement dans les exemples.
| Appel / route | Paramètres et résultat |
|---|---|
Navigation /feedback ou /feedback/{id} | Liste ou synthèse liée au tenant ; tri par date de fin décroissante. |
Navigation /feedback/new | Persiste immédiatement un brouillon et redirige. |
POST /feedback/update | interview, name, description, status, startdate, enddate ; JSON de succès après flush. |
POST /feedback/update/type | id, type ; modifie le type. |
POST /feedback/assessment | interview, assessment ; lie la trame. |
POST /feedback/userupdate | interview, tableau collaborateur ; remplace les membres et synchronise les contributeurs managers. |
POST /feedback/addreviewers | Ajax, interviewuser, éléments reviewers avec id ; crée des affectations et peut envoyer des invitations. |
POST /feedback/canadd | Ajax, interviewuser, canadd ; option du participant. |
Navigation /feedback/questionnaire/{id} | Identifiant d'affectation reviewer ; rendu entreprise en lecture seule. |
GET /plateforme/feedback/ | Contributions et adhésions évaluées de l'utilisateur courant. |
GET /plateforme/feedback/{id} | Affectation reviewer ; not-found si absente ou affectée à un autre utilisateur. |
POST /plateforme/feedback/save | Ajax, review, assessment, name_<questionId>, comment_<questionId> et champs d'items ; persiste les réponses. |
POST /plateforme/feedback/done | Ajax, review ; positionne les deux complétions et la date de fin AssessmentUser. |
Exemple de navigation en lecture :
GET /plateforme/feedback/ HTTP/1.1
Accept: text/html
L'enregistrement collaborateur renvoie 400 hors Ajax, 404 si Assessment/reviewer absent et un JSON de succès après traitement. La complétion renvoie une enveloppe d'erreur différente si le reviewer manque, sans le même 404 explicite. Il n'existe pas de schéma d'erreur uniforme établi.
Réponses et soumission
saveQuestionnaireAction() parcourt les questions de l'Assessment demandé, trouve/crée AssessmentAnswer par AssessmentUser et question, puis traite scalaires, sélections et items. L'utilisateur courant est enregistré à la création. Les tableaux suppriment les anciens items avant reconstruction. Le nettoyage des valeurs vides varie selon le type ; une sélection vide efface sa réponse et son item. Un commentaire vide n'efface pas universellement l'existant : l'écriture est conditionnée à une valeur non vide.
questionnaireDoneAction() positionne reviewer.done, AssessmentUser.done et finished. Le rendu collaborateur utilise reviewer.done pour la lecture seule ; la consultation entreprise impose readOnly: true. Cela ne prouve pas l'immutabilité serveur. Enregistrement et complétion sont deux requêtes distinctes : ni atomicité ni validation serveur exhaustive des champs obligatoires n'est déduite.
Autorisation, éligibilité et confidentialité
Les lectures entreprise résolvent généralement School et tenant ; plusieurs lectures détaillées lient explicitement la campagne au Setting. Les modèles Twig appliquent aussi interview_all, visibilité management et relations manager/délégataire selon le type et la vue. Le lien de création dépend d'interview_create. Les prédicats diffèrent entre onglets ; la liste du repository est ensuite réduite dans les modèles.
L'index collaborateur charge reviewer=utilisateur courant, conserve les campagnes publiées et inclut les contributions terminées ou inachevées dans [début, fin[. Les feedbacks reçus sont chargés séparément par participant courant ; ils ne partagent pas toutes ces conditions. Un calcul dérivé de fin de la vue reçue mélange heure formatée et timestamp ; il ne prouve pas un contrôle fiable de l'échéance.
Le GET questionnaire vérifie explicitement l'identité du reviewer. Les corps des handlers save/done ne répètent pas visiblement ce même contrôle et ne valident pas exhaustivement dates, immutabilité et cohérence Assessment/affectation. Plusieurs mutations entreprise chargent aussi les entités par ID sans répéter le prédicat tenant des lectures. La couverture globale des middlewares n'a pas été auditée. Ne déduisez donc pas une isolation complète des endpoints à partir des menus ou du GET ; vérifiez chaque opération et liaison de ressource avant d'ajouter des appelants.
Les réponses et identités sont des données RH. Le modèle reçu affiche des contributeurs nommés, conformément à la FAQ anonymat (Documenté dans Confluence). Ne journalisez pas les réponses et ne présentez aucun paramètre de liste comme une anonymisation.
Notifications et dépendances d'exécution
Le service utilise Doctrine, Swift Mailer, NotificationEmail traduit et le modèle email du tenant. addReviewers() envoie seulement sur demande, en campagne publiée et avec une adresse syntaxiquement valide. listReviewers() exclut en plus les contributions terminées pour sa branche d'envoi. sendMail() choisit le modèle collaborateur/manager et la langue du reviewer, avec repli sur la première traduction. Un modèle absent peut interrompre l'envoi ; le traitement complet d'une collection de traductions vide n'a pas été validé.
Un passage à Publiée pour une campagne managers lance app:feedback:send-mail-reviewers de façon asynchrone via l'exécutable PHP configuré. Ce lancement de processus ne garantit pas une file de livraison. AddReviewerManagerCommand est un autre chemin. Ces noms décrivent l'implémentation, sans constituer des instructions d'exécution en production.
interviewNotificationAction() persiste des Email avec entité FeedbackInterview, destinataires, date/heure, emplacement et conditions de complétion. FeedbackInterviewUserRepository::getInterviewUser() filtre l'emplacement via customer.entity. Ordonnanceur, conditions complètes, reprises et livraison n'ont pas été tracés. Distinguez publication, ajout, relance manuelle et planification.
Générations et extensions
Les recherches ciblées dans les routes frontend nextgen et API backend n'ont pas établi de ressource/assistant 360 remplaçant le legacy. Ni migration automatique ni contrat partagé nextgen n'ont été vérifiés. AIHub src/data_exchange/feedback/router.py importe du feedback de matching/offres d'emploi : il ne constitue pas une preuve de traitement des questionnaires 360. Aucun appel AIHub n'a été tracé depuis ces contrôleurs.
Les activations sont déclarées dans fixtures/FeatureSwitchFixtures.php et config/configuration/feature_module.yml ; src/Main/SitemapBundle/Enum/Customer/NavigationEnum.php associe l'entrée collaborateur à module_360feedback. Changer la navigation ne remplace pas le contrôleur.
Pour une extension, suivez contrôle UI → route → liaison/autorisations → membre/AssessmentUser → réponses, puis les deux rendus. Préservez nettoyage des items, commentaires, lecture seule et validation. Traitez séparément type de notification, langue et déclencheur. Réévaluez l'autorisation de chaque lecture/écriture ajoutée.
Pannes, observabilité et preuves
| Symptôme | Point d'inspection |
|---|---|
| Liste vide | Affectation, publication, dates et done dans indexAction collaborateur. |
| Formulaire absent | Lien Assessment, AssessmentUser du reviewer, type/tenant du sélecteur. |
| Mauvais contributeurs managers | School, sauvegarde des participants, nettoyage des désactivés et commande explicite. |
| Compteurs différents | Périmètre propre à l'onglet, comptes actifs et AssessmentUser.done/reviewer.done. |
| Enregistrement/soumission incohérents | Requêtes séparées, Ajax, cohérence des liens, nettoyage par type et deux complétions. |
| Email absent | Déclencheur, adresse, modèle/traduction, processus asynchrone et transport. |
Calendrier d'exécution, délai de livraison, reprise et version déployée relèvent de la configuration de l'environnement. Utilisez des identifiants de corrélation sans données personnelles ni réponses.
Documenté dans Confluence : Feedback 360, v4, 27 novembre 2024, corrobore les relations ; playbook, v1, 13 septembre 2023, décrit configuration et rattachements directs ; FAQ anonymat, v4, 22 juin 2026, décrit le produit. Les instructions historiques date/heure diffèrent de la normalisation actuelle. Les requêtes de reporting propres à un client sont exclues.
La documentation de référence décrit les relations campaign/participant/reviewer/AssessmentUser, la configuration des campagnes et la confidentialité nominative. Les contrats d'API restent internes et ne constituent pas une intégration publique prise en charge.
Dernière mise à jour : 3 novembre 2026