Apparence
8. Concept central : Référentiel & Snapshots de campagne
Ce mécanisme est le cœur métier de l'application — conservé à l'identique en v2. Le comprendre est indispensable. Seule l'implémentation change (mutations Convex au lieu de RPC SQL).
Deux périmètres coexistent
| Périmètre | Discriminant (v2, Convex) | Nature | Modifiable ? |
|---|---|---|---|
| Référentiel maître | campaignId / campaignIdSnapshot = null | Modèle réutilisable du plan de test | Définitions oui (admin/consultant) ; résultats : non |
| Snapshot de campagne | campaignIdSnapshot = Id<"campaigns"> | Copie figée appartenant à une campagne | Résultats : oui, uniquement si campagne active |
Chaque document snapshot conserve un sourceRefId pointant vers son document maître (traçabilité, résolu par relationship helper).
Activation d'une campagne = photographie figée
À la première activation d'une campagne (mutation campaigns.activate) :
- La campagne devient active (
isActive = true) ; toute autre campagne active du même (organisation, projet) est désactivée (unicité garantie par index Convex + garde dans la mutation, en remplacement de l'index partiel SQL de v1). - L'arbre maître complet est copié en profondeur vers des documents scopés à la campagne : modules → fonctionnalités → scénarios → flux → étapes.
- Les définitions d'étapes (nom, description, jeu de données, attendu, CRIM) sont copiées ; les résultats sont remis à zéro (
Non testé). - Le champ
snapshotCreatedAtest posé → garde d'idempotence : réactiver la campagne ne recopie jamais (les résultats saisis sont préservés).
Règle d'exécution
- Les résultats et anomalies ne sont saisissables que sur le snapshot de la campagne ACTIVE (garde
assertCampaignActive, appliquée dans les mutationsetapes/anomalies). - Le référentiel et les campagnes non actives (figées) sont en lecture seule pour les résultats — une règle d'état portée par la couche ABAC.
⚠️ Point d'attention : ce modèle « référentiel + snapshots » entraîne une duplication de la hiérarchie à chaque campagne, et des champs dénormalisés (
metier,fonctId,scId,fonctNom,scNomsurtests) à maintenir. En v1 c'était une dette fragile (propagation fire-and-forget) ; en v2 ces champs sont synchronisés atomiquement par triggersconvex-helpers. La pertinence même du modèle à l'échelle visée reste à confirmer — voir Q5.