Care Plan Service — Application Logic
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services · 02 DDD
Use Cases — Commands
| Use case | File | Trigger | Emits event |
|---|---|---|---|
CreateCarePlanUseCase | create-care-plan.use-case.ts | POST /api/v1/care-plans | care_plan.care_plan.created.v1 |
UpdateCarePlanUseCase | update-care-plan.use-case.ts | PATCH /api/v1/care-plans/:id | care_plan.care_plan.updated.v1 |
ActivateCarePlanUseCase | activate-care-plan.use-case.ts | POST /api/v1/care-plans/:id/activate | care_plan.care_plan.updated.v1 |
ReviewCarePlanUseCase | review-care-plan.use-case.ts | POST /api/v1/care-plans/:id/review | care_plan.care_plan.reviewed.v1 |
CloseCarePlanUseCase | close-care-plan.use-case.ts | POST /api/v1/care-plans/:id/close | care_plan.care_plan.updated.v1 |
AddGoalUseCase | add-goal.use-case.ts | POST /api/v1/care-plans/:id/goals | care_plan.goal.created.v1 |
UpdateGoalUseCase | update-goal.use-case.ts | PATCH /api/v1/care-plans/:id/goals/:goalId | care_plan.goal.updated.v1 |
AddActivityUseCase | add-activity.use-case.ts | POST /api/v1/care-plans/:id/activities | care_plan.activity.created.v1 |
CompleteActivityUseCase | complete-activity.use-case.ts | POST /api/v1/care-plans/:id/activities/:actId/complete | care_plan.activity.completed.v1 |
UpdateCareTeamUseCase | update-care-team.use-case.ts | PUT /api/v1/care-plans/:id/care-team | care_plan.care_team.updated.v1 |
Use Cases — Queries
| Use case | File | Returns |
|---|---|---|
GetCarePlanUseCase | get-care-plan.use-case.ts | Full CarePlan with goals, activities, team |
ListCarePlansUseCase | list-care-plans.use-case.ts | Paginated CarePlanSummary[] |
GetCarePlanFhirUseCase | get-care-plan-fhir.use-case.ts | FHIR CarePlan resource for fhir-gateway |
SearchGoalsFhirUseCase | search-goals-fhir.use-case.ts | FHIR Bundle of Goal resources |
Ports (Interfaces)
| Port | File | Direction |
|---|---|---|
CarePlanRepository | care-plan.repository.port.ts | Outbound — Postgres via Drizzle |
EventPublisher | event-publisher.port.ts | Outbound — NATS JetStream outbox |
AuditClient | audit-client.port.ts | Outbound — audit-service |
TerminologyClient | terminology-client.port.ts | Outbound — terminology-service (validate codings) |
ProviderDirectoryClient | provider-directory-client.port.ts | Outbound — provider-directory-service (validate practitioners) |
FhirMapper | fhir-mapper.port.ts | Internal — maps domain entities to FHIR resources |
Orchestration Flows
Create Care Plan
Review Care Plan
Complete Activity
Saga / Outbox Pattern
All domain events use the transactional outbox:
- Domain event is inserted into
outboxtable in the same database transaction as the entity mutation. OutboxRelayWorkerpollsoutboxat 500 ms intervals; publishes to NATS JetStream.- On successful NATS publish, outbox row is marked
published. - If NATS is unavailable, messages accumulate; relay retries with exponential backoff (max 5 min).
- Dead-letter entries alert on-call after 15 min without publish.
Error Handling
| Error condition | HTTP code | Error code |
|---|---|---|
| Plan not found | 404 | CARE_PLAN_NOT_FOUND |
| Stale version | 409 | VERSION_CONFLICT |
| Plan is closed (immutable) | 409 | CARE_PLAN_CLOSED |
| Invalid status transition | 422 | INVALID_STATUS_TRANSITION |
| Module not licensed | 403 | MODULE_NOT_LICENSED |
| Validation failure (coding) | 422 | INVALID_CODING |
| Missing required field | 400 | VALIDATION_ERROR |
| Cross-tenant access attempt | 403 | TENANT_ISOLATION_VIOLATION |