Aller au contenu

PD-279 — Expression de besoin

User Story

En tant que responsable d'archives numériques, je veux pouvoir restituer un document archivé (état SEALED) à son originateur conformément à l'ISO 14641 §11.3, afin que le cycle de vie complet du document soit traçable et que l'ASSUME TLA+ AnchorAssume_States soit satisfait.

Contexte

Origine

L'audit de vérification formelle du 2026-03-01 a détecté un écart entre le modèle TLA+ ISO 14641 et l'implémentation backend. Le modèle définit 4 états (CAPTURED, ARCHIVED, RESTITUTED, DISPOSED) mais le code n'en implémente que 3 (PENDING→CAPTURED, SEALED→ARCHIVED, EXPIRED→DISPOSED). L'état RESTITUTED est absent, provoquant l'échec de l'ASSUME AnchorAssume_States (ligne 22 du modèle TLA+).

Référence normative

  • ISO 14641 §11.3 : Restitution des documents archivés — retour du document à son originateur
  • ISO 14641 §5.5.8 : Exigence de copies géo-distribuées (≥ 2 copies) avant restitution
  • Modèle TLA+ : ProbatioVault-doc/docs/normes/iso-14641/formal/ISO_14641.tla (lignes 198-213)

Learnings injectés

  • PD-250 (#iso14641, #legal-compliance) : Modéliser les états formels de documents, contractualiser confirmation S3 + séquence PostgreSQL monotone pour audit trail
  • PD-81 (#legal-pre, #eidas) : SLA temporels exhaustifs pour chaque transition d'état (min/max/default)

Périmètre fonctionnel

F-279-01 : Nouvel état RESTITUTED

Ajouter l'état RESTITUTED dans l'enum DocumentStatus et créer la migration TypeORM correspondante. Cet état représente un document archivé temporairement restitué à son originateur.

F-279-02 : Endpoint de restitution

POST /documents/:id/restitute — Transition SEALED → RESTITUTED.

Gardes : - Le document DOIT être en état SEALED - Le nombre de copies géo-distribuées DOIT être ≥ 2 (INV-04 du modèle TLA+, ISO §5.5.8) - L'appelant DOIT être le propriétaire du document (owner) - Le document ne DOIT PAS être en legal_lock

Effets : - Transition du statut vers RESTITUTED - Création d'une attestation dans lifecycle_log : timestamp UTC, acteur, security_level, type=RESTITUTION - Log d'audit (JournalEventType)

F-279-03 : Endpoint de retour de restitution

POST /documents/:id/return-from-restitution — Transition RESTITUTED → SEALED.

Gardes : - Le document DOIT être en état RESTITUTED - L'appelant DOIT être le propriétaire du document

Effets : - Transition du statut vers SEALED - Création d'une attestation dans lifecycle_log : timestamp UTC, acteur, type=RETURN_FROM_RESTITUTION - Log d'audit (JournalEventType)

F-279-04 : SLA temporels de restitution

  • Durée maximale de restitution : configurable (défaut 30 jours)
  • Champ restituted_at (timestamp) sur l'entité document
  • Champ restitution_deadline (calculé = restituted_at + SLA max)
  • Job planifié : alerte à 80% du SLA, escalade à 100%

F-279-05 : Garde ISO — interdiction de destruction

Un document en état RESTITUTED ne DOIT PAS pouvoir être détruit (DISPOSED). Le module destruction (PD-250) DOIT rejeter les documents en état RESTITUTED avec HTTP 409 Conflict.

Hors périmètre (stubs)

  • DISPOSED formel : PD-250 a traité la destruction en soft-delete ; formalisation de l'état DISPOSED en story future
  • NF Z42-013 DIP : PD-278 (story séparée)
  • Restitution multi-destinataire : hors ISO 14641, story future si besoin métier

Critères d'acceptation

  1. L'enum DocumentStatus contient l'état RESTITUTED
  2. La migration TypeORM est réversible (up/down)
  3. POST /documents/:id/restitute retourne 200 si gardes satisfaites, 409 sinon
  4. POST /documents/:id/return-from-restitution retourne 200 si gardes satisfaites, 409 sinon
  5. Chaque transition crée une attestation dans lifecycle_log
  6. La destruction d'un document RESTITUTED retourne HTTP 409
  7. L'ASSUME TLA+ AnchorAssume_States passe après implémentation
  8. Tests unitaires couvrent les transitions valides et invalides
  9. Tests d'intégration couvrent le cycle complet SEALED → RESTITUTED → SEALED
  10. RLS : un utilisateur non-propriétaire ne peut pas restituer un document d'un autre utilisateur

Dépendances

Story Relation Statut
PD-250 Destruction bordereau (DISPOSED partiel) DONE
PD-251 Intégrité archives (orthogonal) DONE
PD-278 NF Z42-013 DIP (hors périmètre) PENDING
PD-63 Download endpoint (existant) DONE

Machine d'états documentaire (cycle de vie complet ISO 14641)

Transitions contractualisées dans ce besoin : - SEALEDRESTITUTED (F-279-02 : restitution) - RESTITUTEDSEALED (F-279-03 : retour de restitution)

Transitions existantes (PD-250, PD-80) : - PENDINGSEALED (scellement — PD-80) - SEALEDEXPIRED (expiration SLA — job planifié PD-250) - EXPIREDDISPOSED (destruction — PD-250)

Transition interdite : - RESTITUTEDDISPOSED (F-279-05 : garde ISO)

Architecture existante

  • Entité : DocumentSecure (src/modules/documents/entities/document-secure.entity.ts)
  • Enum actuel : DocumentStatus (PENDING, SEALED, EXPIRED) → étendu avec RESTITUTED
  • Module download : src/modules/documents/download/
  • Module destruction : src/modules/destruction/
  • Module intégrité : src/modules/integrity/