Aller au contenu

PD-279 — Restitution ISO 14641 d’un document archivé (état RESTITUTED)

1. Objectif

Spécifier contractuellement l’ajout du statut RESTITUTED et des transitions de restitution d’un document archivé, afin d’aligner le backend avec ISO 14641 §11.3 et de satisfaire l’ASSUME TLA+ AnchorAssume_States, sans ambiguïté fonctionnelle, temporelle, ni de traçabilité.

2. Périmètre / Hors périmètre

Inclus

  • Ajout du statut RESTITUTED au cycle de vie documentaire.
  • Transition SEALED -> RESTITUTED via POST /documents/:id/restitute.
  • Transition retour RESTITUTED -> SEALED via POST /documents/:id/return-from-restitution.
  • Vérification des gardes métier: ownership, legal_lock=false, geo_copy_count >= 2, état source valide.
  • Journalisation obligatoire des transitions dans lifecycle_log et journal d’audit.
  • SLA de restitution: durée max configurable, calcul de deadline, alerte à 80%, escalade à 100%.
  • Interdiction de destruction d’un document RESTITUTED (rejet HTTP 409 côté module destruction).
  • Migration BD réversible (up/down), incluant extension d’enum + champs temporels.

Exclu

  • Formalisation complète de l’état DISPOSED (traitée hors de cette story).
  • NF Z42-013 DIP (PD-278).
  • Restitution multi-destinataire.
  • Refonte des flux hors restitution (capture, sealing, expiration), sauf impacts explicitement listés ici.

3. Définitions

  • DocumentStatus: statut métier du document (PENDING, SEALED, RESTITUTED, EXPIRED).
  • RESTITUTED: document archivé restitué temporairement à son originateur.
  • Originateur / Owner: utilisateur propriétaire du document.
  • legal_lock: verrou juridique interdisant les actions de restitution.
  • geo_copy_count: nombre de copies géo-distribuées validées.
  • lifecycle_log: registre d’attestations de transitions d’état.
  • JournalEventType: type d’événement d’audit applicatif.
  • SLA restitution: durée maximale autorisée entre restitution et retour en archivage.
  • Deadline restitution: restituted_at + restitution_max_duration.
  • État terminal (dans ce périmètre): état sans transition sortante autorisée par cette spécification.

4. Invariants (non négociables)

ID Règle Justification
INV-279-01-state-model Le statut RESTITUTED DOIT exister dans DocumentStatus et être persistant. Alignement modèle TLA+ / implémentation.
INV-279-02-restitute-guards SEALED -> RESTITUTED autorisée uniquement si: owner, legal_lock=false, geo_copy_count >= 2, état courant SEALED. La garde geo_copy_count >= 2 s'applique UNIQUEMENT à cette transition (pas au retour). ISO 14641 §11.3 et §5.5.8.
INV-279-03-return-guards RESTITUTED -> SEALED autorisée uniquement si owner et état courant RESTITUTED. Aucune vérification de geo_copy_count requise (le document n'a jamais quitté le stockage). Contrôle du retour de restitution.
INV-279-04-traceability Chaque transition de restitution DOIT créer une attestation lifecycle_log horodatée UTC + acteur + type d’événement + security_level, et un log d’audit. Exigence de traçabilité complète.
INV-279-05-sla Tout document RESTITUTED DOIT porter restituted_at et restitution_deadline; alerte à 80% du SLA et escalade à 100%. Gouvernance temporelle et conformité.
INV-279-06-no-destruction-while-restituted Toute tentative de destruction d’un document RESTITUTED DOIT être rejetée avec HTTP 409 Conflict. Cohérence cycle de vie ISO.
INV-279-07-transition-matrix Les transitions sortantes de chaque état du périmètre DOIVENT être explicitement autorisées ou interdites; aucune transition implicite. Exigence anti-ambiguïté de machine à états.
INV-279-08-ddl-reversible La migration de schéma DOIT être réversible sans perte de cohérence structurelle (up/down). Robustesse opérationnelle.
INV-279-09-atomicity Une transition d’état et l’attestation associée DOIVENT être atomiques (même transaction DB). Les traitements asynchrones SLA sont post-commit, idempotents et rattrapables. Cohérence en cas d’incident.
INV-279-10-cross-module-guard Le module destruction DOIT vérifier document.status AVANT inclusion dans un batch de destruction ET AVANT exécution. Un document RESTITUTED DOIT être rejeté avec HTTP 409 à l'inclusion (pas seulement à l'exécution). Contrainte inter-modules explicite, anti-contournement batch.
INV-279-11-idempotency POST /documents/:id/restitute est idempotent : si le document est déjà RESTITUTED, retourner HTTP 200 sans nouvelle attestation. POST /documents/:id/return-from-restitution est idempotent : si le document est déjà SEALED, retourner HTTP 200 sans nouvelle attestation. Robustesse face aux retries réseau.

