Aller au contenu

PD-279 — Scénarios de tests contractuels

1. Références

  • Spécification : PD-279-specification.md
  • Epic : EPIC-XX

2. Matrice de couverture

ID Invariant ID Critère ID Test Couverture Commentaire
INV-279-01-state-model CA-279-01 TC-NOM-01 Oui Enum RESTITUTED présent et exploitable en runtime.
INV-279-02-restitute-guards CA-279-03 TC-NOM-01 Oui Restitution autorisée quand toutes gardes sont vraies.
INV-279-02-restitute-guards CA-279-04 TC-ERR-05 Oui Refus 409 si état source invalide.
INV-279-02-restitute-guards CA-279-04 TC-ERR-06 Oui Refus 409 si geo_copy_count < 2.
INV-279-02-restitute-guards CA-279-04 TC-ERR-07 Oui Refus 409 si legal_lock=true.
INV-279-02-restitute-guards CA-279-12 TC-ERR-03 Oui Refus 403 si appelant non propriétaire.
INV-279-03-return-guards CA-279-05 TC-NOM-02 Oui Retour autorisé si owner et état RESTITUTED.
INV-279-03-return-guards CA-279-06 TC-ERR-08 Oui Refus 409 si état source != RESTITUTED.
INV-279-03-return-guards CA-279-12 TC-ERR-04 Oui Refus 403 au retour si non owner.
INV-279-04-traceability CA-279-07 TC-NOM-04 Oui Attestation complète + audit sur chaque transition.
INV-279-05-sla CA-279-09 TC-NOM-01 Oui deadline = restituted_at + SLA à la seconde.
INV-279-05-sla CA-279-10 TC-NOM-03 Oui Alerte 80% et escalade 100% observables et distinctes.
INV-279-06-no-destruction-while-restituted CA-279-08 TC-NOM-05 Oui Destruction refusée en 409 pour RESTITUTED.
INV-279-07-transition-matrix CA-279-04 TC-ERR-05 Oui Transition non autorisée explicitement rejetée.
INV-279-07-transition-matrix CA-279-06 TC-ERR-08 Oui Matrice appliquée côté retour restitution.
INV-279-08-ddl-reversible CA-279-02 TC-NOM-06 Oui Migration up/down validée en CI.
INV-279-09-atomicity CA-279-07 TC-INV-09A Oui Changement état + lifecycle_log atomiques (même transaction).
INV-279-09-atomicity CA-279-10 TC-INV-09B Oui Jobs SLA post-commit idempotents et rattrapables.
INV-279-10-cross-module-guard CA-279-08 TC-NOM-05 Oui Garde cross-module destruction active et auditée.
INV-279-01-state-model CA-279-11 TC-NOM-07 Oui Vérification formelle AnchorAssume_States en PASS.

3. Scénarios de test – Flux nominaux

TEST-ID: TC-NOM-01
Référence spec: INV-279-01, INV-279-02, INV-279-05, CA-279-01, CA-279-03, CA-279-09

GIVEN
  - Document existant avec `status=SEALED`, `legal_lock=false`, `geo_copy_count=2`
  - Appelant authentifié propriétaire du document
  - Configuration SLA valide (ex: `restitution_max_duration=30j`)
  - Horloge de test figée en UTC (T0) pour déterminisme
WHEN
  - `POST /documents/:id/restitute`
THEN
  - Réponse HTTP 200
  - `status` devient `RESTITUTED`
  - `restituted_at = T0` (UTC) et `restitution_deadline = T0 + 30j` (écart 0 seconde)
AND
  - Une attestation `lifecycle_log(type=RESTITUTION)` est persistée
  - Un événement d'audit de restitution est émis post-commit
TEST-ID: TC-NOM-02
Référence spec: INV-279-03, CA-279-05

GIVEN
  - Document existant avec `status=RESTITUTED`
  - Appelant authentifié propriétaire du document
WHEN
  - `POST /documents/:id/return-from-restitution`
THEN
  - Réponse HTTP 200
  - `status` devient `SEALED`
