refactor(backend/api): extract DSFA schemas + services (Step 4 — file 14 of 18)

- Create compliance/schemas/dsfa.py (161 LOC) — extract DSFACreate,
  DSFAUpdate, DSFAStatusUpdate, DSFASectionUpdate, DSFAApproveRequest
- Create compliance/services/dsfa_service.py (386 LOC) — CRUD + helpers
  + stats + audit-log + CSV export; uses domain errors
- Create compliance/services/dsfa_workflow_service.py (347 LOC) — status
  update, section update, submit-for-review, approve, export JSON, versions
- Rewrite compliance/api/dsfa_routes.py (339 LOC) as thin handlers with
  Depends + translate_domain_errors(); re-export legacy symbols via __all__
- Add [mypy-compliance.api.dsfa_routes] ignore_errors = False to mypy.ini
- Update tests: 422 -> 400 for domain ValidationError (6 assertions)
- Regenerate OpenAPI baseline (360 paths / 484 operations — unchanged)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-04-09 19:20:48 +02:00
parent 6658776610
commit ae008d7d25
7 changed files with 1359 additions and 999 deletions

View File

@@ -712,11 +712,11 @@ class TestDSFARouteCRUD:
def test_create_invalid_status(self):
resp = client.post("/api/compliance/dsfa", json={"title": "Bad", "status": "invalid"})
assert resp.status_code == 422
assert resp.status_code == 400 # ValidationError -> 400
def test_create_invalid_risk_level(self):
resp = client.post("/api/compliance/dsfa", json={"title": "Bad", "risk_level": "extreme"})
assert resp.status_code == 422
assert resp.status_code == 400 # ValidationError -> 400
# =============================================================================
@@ -760,7 +760,7 @@ class TestDSFARouteStatusPatch:
f"/api/compliance/dsfa/{created['id']}/status",
json={"status": "bogus"},
)
assert resp.status_code == 422
assert resp.status_code == 400 # ValidationError -> 400
def test_patch_status_not_found(self):
resp = client.patch(
@@ -810,7 +810,7 @@ class TestDSFARouteSectionUpdate:
f"/api/compliance/dsfa/{created['id']}/sections/9",
json={"content": "X"},
)
assert resp.status_code == 422
assert resp.status_code == 400 # ValidationError -> 400
def test_update_section_not_found(self):
resp = client.put(
@@ -839,7 +839,7 @@ class TestDSFARouteWorkflow:
client.post(f"/api/compliance/dsfa/{created['id']}/submit-for-review")
# Try to submit again (already in-review)
resp = client.post(f"/api/compliance/dsfa/{created['id']}/submit-for-review")
assert resp.status_code == 422
assert resp.status_code == 400 # ValidationError -> 400
def test_submit_not_found(self):
resp = client.post(f"/api/compliance/dsfa/{uuid.uuid4()}/submit-for-review")
@@ -871,7 +871,7 @@ class TestDSFARouteWorkflow:
f"/api/compliance/dsfa/{created['id']}/approve",
json={"approved": True},
)
assert resp.status_code == 422
assert resp.status_code == 400 # ValidationError -> 400
def test_approve_not_found(self):
resp = client.post(