5. Flux nominaux

5.1 Modèle de données (formats et contraintes contractuelles)

Définitions centralisées; les sections 5.2, 6, 7, 8 y font référence sans redéfinition.

Donnée Format / encodage Taille / longueur Jeu caractères Sensibilité casse Validation Comportement si invalide
document_id (path :id) UUID v4 canonique texte 36 caractères [0-9a-f-] case-insensitive sur hex, format canonical recommandé ^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$ HTTP 400
status Enum string 1 valeur parmi 4 A-Z_ case-sensitive appartenance enum stricte HTTP 409 si transition interdite
legal_lock Booléen 1 bit logique n/a n/a {true,false} HTTP 409 si true pour restitution
geo_copy_count Entier non signé 0..2147483647 chiffres n/a entier >= 0 HTTP 409 si <2
restituted_at Timestamp UTC RFC3339/ISO8601 précision seconde min UTF-8 n/a datetime valide UTC rejet transaction (400/500 selon source)
restitution_deadline Timestamp UTC RFC3339/ISO8601 précision seconde min UTF-8 n/a deadline = restituted_at + SLA rejet transaction si non calculable
lifecycle_log.type Enum string valeurs: RESTITUTION, RETURN_FROM_RESTITUTION A-Z_ case-sensitive appartenance enum stricte rejet transaction
actor_id UUID v4 canonique texte 36 caractères [0-9a-f-] idem document_id regex UUID v4 rejet transaction
security_level Enum de sécurité existant (contrat module documents) selon contrat existant selon contrat existant selon contrat existant validation par contrat existant rejet transaction

Bornes numériques obligatoires

Paramètre Défaut Min Max Unité Percentile / Référence Hors bornes
geo_copy_count pour restitution n/a (mesure observée) 2 (pour autoriser) 2147483647 copies n/a <2 => HTTP 409
restitution_max_duration 30 1 30 jours n/a config invalide => rejet au chargement config
Seuil alerte SLA 80 1 99 % n/a hors bornes => rejet config
Seuil escalade SLA 100 100 100 % n/a toute autre valeur interdite

5.2 Machine à états (transitions explicites, incluant retours)

Portée: modèle documentaire concerné par restitution (PENDING, SEALED, RESTITUTED, EXPIRED).

  • PENDING:
  • PENDING -> *: INTERDITE dans ce périmètre (transitions hors restitution inchangées, hors périmètre de cette story).
  • SEALED:
  • SEALED -> RESTITUTED: AUTORISÉE si INV-279-02.
  • SEALED -> SEALED: INTERDITE (pas d’opération no-op de restitution).
  • SEALED -> EXPIRED et autres: hors périmètre, inchangé par cette story.
  • RESTITUTED:
  • RESTITUTED -> SEALED: AUTORISÉE si INV-279-03.
  • RESTITUTED -> DISPOSED: INTERDITE (INV-279-06).
  • RESTITUTED -> RESTITUTED: INTERDITE.
  • RESTITUTED -> PENDING/EXPIRED: INTERDITE dans ce périmètre.
  • EXPIRED (terminal pour ce périmètre):
  • EXPIRED -> *: INTERDITE (état terminal, résolution manuelle uniquement).

