Lorsqu’une application reçoit une donnée ambiguë, la classer de force comme « valide » ou « invalide » tend à masquer le problème plutôt qu’à le résoudre. Cela peut se produire avec des formulaires, des intégrations ou des résultats proposés par un système automatisé : le contexte manque pour accepter ou écarter le dossier en toute sécurité. Dans ces cas, la révision humaine de données incertaines en PHP doit être un état du domaine, régi par des règles explicites, et non une étiquette informelle ou une file d’attente improvisée.
La conception doit répondre à quatre questions : qu’est-ce qui a été reçu, qu’est-ce qui est proposé, qui doit décider et que se passe-t-il ensuite ? La séparation de ces responsabilités facilite l’exploitation du flux, la correction des erreurs et l’explication des raisons pour lesquelles une donnée a été traitée d’une manière donnée.
Classez le problème avant de créer des états

Toutes les données qui ne peuvent pas continuer leur parcours ne nécessitent pas une révision humaine. Distinguez au moins les situations suivantes :
- Invalide : la donnée ne respecte pas une règle vérifiable, par exemple un format impossible à interpréter. Il convient de la rejeter ou de demander sa correction, selon sa provenance et le produit.
- Incomplète : un champ nécessaire est manquant. L’action peut consister à demander la donnée, à conserver le brouillon ou à attendre une source supplémentaire.
- Incertaine : plusieurs interprétations sont plausibles ou les éléments disponibles ne permettent pas de décider automatiquement. Une évaluation par une personne peut être nécessaire.
La révision ne doit pas devenir la destination générique de toutes les erreurs. Si une valeur ne respecte pas une contrainte sans ambiguïté, l’envoyer dans une file de révision ne fait qu’ajouter du travail. En revanche, lorsqu’une décision dépend du contexte ou de l’appréciation d’une personne, un état révisable permet d’interrompre le traitement sans déclarer prématurément la donnée correcte ou incorrecte.
Il convient également de distinguer ce flux d’une mise en quarantaine à l’importation. La quarantaine sert généralement à isoler les entrées qui ne doivent pas être intégrées au système, par exemple parce qu’elles ont échoué aux contrôles techniques ou de sécurité. La révision permet de résoudre une ambiguïté métier. Un même dossier peut passer par les deux mécanismes, mais leurs objectifs, leurs autorisations et leurs critères de sortie ne sont pas interchangeables.
Définissez un cycle de vie simple et explicite
Commencez par les états nécessaires pour décrire le processus, plutôt que par une liste de toutes les possibilités futures. Un cycle de base pourrait être le suivant :
pending_review: en attente d’une décision.confirmed: une personne confirme une valeur exploitable.rejected: la personne détermine que la donnée ne doit pas être traitée.reopenedou une nouvelle entrée en révision : une décision antérieure est remise en question.
Définissez les transitions autorisées. Par exemple, un dossier en attente peut être confirmé ou rejeté ; un dossier déjà résolu ne peut être rouvert que dans des conditions autorisées. Ne permettez pas à une requête quelconque de faire passer directement l’état à n’importe quelle valeur. Une transition doit préciser l’état d’origine, l’état de destination, l’acteur autorisé et les effets associés.
Enregistrez le motif de la décision et l’identité de la personne responsable. Si une donnée est rejetée, consignez une raison utile, et pas seulement une valeur booléenne. Si une interprétation est confirmée, conservez la valeur approuvée et, le cas échéant, les éléments qui ont étayé la décision. Déterminez si le motif est obligatoire en fonction de l’action et évitez d’inclure des informations personnelles inutiles dans des notes libres.
Séparez l’entrée, la proposition et la valeur confirmée
Une conception robuste ne remplace pas la donnée reçue par l’interprétation d’un processus automatique ou par la correction d’une personne. Distinguez ces notions :
- Donnée reçue : l’entrée d’origine et sa provenance, avec les contrôles d’accès et de conservation appropriés.
- Interprétation proposée : une suggestion générée par des règles, une intégration ou un système d’assistance, accompagnée des informations nécessaires à son évaluation.
- Valeur confirmée : la valeur que l’application utilise après la décision autorisée.
Cette séparation évite qu’une proposition soit accidentellement traitée comme une vérité et permet de reconstituer la manière dont la valeur actuelle a été obtenue. Il n’est pas nécessaire de dupliquer systématiquement chaque champ : conservez les données nécessaires à l’audit et à l’assistance, en appliquant des politiques de conservation et de protection des données. Si une proposition comprend un score ou une explication automatisée, traitez-la comme un élément de contexte, et non comme une décision.
Consignez les changements sous forme d’événements ou d’entrées d’historique immuables pour l’usage normal de l’application : identifiant du dossier, action, état précédent et nouvel état, acteur, date et motif. Le modèle peut également conserver l’état actuel pour faciliter la consultation de la file. La correction est représentée par une nouvelle décision ou une réouverture liée à l’historique ; supprimer la décision précédente détruit la traçabilité.
Implémentez les décisions dans la couche métier
En PHP, encapsulez les transitions dans un service applicatif ou une entité du domaine, au lieu de compter sur chaque contrôleur pour appliquer les mêmes règles. Voici un exemple schématique :
final class ReviewDecisionService
{
public function confirm(ReviewCase $case, User $actor, string $value, string $reason): void
{
if (!$actor->canReview($case)) {
throw new DomainException('Accès non autorisé');
}
if (!$case->isPending()) {
throw new DomainException('Le dossier n’est pas en attente');
}
$case->confirm($value, $actor->id(), $reason);
}
}
Ce fragment illustre où placer les règles ; il ne constitue pas une implémentation complète. Validez également le format et les limites de la valeur, vérifiez que l’acteur est autorisé à traiter ce dossier et consignez la décision. Ne confondez pas authentification — qui est l’utilisateur — et autorisation — ce qu’il peut faire sur cet enregistrement. Si des rôles ou une séparation des tâches sont en place, exprimez ces contraintes sous forme de règles du produit.
Lorsque la mise à jour du dossier et l’écriture de l’historique doivent être cohérentes, enregistrez-les dans une transaction de base de données. Si la décision déclenche des effets externes, comme un appel à une autre API, ne partez pas du principe que la transaction locale couvre également ce système. Utilisez un mécanisme de livraison fiable, comme une outbox transactionnelle lorsque l’architecture le nécessite, et concevez les consommateurs de manière à ce qu’ils tolèrent les tentatives répétées.
Concevez une file qui aide à prendre une décision
Une file utile permet de hiérarchiser les dossiers et de les retrouver sans masquer leur contexte. Incluez des filtres pertinents — état, date, type ou attribution — et n’affichez que les informations nécessaires à la compréhension du dossier. Si une proposition existe, indiquez clairement qu’il s’agit d’une proposition. Présentez la provenance, le motif de la révision et les actions disponibles, et évitez d’afficher des commandes que l’utilisateur n’est pas autorisé à exécuter.
L’attribution peut réduire le travail en double, mais elle ne remplace ni l’autorisation ni la protection contre les décisions simultanées. Une personne peut ouvrir un dossier pendant qu’une autre le résout avant l’envoi de sa réponse. Pour éviter qu’un écran obsolète n’écrase une modification récente, utilisez un contrôle de concurrence optimiste : comparez une version ou un horodatage lors de l’enregistrement et rejetez l’opération devenue obsolète afin que l’utilisateur recharge le dossier.
Si le processus nécessite des réservations temporaires, définissez leur expiration et ce qui se passe lorsqu’elles expirent. N’utilisez pas une attribution permanente comme verrouillage accidentel. Consignez les actions pertinentes afin de pouvoir déterminer qui a examiné le dossier et repérer ceux qui restent en attente plus longtemps que ce qui est acceptable pour l’exploitation.
Corrigez et rouvrez sans effacer le passé
Une décision peut être erronée ou devoir changer à la suite de l’arrivée de nouveaux éléments. Définissez qui peut la rouvrir, quel motif doit être fourni et si la donnée confirmée cesse d’être disponible pendant la nouvelle révision. La réponse dépend de l’incidence de la valeur sur les processus ultérieurs ; par exemple, il peut être nécessaire d’interrompre de nouvelles actions, mais pas de supprimer automatiquement les effets déjà produits.
Conservez la décision précédente dans l’historique et créez une nouvelle version ou un nouvel événement de révision. Si la correction de la donnée exige de recalculer des informations dépendantes, identifiez explicitement ces effets et définissez une procédure idempotente pour éviter les doublons. Une correction d’état ne doit pas laisser croire qu’une opération externe a déjà été annulée.
Testez les règles, les autorisations et les effets ultérieurs

Les tests doivent couvrir l’ensemble du flux et ses limites, et pas seulement vérifier que le formulaire est enregistré. Vérifiez au minimum les points suivants :
- Un dossier en attente accepte les transitions prévues et rejette les autres.
- Les acteurs sans autorisation ne peuvent ni prendre une décision, ni rouvrir un dossier, ni consulter des données restreintes.
- Chaque décision conserve l’acteur, le motif ainsi que les valeurs précédentes et nouvelles, conformément à la politique définie.
- Deux modifications simultanées ne permettent pas à une décision obsolète d’en écraser une autre.
- Un échec lors de l’enregistrement de l’historique ne laisse pas l’état à jour sans traçabilité.
- La répétition d’un effet ultérieur ne duplique ni les opérations ni les notifications.
Comme liste de contrôle de conception, vérifiez que l’incertitude a une cause identifiable ; que la donnée d’origine, la proposition et la valeur confirmée sont différenciées ; que chaque transition est assortie d’une autorisation et d’un motif ; que la file fournit suffisamment de contexte ; et que la réouverture conserve l’historique et définit l’incidence opérationnelle. Si l’un de ces points repose sur des conventions informelles, il manque encore une règle au système.



