Deux lots regroupés sur la branche feat/absence-management. Suppression complète du portail client : - retire ROLE_CLIENT (security.yaml) ; User::getRoles() ajoute toujours ROLE_USER - supprime l'entité ClientTicket (+ repo, states, relations), User.client et User.allowedProjects, NotificationService, ProjectAllowedExtension, le bloc ROLE_CLIENT de MailAccessChecker - front : pages /portal, layout portal, composants client-ticket/, AdminClientTicketTab, services/dto/i18n/docs associés - fixtures : retire les users client-liot / client-acme - migration Version20260522110000 (drop client_ticket, user_allowed_projects, colonnes liées ; task_document.task_id -> NOT NULL) - tests : retire les cas obsolètes testant le blocage des clients sur le mail Module gestion des absences (WIP) : - entités / migrations (Version20260521160000, Version20260522090000) - pages absences.vue / team-absences.vue, composants frontend/components/absence/ - services front, AccrueLeaveCommand, PublicHolidayController Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5.7 KiB
Réorganisation de la gestion des employés (module Absences)
Date : 2026-05-22
Branche : feat/absence-management
Statut : design approuvé, prêt pour plan d'implémentation
Contexte
Aujourd'hui, le UserDrawer (admin → utilisateurs) porte deux responsabilités mélangées :
- l'administration du compte (nom, mot de passe, rôles, client, projets) ;
- tout le détail RH/employé : case « Employé » + un bloc de champs (date d'embauche, date de sortie, type de contrat, situation familiale, temps de travail, CP annuels, début de période de référence, solde CP initial, nombre d'enfants).
Ces champs existent déjà sur l'entité User (backend) et dans le DTO UserData/UserWrite (frontend). La persistance se fait via l'API user (PATCH /api/users/{id}).
On veut séparer ces deux préoccupations : le UserDrawer ne décide plus que si un utilisateur est un employé ; l'édition des informations RH se fait dans un espace dédié, dans le module Absences.
Objectifs
UserDrawer: ne conserver que la case à cocher « Employé ».team-absences: ajouter un onglet « Employés » (la page est déjàmiddleware: ["admin"], donc admin-only).- L'onglet liste les utilisateurs marqués
isEmployeeavec leurs soldes de congés. - Un drawer dédié permet d'éditer les informations RH d'un employé.
Hors périmètre : création d'utilisateur (reste dans l'admin), modification du flag isEmployee ailleurs que dans le UserDrawer, backend (déjà en place).
Composants
1. frontend/components/user/UserDrawer.vue
- Supprimer le bloc détaillé employé (
hireDate,endDate,contractType,familySituation,workTimeRatio,annualLeaveDays,referencePeriodStart,initialLeaveBalance,nbChildren). - Conserver uniquement la case
isEmployee(« Employé (soumis à la gestion des absences) »). - Le payload de sauvegarde du user n'envoie plus les champs détaillés, pour ne pas les écraser. Il continue d'envoyer
isEmployeeet les champs de compte existants. - Nettoyer l'état du formulaire et les imports devenus inutiles (options contrat / situation familiale si elles ne servent plus que là).
2. frontend/pages/team-absences.vue — onglet « Employés »
- Ajouter un 4ᵉ onglet dans
tabs:{ key: 'employees', label: t('absences.admin.tabs.employees'), icon: 'mdi:account-group' }. - Slot
#employees:MalioDataTableavec les colonnes Nom · Contrat · CP pris · CP restants. - Clic sur une ligne → ouvre
EmployeeDraweravec l'utilisateur sélectionné (cohérent avec l'onglet Demandes qui ouvre le détail au clic ligne). - Chargement des données :
usersService.getAll()filtré surisEmployee === true;absenceService.getBalances({ type: 'cp' })→ map paruser.idpour récupérertaken(CP pris) etavailable(CP restants) ;- fusion en lignes de tableau (
taken/availableà—si pas de solde CP pour l'employé).
- Recharger la liste après
saveddu drawer.
3. frontend/components/absence/EmployeeDrawer.vue (nouveau)
- Props :
modelValue: boolean,user: UserData | null. - Events :
update:modelValue,saved. - Formulaire en composants Malio :
MalioDate:hireDate,endDate(valeurs ISOYYYY-MM-DD) ;MalioSelect:contractType(CDI/CDD/Stage/Alternance/Autre),familySituation(Célibataire/Marié/Pacsé/Divorcé/Veuf) ;MalioInputText:workTimeRatio,annualLeaveDays,referencePeriodStart(MM-DD),initialLeaveBalance,nbChildren.
- À l'ouverture, initialiser le formulaire depuis
props.user; remettre à jour siuserchange. - Sauvegarde :
usersService.update(user.id, { …champs employé }); à la réussite, émettresavedet fermer. - En-tête : nom de l'employé.
4. i18n (frontend/i18n/locales/fr.json)
Nouvelles clés regroupées sous absences.admin.employees.* (et l'onglet sous absences.admin.tabs.employees) :
- onglet :
absences.admin.tabs.employees= « Employés » ; - colonnes liste :
absences.admin.employees.columns.{name,contract,cpTaken,cpRemaining}; - drawer :
absences.admin.employees.drawer.title+ libellés de champs sousabsences.admin.employees.fields.*.
Les libellés de contrat et de situation familiale (CDI/CDD/…, Célibataire/Marié/…) actuellement codés en dur dans UserDrawer sont déplacés avec leur drawer ; on les passe en clés i18n à cette occasion.
Flux de données
UserDrawer --PATCH isEmployee--> User (backend)
|
team-absences (onglet Employés) |
getAll() ∩ isEmployee <-----------+
getBalances({type:'cp'}) --> map user.id -> {taken, available}
=> lignes tableau (nom, contrat, CP pris, CP restants)
|
clic ligne
v
EmployeeDrawer(user) --usersService.update--> User (backend)
|
@saved --> recharge liste
Découpage / responsabilités
UserDrawer: compte + flag employé. Ne connaît plus le détail RH.- Onglet Employés : vue dérivée en lecture (jointure users ⋈ soldes), aiguille vers le drawer.
EmployeeDrawer: seule unité qui édite les champs RH ; interface claire (useren entrée,saveden sortie), testable isolément.
Vérification
UserDrawer: ouvrir un user, vérifier qu'il ne reste que la case « Employé », cocher/décocher et sauvegarder sans perte des autres champs RH (qui ne sont plus envoyés).- Onglet Employés : la liste affiche les users
isEmployeeavec CP pris/restants cohérents avec l'onglet Soldes. EmployeeDrawer: éditer un employé (dates en JJ/MM/AAAA, selects FR), sauvegarder, vérifier la persistance (recharge) et l'absence d'erreurs console.- Vérification navigateur via Chrome DevTools sur les trois écrans.