AND
  - Une attestation `lifecycle_log(type=RETURN_FROM_RESTITUTION)` est persistée
  - Un événement d'audit de retour est émis
  - Les alertes/escalades SLA actives pour cette fenêtre de restitution sont clôturées
TEST-ID: TC-NOM-03
Référence spec: INV-279-05, CA-279-10

GIVEN
  - Document en `RESTITUTED` avec `restituted_at=T0`, SLA=30 jours
  - Scheduler SLA actif avec source temps contrôlée
WHEN
  - Le temps simulé atteint T0 + 24 jours (80%), puis T0 + 30 jours (100%)
THEN
  - Un événement d'alerte 80% est produit exactement une fois
  - Un événement d'escalade 100% est produit exactement une fois
AND
  - Le document reste `RESTITUTED` (pas de transition automatique)
  - Les deux événements sont traçables (horodatage UTC, document_id)
TEST-ID: TC-NOM-04
Référence spec: INV-279-04, CA-279-07

GIVEN
  - Un document éligible pour restitution puis retour
  - Appelant owner avec `actor_id` UUID v4 valide
WHEN
  - Exécution séquentielle de `restitute` puis `return-from-restitution`
THEN
  - Deux entrées `lifecycle_log` existent avec types attendus
  - Chaque entrée contient `timestamp_utc`, `actor_id`, `type`, `security_level`
AND
  - Deux événements d'audit correspondants existent
  - Les timestamps sont en UTC RFC3339
TEST-ID: TC-NOM-05
Référence spec: INV-279-06, INV-279-10, CA-279-08

GIVEN
  - Document existant avec `status=RESTITUTED`
  - Appelant autorisé sur module destruction
WHEN
  - Appel endpoint destruction du module PD-250
THEN
  - Réponse HTTP 409 avec code métier de refus destruction
  - Aucune destruction effective (intégrité document préservée)
AND
  - Un audit de refus est enregistré
TEST-ID: TC-NOM-06
Référence spec: INV-279-08, CA-279-02

GIVEN
  - Base de données initiale au schéma n-1
WHEN
  - Exécution migration `up` puis migration `down`
THEN
  - Les deux commandes réussissent sans erreur
  - Le schéma final après `down` est cohérent avec l'état initial attendu
AND
  - Aucun état structurel invalide n'est introduit
TEST-ID: TC-NOM-07
Référence spec: CA-279-11

GIVEN
  - Modèle formel et implémentation de statuts synchronisés
WHEN
  - Exécution de la vérification `AnchorAssume_States`
THEN
  - Résultat PASS
AND
  - Rapport de vérification archivé comme preuve de conformité

4. Scénarios de test – Cas d’erreur

TEST-ID: TC-ERR-01
Référence spec: §6 (400 Bad Request), §5.1

GIVEN
  - `document_id` non conforme UUID v4
WHEN
  - `POST /documents/:id/restitute`
THEN
  - HTTP 400
  - Aucune mutation de statut
  - Aucune attestation de transition
TEST-ID: TC-ERR-02
Référence spec: §6 (404 Not Found)

GIVEN
  - `document_id` valide mais inexistant
WHEN
  - `POST /documents/:id/restitute`
THEN
  - HTTP 404
  - Aucune attestation
  - Aucun événement de transition
TEST-ID: TC-ERR-03
Référence spec: INV-279-02, CA-279-12, §6 (403)

GIVEN
  - Document `SEALED` appartenant à un autre utilisateur
WHEN
  - `POST /documents/:id/restitute`
THEN
  - HTTP 403
  - Statut inchangé
  - Aucune attestation de restitution
TEST-ID: TC-ERR-04
Référence spec: INV-279-03, CA-279-12, §6 (403)

GIVEN
  - Document `RESTITUTED` appartenant à un autre utilisateur
WHEN
  - `POST /documents/:id/return-from-restitution`
THEN
  - HTTP 403
  - Statut inchangé
  - Aucune attestation de retour