Comportement downgrade/retour RESTITUTED -> SEALED: - Données de preuve (lifecycle_log, audit) conservées. - SLA restitution clos (plus d’alerte/escalade active sur la fenêtre terminée). - Protections d’archive SEALED réappliquées immédiatement.

5.3 Flux nominal A — Restitution (POST /documents/:id/restitute)

Ordre d’évaluation des gardes (priorité stricte) : 1. Authentification → 401 Unauthorized 2. Validation document_id → 400 Bad Request 3. Existence document → 404 Not Found 4. Ownership (owner) → 403 Forbidden 5. État courant SEALED → 409 Conflict (error_code: INVALID_SOURCE_STATE) 6. Idempotence : si déjà RESTITUTED → 200 OK (pas de nouvelle attestation, retour état actuel) 7. legal_lock=false → 409 Conflict (error_code: DOCUMENT_UNDER_LEGAL_LOCK) 8. geo_copy_count >= 2 → 409 Conflict (error_code: INSUFFICIENT_GEO_COPIES)

Flux nominal (gardes satisfaites, pas idempotent) : 1. Le système calcule restituted_at=now_utc et restitution_deadline=restituted_at + restitution_max_duration. 2. Le système persiste atomiquement: - status=RESTITUTED - restituted_at - restitution_deadline - attestation lifecycle_log(type=RESTITUTION, actor_id, security_level, timestamp_utc). 3. Le système émet l’événement d’audit correspondant. 4. Réponse HTTP 200.

5.4 Flux nominal B — Retour de restitution (POST /documents/:id/return-from-restitution)

Ordre d’évaluation des gardes (priorité stricte) : 1. Authentification → 401 Unauthorized 2. Validation document_id → 400 Bad Request 3. Existence document → 404 Not Found 4. Ownership (owner) → 403 Forbidden 5. État courant RESTITUTED → 409 Conflict (error_code: INVALID_SOURCE_STATE) 6. Idempotence : si déjà SEALED → 200 OK (pas de nouvelle attestation, retour état actuel)

Flux nominal (gardes satisfaites, pas idempotent) : 1. Le système persiste atomiquement: - status=SEALED - attestation lifecycle_log(type=RETURN_FROM_RESTITUTION, actor_id, security_level, timestamp_utc). 2. Le système émet l’événement d’audit correspondant. 3. Réponse HTTP 200.

5.5 Flux nominal C — Contrôle destruction cross-module

Routes protégées (liste exhaustive) : - POST /destruction/batches — inclusion d’un document dans un batch de destruction - POST /destruction/batches/:id/execute — exécution d’un batch de destruction - DELETE /documents/:id — soft-delete direct d’un document

Garde : À CHAQUE route ci-dessus, le système DOIT vérifier document.status : 1. Si status=RESTITUTED, la destruction est refusée avec HTTP 409 (error_code: DOCUMENT_RESTITUTED_DESTRUCTION_FORBIDDEN). 2. Événement d’audit de refus enregistré. 3. Le contrôle s’applique à l’inclusion dans le batch ET à l’exécution (double vérification anti-race-condition).

5.6 SLA temporels (checklist complète)

Élément Valeur
Valeur par défaut restitution_max_duration = 30 jours
Borne minimale 1 jour
Borne maximale 30 jours
Configurabilité Oui, paramètre de configuration service (runtime)
Expiration à 80% Alerte opérationnelle obligatoire
Expiration à 100% Escalade obligatoire + événement audit
Comportement à expiration Le document reste en RESTITUTED tant qu’aucun retour explicite n’est effectué. Le système émet un événement RESTITUTION_OVERDUE (JournalEventType). Aucune transition automatique — le PO décide via intervention manuelle. Le document reste fonctionnel (pas de blocage d’actions).

5.7 Stratégie de migration DDL (modification colonne/enum existant)

