Le copilote : refus expliqués, procédures guidées

Ce que le copilote fait avec un refus structuré et avec l’état réel de l’installation : l’expliquer en langage courant, guider pas à pas, agir seulement après confirmation — et ce qu’il ne fait jamais.

Le principe

Un rail présent partout, un contexte fourni

Le rail du copilote se pose sur le bord droit de chaque écran (visible sur chaque capture de cette page et sur la page pilotage). Il a trois modes distincts — un fil de conversation libre, un mode explication déclenché par le dernier refus, et un mode guide pour les trois procédures de bout en bout ci-dessous — mais la règle qui tient sur les trois est la même : le prompt est restreint à uniquement le contexte fourni. Le copilote explique et guide à partir de données structurées déjà calculées par le portail ; il n’invente jamais un chiffre.

Expliquer un refus

« Pourquoi le dernier refus ? »

N’importe quel refus de règle métier reçu par un écran — un { code, params, message } structuré, le même contrat que produit chaque règle métier décrite sur ce site — est publié sur un petit bus d’événements (lib/refusal-bus.ts) dès que backendFetch le voit, quel que soit l’écran qui l’a déclenché. Le copilote, monté une seule fois globalement, s’abonne à ce bus : le bouton « Pourquoi le dernier refus ? » apparaît dès qu’un refus arrive, sur n’importe quel écran, pas seulement sur les formulaires de document — créer une règle métier avec un paramètre invalide compte aussi, comme le montre la capture ci-dessous.

Création d’une règle de tolérance de sur-réception avec un paramètre invalide -5, puis question au copilote sur le dernier refus

Règles métier > Nouvelle règle, une tolérance invalide déclenche regle_parametre_invalide ; le copilote lit le même code et les mêmes paramètres pour l’expliquer.

Le contexte envoyé à GET /api/v1/ai/explain-refusal est construit, jamais deviné : quand le code correspond à un type de règle paramétrable (codeRefusVersTypeRegle, ex. limite_credit_depasseelimite_credit_client), la règle active (type, paramètres, condition, mode) est lue depuis le même catalogue que Paramètres › Règles métier — jamais une seconde définition qui pourrait diverger — plus une lecture bornée du document quand le refus vient d’une écriture. Un code sans règle paramétrable derrière (document_fige, referentiel_bloque…) s’explique quand même, simplement sans la section « règle active ».

Contexte du copilote (extrait)
GET /api/v1/ai/explain-refusal
{
  "code": "regle_parametre_invalide",
  "params": { "parametre": "pct_max", "type": "sur_reception", "attendu": "minimum 0" },
  "message": "Paramètre « pct_max » invalide pour la règle « sur_reception » (attendu : minimum 0)."
}

Quand le code correspond bien à un type de règle, la réponse porte une rules_settings_route — le portail en fait un lien direct « Régler cette règle » à côté de l’explication, la correction à un clic plutôt qu’une relecture du message.

Guider une procédure

« Guide-moi »

« Guide-moi » liste trois procédures de bout en bout, déclarées comme de simples données Go (internal/ai/procedures.go) de la même façon que le catalogue de règles — le code reste compilé et testé, seuls les libellés sont traduits (copilot.procedures.<code>.*, à l’image de rules.types.<code>.*). Ouvrir une procédure affiche un stepper avec l’état réel du locataire : le drapeau « fait » de chaque étape vient d’un COUNT(*) borné sur le schéma du locataire, jamais une supposition.

ProcédureÉtapesParcours
creer_fournisseur_et_commander6Fiche fournisseur → évaluation → DA → commande d’achat → réception → facture.
lancer_production5Article fini → nomenclature → OF → lancement → clôture stock (consommation + entrée produit fini).
cloturer_periode3Valider les factures en brouillon → enregistrer les paiements → clôturer la période.
Guide-moi ouvert sur la procédure Lancer un ordre de fabrication, stepper avec les étapes 2 à 5 déjà faites et le mini-formulaire de l’étape 1 ouvert

Le stepper lit l’état réel du locataire (étapes 2 à 5 déjà faites ici) ; « Faire pour moi » ouvre un mini-formulaire pour l’étape restante.

Agir, seulement confirmé

« Faire pour moi »

Une étape ne propose « Faire pour moi » que si deux conditions tiennent : l’étape déclare une action_entity (un fournisseur, un article, une demande d’achat…) et cette entité a un mini-formulaire déclaré (COPILOT_ACTION_FIELDS). La plupart des étapes — une commande d’achat, une réception — portent trop de logique de prix et de lignes pour un formulaire de taille vocale, elles restent un simple lien vers l’écran (« Faire »), exactement comme le prévoit le plan : une action, sinon un lien, jamais un raccourci inventé. Quand un mini-formulaire existe, rien n’écrit tant que l’utilisateur n’a pas cliqué sur Confirmer et exécuter à l’intérieur — la même porte de confirmation explicite que l’agent vocal pose pour une commande tapée.

Après une action réussie, l’état de la procédure est recalculé depuis le même COUNT(*) que lit le stepper — jamais un drapeau corrigé localement — et le document créé s’ajoute à un récapitulatif qui renvoie directement à sa fiche : un parcours complet de « Créer un fournisseur et commander » se termine avec six preuves cliquables, pas un « terminé » aveugle.

Ce qu’il ne fait jamais

Explique, ne décide pas

Le copilote n’écrit jamais sans un clic de confirmation explicite, n’invente jamais un type de règle, un seuil ou un chiffre que le portail n’a pas déjà calculé, et ne saute jamais le mini-formulaire d’une entité qui porte une logique de prix ou de coûts — celles-ci restent un lien vers l’écran complet. Sur le flow-designer et sur une page d’affaire, il lit exactement le même JSON de signaux de risque que le panneau affiche déjà ; rien n’est recalculé côté IA. Il explique et guide — le chemin d’écriture reste celui que décrit le reste de ce site : règles typées, profils de statuts, et le CRUD générique.

Retour à Règles métier et contrôle
Voir aussi : Mise en service · Pilotage et signaux de risque · Profils de statuts