Move layer dispatch, entity-not-found checks, and validation from router to heatmap_service. Router now only validates requests, calls service, and formats responses (no HTTPException, no business logic). Service raises EntityNotFoundError/BusinessRuleViolation instead of returning None. Add build_navigator_export() for centralized dispatch. 29 new tests (253 total, 0 failures).
- Create heatmap_service.py with all layer-building logic (coverage, threat-actor, detection-rules, campaign)
- Service is framework-agnostic: no FastAPI imports, no HTTPException, no db.commit()
- Fix N+1 in coverage and threat-actor layers: bulk-fetch test_counts and rule_counts with GROUP BY
- Router reduced from 528 to 140 lines: validates request, calls service, returns response