ملفات الحالات: تقييد دون توسيع

تبقى آلة الحالات مُبرمجة؛ لا يفعل ملف الحالات سوى إزالة انتقالات، ولا يضيف أيا منها أبدا، ويمكنه اشتراط دور أدنى لكل انتقال. يُحاكى قبل التفعيل، تماما مثل قاعدة العمل.

المبدأ

آلة الحالات تبقى في الشفرة

Chaque document qui passe par un statut au ferme — demandes d’achat, devis, ordres de fabrication, non-conformités, et les tables que ferme le CRUD générique (factures, commandes d’achat, commandes clients, bons de livraison, avoirs, réceptions, bons de consommation) — a déjà une machine à états codée : un graphe Go ValidTransitions par module (achats, production, qualité…), enregistré au démarrage. Un profil de statuts ne touche jamais ce graphe. Il ne peut que retirer une transition que le code autorise, jamais en ajouter une que le code n’autorise pas — la même asymétrie qu’une règle métier a envers l’écriture qu’elle garde : restreindre, jamais élargir.

Un point d’application unique l’applique : Autoriser (pkg/statuts), appelé à la fois par la route de ferme du CRUD générique et par chaque route dédiée de transition de statut (ordres de fabrication, devis, demandes d’achat, non-conformités) — le même motif de garde partagée que pkg/documentsrequis.GardeOF ou pkg/sod.Verifier pour le type de règle séparation des tâches.

الإعدادات › ملفات الحالات

مصفوفة الانتقالات

L’écran se trouve dans Paramètres → Profils de statuts, une table à la fois (GET /api/v1/status-machine/{table}). Pour une table dont le graphe codé est connu, une matrice de cases à cocher montre chaque transition codée depuis → vers, cochée par défaut — décocher une case la restreint, et décocher est la seule action que l’écran permet : impossible d’ajouter une case pour une transition que le graphe ne contient pas.

Écran Paramètres > Profils de statuts, table Demandes d’achat (DA), matrice des transitions avec chaque combinaison depuis/vers codée

La matrice ne montre que les transitions déjà autorisées par le code ; décocher restreint, rien ne peut être ajouté.

Onze tables portent un profil aujourd’hui :

purchase_requestsquotesmanufacturing_ordersnon_conformitiesconsumption_vouchersinvoicespurchase_orderssales_ordersdelivery_notescredit_notesreceptions

Pour une table sans graphe codé connu, l’écran bascule sur une liste libre de transitions à autoriser explicitement plutôt qu’une matrice — même principe de restriction, une saisie différente.

دور لكل انتقال

اشتراط دور أدنى

Au-delà de restreindre quelles transitions existent, un profil peut exiger un rôle minimal pour une transition précise (roles_par_transition, clé depuis:vers → rôle) — une demande d’achat qui passe de submitted à approved peut être réservée à un rôle direction achat, indépendamment de l’approbation par montant qu’une règle métier applique déjà sur le même document. Les deux contrôles se cumulent : une règle métier peut exiger un workflow d’approbation, et un profil de statuts peut en plus exiger le rôle qui le ferme.

المحاكاة قبل التقييد

إعادة تشغيل آخر 90 يوما

Exactement comme une règle métier, un profil enregistré peut être simulé avant d’activer son affectation : POST /api/v1/status-profiles/{id}/simulate rejoue les 90 derniers jours de transitions réelles sur cette table et rapporte combien auraient été refusées sous le profil restreint — évaluées, refusées, et quelques exemples avec leur depuis → vers et leur date. Rien n’est écrit ; la même discipline « observer avant de durcir » que décrivent les pages sur les règles métier.

Résultat de simulation (extrait)
POST /api/v1/status-profiles/{id}/simulate  { "jours": 90 }

{
  "table": "purchase_requests",
  "profil": "Achats — restreint",
  "jours": 90,
  "disponible": true,
  "total": 86,
  "refusees": 4,
  "exemples": [
    { "record_id": "DA-2026-0031", "de": "submitted", "vers": "approved", "date": "2026-08-12" }
  ]
}

النطاق والأولوية

العميل، المورّد، نوع المستند، المستأجر

Un profil ne s’applique qu’une fois affecté (status_profile_assignments), et une affectation porte une portée : locataire par défaut, ou restreinte à un client, un fournisseur, ou une classification de type de document (ex. le type d’une non-conformité) — cette dernière résolue depuis le document lui-même, par une lecture bornée à une seule ligne (LireContexteDocumentEnBase), jamais une seconde copie des données du document. Quand plusieurs affectations pourraient correspondre au même document, la plus précise l’emporte : client, puis fournisseur, puis type de document, puis locataire — les portées client et fournisseur visent un tiers, le type de document vise une catégorie, et un tiers est traité comme plus précis qu’une catégorie.

Pour la portée type de document, dont la classification source est un texte libre en base (ex. non_conformities.type), le scope_id de l’affectation reste un UUID : ScopeIDTypeDocument dérive un identifiant UUID stable et déterministe (v5) depuis le libellé choisi, ce qui permet à l’écran de réglages de calculer exactement le même identifiant sans demander à un consultant de le saisir à la main.

العودة إلى قواعد العمل والمراقبة
انظر أيضا : التشغيل · القيادة وإشارات الخطر · المساعد الذكي