Skip to content

20. Microservices Readiness

Date: 2026-04-10 Status: Audit complete, principles enforced via subagents

Foundational Principle

The codebase must remain extractable into independent services at any point in time. Every PR that adds cross-domain coupling is adding debt that compounds. The subagent review pipeline (architecture-reviewer, code-reviewer, compliance-reviewer, platform-integrity-checker) enforces this on every change.

Current State: 65% Ready

What's Clean

  • Data ownership: each table written by one service domain
  • No shared state: zero global singletons, DI via FastAPI
  • Configuration: per-domain agnostic, optional services degrade gracefully
  • Graceful degradation: Neo4j, Qdrant, Redis, QStash all return empty/None on failure
  • Prompt abstraction: all LLM prompts in YAML, no inline constants

3 Critical Blockers

  1. case_orchestrator.py — 96KB god object with 21 cross-domain imports
  2. Shared DB sessions — one AsyncSession per request spans 8+ services
  3. Synchronous agent calls — orchestrator calls agents via direct await

9 Service Boundary Candidates

Domain Routers Extractable Now?
Patient patients.py Yes
Case cases.py After orchestrator refactor
Clinical/FHIR fhir.py Yes
Provider providers.py, doctors.py Yes
Matching match.py After orchestrator refactor
Document documents.py Yes
Agent/Orchestration agents.py Last (depends on all others)
Consent consent.py Yes
Notification (embedded) Yes

Rules for New Code

MUST (enforced by subagents)

  1. No new cross-domain direct imports
  2. Own your transaction — don't pass sessions across domains
  3. Events over function calls for cross-domain side effects
  4. Typed contracts (dataclass/Pydantic) between domains — no raw dicts
  5. Config per domain — don't import full settings object
  6. Prompts via prompt_loader — no inline string constants

MUST NOT (flagged as [RED])

  1. Adding imports from service A into service B
  2. Passing DB session from one domain's service to another's
  3. Returning raw dict from a service function
  4. Adding module-level singletons outside app/integrations/
  5. Adding inline LLM prompt constants

Known Debt (tracked, don't grow)

  • case_orchestrator.py: 21 cross-domain imports
  • match_service.py: reads from patient, FHIR, provider, graph
  • document_processing.py: calls clinical_context agent directly

Extraction Sequence (When Ready)

Phase Services Prerequisite
1 Consent, Patient, Provider None
2A Document, FHIR/Clinical Phase 1
2B Orchestrator refactor (HTTP + events) Phase 1
3 Matching Phase 2B
4 Agent Orchestrator Phase 2B + 3

References

  • Architecture reviewer: .claude/agents/architecture-reviewer.md
  • Code reviewer: .claude/agents/code-reviewer.md
  • Compliance reviewer: .claude/agents/compliance-reviewer.md
  • Platform integrity checker: .claude/agents/platform-integrity-checker.md
  • DAO layer spec: docs/specs/ai-steer/dao-layer-steer.md (pending)