Élément Spécification
Type actuel / cible documents.status: enum existant (PENDING,SEALED,EXPIRED) -> enum étendu avec RESTITUTED
Colonnes ajoutées restituted_at (timestamp UTC nullable), restitution_deadline (timestamp UTC nullable)
Backfill Aucun backfill massif requis; documents déjà SEALED restent sans valeurs tant qu’aucune restitution n’a eu lieu
Impact triggers existants Doit rester compatible avec triggers de traçabilité/immutabilité; aucun trigger ne doit empêcher l’écriture atomique des attestations
Impact workers/services Workers SLA doivent supporter enregistrement tardif/retry; modules lisant status doivent accepter la nouvelle valeur RESTITUTED
Down migration Retrait des colonnes ajoutées + suppression de la valeur enum selon stratégie DB sûre et réversible contractuelle. Précondition : tous les documents en état RESTITUTED DOIVENT être retournés (SEALED) avant exécution de la down migration. La migration DOIT vérifier cette précondition et échouer si non satisfaite.
Contraintes ajoutées restitution_deadline >= restituted_at quand les deux sont non null; cohérence transactionnelle obligatoire

5.8 Atomicité multi-composant

Scope Sync/Async Garantie
MAJ document + insertion lifecycle_log Synchrone (transaction DB) Atomicité ACID
Événement audit applicatif Post-commit At-least-once, idempotent
Alerte 80% / escalade 100% SLA Async (job planifié) Retry-safe, rattrapage sur redémarrage
Crash pré-commit n/a rollback total, aucun artefact persistant
Crash post-commit n/a état DB valide, traitements async rattrapés

5.9 Contraintes inter-modules

Élément Spécification
Routes d’autre module à protéger Routes de destruction documentaire (module destruction PD-250)
Mécanisme de protection Vérification du DocumentStatus avant destruction
Données cross-module nécessaires document.status exposé au module destruction
Résolution FK/liaison Identifiant document métier (document_id) selon contrat module documents
Scope d’enregistrement Contrôle appliqué au niveau service/guard du module destruction (pas de règle globale transverse implicite)
Exceptions d’accès Aucune exception: même rôle privilégié ne peut détruire un RESTITUTED dans ce périmètre

5bis. Diagrammes Mermaid

5bis.1 Machine a etats — Cycle de vie documentaire (perimetre restitution)

Transitions autorisees et interdites conformement a INV-279-07 (matrice explicite).

stateDiagram-v2
    [*] --> PENDING

    PENDING --> SEALED : capture + sealing\n(hors perimetre PD-279)

    SEALED --> RESTITUTED : POST /documents/:id/restitute\n[owner AND legal_lock=false\nAND geo_copy_count>=2]\n(INV-279-02)

    RESTITUTED --> SEALED : POST /documents/:id/return-from-restitution\n[owner]\n(INV-279-03)

    SEALED --> EXPIRED : expiration\n(hors perimetre PD-279)

    state RESTITUTED {
        direction LR
        [*] --> actif
        actif --> alerte_80pct : elapsed >= 80% SLA\n(INV-279-05)
        alerte_80pct --> escalade_100pct : elapsed >= 100% SLA\n(INV-279-05)
        escalade_100pct --> overdue : RESTITUTION_OVERDUE emis\npas de transition auto
    }

    note right of RESTITUTED
        INV-279-06 : destruction INTERDITE
        INV-279-11 : idempotence (200 si deja RESTITUTED)
    end note

    note right of EXPIRED
        Etat terminal dans ce perimetre
        (INV-279-07)
    end note

5bis.2 Sequence — Flux A : Restitution nominale (POST /documents/:id/restitute)

Evaluation des gardes en ordre strict (§5.3), atomicite transaction + audit post-commit (INV-279-09).