TEST-ID: TC-ERR-05
Référence spec: INV-279-02, INV-279-07, CA-279-04, §6 (409)

GIVEN
  - Document existant avec `status` différent de `SEALED`
WHEN
  - `POST /documents/:id/restitute`
THEN
  - HTTP 409
  - Transition refusée selon matrice d'états
  - Aucune attestation de restitution
TEST-ID: TC-ERR-06
Référence spec: INV-279-02, CA-279-04, §6 (409)

GIVEN
  - Document `SEALED` avec `geo_copy_count=1`
WHEN
  - `POST /documents/:id/restitute`
THEN
  - HTTP 409
  - Statut inchangé
  - Aucune attestation de restitution
TEST-ID: TC-ERR-07
Référence spec: INV-279-02, CA-279-04, §6 (409)

GIVEN
  - Document `SEALED` avec `legal_lock=true`
WHEN
  - `POST /documents/:id/restitute`
THEN
  - HTTP 409
  - Statut inchangé
  - Audit de refus présent
TEST-ID: TC-ERR-08
Référence spec: INV-279-03, INV-279-07, CA-279-06, §6 (409)

GIVEN
  - Document existant avec `status != RESTITUTED`
WHEN
  - `POST /documents/:id/return-from-restitution`
THEN
  - HTTP 409
  - Statut inchangé
  - Aucune attestation `RETURN_FROM_RESTITUTION`
TEST-ID: TC-ERR-09
Référence spec: INV-279-05, §6 (422 ou rejet config)

GIVEN
  - Configuration SLA invalide (ex: `restitution_max_duration=0` ou `31`)
WHEN
  - Démarrage service / chargement configuration
THEN
  - Rejet explicite de la configuration (422 ou erreur de validation config)
  - Aucun traitement de restitution accepté tant que configuration invalide
TEST-ID: TC-ERR-10
Référence spec: INV-279-09, §6 (500)

GIVEN
  - Injection d'une faute transactionnelle au moment de l'écriture `lifecycle_log`
WHEN
  - `POST /documents/:id/restitute`
THEN
  - HTTP 500
  - Rollback total: statut document inchangé
  - Aucune attestation partielle persistée

5. Tests d’invariants (non négociables)

Invariant Test(s) dédiés Observable Commentaire
INV-279-01-state-model TC-NOM-01 Enum RESTITUTED accepté en lecture/écriture runtime Couvre alignement modèle/implémentation.
INV-279-02-restitute-guards TC-NOM-01, TC-ERR-03, TC-ERR-05, TC-ERR-06, TC-ERR-07 Autorisation/refus strict selon gardes Aucune garde implicite.
INV-279-03-return-guards TC-NOM-02, TC-ERR-04, TC-ERR-08 Retour autorisé uniquement si owner + RESTITUTED Contrôle d'accès et état source vérifiés.
INV-279-04-traceability TC-NOM-04 lifecycle_log complet + audit pour chaque transition Horodatage UTC obligatoire.
INV-279-05-sla TC-NOM-01, TC-NOM-03, TC-ERR-09 Deadline exacte + événements 80/100 + validation bornes config Vérifie temps et gouvernance SLA.
INV-279-06-no-destruction-while-restituted TC-NOM-05 Refus destruction en 409 Non-destruction effective contrôlée.
INV-279-07-transition-matrix TC-ERR-05, TC-ERR-08 Rejets explicites des transitions interdites Anti-ambiguïté machine à états.
INV-279-08-ddl-reversible TC-NOM-06 Migration up/down sans incohérence structurelle Test CI obligatoire.
INV-279-09-atomicity TC-INV-09A, TC-INV-09B, TC-ERR-10 Atomicité sync + fiabilité async post-commit Couvre crash/retry/rattrapage.
INV-279-10-cross-module-guard TC-NOM-05 Garde destruction active au niveau service module destruction Couvre contrainte inter-modules.

Détails complémentaires atomicité

TEST-ID: TC-INV-09A
Référence spec: INV-279-09

GIVEN
  - Transaction DB instrumentée avec point d'échec contrôlé
