compliance/api/vvt_routes.py (550 LOC) -> 225 LOC thin routes + 475-line
VVTService. Covers the organization header, processing activities CRUD,
audit log, JSON/CSV export, stats, and version lookups for the Art. 30
DSGVO Verzeichnis.
Single-service split: organization + activities + audit + stats all
revolve around the same tenant's VVT document, and the existing test
suite (tests/test_vvt_routes.py — 768 LOC, tests/test_vvt_tenant_isolation.py
— 205 LOC) exercises them together.
Module-level helpers (_activity_to_response, _log_audit, _export_csv)
stay module-level in compliance.services.vvt_service and are re-exported
from compliance.api.vvt_routes so the two test files keep importing
from the old path.
Pydantic schemas already live in compliance.schemas.vvt from Step 3 —
no new schema file needed this round.
mypy.ini flips compliance.api.vvt_routes from ignore_errors=True to
False. Two SQLAlchemy Column[str] vs str dict-index errors fixed with
explicit str() casts on status/business_function in the stats loop.
Verified:
- 242/242 pytest (173 core + 69 VVT integration) pass
- OpenAPI 360/484 unchanged
- mypy compliance/ -> Success on 128 source files
- vvt_routes.py 550 -> 225 LOC
- vvt_service.py 475 LOC (under 500 hard cap)
- Hard-cap violations: 14 -> 13
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>