sequenceDiagram
    participant Client
    participant API as DocumentController
    participant Guard as RestitutionGuard
    participant Service as DocumentService
    participant DB as PostgreSQL
    participant Audit as AuditService
    participant SLA as SLA Worker

    Client->>API: POST /documents/:id/restitute
    API->>Guard: authenticate + validate UUID
    Guard-->>API: 401/400 si invalide

    API->>Service: restitute(documentId, actorId)
    Service->>DB: SELECT document (id, status, owner_id, legal_lock, geo_copy_count)

    alt document inexistant
        DB-->>Service: null
        Service-->>Client: 404 DOCUMENT_NOT_FOUND
    else not owner
        Service-->>Client: 403 NOT_DOCUMENT_OWNER
    else status = RESTITUTED (idempotence INV-279-11)
        Service-->>Client: 200 OK (etat actuel, pas de nouvelle attestation)
    else status != SEALED
        Service-->>Client: 409 INVALID_SOURCE_STATE
    else legal_lock = true
        Service-->>Client: 409 DOCUMENT_UNDER_LEGAL_LOCK
    else geo_copy_count < 2
        Service-->>Client: 409 INSUFFICIENT_GEO_COPIES
    else gardes OK
        Service->>DB: BEGIN TRANSACTION
        Service->>DB: UPDATE status=RESTITUTED, restituted_at, restitution_deadline
        Service->>DB: INSERT lifecycle_log (RESTITUTION, actor_id, security_level, timestamp)
        Note over Service,DB: Atomicite ACID (INV-279-09)
        Service->>DB: COMMIT
        Service->>Audit: emit audit event (post-commit, at-least-once)
        Service->>SLA: planifier alerte 80% + escalade 100% (INV-279-05)
        Service-->>Client: 200 OK {status: RESTITUTED, restituted_at, restitution_deadline}
    end

5bis.3 Sequence — Flux B : Retour de restitution (POST /documents/:id/return-from-restitution)

Gardes simplifiees (§5.4) : pas de verification geo_copy_count (INV-279-03).

sequenceDiagram
    participant Client
    participant API as DocumentController
    participant Service as DocumentService
    participant DB as PostgreSQL
    participant Audit as AuditService

    Client->>API: POST /documents/:id/return-from-restitution
    API->>Service: returnFromRestitution(documentId, actorId)
    Service->>DB: SELECT document (id, status, owner_id)

    alt document inexistant
        Service-->>Client: 404 DOCUMENT_NOT_FOUND
    else not owner
        Service-->>Client: 403 NOT_DOCUMENT_OWNER
    else status = SEALED (idempotence INV-279-11)
        Service-->>Client: 200 OK (etat actuel, pas de nouvelle attestation)
    else status != RESTITUTED
        Service-->>Client: 409 INVALID_SOURCE_STATE
    else gardes OK
        Service->>DB: BEGIN TRANSACTION
        Service->>DB: UPDATE status=SEALED
        Service->>DB: INSERT lifecycle_log (RETURN_FROM_RESTITUTION, actor_id, security_level, timestamp)
        Note over Service,DB: Atomicite ACID (INV-279-09)
        Service->>DB: COMMIT
        Service->>Audit: emit audit event (post-commit)
        Note over Service: SLA clos — plus d’alerte/escalade active (§5.2)
        Service-->>Client: 200 OK {status: SEALED}
    end

5bis.4 Sequence — Flux C : Garde cross-module destruction (INV-279-10)

Double verification anti-race-condition a l’inclusion ET a l’execution (§5.5).

sequenceDiagram
    participant Client
    participant Destruction as DestructionModule
    participant DocService as DocumentService
    participant DB as PostgreSQL
    participant Audit as AuditService

    rect rgb(255, 240, 240)
        Note over Client,Audit: Phase 1 — Inclusion dans batch (POST /destruction/batches)
        Client->>Destruction: POST /destruction/batches {document_ids}
        Destruction->>DocService: getStatus(documentId)
        DocService->>DB: SELECT status FROM documents WHERE id = :id
        DB-->>DocService: status

        alt status = RESTITUTED
            Destruction->>Audit: emit refus destruction (INV-279-04)
            Destruction-->>Client: 409 DOCUMENT_RESTITUTED_DESTRUCTION_FORBIDDEN
        else status != RESTITUTED
            Destruction-->>Client: 200 OK (batch cree)
        end
    end

    rect rgb(255, 240, 240)
        Note over Client,Audit: Phase 2 — Execution batch (POST /destruction/batches/:id/execute)
        Client->>Destruction: POST /destruction/batches/:id/execute
        loop pour chaque document du batch
            Destruction->>DocService: getStatus(documentId)
            DocService->>DB: SELECT status FROM documents WHERE id = :id
            DB-->>DocService: status
            alt status = RESTITUTED (race condition detectee)
                Destruction->>Audit: emit refus destruction (INV-279-06)
                Note over Destruction: Document exclu du batch, 409
            end
        end
    end

