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¶
- L'enum
DocumentStatuscontient l'étatRESTITUTED - La migration TypeORM est réversible (up/down)
POST /documents/:id/restituteretourne 200 si gardes satisfaites, 409 sinonPOST /documents/:id/return-from-restitutionretourne 200 si gardes satisfaites, 409 sinon- Chaque transition crée une attestation dans
lifecycle_log - La destruction d'un document RESTITUTED retourne HTTP 409
- L'ASSUME TLA+
AnchorAssume_Statespasse après implémentation - Tests unitaires couvrent les transitions valides et invalides
- Tests d'intégration couvrent le cycle complet SEALED → RESTITUTED → SEALED
- 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 : - SEALED → RESTITUTED (F-279-02 : restitution) - RESTITUTED → SEALED (F-279-03 : retour de restitution)
Transitions existantes (PD-250, PD-80) : - PENDING → SEALED (scellement — PD-80) - SEALED → EXPIRED (expiration SLA — job planifié PD-250) - EXPIRED → DISPOSED (destruction — PD-250)
Transition interdite : - RESTITUTED → DISPOSED (F-279-05 : garde ISO)
Architecture existante¶
- Entité :
DocumentSecure(src/modules/documents/entities/document-secure.entity.ts) - Enum actuel :
DocumentStatus(PENDING, SEALED, EXPIRED) → étendu avecRESTITUTED - Module download :
src/modules/documents/download/ - Module destruction :
src/modules/destruction/ - Module intégrité :
src/modules/integrity/