383 lines
13 KiB
JSON
383 lines
13 KiB
JSON
|
|
{
|
||
|
|
"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
|
||
|
|
}
|
||
|
|
}
|