6. Cas d’erreur

HTTP error_code Condition
400 Bad Request INVALID_DOCUMENT_ID document_id non conforme UUID v4 (§5.1)
401 Unauthorized Authentification absente ou invalide
403 Forbidden NOT_DOCUMENT_OWNER Appelant non propriétaire du document
404 Not Found DOCUMENT_NOT_FOUND Document inexistant
409 Conflict INVALID_SOURCE_STATE État courant incompatible avec la transition demandée
409 Conflict INSUFFICIENT_GEO_COPIES geo_copy_count < 2 lors de restitution
409 Conflict DOCUMENT_UNDER_LEGAL_LOCK legal_lock=true lors de restitution
409 Conflict DOCUMENT_RESTITUTED_DESTRUCTION_FORBIDDEN Tentative de destruction d’un document RESTITUTED
422 Unprocessable Entity INVALID_SLA_CONFIG Bornes SLA invalides (hors [1j,30j])
500 Internal Server Error Échec transactionnel non métier (rollback garanti)

7. Critères d’acceptation (testables)

ID Critère Observable
CA-279-01 DocumentStatus contient RESTITUTED. Enum persistée et lisible en runtime.
CA-279-02 Migration DB up/down est exécutable et réversible. Exécution CI de migration aller/retour sans erreur.
CA-279-03 POST /documents/:id/restitute renvoie 200 si toutes gardes OK. Réponse 200 + status final RESTITUTED.
CA-279-04 POST /documents/:id/restitute renvoie 409 sur garde violée. 409 pour status!=SEALED, geo_copy_count<2, legal_lock=true.
CA-279-05 POST /documents/:id/return-from-restitution renvoie 200 si gardes OK. Réponse 200 + status final SEALED.
CA-279-06 POST /documents/:id/return-from-restitution renvoie 409 si status!=RESTITUTED. Réponse 409.
CA-279-07 Chaque transition crée une attestation lifecycle_log complète. Entrée avec timestamp UTC, actor_id, type, security_level.
CA-279-08 Module destruction rejette RESTITUTED avec 409. Réponse 409 + audit de refus.
CA-279-09 restitution_deadline est calculée exactement à partir de restituted_at + SLA. Écart nul à la seconde près.
CA-279-10 Alerte à 80% et escalade à 100% sont produites. Deux événements observables distincts.
CA-279-11 L’ASSUME TLA+ AnchorAssume_States passe. Exécution de vérification formelle: PASS.
CA-279-12 Utilisateur non propriétaire ne peut ni restituer ni retourner. Réponse 403 sur les deux endpoints.

