Files
breakpilot-compliance/backend-compliance/compliance/api
Sharang Parnerkar 4a91814bfc refactor(backend/api): extract AuditSession service layer (Step 4 worked example)
Phase 1 Step 4 of PHASE1_RUNBOOK.md, first worked example. Demonstrates
the router -> service delegation pattern for all 18 oversized route
files still above the 500 LOC hard cap.

compliance/api/audit_routes.py (637 LOC) is decomposed into:

  compliance/api/audit_routes.py              (198) — thin handlers
  compliance/services/audit_session_service.py (259) — session lifecycle
  compliance/services/audit_signoff_service.py (319) — checklist + sign-off
  compliance/api/_http_errors.py               ( 43) — reusable error translator

Handlers shrink to 3-6 lines each:

    @router.post("/sessions", response_model=AuditSessionResponse)
    async def create_audit_session(
        request: CreateAuditSessionRequest,
        service: AuditSessionService = Depends(get_audit_session_service),
    ):
        with translate_domain_errors():
            return service.create(request)

Services are HTTP-agnostic: they raise NotFoundError / ConflictError /
ValidationError from compliance.domain, and the route layer translates
those to HTTPException(404/409/400) via the translate_domain_errors()
context manager in compliance.api._http_errors. The error translator is
reusable by every future Step 4 refactor.

Services take a sqlalchemy Session in the constructor and are wired via
Depends factories (get_audit_session_service / get_audit_signoff_service).
No globals, no module-level state.

Behavior is byte-identical at the HTTP boundary:
  - Same paths, methods, status codes, response models
  - Same error messages (domain error __str__ preserved)
  - Same auto-start-on-first-signoff, same statistics calculation,
    same signature hash format, same PDF streaming response

Verified:
  - 173/173 pytest compliance/tests/ tests/contracts/ pass
  - OpenAPI 360 paths / 484 operations unchanged
  - audit_routes.py under soft 300 target
  - Both new service files under soft 300 / hard 500

Note: compliance/tests/test_audit_routes.py contains placeholder tests
that do not actually import or call the handler functions — they only
assert on request-data shape. Real behavioral coverage relies on the
contract test. A follow-up commit should add TestClient-based
integration tests for the audit endpoints. Flagged in PHASE1_RUNBOOK.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 18:16:50 +02:00
..