=============================================================================== PREUVE TECHNIQUE QA — Ticket #48 Présentation & sécurité : endpoint POST /scan-results, validation, permissions + doc Epic parent : #24 | PR #28 -> dev | Branche : feat/48-scan-results-endpoint Commit testé : f247858 Date : 2026-06-11 Note : aucun [REDACTED]/[REDACTED]/mot de passe inclus (valeurs de fixture caviardees). =============================================================================== --- ENVIRONNEMENT --- Python 3.10.12 pytest : pytest 9.0.3 --- GATE BACKEND (suite complete, Postgres pgvector:pg16 ephemere + alembic upgrade head) --- pytest -q (suite complete) : 438 passed, 2 skipped ruff check . : All checks passed! mypy src : Success: no issues found in 116 source files => Conforme au baseline dev-run (438 passed / 2 skipped, ruff/mypy clean). --- SMOKE TEST : tests/test_scan_results_api.py (15 tests) --- ============================= test session starts ============================== platform linux -- Python 3.10.12, pytest-9.0.3, pluggy-1.6.0 -- /home/naqued/Development/omdev/Client-Dashboard/api/.venv/bin/python rootdir: /home/naqued/Development/omdev/Client-Dashboard/.claude/worktrees/agent-aaf82bdab5d578167/api configfile: pyproject.toml plugins: asyncio-1.4.0, respx-0.23.1, anyio-4.13.0 asyncio: mode=auto, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=session collecting ... collected 15 items tests/test_scan_results_api.py::test_missing_[REDACTED] PASSED [ 6%] tests/test_scan_results_api.py::test_wrong_[REDACTED] PASSED [ 13%] tests/test_scan_results_api.py::test_empty_configured_[REDACTED] PASSED [ 20%] tests/test_scan_results_api.py::test_unknown_tool_is_400 PASSED [ 26%] tests/test_scan_results_api.py::test_extra_top_level_[REDACTED] PASSED [ 33%] tests/test_scan_results_api.py::test_injection_project_[REDACTED] PASSED [ 40%] tests/test_scan_results_api.py::test_report_not_an_object_is_400 PASSED [ 46%] tests/test_scan_results_api.py::test_non_json_body_is_400 PASSED [ 53%] tests/test_scan_results_api.py::test_unknown_project_[REDACTED] PASSED [ 60%] tests/test_scan_results_api.py::test_unlinked_project_is_403 PASSED [ 66%] tests/test_scan_results_api.py::test_trivy_creates_ticket_and_summarizes PASSED [ 73%] tests/test_scan_results_api.py::test_semgrep_is_accepted PASSED [ 80%] tests/test_scan_results_api.py::test_open_duplicate_is_deduped PASSED [ 86%] tests/test_scan_results_api.py::test_resolved_ticket_is_regression PASSED [ 93%] tests/test_scan_results_api.py::test_degraded_redmine_returns_200_envelope PASSED [100%] ============================== 15 passed in 1.54s ============================== --- DOCUMENTATION --- -rw-rw-r-- 1 naqued naqued 7499 juin 11 22:03 docs/superpowers/specs/2026-06-11-scan-results-webhook.md => Spec presente : docs/superpowers/specs/2026-06-11-scan-results-webhook.md (formats Trivy/Semgrep, anti-doublons/regression, prerequis security_key). --- MAPPING CRITERES D'ACCEPTATION -> RESULTAT --- [OK] POST /scan-results accepte Trivy et Semgrep et declenche CreateTicketsFromScan (#46) via adaptateur #47 -> test_trivy_creates_ticket_and_summarizes, test_semgrep_is_accepted [OK] Payloads malformes/abusifs rejetes en 400 (jamais 422/500) ; anti-injection sur project_key -> test_unknown_tool_is_400, test_extra_top_level_key_is_400, test_injection_project_key_is_400, test_report_not_an_object_is_400, test_non_json_body_is_400 [OK] Permissions : [REDACTED] webhook (X-Webhook-[REDACTED]) manquant/mauvais -> 401 ; project_key inconnu/non-lie -> 403 -> test_missing_[REDACTED]_is_401, test_wrong_[REDACTED]_is_401, test_empty_configured_[REDACTED]_disables_webhook, test_unknown_project_key_is_403, test_unlinked_project_is_403 [OK] Reponse resume creees/doublons/regressions -> test_trivy_creates_ticket_and_summarizes, test_open_duplicate_is_deduped, test_resolved_ticket_is_regression [OK] Pas de 500 sur Redmine degrade : 200 schema-valide avec degraded:true -> test_degraded_redmine_returns_200_envelope [OK] Documentation livree ; tests d'API verts (15/15) ; ruff + mypy passent --- VERDICT : PASS (5/5 criteres OK) ---