8. Scénarios de test (Given / When / Then)

  • ST-279-01 Restitution nominale
  • Given un document SEALED, owner authentifié, geo_copy_count=2, legal_lock=false
  • When POST /documents/:id/restitute
  • Then HTTP 200, statut RESTITUTED, restituted_at et restitution_deadline renseignés, attestation RESTITUTION créée.

  • ST-279-02 Restitution refusée copies insuffisantes

  • Given un document SEALED avec geo_copy_count=1
  • When POST /documents/:id/restitute
  • Then HTTP 409, statut inchangé, aucune attestation de transition.

  • ST-279-03 Restitution refusée legal lock

  • Given un document SEALED avec legal_lock=true
  • When POST /documents/:id/restitute
  • Then HTTP 409, statut inchangé, audit de refus.

  • ST-279-04 Restitution refusée non owner

  • Given un document SEALED appartenant à un autre utilisateur
  • When POST /documents/:id/restitute
  • Then HTTP 403.

  • ST-279-05 Retour nominal

  • Given un document RESTITUTED dont l’appelant est owner
  • When POST /documents/:id/return-from-restitution
  • Then HTTP 200, statut SEALED, attestation RETURN_FROM_RESTITUTION créée.

  • ST-279-06 Retour refusé mauvais état

  • Given un document SEALED
  • When POST /documents/:id/return-from-restitution
  • Then HTTP 409.

  • ST-279-07 Interdiction destruction

  • Given un document RESTITUTED
  • When appel de l’endpoint de destruction
  • Then HTTP 409, aucune destruction effective.

  • ST-279-08 SLA événements

  • Given un document RESTITUTED avec SLA configuré à 30 jours
  • When le temps atteint 24 jours (80%) puis 30 jours (100%)
  • Then une alerte 80% puis une escalade 100% sont émises et tracées.

  • ST-279-09 Vérification TLA+

  • Given code et modèle mis à jour
  • When exécution de la vérification AnchorAssume_States
  • Then résultat PASS.

9. Hypothèses explicites

ID Hypothèse Impact si faux
H-279-01 document_id est un UUID v4 (contrat API existant). Adapter regex/validation et tests d’API.
H-279-02 Le module destruction dispose d’un point de contrôle unique avant destruction effective. Si faux: appliquer la règle sur plusieurs chemins, risque de contournement.
H-279-03 security_level est déjà défini dans le contrat documentaire et disponible au moment du log. Si faux: compléter le modèle d’attestation avant livraison.
H-279-04 L’état EXPIRED est terminal dans le périmètre restitution. Si faux: compléter la matrice de transitions et les tests retour.
H-279-05 Les jobs planifiés SLA supportent l’idempotence. Si faux: risque de doublons d’alertes/escalades.

10. Contraintes techniques et points à clarifier

10.1 Contraintes techniques (stack réelle, obligatoire)

  • Projet cible: ProbatioVault-backend.
  • Stack contractuelle: NestJS + TypeORM + PostgreSQL.
  • Endpoints exposés via module documents backend.
  • Migration via mécanisme TypeORM du backend.
  • Aucune hypothèse frontend/mobile dans cette story.

10.2 Points à clarifier (statut)

ID Point Résolution v2
Q-279-01 Politique post-expiration SLA 100% RÉSOLU : Événement RESTITUTION_OVERDUE, aucune transition automatique, intervention PO manuelle (§5.6).
Q-279-02 Error codes métier 409 RÉSOLU : 4 constantes définies — INVALID_SOURCE_STATE, INSUFFICIENT_GEO_COPIES, DOCUMENT_UNDER_LEGAL_LOCK, DOCUMENT_RESTITUTED_DESTRUCTION_FORBIDDEN (§6).
Q-279-03 security_level pour RETURN_FROM_RESTITUTION RÉSOLU : Obligatoire (même contrat que RESTITUTION) — voir §5.4 flux nominal.
Q-279-04 Down migration enum PostgreSQL RÉSOLU : Précondition ajoutée — tous documents RESTITUTED doivent être SEALED avant down migration (§5.7).
Q-279-05 Routes destruction concernées RÉSOLU : 3 routes listées exhaustivement — POST batches, POST execute, DELETE documents (§5.5).

Références

  • Epic : PD-279-iso14641-restituted
  • JIRA : PD-279
  • Repos concernés : ProbatioVault-backend (principal), ProbatioVault-doc (normes/TLA+)
  • Documents associés :
  • ProbatioVault-doc/docs/normes/iso-14641/formal/ISO_14641.tla
  • ISO 14641 §11.3
  • ISO 14641 §5.5.8
  • PD-250 (destruction), PD-251 (intégrité), PD-81 (SLA temporels)