Apparence
10. Règles métier
👔 En clair
Les règles de gestion (ce que l'application autorise, interdit ou automatise) sont fonctionnelles — lisez les colonnes Règle et Type. La colonne Source (v2) est technique (où la règle est appliquée dans le code) et peut être ignorée côté métier.
Les règles (RG-xx) sont fonctionnelles et inchangées. La colonne Source (v2) indique où chaque règle est appliquée dans la stack Convex (les origines v1 — RPC SQL, routes
/api/*, RLS, triggers Postgres — sont remplacées, voir Architecture).
| ID | Règle | Type | Source (v2) |
|---|---|---|---|
| RG-01 | Un utilisateur doit être authentifié pour accéder à l'application | Stricte | Better Auth (authComponent) + wrapper zQuery/zMutation |
| RG-02 | Tout nouvel inscrit reçoit le rôle metier (v2 : testeur) par défaut | Stricte | Hook post-inscription Better Auth |
| RG-03 | L'écriture du référentiel (flux, étapes, renommages) est réservée à admin + consultant | Stricte | can('referentiel:write'), mutations tests/etapes |
| RG-04 | Les résultats et anomalies ne sont saisissables que sur le snapshot de la campagne active | Stricte | garde assertCampaignActive (mutations) |
| RG-05 | Le référentiel et les campagnes non actives sont en lecture seule pour les résultats | Stricte | règle d'état ABAC (canInContext) |
| RG-06 | Passer une étape à un résultat ≠ KO efface son anomalie et sa gravité | Stricte | mutation etapes.updateResult |
| RG-07 | Une étape ne porte qu'une seule anomalie | Stricte | index unique anomalies.by_etape |
| RG-08 | Une preuve doit faire ≤ 5 Mo et être une image (jpg/png/gif/webp) ou un PDF | Stricte | validation Zod (upload) + Convex File Storage |
| RG-09 | Une seule campagne active par (organisation, projet) | Stricte | index Convex + garde campaigns.activate |
| RG-10 | La création d'un module amorce toute la hiérarchie (module → … → étape) | Stricte | mutation modules.setup |
| RG-11 | La suppression d'un module supprime en cascade tous les flux du scope | Stricte | mutation modules.remove (cascade applicative) |
| RG-12 | Les codes sont uniques par scope (module/functionality/scenario/test) | Stricte | index Convex + garde de mutation |
| RG-13 | Le prochain code (F/SC/T) est dérivé du max numérique existant sur le référentiel maître | Stricte | helper de génération de code (mutation) |
| RG-14 | La première activation copie l'arbre maître (snapshot) ; les suivantes ne recopient pas | Stricte | campaigns.activate + snapshotCreatedAt |
| RG-15 | Au snapshot, les définitions d'étapes sont copiées mais les résultats remis à « Non testé » | Stricte | campaigns.activate |
| RG-16 | Un run de journal est créé/mis à jour automatiquement à chaque saisie de résultat | Stricte | mutation appendJournal |
| RG-17 | Un CRIM a un code unique ; l'association CRIM↔test se fait par code | Stricte | collection crims (index code), etapes.crimCode |
| RG-18 | Le cache tests.crims = union des crimCode des étapes du flux | Stricte | trigger refreshFluxCrims |
| RG-19 | Impossible de supprimer le dernier administrateur ou son propre compte | Stricte | domaine admin (garde) + Better Auth |
| RG-20 | La couverture (%) = étapes « faites » (OK ou KO) / total, calculée sur les étapes | Stricte | helper coverage |
| RG-21 | Seul un admin peut activer/supprimer une campagne, éditer/créer un projet, gérer les utilisateurs | Stricte | can() (admin) dans les mutations concernées |
| RG-22 | À la création d'un projet, le code projet est auto-généré si absent (6 premières lettres, majuscules) | Souple | mutation projects.create |
| RG-23 | L'export Excel est nommé recette-<PROJET>-<CODE|REF>-<date>.xlsx | Souple | export client (ExcelJS) |
| RG-30 | Le déplacement d'un flux/scénario/fonctionnalité échange sa position avec l'élément adjacent | Stricte | mutations move* |
| RG-31 | Ouvrir un flux enregistre les informations testeur de l'utilisateur courant sur le flux | Souple | mutation (feature synthese) |
| RG-32 | « Proposer un test » recopie intégralement le flux d'origine dans la campagne cible, en « À rédiger » | Stricte | mutation proposeCorrectionTest |
| RG-33 | Une preuve d'anomalie / de run est stockée sous un chemin structuré (org/campagne/…) | Stricte | Convex File Storage (métadonnées evidence_files) |
| RG-34 | La suppression d'une campagne nettoie d'abord les fichiers de preuve puis supprime la campagne (cascade) | Souple | mutation campaigns.remove |