PD-101 — Décomposition d'implémentation¶
Méta¶
- Story : PD-101 — Upload probatoire mobile chiffré
- Date : 2026-03-10
- Mode : Exécution unifiée (claude -p a produit T1-T13 en une passe)
- Branche :
feature/PD-101-upload-document-progress
Architecture des modules¶
src/
types/upload.ts ← T1 : Branded types, enums, constantes
services/upload/
uploadPurge.ts ← T2 : purgeStale + nullifyMemoryRefs
uploadCrypto.ts ← T3 : SHA3-256 + AES-256-GCM FILE-LEVEL
uploadNetwork.ts ← T4 : init/simple/multipart/finalize/cancel
uploadRetry.ts ← T5 : withRetry + backoff + jitter CSPRNG
uploadProgress.ts ← T6 : ProgressTracker (percent, speed, ETA)
uploadCancel.ts ← T7 : cancelCurrentUpload orchestré
uploadOrchestrator.ts ← T9 : Flux principal séquencé
uploadBackground.ts ← T10 : URLSession background + notification
uploadAudit.ts ← T11 : Audit fire-and-forget + sanitizer
index.ts ← Barrel re-exports
store/useUploadStore.ts ← T8 : Zustand state machine stricte
components/upload/
ExifDisclaimerSheet.tsx ← T12 : Bottom sheet EXIF
TranscodingWarningSheet.tsx ← T12 : Bottom sheet transcodage iOS
OptimizedConsentSheet.tsx ← T12 : Consent mode optimisé
UploadProgressBar.tsx ← T12 : Barre de progression
UploadStatusBadge.tsx ← T12 : Badge état upload
screens/vault/UploadDocumentScreen.tsx ← T12 : Écran principal (modifié)
i18n/locales/{fr,en}/upload.json ← T12 : Traductions upload
Manifest des tâches (T1-T13)¶
| # | Contract | Module | Agent | Description |
|---|---|---|---|---|
| T1 | CC-101-T1 | types/upload.ts | agent-developer | Branded types DocId/Sha3Hash, UploadUIState, constantes contractuelles |
| T2 | CC-101-T2 | uploadPurge.ts | agent-developer | purgeStale() INV-07, purgeCurrentFlowArtifacts, nullifyMemoryRefs |
| T3 | CC-101-T3 | uploadCrypto.ts | agent-developer | SHA3-256 hash + AES-256-GCM FILE-LEVEL + vérification intégrité |
| T4 | CC-101-T4 | uploadNetwork.ts | agent-developer | init backend, upload simple/multipart, finalize, cancel, abort |
| T5 | CC-101-T5 | uploadRetry.ts | agent-developer | withRetry + backoff [1000,2000,4000] + jitter CSPRNG obligatoire |
| T6 | CC-101-T6 | uploadProgress.ts | agent-developer | ProgressTracker (percent, speed, ETA, timestamps) |
| T7 | CC-101-T7 | uploadCancel.ts | agent-developer | cancelCurrentUpload orchestré (abort + backend + store + audit) |
| T8 | CC-101-T8 | useUploadStore.ts | agent-developer | Zustand store, transitions strictes INV-09, COMPLETED/CANCELLED terminaux |
| T9 | CC-101-T9 | uploadOrchestrator.ts | agent-developer | Flux principal : purge→validate→hash→encrypt→init→upload→finalize |
| T10 | CC-101-T10 | uploadBackground.ts | agent-developer | URLSession background task + local notification |
| T11 | CC-101-T11 | uploadAudit.ts | agent-developer | Audit events fire-and-forget + sanitizer deny-list INV-10 |
| T12 | CC-101-T12 | components/upload/* | agent-developer | 5 composants UI + écran + i18n |
| T13 | CC-101-T13 | __tests__/** | agent-qa | 10 fichiers test (36 TC-* couverts) |
Parallelization¶
strategy: sequential
reason: "Exécution unifiée — claude -p a produit T1-T13 en une seule passe (111KB prompt)"
Couverture Invariants → Modules¶
| INV | Module(s) | Mécanisme |
|---|---|---|
| INV-01 | uploadNetwork, uploadOrchestrator | Payload = ciphertext uniquement, encrypt avant tout appel réseau |
| INV-02 | uploadCrypto, uploadOrchestrator | FILE-LEVEL AES-256-GCM complet, aucun appel réseau avant fin encrypt |
| INV-03 | uploadCrypto | Hash sur fichier soumis, aucune transformation |
| INV-05 | uploadCrypto | Recalcul hash post-chiffrement, divergence → ERR-02 |
| INV-06 | uploadCrypto | Un seul nonce 12 bytes CSPRNG par doc_id |
| INV-07 | uploadPurge, uploadOrchestrator | purgeStale() en première étape du flux |
| INV-08 | uploadRetry | Backoff [1000, 2000, 4000] + jitter CSPRNG |
| INV-09 | useUploadStore | Transitions strictes, COMPLETED/CANCELLED terminaux |
| INV-10 | uploadAudit | Sanitizer deny-list, REDACTED sur patterns sensibles |
Couverture CA → Modules¶
| CA | Module(s) |
|---|---|
| CA-01 | uploadOrchestrator (flux complet) |
| CA-02 | uploadProgress, UploadProgressBar |
| CA-03 | uploadRetry, uploadNetwork |
| CA-04 | uploadCancel |
| CA-05 | uploadOrchestrator (validation taille) |
| CA-06 | uploadNetwork (selectUploadStrategy) |
| CA-07 | uploadRetry (withRetry) |
| CA-08 | uploadBackground |
| CA-09 | uploadCrypto, UploadDocumentScreen |
| CA-10 | UploadDocumentScreen (transcoding detection) |
| CA-11 | uploadAudit (REDACTED) |
| CA-12 | uploadPurge |
| CA-13 | uploadCrypto (FILE-LEVEL) |
| CA-14 | uploadAudit (sanitizer) |
Stubs identifiés¶
| Stub | Story destination | Localisation |
|---|---|---|
ensureMasterKey("user-password-placeholder") | PD-99 (connexion SRP6a) | UploadDocumentScreen.tsx |
getAuthHeaders() (pas de JWT) | PD-28 (session management) | uploadNetwork.ts |
Tests — Matrice TC → Fichiers¶
| Test-ID | Fichier test |
|---|---|
| TC-NOM-01..02, TC-INV-01..06 | uploadCrypto.test.ts |
| TC-NOM-03, TC-ERR-05..06 | uploadNetwork.test.ts |
| TC-NOM-04, TC-INV-07 | uploadPurge.test.ts |
| TC-NOM-05..06, TC-ERR-03..04, TC-INV-08 | uploadRetry.test.ts |
| TC-NOM-07 | uploadProgress.test.ts |
| TC-NOM-08, TC-NEG-01 | uploadCancel.test.ts |
| TC-NOM-09, TC-ERR-01..02, TC-INV-07, TC-NR-01 | uploadOrchestrator.test.ts |
| TC-NOM-10, TC-ERR-08 | uploadBackground.test.ts |
| TC-INV-10 | uploadAudit.test.ts |
| TC-INV-09, TC-NEG-02..03 | useUploadStore.test.ts |
Total : 36 TC-* couverts dans 10 fichiers test.