PD-250 — Spécification — Job destruction définitive et bordereau (v4)¶
1. Objectif et conformité normative¶
Spécifier de manière contractuelle le processus automatique de destruction définitive des documents expirés, avec production d'un bordereau probatoire signé/horodaté, traçabilité unitaire et conservation permanente de la preuve, en conformité avec : - ISO 14641:2018 §11.4 (traçabilité, preuve de destruction, auditabilité), - NF Z42-013:2020 §9.2 (exigences de journalisation, intégrité et conservation des preuves), - Règlement eIDAS (UE) n°910/2014 art. 26 (signature qualifiée) et art. 42 (horodatage qualifié), - RFC 3161 (Time-Stamp Protocol), - RGPD (minimisation des données).
2. Périmètre / Hors périmètre¶
Inclus¶
- Automatisation de la destruction définitive des documents éligibles (base + objet S3).
- Fusion dans un même pipeline des documents expirés avec ou sans historique
legal_lock, sous réserve d'éligibilité complète. - Génération d'un bordereau consolidé par batch, au format PDF/A, signé électroniquement et horodaté RFC 3161.
- Traçabilité unitaire en audit log avec référence obligatoire au bordereau.
- Conservation sans limite de durée des bordereaux.
- Endpoint d'administration pour consultation des bordereaux (filtre date, batch), restreint aux rôles habilités
ADMIN. - Notification de préavis avant destruction automatique.
Exclu¶
- Modification des durées légales de rétention existantes.
- Restauration d'un document détruit.
- Refonte de la destruction manuelle utilisateur déjà existante.
- Migration rétroactive des destructions historiques antérieures à la mise en service.
- Zeroization cryptographique pour les destructions post-rétention standard (hors documents
legal_lock) : hors périmètre.
3. Définitions¶
- Document éligible à destruction : document satisfaisant simultanément les conditions d'éligibilité définies en section 4.
- Batch de destruction : ensemble des documents traités dans un run unique du job, associé à un identifiant unique de batch (
batchId, UUID). - Bordereau de destruction : preuve consolidée du batch, en PDF/A signé et horodaté RFC 3161.
- Traçabilité unitaire : entrée d'audit par document détruit, liée à l'identifiant du bordereau.
- Fail-closed : en cas d'échec de prérequis probatoire (signature, horodatage, intégrité), aucune destruction physique n'est autorisée.
- Convergence WORM : état où les contraintes de rétention DB et S3 Object Lock sont toutes expirées.
- Flux
legal_lock: un document appartient au fluxlegal_locksi unlegal_locklui a été assigné à un moment quelconque de son cycle de vie, qu'il soit actif ou expiré au moment de la destruction. Ce critère détermine l'obligation de zeroization cryptographique (cf. INV-250-12). - Données personnelles directes (liste fermée) : nom, prénom, email, adresse postale, numéro de téléphone, numéro de sécurité sociale, et toute donnée permettant l'identification directe d'une personne physique.
- Champs autorisés dans le bordereau :
batchId, horodatage run,documentIdtechnique, type documentaire, hash probatoire, date scellement, date expiration, date destruction prévue.
4. Invariants (non négociables)¶
| ID | Règle | Justification |
|---|---|---|
| INV-250-01 | Un document est destructible uniquement si rétention DB expirée ET rétention S3 Object Lock expirée ET (legal_lock absent OU expiré). | Conformité WORM + RGPD + sécurité juridique |
| INV-250-02 | Aucun document SEALED ou PENDING ne peut être ciblé. | Protection WORM |
| INV-250-03 | Aucune destruction physique (DB/S3) sans bordereau de batch signé + horodaté valide. | Fail-closed, ISO 14641:2018 §11.4, NF Z42-013:2020 §9.2 |
| INV-250-04 | Un batch produit exactement un bordereau consolidé. | Exigence métier OBJ-03 |
| INV-250-05 | Chaque destruction unitaire génère un audit log liant documentId, batchId, bordereauId. L'audit est mesurable : non-perte (tout événement émis est persisté via transaction ACID, cf. §10.4b), ordre causal (timestamps monotones croissants par document, garantis par une séquence PostgreSQL audit_seq incrémentale utilisée comme clé d'ordonnancement — l'horloge système n'est PAS le mécanisme de monotonie), complétude (exactement une entrée par document traité, incluant les documents en RECONCILIATION_FAILED avec type d'événement correspondant, cf. §10.5). | Traçabilité complète |
| INV-250-06 | Les bordereaux sont conservés indéfiniment : aucune date d'expiration de rétention assignée (retentionExpiry absent ou null). Ils ne sont jamais éligibles à la destruction automatique. | Preuve permanente NF Z42-013:2020 §9.2 |
| INV-250-07 | Le contenu du bordereau exclut les données personnelles directes (cf. §3, liste fermée); seuls les champs autorisés (cf. §3) sont inclus. | Résolution TENSION-01, RGPD |
| INV-250-08 | Le job est idempotent : un document déjà marqué DESTROYED ne peut jamais être retraité. L'identité d'un batch est son batchId (UUID). L'idempotence repose sur le statut DESTROYED comme marqueur terminal (pas sur un TTL de rejeu). | Robustesse opérationnelle |
| INV-250-09 | En échec TSA persistant après tsaRetryCount tentatives (défaut 3, configurable en §10.2), le batch est en échec bloquant et aucune destruction n'est exécutée. | Décision PO Q-04 |
| INV-250-10 | Toute erreur partielle est observable (audit + alerte) et reprise possible sans corruption d'état. Échec silencieux = non conforme. | Non-silence des échecs |
| INV-250-11 | Les transitions inverses sont interdites : DESTROYED→EXPIRED, EXPIRED→SEALED, SEALED→PENDING, DESTROYED→SEALED. | Irréversibilité légale |
| INV-250-12 | La destruction cryptographique (PD-81) est obligatoire uniquement pour documents du flux legal_lock; hors flux legal_lock, suppression physique seule. | Résolution TENSION-03 |
| INV-250-13 | Les noms de queue BullMQ ne contiennent pas :. | Compatibilité conventions existantes |
| INV-250-14 | Les API BullMQ dépréciées (getRepeatableJobs, removeRepeatableByKey) sont interdites. Seules getJobSchedulers/removeJobScheduler sont autorisées. | Conformité BullMQ v5 |
| INV-250-15 | L'endpoint admin bordereaux est restreint au rôle ADMIN. Toute requête sans habilitation est rejetée avec code d'erreur explicite et trace d'audit. | Sécurité, contrôle d'accès |
| INV-250-16 | Les SLA temporels (batchFinalizeSla, destructionExecutionSla, reconciliationSla) sont contractuels : tout dépassement déclenche le comportement spécifié en §10.3 (respectivement batch FAILED, batch PARTIAL_FAILED, RECONCILIATION_FAILED). | Observabilité, conformité opérationnelle |
5. Flux nominaux¶
5.1 Sélection éligible¶
Le job identifie les documents candidats selon INV-250-01, dans la limite du batchSize configuré. La sélection d'éligibilité applique clockSkewTolerance comme marge de sécurité soustractive : un document n'est considéré éligible que si sa date d'expiration + clockSkewTolerance est strictement inférieure à la date courante. Cette règle s'applique aux trois contrôles d'éligibilité (rétention DB, S3 Object Lock, legal_lock). La clockSkewTolerance ne s'applique PAS à la validation du jeton TSA (§5.3) : la vérification du jeton TSA utilise la tolérance horaire intégrée au protocole RFC 3161 (champ accuracy du jeton). La désynchronisation horloge applicatif/TSA est couverte par HYP-250-01 et l'attribut accuracy du jeton.
5.2 Prévalidation probatoire batch¶
Le système prépare le bordereau consolidé du batch avec les champs autorisés (cf. §3) : batchId, horodatage run, liste {documentId technique, type documentaire, hash probatoire, date scellement, date expiration, date destruction prévue}. Les données personnelles directes (cf. §3, liste fermée) sont interdites.
5.3 Scellement probatoire du bordereau¶
Le bordereau est produit en PDF/A, signé électroniquement par un service de signature qualifié (eIDAS art. 26) puis horodaté par un TSA qualifié (eIDAS art. 42, RFC 3161).
5.4 Validation fail-closed¶
Si signature/horodatage invalides ou absents, arrêt du batch sans destruction physique.
5.5 Destruction unitaire post-validation (ordonnancement en deux temps)¶
La suppression est orchestrée dans le même job BullMQ, document par document de manière séquentielle. La phase de suppression S3 démarre uniquement après validation complète du bordereau (pas pendant). Le pattern est séquentiel par document (pas de fire-and-forget). Le délai entre la validation du bordereau (§5.4) et le début de la destruction du premier document est borné par le SLA destructionExecutionSla (§10.3). Si ce SLA est dépassé avant le traitement du premier document, le batch passe en FAILED (pas PARTIAL_FAILED, car aucune destruction n'a eu lieu).
Pour chaque document du batch : 1. Suppression S3 : await sur l'opération de suppression (DeleteObject), avec retry contrôlé selon s3DeleteRetryCount. 2. Confirmation S3 : la confirmation est définie comme la réception d'un code HTTP 204 (No Content) de l'opération DeleteObject. S3 (OVH Object Storage) est eventually consistent — un objet peut rester temporairement lisible après un 204. Cette persistance physique résiduelle est un risque accepté (cf. §10.6). La confirmation 204 est suffisante pour autoriser la finalisation DB. 3. Finalisation DB synchrone par unité : suppression de la référence DB et marquage final DESTROYED, uniquement après confirmation S3 (HTTP 204). L'audit log est inséré dans la même transaction DB (cf. §10.4b).
Si un document devient non éligible entre la sélection et son traitement unitaire (ex: re-scellement d'urgence → SEALED), le document est exclu de la destruction avec audit d'anomalie, et le batch continue sans lui (cf. ERR-250-03).
Pour les documents du flux legal_lock (cf. §3, définition), la séquence de destruction est strictement ordonnancée : 1. Zeroization cryptographique (PD-81) : await sur la confirmation de zeroization. 2. Suppression S3 : uniquement après confirmation de zeroization réussie. 3. Finalisation DB : après confirmation S3 (HTTP 204). Si la zeroization échoue, le document n'est PAS supprimé de S3 (fail-closed). Cette séquence garantit l'auditabilité de la zeroization avant la disparition physique de l'objet.
5.6 Journalisation unitaire¶
Écriture d'un audit log par document avec référence du bordereau. L'audit respecte les propriétés mesurables : non-perte, ordre causal, complétude (cf. INV-250-05).
5.7 Conservation du bordereau¶
Le bordereau est stocké en tant que document probatoire à conservation indéfinie (retentionExpiry absent/null, cf. INV-250-06). La protection physique du bordereau est assurée par : (1) la protection WORM PostgreSQL (triggers SECURITY DEFINER existants, empêchant modification/suppression), (2) le statut SEALED sans date d'expiration (jamais éligible à la destruction automatique), (3) Object Lock COMPLIANCE sur S3 avec rétention maximale supportée par le provider (configuration d'exploitation, cf. HYP-250-04).
5.8 Notification de préavis¶
Le préavis de destruction est émis comme événement applicatif sur le bus d'événements interne. Le contenu est limité aux identifiants techniques : documentId, date d'éligibilité prévue, preNoticeDays. Le destinataire direct est le bus d'événements ; le routage vers les canaux finaux (email, webhook) est hors périmètre de cette story (cf. HYP-250-08).
Déclencheur : le préavis est émis par un job BullMQ dédié de préavis (distinct du job de destruction), exécuté quotidiennement. Il sélectionne les documents dont la date d'éligibilité est à J+N (avec N = preNoticeDays).
Cas N=0 : avec preNoticeDays=0, le préavis est émis le jour même de l'éligibilité, avant le run du job de destruction (le job de préavis s'exécute en premier dans la séquence). Le préavis N=0 a valeur de notification informative « jour J », pas de délai de préavis effectif. L'intervalle entre préavis et destruction est la différence de scheduling entre les deux jobs (typiquement quelques heures, configurable).
5.9 Machine à états du batch et reprise¶
États d'un batch : PENDING → RUNNING → (SUCCESS | PARTIAL_FAILED | FAILED).
- Les états
SUCCESS,PARTIAL_FAILED,FAILEDsont finaux pour le batch courant : aucune transition retour n'est autorisée (un batchFAILEDne peut jamais devenirSUCCESS). Le terme « terminal » signifie que le batch lui-même ne change plus d'état. Il ne signifie PAS que les documents non détruits sont abandonnés. - Reprise après
PARTIAL_FAILED: la reprise crée un nouveau batch (nouveaubatchId) qui sélectionne uniquement les documents encore non-DESTROYEDdu batch d'origine. Le batch d'origine reste enPARTIAL_FAILED(pas de modification rétroactive). La traçabilité de la filiation est assurée par un champparentBatchIdobligatoire dans l'audit log du nouveau batch, référençant lebatchIdd'origine. Ce champ est absent (null) pour les batches initiaux (sans parent). - Reprise après
FAILED: idem, nouveau batch avecparentBatchIdobligatoire. Un batchFAILEDavant toute destruction ne produit que des documents non-DESTROYED, tous reprisables.
5.10 Publication de résultat batch¶
À la fin de chaque batch, l'état final est publié avec métriques agrégées (nombre de documents traités/détruits/en erreur, durée totale) et alertes (si erreurs). Les métriques sont publiées sur le bus d'événements interne avec restriction d'accès : seuls les consumers avec rôle ADMIN ou SYSTEM peuvent consommer les événements de type batch_result. Le contenu des métriques exclut les identifiants de documents individuels (seuls les compteurs agrégés sont publiés).
5bis. Diagrammes Mermaid¶
5bis.1 Machine à états — Document (INV-250-11, §10.5)¶
stateDiagram-v2
[*] --> PENDING
PENDING --> SEALED : scellement probatoire
SEALED --> EXPIRED : rétention DB + S3 expirées
EXPIRED --> DESTROYED : destruction confirmée (S3 204 + finalisation DB)
EXPIRED --> RECONCILIATION_FAILED : échec réconciliation post-crash (ERR-250-05)
RECONCILIATION_FAILED --> [*] : état terminal — résolution manuelle uniquement
DESTROYED --> [*] : état terminal
note right of PENDING : INV-250-02 — PENDING\nne peut être ciblé\npar la destruction
note right of SEALED : INV-250-02 — SEALED\nne peut être ciblé\npar la destruction
note left of RECONCILIATION_FAILED : S3 supprimé mais\nfinalisation DB échouée\naprès reconciliationDbRetryCount retries
%% Transitions inverses INTERDITES (INV-250-11)
%% DESTROYED → EXPIRED : INTERDITE
%% DESTROYED → SEALED : INTERDITE
%% EXPIRED → SEALED : INTERDITE
%% SEALED → PENDING : INTERDITE
%% RECONCILIATION_FAILED → * : INTERDITE 5bis.2 Machine à états — Batch (§5.9)¶
stateDiagram-v2
[*] --> PENDING : création batch (batchId UUID)
PENDING --> RUNNING : démarrage job BullMQ
RUNNING --> SUCCESS : tous documents détruits
RUNNING --> PARTIAL_FAILED : au moins un document en échec (ERR-250-03, ERR-250-04)
RUNNING --> FAILED : échec bloquant (ERR-250-01, ERR-250-02, ERR-250-06, INV-250-09)
SUCCESS --> [*] : état final
PARTIAL_FAILED --> [*] : état final — reprise via nouveau batch (parentBatchId)
FAILED --> [*] : état final — reprise via nouveau batch (parentBatchId)
note right of FAILED : INV-250-03 — aucune\ndestruction si bordereau\nnon validé
note left of PARTIAL_FAILED : Reprise crée un nouveau\nbatch avec parentBatchId\nobligatoire (§5.9) 5bis.3 Séquence — Destruction nominale d'un batch (§5.1→§5.7)¶
sequenceDiagram
autonumber
participant Job as Job BullMQ<br/>(destruction)
participant DB as PostgreSQL
participant S3 as OVH S3<br/>(Object Storage)
participant Sign as Service Signature<br/>(eIDAS art. 26)
participant TSA as TSA qualifié<br/>(RFC 3161)
participant Bus as Bus événements
Note over Job,DB: §5.1 — Sélection éligible (INV-250-01)
Job->>DB: SELECT documents éligibles<br/>(rétention DB + S3 expirées, legal_lock absent/expiré)<br/>clockSkewTolerance appliquée
DB-->>Job: liste candidats (≤ batchSize)
Note over Job,Sign: §5.2–§5.3 — Prévalidation + scellement probatoire
Job->>Job: génération bordereau PDF/A<br/>(champs autorisés §3, INV-250-07)
Job->>Sign: signature qualifiée du bordereau
Sign-->>Job: bordereau signé
Job->>TSA: horodatage RFC 3161
TSA-->>Job: jeton TSA
Note over Job: §5.4 — Validation fail-closed (INV-250-03)
alt signature/horodatage invalide
Job->>DB: batch → FAILED, aucune destruction
end
Note over Job,S3: §5.5 — Destruction unitaire post-validation
loop pour chaque document du batch (séquentiel)
Job->>S3: DeleteObject (await, retry ≤ s3DeleteRetryCount)
S3-->>Job: HTTP 204 (confirmation)
Job->>DB: BEGIN transaction
Job->>DB: suppression référence + marquage DESTROYED
Job->>DB: INSERT audit log (documentId, batchId, bordereauId) — INV-250-05
Job->>DB: COMMIT
end
Note over Job,DB: §5.7 — Conservation bordereau (INV-250-06)
Job->>DB: persistance bordereau (retentionExpiry = null)
Job->>S3: stockage bordereau (Object Lock COMPLIANCE)
Note over Job,Bus: §5.10 — Publication résultat
Job->>Bus: événement batch_result<br/>(métriques agrégées, accès ADMIN/SYSTEM) 5bis.4 Séquence — Destruction flux legal_lock (INV-250-12, §5.5)¶
sequenceDiagram
autonumber
participant Job as Job BullMQ
participant Crypto as Zeroization<br/>(PD-81)
participant S3 as OVH S3
participant DB as PostgreSQL
Note over Job: Document du flux legal_lock détecté<br/>(INV-250-12 — zeroization obligatoire)
Job->>Crypto: zeroization cryptographique (await)
alt zeroization échouée
Crypto-->>Job: échec
Note over Job,S3: fail-closed — document NON supprimé de S3
Job->>DB: audit anomalie zeroization
else zeroization réussie
Crypto-->>Job: confirmation
Job->>S3: DeleteObject (await)
S3-->>Job: HTTP 204
Job->>DB: BEGIN transaction
Job->>DB: suppression référence + DESTROYED
Job->>DB: INSERT audit log (documentId, batchId, bordereauId)
Job->>DB: COMMIT
end 6. Cas d'erreur¶
- ERR-250-01 — TSA indisponible/timeout : 3 tentatives, puis
FAILED; destruction interdite. - ERR-250-02 — Signature invalide :
FAILED; destruction interdite. - ERR-250-03 — Document non éligible détecté en cours de run : document exclu, événement d'audit d'anomalie, batch continue sans ce document. L'état final du batch est
PARTIAL_FAILED(car au moins un document sélectionné n'a pas été détruit). Un document exclu pour ERR-250-03 conserve son état courant (ex:SEALEDsi re-scellé) et n'est pas comptabilisé comme « détruit ». - ERR-250-04 — S3 injoignable après prévalidation : document en échec unitaire, batch
PARTIAL_FAILED, reprise idempotente obligatoire. - ERR-250-05 — Échec suppression DB après suppression S3 : anomalie critique, traçabilité obligatoire. Réconciliation vers état terminal contractuel :
DESTROYEDsi S3 confirmé supprimé et DB nettoyée,RECONCILIATION_FAILEDsi DB échoue aprèsreconciliationDbRetryCountretries (escalade obligatoire). Délai borné parreconciliationSla. - ERR-250-06 — Bordereau non persistant : rollback logique du batch, aucune destruction autorisée.
- ERR-250-07 — Échec silencieux interdit : absence d'audit/alerte = non conforme. Si chaîne d'audit indisponible, arrêt fail-closed du job + alerte immédiate.
- ERR-250-08 — Dépassement de bornes de configuration : rejet de configuration au démarrage du job, aucun traitement, alerte.
7. Critères d'acceptation (testables)¶
| ID | Critère | Observable |
|---|---|---|
| CA-250-01 | Le job ne détruit que des documents satisfaisant toutes les conditions d'éligibilité. | Journal d'exécution + audit des filtres |
| CA-250-02 | Un batch réussi génère exactement un bordereau PDF/A signé+horodaté valide. | Artefact bordereau + vérification signature/TSA |
| CA-250-03 | Aucune destruction n'a lieu si le bordereau n'est pas validé. | Zéro transition DESTROYED en cas d'échec probatoire |
| CA-250-04 | Chaque document détruit a une trace d'audit unitaire liée au bordereau, respectant non-perte, ordre causal et complétude. | Audit log corrélé documentId/batchId/bordereauId |
| CA-250-05 | Les bordereaux restent accessibles sans limite temporelle (retentionExpiry absent/null, non ciblés par le job). | Lecture API admin sur bordereaux historiques + absence de sélection |
| CA-250-06 | Les données personnelles directes (cf. §3 liste fermée) ne figurent pas dans le bordereau. | Contrôle de schéma bordereau vs liste fermée |
| CA-250-07 | Le retry TSA est de tsaRetryCount tentatives max (défaut 3, cf. §10.2), puis arrêt fail-closed. | Logs retry + statut batch FAILED |
| CA-250-08 | Le traitement est idempotent : un document DESTROYED n'est jamais retraité. | Absence de double destruction/audit doublon interdit |
| CA-250-09 | Les documents avec legal_lock actif ne sont jamais détruits. | Tests de sélection |
| CA-250-10 | Endpoint admin retourne les bordereaux filtrables par date et batch. | Réponse API conforme aux filtres |
| CA-250-11 | Préavis N jours est émis avant destruction automatique (y compris N=0 = jour J avant exécution). | Traces notification horodatées |
| CA-250-12 | Les transitions inverses (DESTROYED→EXPIRED, EXPIRED→SEALED, SEALED→PENDING, DESTROYED→SEALED) sont rejetées. | Tentatives de rollback en erreur explicite |
| CA-250-13 | Les noms de queue BullMQ ne contiennent pas :. | Test contractuel de configuration |
| CA-250-14 | Les API BullMQ dépréciées sont absentes du code. Seules getJobSchedulers/removeJobScheduler sont utilisées. | Scan statique CI |
| CA-250-15 | L'endpoint admin bordereaux est accessible uniquement au rôle ADMIN. Requête non autorisée → rejet 403 + trace d'audit. | Test d'accès refusé |
| CA-250-16 | Le dépassement de chaque SLA temporel (§10.3) déclenche le comportement contractualisé : batchFinalizeSla → FAILED, destructionExecutionSla → PARTIAL_FAILED, reconciliationSla → RECONCILIATION_FAILED. | Statut batch/document après timeout |
8. Scénarios de test (Given / When / Then)¶
-
ST-250-01 — Batch nominal : Given des documents éligibles complets. When le job s'exécute. Then un bordereau valide est généré, les documents passent à
DESTROYED, et chaque trace unitaire référence le bordereau. -
ST-250-02 — TSA en échec persistant : Given des documents éligibles et TSA indisponible. When le job tente la signature/horodatage 3 fois. Then le batch est
FAILEDet aucun document n'est détruit. -
ST-250-03 — legal_lock actif : Given un document avec
legal_locknon expiré. When le job filtre les candidats. Then le document est exclu avec trace d'exclusion. -
ST-250-04 — Rétention S3 non expirée : Given rétention DB expirée mais S3 Object Lock actif. When le job évalue l'éligibilité. Then destruction refusée, document maintenu hors
DESTROYED. -
ST-250-05 — Reprise idempotente après panne partielle : Given panne S3 pendant un batch partiellement traité. When le job est relancé. Then seuls les documents non convergés sont retraités sans doublon.
-
ST-250-06 — Contrôle RGPD du bordereau : Given un bordereau produit. When son contenu est inspecté. Then aucune donnée personnelle directe (cf. §3) n'est présente, uniquement les champs probatoires autorisés.
-
ST-250-07 — Flux legal_lock expiré : Given un document avec
legal_lockexpiré et autres verrous expirés. When le job exécute la destruction. Then la destruction inclut l'étape cryptographique obligatoire et la trace associée. -
ST-250-08 — Transition inverse interdite : Given un document
DESTROYED. When une transition versEXPIREDouSEALEDest demandée. Then la requête est rejetée avec erreur métier. -
ST-250-09 — Endpoint admin non autorisé : Given un utilisateur sans rôle
ADMIN. When il appelle l'endpoint de consultation des bordereaux. Then accès refusé (403), aucun contenu renvoyé, trace d'audit. -
ST-250-10 — Configuration hors bornes : Given une configuration avec paramètre hors bornes. When le job démarre. Then erreur de validation, aucun traitement, alerte.
9. Hypothèses explicites¶
| ID | Hypothèse | Impact si faux |
|---|---|---|
| HYP-250-01 | Les horloges systèmes sont synchronisées (tolérance max définie en §10.2). | Invalidité de fenêtres SLA et timestamps probatoires |
| HYP-250-02 | Le service TSA est joignable sur la fenêtre de job. | Batchs en échec fail-closed répétés |
| HYP-250-03 | Les métadonnées probatoires minimales (hash, dates, type) existent pour chaque document. | Document non destructible automatiquement |
| HYP-250-04 | Le stockage des bordereaux dispose d'une politique de conservation indéfinie effective (retentionExpiry absent/null). | Non-conformité NF Z42-013:2020 §9.2 |
| HYP-250-05 | Les notifications de préavis disposent d'un canal opérationnel. | Préavis non délivré, anomalie de conformité opérationnelle |
| HYP-250-06 | Les contraintes WORM DB et S3 sont vérifiables au moment de la sélection. | Risque de faux positifs d'éligibilité |
| HYP-250-07 | Le TSP utilisé pour signature et TSA est qualifié eIDAS (listé UE Trust List). Si faux, destruction non conforme, blocage mise en production. | Non-conformité eIDAS, invalidité probatoire |
| HYP-250-08 | Un consumer du bus d'événements existe pour router les préavis de destruction vers les canaux finaux (email, webhook). Ce routage est hors périmètre de cette story. | Préavis émis mais non délivré aux utilisateurs finaux |
10. Contraintes techniques¶
10.1 Stack technique cible (obligatoire)¶
Projet cible : ProbatioVault-backend Stack contractuelle : NestJS + TypeORM + PostgreSQL + BullMQ v5 + S3 (OVH Object Storage)
Toute spécification incompatible avec cette stack est non conforme.
10.2 Paramètres numériques contractualisés¶
| Paramètre | Valeur par défaut | Min | Max | Unité | Comportement hors bornes |
|---|---|---|---|---|---|
destructionBatchSize | 500 | 1 | 5000 | documents | rejet de configuration + alerte |
destructionJobInterval | 24 | 1 | 168 | heures | rejet de configuration + alerte |
preNoticeDays | 30 | 0 | 365 | jours | rejet de configuration + alerte |
tsaRetryCount | 3 | 0 | 5 | tentatives | clamp interdit, rejet requis |
tsaTimeout | 5000 | 1000 | 30000 | ms | rejet de configuration + alerte |
signatureTimeout | 10000 | 1000 | 60000 | ms | rejet de configuration + alerte |
s3DeleteRetryCount | 5 | 0 | 10 | tentatives | rejet de configuration + alerte |
s3DeleteTimeout | 10000 | 1000 | 60000 | ms | rejet de configuration + alerte |
clockSkewTolerance | 5 | 1 | 60 | secondes | rejet de configuration + alerte |
reconciliationDbRetryCount | 3 | 1 | 10 | tentatives | rejet de configuration + alerte |
10.3 SLA temporels contractuels¶
| Paramètre | Valeur par défaut | Borne minimale | Borne maximale | Configurabilité | Comportement à expiration |
|---|---|---|---|---|---|
Préavis destruction (preNoticeDays) | 30j | 0j | 365j | via configuration | notification émise puis éligibilité inchangée |
Fenêtre max de finalisation d'un batch (batchFinalizeSla) | 2h | 5min | 24h | via configuration | batch FAILED + alerte critique |
Délai max de réconciliation post-crash (reconciliationSla) | 24h | 1h | 168h | via configuration | RECONCILIATION_FAILED + escalade critique |
Délai max entre bordereau validé et destruction unitaire (destructionExecutionSla) | 30min | 1min | 24h | via configuration | batch PARTIAL_FAILED + reprise |
10.4 Atomicité multi-composant¶
| Scope | Synchrone/Async | Garantie |
|---|---|---|
| Validation d'éligibilité + préparation bordereau | Synchrone | Cohérence de sélection |
| Signature + horodatage bordereau | Synchrone | Précondition bloquante (fail-closed) |
| Suppression S3 | Async post-validation | Idempotent, retry-safe (cf. §5.5 ordonnancement deux temps) |
Finalisation DB / marquage DESTROYED | Synchrone par unité, après confirmation S3 | Atomicité unitaire (cf. §5.5) |
| Audit log unitaire | Transactionnel : inséré dans la même transaction DB que la finalisation DESTROYED (cf. §10.4b) | Non-perte, ordre causal, complétude |
| Crash pré-validation bordereau | — | Aucun document détruit |
| Crash post-validation et en cours de destruction | — | Reprise par réconciliation vers état terminal contractuel (cf. ERR-250-05) |
10.4b Mécanisme de non-perte audit log (contractuel)¶
Le mécanisme de non-perte est garanti par écriture transactionnelle dans la même transaction DB que la finalisation de l'état DESTROYED. L'audit log est inséré avant le commit de transition d'état. En cas d'échec de la transaction, ni l'état ni l'audit ne sont persistés (atomicité ACID). Ce mécanisme élimine l'ambiguïté sync/async pour l'audit.
10.5 Modèle d'états et transitions¶
États d'un document : PENDING, SEALED, EXPIRED, DESTROYED, RECONCILIATION_FAILED.
- Transitions nominales :
PENDING → SEALED → EXPIRED → DESTROYED. - Transition de réconciliation :
EXPIRED → RECONCILIATION_FAILED(uniquement en cas d'échec de réconciliation post-crash, cf. ERR-250-05).RECONCILIATION_FAILEDest un état terminal de document (pas de batch). Un document enRECONCILIATION_FAILEDa été supprimé physiquement sur S3 mais la finalisation DB a échoué aprèsreconciliationDbRetryCountretries. C'est un état d'anomalie nécessitant une escalade obligatoire. - Transitions retour (toutes INTERDITES, alignées avec INV-250-11) :
SEALED → PENDING: INTERDITEEXPIRED → SEALED: INTERDITEDESTROYED → EXPIRED: INTERDITEDESTROYED → SEALED: INTERDITERECONCILIATION_FAILED → *: INTERDITE (état terminal, résolution manuelle uniquement)- Toute tentative de transition inverse doit échouer explicitement et être auditée.
Complétude audit pour RECONCILIATION_FAILED : un document en RECONCILIATION_FAILED DOIT avoir une entrée d'audit de type RECONCILIATION_FAILED (pas DESTROYED). L'invariant INV-250-05 (complétude = exactement une entrée par document traité) s'applique avec le type d'événement correspondant à l'état terminal effectif.
10.6 Résolution contractuelle des tensions¶
- TENSION-01 (granularité bordereau) : le bordereau contient uniquement les champs autorisés (cf. §3) ; aucune donnée personnelle directe (cf. §3, liste fermée).
- TENSION-02 (DB vs S3 convergence) : stratégie de convergence stricte;
DESTROYEDuniquement après expiration des deux rétentions et destruction effective des deux supports. Réconciliation vers état terminal contractuel (cf. ERR-250-05). - TENSION-03 (zeroization) : obligatoire pour flux
legal_lock(cf. §3, définition); hors fluxlegal_lock, suppression physique seule (zeroization hors périmètre). - Risque résiduel accepté : après suppression logique S3, la persistance physique résiduelle sur les supports du provider (OVH) est acceptée. La zeroization cryptographique (INV-250-12) couvre les documents à fort enjeu juridique (flux
legal_lock). Pour les documents standard, le risque est considéré acceptable au regard du rapport coût/bénéfice. Cette décision est traçable dans le besoin PD-250.
11. Références normatives¶
- ISO 14641:2018 §11.4 — Exigences de traçabilité et preuve des opérations de destruction.
- NF Z42-013:2020 §9.2 — Exigences relatives aux journaux, intégrité et auditabilité probatoire.
- Règlement eIDAS (UE) n°910/2014 art. 26 (signature électronique qualifiée), art. 42 (horodatage qualifié).
- RFC 3161 — Time-Stamp Protocol (champs obligatoires du jeton TSA).
- RGPD (UE) 2016/679 — Minimisation des données (art. 5.1.c).
Références projet¶
- Epic : PD-217 LEGAL & COMPLIANCE
- JIRA : PD-250
- Repos concernés : ProbatioVault-backend
- Documents associés : PD-250-besoin.md