PD-85 — Revue de Code¶
Résumé¶
| Critère | Statut |
|---|---|
| Patterns NestJS | ✅ |
| Qualité code | ✅ |
| Gestion erreurs | ⚠️ |
| Maintenabilité | ✅ |
Verdict : ⚠️ RÉSERVES
Points positifs¶
exportIdgénéré viarandomUUID(): conforme INV-85-02- Hash d'intégrité via SHA3-256 sur JSON canonique (JCS), en excluant
integrityHash: conforme INV-85-03 - Pas de déchiffrement de documents ni lecture du contenu S3 (seulement metadata + presign) : conforme INV-85-01 + forbidden pattern Zero-Knowledge
- Flux principal lisible : ownership -> validation -> taille -> manifest/chronologie/URLs -> audit -> réponse
- DTO d'entrée bien contraint (UUID v4, taille tableau, unicité), bon alignement avec pratiques NestJS
Points à améliorer¶
| ID | Description | Fichier | Gravité |
|---|---|---|---|
| R-01 | Preuve contractuelle guards (403 + body vide + audit) non démontrée pour POST /exports/complaint-file | complaint-file.controller.ts | MAJEUR |
| R-02 | INV-85-04 : TTL URL signée non borné à 30 min en code service (seule la constante existe, pas de clamp) | export.service.ts | MAJEUR |
| R-03 | INV-85-05 : audit fail-closed non respecté dans le catch (.catch(...) absorbe l'échec) | export.service.ts:181 | MAJEUR |
| R-04 | checkOwnership() fait du N+1 (1 findOne + 1 SQL par proofId) : correct mais coûteux | export.service.ts:192-218 | MINEUR |
| R-05 | logger.log inclut user.sub : à valider selon politique de minimisation des données | complaint-file.controller.ts:38 | MINEUR |
Conformité contracts¶
- Respectés : INV-85-01, INV-85-02, INV-85-03, INV-85-06, INV-85-07 (avec heuristique V1), INV-85-08, forbidden patterns (Math.random, createVerify, lecture S3)
- Non démontré : INV-85-09 (dépend infra/persistance), preuve tests guards (axe obligatoire)
Détail par fichier¶
complaint-file.controller.ts¶
- Structure correcte : guards, DI, HttpCode(200)
- Role hardcodé à USER (V1 — stub documenté)
- Manque test preuve contractuelle guards (MAJEUR)
export.service.ts¶
- Orchestration bien structurée en 11 étapes
- Audit fail-closed respecté sur le chemin nominal
- Chemin d'erreur catch : audit absorbe l'échec (
.catch(...)) — violation INV-85-05 - TTL non borné en code (dépend uniquement de la config)
- N+1 queries dans checkOwnership (mineur)
export-manifest-builder.service.ts¶
- SHA3-256 JCS correct (INV-85-03)
- extractProofHash() placeholder '0'.repeat(64) — stub V1 documenté
- resolveDocumentType() retourne toujours OTHER — stub V1 documenté
integrity-hash.service.ts¶
- Implémentation conforme : exclusion integrityHash avant calcul, SHA3-256 via createHash