refactor(backend/api): extract SourcePolicyService (Step 4 — file 7 of 18)
compliance/api/source_policy_router.py (580 LOC) -> 253 LOC thin routes
+ 453-line SourcePolicyService + 83-line schemas file. Manages allowed
data sources, operations matrix, PII rules, blocked-content log,
audit trail, and dashboard stats/report.
Single-service split. ORM-based (uses compliance.db.source_policy_models).
Date-string parsing extracted to a module-level _parse_iso_optional
helper so the audit + blocked-content list endpoints share it instead
of duplicating try/except blocks.
Legacy test compat: SourceCreate, SourceUpdate, SourceResponse,
PIIRuleCreate, PIIRuleUpdate, OperationUpdate, _log_audit re-exported
from compliance.api.source_policy_router via __all__.
Verified:
- 208/208 pytest pass (173 core + 35 source policy)
- OpenAPI 360/484 unchanged
- mypy compliance/ -> Success on 132 source files
- source_policy_router.py 580 -> 253 LOC
- Hard-cap violations: 12 -> 11
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>