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
RESTITUTEDau cycle de vie documentaire. - Transition
SEALED -> RESTITUTEDviaPOST /documents/:id/restitute. - Transition retour
RESTITUTED -> SEALEDviaPOST /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_loget 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 -> EXPIREDet 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_atetrestitution_deadlinerenseignés, attestationRESTITUTIONcréée. -
ST-279-02 Restitution refusée copies insuffisantes
- Given un document
SEALEDavecgeo_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
SEALEDaveclegal_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
SEALEDappartenant à un autre utilisateur - When
POST /documents/:id/restitute -
Then HTTP 403.
-
ST-279-05 Retour nominal
- Given un document
RESTITUTEDdont l’appelant est owner - When
POST /documents/:id/return-from-restitution -
Then HTTP 200, statut
SEALED, attestationRETURN_FROM_RESTITUTIONcréé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
RESTITUTEDavec 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)