WHEN
  - Exécution restitution avec erreur forcée avant commit
THEN
  - Ni statut `RESTITUTED` ni attestation `RESTITUTION` ne sont persistés
AND
  - Aucun événement async SLA n'est planifié
TEST-ID: TC-INV-09B
Référence spec: INV-279-09, §5.8

GIVEN
  - Document `RESTITUTED` commité
  - Worker SLA redémarré après interruption
WHEN
  - Reprise des jobs de rattrapage
THEN
  - Les événements 80/100 manquants sont émis
  - Les doublons sont évités (idempotence)
AND
  - L'état DB reste cohérent (aucune mutation transactionnelle rétroactive)

6. Tests de non-régression

Test ID Objet Observable Commentaire
TC-NR-01 Compatibilité lecture status existants (PENDING,SEALED,EXPIRED) Aucune erreur de désérialisation ou de contrat API Vérifie ajout non cassant de RESTITUTED.
TC-NR-02 Flux hors périmètre non modifiés (ex: SEALED -> EXPIRED) Comportement identique baseline pré-PD-279 Non-régression fonctionnelle transversale.
TC-NR-03 Triggers de traçabilité/immutabilité existants Écriture restitution possible sans violer triggers Vérifie compatibilité DDL/runtime.
TC-NR-04 Endpoint destruction pour statuts non RESTITUTED Politique de destruction préexistante inchangée Valide absence d'effet de bord cross-module.

7. Tests négatifs et adversariaux

Test ID Entrée invalide / abus Résultat attendu Observable
TC-NEG-01 Double appel concurrent restitute sur même document SEALED 1 succès 200 max, autres requêtes rejetées 409 Un seul passage à RESTITUTED, une seule attestation RESTITUTION.
TC-NEG-02 Rejeu d'appel return-from-restitution après retour déjà effectué Requête rejouée en 409 Aucune attestation de retour additionnelle.
TC-NEG-03 UUID valide mais avec casse mixte et format correct Traitement normal sans faux négatif Validation UUID conforme contrat v4.
TC-NEG-04 Tentative de forger security_level invalide dans contexte transition Rejet transactionnel Aucune attestation partiellement persistée.
TC-NEG-05 Crash applicatif immédiatement post-commit restitution État DB cohérent + rattrapage async SLA Preuve audit/lifecycle intacte après redémarrage.

8. Observabilité requise pour les tests

  • État système : lecture DB (documents.status, restituted_at, restitution_deadline) avant/après action.
  • Réponse API : code HTTP, payload fonctionnel, code métier de conflit (quand défini).
  • Journal d’audit : événement transition/rejet, document_id, actor_id, horodatage UTC, type événement.
  • Événement signé / horodaté : flux alertes 80% et escalade 100%, corrélables au document et à la fenêtre SLA.
  • Export probatoire : artefacts de preuve (logs, traces, rapport CI migrations, rapport vérification TLA+) versionnés et rejouables.

9. Règles non testables

Règle Raison Impact
Mapping exact des error_code métier pour chaque 409 (Q-279-02) La spécification liste les HTTP mais pas la table normative des codes métier attendus client par client Majeur
Caractère obligatoire de security_level sur RETURN_FROM_RESTITUTION (Q-279-03) Exigence indiquée "si requis par contrat existant" sans contrat consolidé joint Majeur
Exhaustivité des routes destruction couvertes (Q-279-05) Liste exhaustive des endpoints du module PD-250 non fournie dans l'entrée Majeur
Séquence DDL canonique exacte de down migration PostgreSQL (Q-279-04) Réversibilité testable, mais conformité à la convention DBA interne non vérifiable sans standard détaillé Mineur

10. Verdict QA

  • ⚠️ Testable partiellement (avec réserves listées)

Réserve principale: le périmètre est fortement testable sur le comportement métier, transactionnel et temporel, mais certains points contractuels inter-modules (error_code 409, obligation security_level retour, inventaire routes destruction) doivent être figés pour lever toute ambiguïté de conformité stricte.