Document Service — Application Logic
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services · 02 DDD
1. Use Cases — Commands
| Command | Use Case Class | Description |
|---|---|---|
CreateTemplateCommand | CreateTemplateUseCase | Create a draft template |
UpdateTemplateDraftCommand | UpdateTemplateDraftUseCase | Update draft metadata |
CreateTemplateVersionCommand | CreateTemplateVersionUseCase | Create a new draft version from definition |
PublishTemplateVersionCommand | PublishTemplateVersionUseCase | Transition draft version to published (immutable) |
RetireTemplateCommand | RetireTemplateUseCase | Retire a published template |
ForkPlatformTemplateCommand | ForkPlatformTemplateUseCase | Create tenant-owned copy of a platform reference template |
GenerateDocumentSyncCommand | GenerateDocumentSyncUseCase | Synchronous PDF generation + artifact creation |
EnqueueRenderJobCommand | EnqueueRenderJobUseCase | Create async render job |
CompleteRenderJobCommand | CompleteRenderJobUseCase | Worker: mark job completed, store artifact |
FailRenderJobCommand | FailRenderJobUseCase | Worker: mark job failed with error code |
InitiateUploadCommand | InitiateUploadUseCase | Start multipart upload, return staged upload URL |
FinalizeUploadCommand | FinalizeUploadUseCase | Finalize upload; trigger virus scan; create DocumentReference on pass |
2. Use Cases — Queries
| Query | Use Case Class | Description |
|---|---|---|
ListTemplatesQuery | ListTemplatesUseCase | List templates with filters (category, status, origin, facilityId) |
GetTemplateQuery | GetTemplateUseCase | Get template detail with version list |
ListDocumentsQuery | ListDocumentsUseCase | Search documents by patientId, encounterId, category, date range |
GetDocumentDownloadQuery | GetDocumentDownloadUseCase | Generate signed URL for document download |
GetRenderJobStatusQuery | GetRenderJobStatusUseCase | Poll async render job status |
3. Ports (Interfaces)
| Port | Interface | Adapters |
|---|---|---|
TemplateRepository | TemplateRepository port | PostgresTemplateAdapter |
TemplateVersionRepository | TemplateVersionRepository port | PostgresTemplateVersionAdapter |
RenderJobRepository | RenderJobRepository port | PostgresRenderJobAdapter |
ObjectStoragePort | ObjectStoragePort port | S3Adapter / MinIOAdapter |
VirusScannerPort | VirusScannerPort port | ClamAVAdapter |
FHIRClient | FHIRClient port | HttpFHIRAdapter → interop-service |
PDFRendererPort | PDFRendererPort port | PuppeteerPDFAdapter / PDFLibAdapter |
ConfigClient | ConfigClient port | HttpConfigAdapter → config-service (branding) |
EventPublisher | EventPublisher port | NatsEventPublisher |
AuditClient | AuditClient port | NatsAuditPublisher → audit-service |
4. Synchronous PDF Generation Flow
5. Async Render Job Flow
6. Upload and Virus Scan Flow
7. Outbox Pattern
All domain events are written to the outbox table in the same DB transaction. An outbox relay worker publishes to NATS JetStream and marks rows delivered. Guarantees at-least-once delivery.
8. Business Rules Enforced in Application Layer
| Rule | Enforcement |
|---|---|
| Published template version is immutable | PublishTemplateVersionUseCase sets publishedAt; subsequent edits create new draft version |
| Platform reference templates cannot be edited by tenants | UpdateTemplateDraftUseCase checks origin == platform; rejects with 403 |
clientMutationId idempotency | GenerateDocumentSyncUseCase checks (tenantId, clientMutationId) in render_jobs; returns existing result if found |
| Virus scan mandatory on upload | FinalizeUploadUseCase never skips scan; quarantine on detection |
tenantId from JWT only | DTO strips tenantId field; extracted from JWT claim |
| Signed URL short TTL | GetDocumentDownloadUseCase generates presigned URL with configurable TTL (default 15 min) |
| Context IDs validated before render | GenerateDocumentSyncUseCase validates FHIR resource existence; returns 422 on missing required context |