Skip to main content

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

CommandUse Case ClassDescription
CreateTemplateCommandCreateTemplateUseCaseCreate a draft template
UpdateTemplateDraftCommandUpdateTemplateDraftUseCaseUpdate draft metadata
CreateTemplateVersionCommandCreateTemplateVersionUseCaseCreate a new draft version from definition
PublishTemplateVersionCommandPublishTemplateVersionUseCaseTransition draft version to published (immutable)
RetireTemplateCommandRetireTemplateUseCaseRetire a published template
ForkPlatformTemplateCommandForkPlatformTemplateUseCaseCreate tenant-owned copy of a platform reference template
GenerateDocumentSyncCommandGenerateDocumentSyncUseCaseSynchronous PDF generation + artifact creation
EnqueueRenderJobCommandEnqueueRenderJobUseCaseCreate async render job
CompleteRenderJobCommandCompleteRenderJobUseCaseWorker: mark job completed, store artifact
FailRenderJobCommandFailRenderJobUseCaseWorker: mark job failed with error code
InitiateUploadCommandInitiateUploadUseCaseStart multipart upload, return staged upload URL
FinalizeUploadCommandFinalizeUploadUseCaseFinalize upload; trigger virus scan; create DocumentReference on pass

2. Use Cases — Queries

QueryUse Case ClassDescription
ListTemplatesQueryListTemplatesUseCaseList templates with filters (category, status, origin, facilityId)
GetTemplateQueryGetTemplateUseCaseGet template detail with version list
ListDocumentsQueryListDocumentsUseCaseSearch documents by patientId, encounterId, category, date range
GetDocumentDownloadQueryGetDocumentDownloadUseCaseGenerate signed URL for document download
GetRenderJobStatusQueryGetRenderJobStatusUseCasePoll async render job status

3. Ports (Interfaces)

PortInterfaceAdapters
TemplateRepositoryTemplateRepository portPostgresTemplateAdapter
TemplateVersionRepositoryTemplateVersionRepository portPostgresTemplateVersionAdapter
RenderJobRepositoryRenderJobRepository portPostgresRenderJobAdapter
ObjectStoragePortObjectStoragePort portS3Adapter / MinIOAdapter
VirusScannerPortVirusScannerPort portClamAVAdapter
FHIRClientFHIRClient portHttpFHIRAdapter → interop-service
PDFRendererPortPDFRendererPort portPuppeteerPDFAdapter / PDFLibAdapter
ConfigClientConfigClient portHttpConfigAdapter → config-service (branding)
EventPublisherEventPublisher portNatsEventPublisher
AuditClientAuditClient portNatsAuditPublisher → 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

RuleEnforcement
Published template version is immutablePublishTemplateVersionUseCase sets publishedAt; subsequent edits create new draft version
Platform reference templates cannot be edited by tenantsUpdateTemplateDraftUseCase checks origin == platform; rejects with 403
clientMutationId idempotencyGenerateDocumentSyncUseCase checks (tenantId, clientMutationId) in render_jobs; returns existing result if found
Virus scan mandatory on uploadFinalizeUploadUseCase never skips scan; quarantine on detection
tenantId from JWT onlyDTO strips tenantId field; extracted from JWT claim
Signed URL short TTLGetDocumentDownloadUseCase generates presigned URL with configurable TTL (default 15 min)
Context IDs validated before renderGenerateDocumentSyncUseCase validates FHIR resource existence; returns 422 on missing required context