{ "audit_date": "2025-12-15", "module": "veza-backend-api", "go_version": "1.23.8", "total_findings": 18, "findings": [ { "id": "MOD-P0-001", "title": "Erreur compilation: uuid.New() utilisé comme *uuid.UUID", "priority": "P0", "category": "Tests", "severity": "Critique", "probability": "Élevée", "files": [ "internal/core/track/service_async_test.go:219", "internal/core/track/service_n1_test.go:48", "internal/core/track/service_n1_test.go:114" ], "summary": "Les tests utilisent uuid.New() (array) comme *uuid.UUID (pointeur) dans struct literals", "fix_minimal": "Remplacer uuid.New() par &uuid.New() ou créer variable intermédiaire", "effort": "S", "effort_hours": 0.5, "risk": "Low", "dependencies": [] }, { "id": "MOD-P0-002", "title": "Panic dans test: interface conversion nil", "priority": "P0", "category": "Tests", "severity": "Critique", "probability": "Élevée", "files": [ "internal/handlers/playlist_handler_integration_test.go:139" ], "summary": "Test panique avec 'interface conversion: interface {} is nil, not map[string]interface {}'", "fix_minimal": "Ajouter vérification type avec require.True() avant assertion", "effort": "S", "effort_hours": 0.25, "risk": "Low", "dependencies": [] }, { "id": "MOD-P1-001", "title": "57 occurrences c.MustGet() sans vérification", "priority": "P1", "category": "Correctness", "severity": "Haute", "probability": "Moyenne", "files": [ "internal/core/track/handler.go:17", "internal/handlers/playback_analytics_handler.go:2", "internal/handlers/playback_websocket_handler.go:1", "internal/handlers/settings_handler.go:2", "internal/handlers/social.go:3", "internal/handlers/marketplace.go:3", "internal/handlers/playlist_handler.go:1", "internal/handlers/comment_handler.go:3", "internal/handlers/hls_handler.go:1", "internal/handlers/playlist_export_handler.go:13", "internal/handlers/password_reset_handler.go:5", "internal/handlers/role_handler.go:21", "internal/handlers/oauth_handlers.go:3" ], "summary": "c.MustGet() panique si clé absente. 57 occurrences dans 13 fichiers", "fix_minimal": "Remplacer par c.Get() avec vérification exists et type", "effort": "M", "effort_hours": 6, "risk": "Medium", "dependencies": [] }, { "id": "MOD-P1-002", "title": "534 occurrences gin.H{\"error\"} (format non standardisé)", "priority": "P1", "category": "Correctness", "severity": "Haute", "probability": "Élevée", "files": [ "internal/handlers/room_handler.go:14", "internal/handlers/social.go:6", "internal/handlers/webhook_handlers.go:14", "internal/handlers/session.go:31", "internal/handlers/settings_handler.go:5", "internal/handlers/playlist_export_handler.go:13", "internal/handlers/password_reset_handler.go:5", "internal/handlers/notification_handlers.go:9", "internal/handlers/hls_handler.go:13", "internal/handlers/role_handler.go:21", "internal/handlers/comment_handler.go:26", "internal/handlers/oauth_handlers.go:3", "internal/handlers/chat_handler.go:3", "internal/handlers/audit.go:27", "internal/handlers/analytics_handler.go:24", "internal/handlers/avatar_handler.go:12", "internal/handlers/auth.go:13" ], "summary": "Format d'erreur non standardisé. 534 occurrences dans 43 fichiers", "fix_minimal": "Remplacer par RespondWithAppError() ou RespondWithError()", "effort": "L", "effort_hours": 20, "risk": "Medium", "dependencies": [] }, { "id": "MOD-P1-003", "title": "969 occurrences fmt.Errorf sans %w", "priority": "P1", "category": "DX", "severity": "Moyenne", "probability": "Élevée", "files": [ "internal/services/playback_export_service.go:26", "internal/services/playback_comparison_service.go:39", "internal/services/playback_analytics_service.go:47", "internal/services/hls_service.go:28", "internal/services/track_version_service.go:16", "internal/services/playlist_service.go:25", "internal/services/rbac_service.go:24" ], "summary": "Erreurs non wrap, perte de contexte. 969 occurrences dans 107 fichiers", "fix_minimal": "Ajouter %w dans fmt.Errorf pour permettre errors.Is()/errors.As()", "effort": "L", "effort_hours": 30, "risk": "Low", "dependencies": [] }, { "id": "MOD-P1-004", "title": "Pas de timeout context dans tous handlers", "priority": "P1", "category": "Robustness", "severity": "Haute", "probability": "Moyenne", "files": [ "Multiple handlers" ], "summary": "Seulement 32 timeouts explicites pour centaines d'appels DB/Redis/HTTP", "fix_minimal": "Ajouter context.WithTimeout() pour opérations I/O critiques", "effort": "M", "effort_hours": 8, "risk": "Medium", "dependencies": [] }, { "id": "MOD-P1-005", "title": "Stack traces dans logs production", "priority": "P1", "category": "Security", "severity": "Moyenne", "probability": "Moyenne", "files": [ "internal/middleware/error_handler.go:145" ], "summary": "Stack traces loggés même en production, expose info sensible", "fix_minimal": "Utiliser includeStackTrace (déjà présent) pour conditionner logs", "effort": "S", "effort_hours": 0.5, "risk": "Low", "dependencies": [] }, { "id": "MOD-P1-006", "title": "/readyz échoue si Redis/RabbitMQ down", "priority": "P1", "category": "Robustness", "severity": "Haute", "probability": "Moyenne", "files": [ "internal/handlers/health.go:143-159" ], "summary": "Readiness échoue si services optionnels down, Kubernetes peut tuer pod", "fix_minimal": "Mode dégradé: logger warning mais ne pas échouer si services optionnels down", "effort": "S", "effort_hours": 1, "risk": "Low", "dependencies": [] }, { "id": "MOD-P2-001", "title": "201 occurrences TODO/FIXME/HACK/XXX", "priority": "P2", "category": "DX", "severity": "Faible", "probability": "Élevée", "files": [ "internal/api/api_manager.go:4", "internal/services/job_service.go:3", "cmd/modern-server/main.go:7", "internal/database/database.go:4" ], "summary": "Dette technique importante. 201 occurrences dans 49 fichiers", "fix_minimal": "Créer tickets pour chaque TODO et prioriser", "effort": "L", "effort_hours": "Variable", "risk": "Low", "dependencies": [] }, { "id": "MOD-P2-002", "title": "81 tests skippés", "priority": "P2", "category": "Tests", "severity": "Faible", "probability": "Élevée", "files": [ "tests/integration/api_health_test.go:6", "tests/integration/upload_async_polling_test.go:4", "internal/handlers/playlist_handler_integration_test.go:12", "internal/handlers/playlist_collaboration_integration_test.go:6", "internal/handlers/playlist_track_handler_integration_test.go:9" ], "summary": "Couverture incomplète. 81 skips dans 23 fichiers", "fix_minimal": "Réactiver progressivement ou supprimer si obsolètes", "effort": "M", "effort_hours": "Variable", "risk": "Low", "dependencies": [] }, { "id": "MOD-P2-003", "title": "37 occurrences quarantine", "priority": "P2", "category": "Tests", "severity": "Faible", "probability": "Moyenne", "files": [ "tests/integration/QUARANTINE.md", "internal/services/upload_validator.go:11", "docs/INTEGRATION_TESTS_HARDENING_REPORT.md:4" ], "summary": "Tests en quarantaine. 37 occurrences dans 14 fichiers", "fix_minimal": "Réactiver progressivement ou supprimer si obsolètes", "effort": "M", "effort_hours": "Variable", "risk": "Medium", "dependencies": [] }, { "id": "MOD-P2-004", "title": "Métriques DB pool manquantes", "priority": "P2", "category": "Observability", "severity": "Faible", "probability": "Élevée", "files": [ "internal/metrics/prometheus.go" ], "summary": "Pas de métriques pour DB pool stats (connections, idle, wait time)", "fix_minimal": "Ajouter métriques Prometheus pour DB pool (StartDBPoolStatsCollector existe mais métriques non exposées)", "effort": "M", "effort_hours": 2, "risk": "Low", "dependencies": [] }, { "id": "MOD-P2-005", "title": "Pas de redaction PII dans logs", "priority": "P2", "category": "Security", "severity": "Faible", "probability": "Moyenne", "files": [ "internal/middleware/request_logger.go" ], "summary": "Aucune redaction automatique PII (emails, user_ids, tokens)", "fix_minimal": "Ajouter fonction redaction pour emails, user_ids, tokens", "effort": "M", "effort_hours": 4, "risk": "Low", "dependencies": [] }, { "id": "MOD-P2-006", "title": "33 occurrences panic() (principalement tests)", "priority": "P2", "category": "Robustness", "severity": "Faible", "probability": "Faible", "files": [ "internal/testutils/db.go:4", "internal/testutils/fixtures.go:3", "internal/middleware/recovery_test.go:6" ], "summary": "33 panics dans 11 fichiers, principalement tests (acceptable)", "fix_minimal": "Vérifier que panics production sont justifiés (fail-fast)", "effort": "S", "effort_hours": 1, "risk": "Low", "dependencies": [] }, { "id": "MOD-P2-007", "title": "5 occurrences log.Fatal (cmd/*)", "priority": "P2", "category": "Robustness", "severity": "Faible", "probability": "Faible", "files": [ "cmd/api/main.go:1", "cmd/modern-server/main.go:1", "cmd/migrate_tool/main.go:3" ], "summary": "5 log.Fatal dans cmd/*, acceptable pour erreurs démarrage", "fix_minimal": "Aucun (comportement attendu pour erreurs démarrage)", "effort": "N/A", "effort_hours": 0, "risk": "N/A", "dependencies": [] }, { "id": "MOD-P2-008", "title": "2 occurrences os.Exit", "priority": "P2", "category": "Robustness", "severity": "Faible", "probability": "Faible", "files": [ "cmd/generate-config-docs/main.go:2" ], "summary": "2 os.Exit dans tools CLI, acceptable", "fix_minimal": "Aucun (comportement attendu pour outils CLI)", "effort": "N/A", "effort_hours": 0, "risk": "N/A", "dependencies": [] }, { "id": "MOD-P2-009", "title": "Pas de versioning API", "priority": "P2", "category": "DX", "severity": "Faible", "probability": "Élevée", "files": [ "internal/api/router.go:102" ], "summary": "Toutes routes sous /api/v1/*, pas de mécanisme versioning", "fix_minimal": "Prévoir structure pour /api/v2/* quand nécessaire", "effort": "M", "effort_hours": 4, "risk": "Low", "dependencies": [] }, { "id": "MOD-P2-010", "title": "Tests flaky (playlist collaboration)", "priority": "P2", "category": "Tests", "severity": "Faible", "probability": "Moyenne", "files": [ "internal/handlers/playlist_collaboration_integration_test.go" ], "summary": "4 tests échouent: AddCollaborator, RemoveCollaborator, UpdatePermission, GetCollaborators", "fix_minimal": "Corriger assertions et vérifier format réponse", "effort": "M", "effort_hours": 2, "risk": "Low", "dependencies": [] } ], "statistics": { "panic_count": 33, "log_fatal_count": 5, "os_exit_count": 2, "must_get_count": 57, "todo_count": 201, "skip_count": 81, "quarantine_count": 37, "gin_error_count": 534, "fmt_errorf_count": 969, "timeout_count": 32 }, "summary": { "p0_count": 2, "p1_count": 6, "p2_count": 10, "total_effort_hours": 99.25, "estimated_weeks": 3 } }