La création de projet échouait : `Project.workflow` est obligatoire mais
n'était jamais fourni (formulaire frontend, MCP create-project), tout POST
/api/projects partait en erreur de validation/contrainte NOT NULL.
- ProjectDefaultWorkflowListener (prePersist) : assigne le workflow par
défaut quand aucun n'est fourni, couvrant API Platform, API brute et MCP.
- retrait de l'Assert\NotNull sur Project::workflow (la validation tournait
avant le flush et empêchait le filet) ; la contrainte DB reste le garde-fou.
- CreateProjectTool (MCP) : paramètre optionnel workflowId.
- ProjectDrawer : sélecteur Workflow en création, pré-rempli sur le défaut,
IRI envoyée dans le payload.
- tests fonctionnels : création avec et sans workflow.
- ajoute des tests fonctionnels (archive au DELETE, exclusion de la
collection, listing/désarchivage admin, anti-auto-archivage) et un test
unitaire du ArchivedUserChecker
- expose un filtre BooleanFilter `archived` + bypass admin dans
ExcludeArchivedUserExtension pour lister les archivés (?archived=true)
- rend `archived` modifiable par un admin (groupe user:write + ApiProperty
ROLE_ADMIN) → désarchivage possible via PATCH /api/users/{id}
- RestoreMissingUsersCommand : ne compte que les insertions réelles
(ON CONFLICT DO NOTHING n'est plus comptabilisé à tort)
- relève memory_limit des tests à 512M (boot sérialiseur API Platform)
- Prestataire : entité/repo + ressource API Platform (RBAC directory.providers.*),
ownership prestataire sur contacts/adresses/comptes-rendus (CHECK XOR à 3),
DTO/service/drawer/fiche détail + onglet dédié dans le répertoire.
- Prospect : société uniquement (suppression du champ name, company requis) ;
migration de backfill, conversion prospect→client et MCP adaptés.
- Champ site web sur client/prospect/prestataire (entités, DTO, onglet Information, MCP).
- Validateurs front email / téléphone FR (0549200910) / URL sur Information et Contacts,
enregistrement bloqué tant qu'un champ est invalide.
- Autocomplete adresse branché sur la Base Adresse Nationale (api-adresse.data.gouv.fr)
avec mode dégradé en saisie libre.
- Administration : retrait de l'onglet Clients.
Les ressources métier (ProjectManagement, Directory, TimeTracking) étaient
gardées par is_granted('ROLE_USER')/'ROLE_ADMIN', ignorant les permissions
RBAC granulaires déclarées par les modules : un utilisateur sans permission
voyait quand même projets, tâches, clients, etc.
- PermissionVoter : le regex excluait les tirets, donc project-management.* et
time-tracking.* n'étaient supportées par aucun voter (refus pour tous, admin
compris car le bypass ROLE_ADMIN est interne au voter). Ajout du tiret.
- Câblage des permissions *.view (lecture) / *.manage (écriture) sur les 17
ressources métier. Métadonnées tâches lisibles via projects.view OR tasks.view.
Directory partagé client/prospect via clients.* OR prospects.*. TimeEntry
conserve le self-service (object.getUser() == user).
- Sidebar : gating par permission effective des onglets Projets / Mes tâches /
Suivi du temps (config/sidebar.php).
- Test fonctionnel ProjectAccessControlTest (0 perm -> 403, view -> 200,
view ne donne pas l'écriture -> 403).
Add ContractRelationDenormalizer to resolve IRIs for collections typed
against an interface (Contract), fixing POST/PATCH 400 errors. Cover it
with InterfaceCollectionDenormalizationTest.