Skip to main content

Ghasi e-Prescribing Gateway Service — Domain Model

Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services · 02 DDD

Aggregates

PrescriptionRecord (Root Aggregate)

Represents the gateway's authoritative interop copy of a MedicationRequest. The EHR is the clinical author; the gateway mediates and persists the interop copy.

Invariants:

  • tenantId is extracted from JWT — never client-supplied.
  • prescriberId must be a valid EHR actor (enforced by ehr-backend persona scope).
  • Status transitions strictly follow the FHIR MedicationRequest state machine.
  • ETag is issued on create and required on update (If-Match); stale writes return 412.
  • Idempotent create: same Idempotency-Key + payload fingerprint → same resource ID, no duplicate.
  • A MedicationDispense cannot reference a prescriptionId unknown to this tenant (BR-RX-001).

FHIR resource: MedicationRequest

Status state machine:


DispenseRecord (Root Aggregate)

Represents the gateway's interop copy of a MedicationDispense. The Pharmacy is the author.

Invariants:

  • Must reference a known PrescriptionRecord for the same tenant (BR-RX-001).
  • Only pharmacy-backend persona may create.
  • ETag issued; If-Match required on update.
  • Partial fills allowed when tenant policy permits; quantity.value < prescribed.quantity.value.

FHIR resource: MedicationDispense


SubscriptionChannel (Aggregate)

Represents a registered HTTPS notification channel for a consumer (EHR or Pharmacy per tenant).

Invariants:

  • Must have a valid endpointUrl (HTTPS, verified on registration).
  • Signing key pair rotates per tenant policy.
  • Cursor tracks last delivered event sequence; replay from cursor on reconnect.

FHIR resource: Subscription


WorkflowTask (Aggregate)

Represents a renewal or clarification task (P1+).

FHIR resource: Task

Invariants:

  • requester is the pharmacy or patient proxy.
  • owner is the prescriber queue (EHR).
  • Terminal states: completed, rejected, cancelled.

Domain Events

Event type (NATS subject)VersionTrigger
eprescribing.medication_request.created.v1v1MR successfully persisted and routed
eprescribing.medication_request.updated.v1v1MR status changed or revised
eprescribing.medication_request.cancelled.v1v1MR cancelled by EHR actor
eprescribing.medication_dispense.created.v1v1MD accepted by gateway
eprescribing.medication_dispense.updated.v1v1MD status/quantity updated
eprescribing.task.status_changed.v1v1Renewal/clarification task state change (P1)
eprescribing.subscription.delivery_failed.v1v1After retry exhaustion → DLQ
eprescribing.subscription.replayed.v1v1Manual replay triggered

Value Objects

Value objectDescription
PrescriptionBusinessIdPlatform-issued correlation ID spanning EHR–Gateway–Pharmacy; format prx_<ULID>
ETagOpaque version token; format W/"<sha256-of-resource>"
IdempotencyKeyClient-supplied string + payload fingerprint hash
TenantIdBranded string Branded<string, 'TenantId'>
PrescriptionRecordIdULID with prefix mr_
DispenseRecordIdULID with prefix md_
SubscriptionIdULID with prefix sub_
WorkflowTaskIdULID with prefix wtk_
RoutingEnvelope{ targetOrgId, targetEndpointId, region, fallbackEndpointId? }
ValidationOutcome{ valid: boolean, issues: OperationOutcomeIssue[] }
PersonaTypeenum { ehr_backend, pharmacy_backend, b2b_external }

Ubiquitous Language

TermDefinition
GatewayThe ghasi-eprescribing-gateway-service as a platform component
PrescriptionRecordGateway's authoritative interop copy of a MedicationRequest
DispenseRecordGateway's interop copy of a MedicationDispense
Prescription business IDPlatform-level correlation identifier (prx_) spanning all systems
ETagOpaque concurrency token issued per resource version; required on updates
Idempotency-KeyClient-supplied header to deduplicate creates on retry
IG packageFHIR Implementation Guide package (StructureDefinition + ValueSets) pinned per tenant
SubscriptionFHIR R4 Subscription: durable HTTPS notification channel
DLQDead-letter queue for failed notification deliveries
Persona typeehr_backend, pharmacy_backend, or b2b_external — dictates which resources the actor may write
Routing envelopeResolved pharmacy target (Organization + Endpoint) for a prescription
Store-and-forwardOffline-tolerant mode: gateway accepts and queues prescriptions when pharmacy endpoint is unreachable