{
  "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
  }
}
