Skip to main content

Facility Service — Event Schemas

Status: populated Owner: TBD Last updated: 2026-04-17 Companion: 04 Event-Driven Architecture · NAMING

1. Subject Naming

All events are published on NATS JetStream stream FACILITY with subjects facility.{aggregate}.{event}.v{N}.

AttributeValue
StreamFACILITY
Retention classconfig (180d hot; snapshot to cold 2y)
Partition keytenantId + aggregate id
EnvelopePlatform EventEnvelope (F01)

2. Produced Events

EventAggregateRetentionNotes
facility.hierarchy_node.created.v1HierarchyNodeconfig
facility.hierarchy_node.updated.v1HierarchyNodeconfig
facility.hierarchy_node.deactivated.v1HierarchyNodeconfig
facility.hierarchy_edge.created.v1HierarchyEdgeconfig
facility.hierarchy_edge.removed.v1HierarchyEdgeconfig
facility.hierarchy_profile.updated.v1HierarchyProfileconfig
facility.location.created.v1Locationconfig
facility.location.updated.v1Locationconfig
facility.location.deactivated.v1Locationconfig
facility.bed.created.v1Bedoperational
facility.bed.status_changed.v1BedoperationalHot path — high volume
facility.resource.created.v1Resourceconfig
facility.resource.updated.v1Resourceconfig
facility.provider_membership.assigned.v1Membershipconfig
facility.provider_membership.revoked.v1Membershipconfig

3. Schemas

3.1 facility.hierarchy_node.created.v1

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "schemas://facility/hierarchy_node/created/v1",
"type": "object", "additionalProperties": false,
"required": ["nodeId","tenantId","profileId","type","name","status","createdAt"],
"properties": {
"nodeId": { "type": "string", "pattern": "^hnd_[0-9A-HJKMNP-TV-Z]{26}$" },
"tenantId": { "type": "string", "pattern": "^ten_[0-9A-HJKMNP-TV-Z]{26}$" },
"profileId": { "type": "string", "pattern": "^hpf_[0-9A-HJKMNP-TV-Z]{26}$" },
"type": { "type": "string" },
"name": { "type": "string", "maxLength": 200 },
"code": { "type": "string" },
"parentNodeId": { "type": "string" },
"status": { "enum": ["active","inactive"] },
"createdAt": { "type": "string", "format": "date-time" }
}
}

3.2 facility.hierarchy_edge.created.v1

{ "required": ["edgeId","tenantId","parentNodeId","childNodeId","relationshipType","createdAt"],
"properties": {
"edgeId": { "type": "string", "pattern": "^hed_..." },
"parentNodeId": { "type": "string" },
"childNodeId": { "type": "string" },
"relationshipType": { "enum": ["contains","manages","refers-to"] }
} }

3.3 facility.location.created.v1

{ "required": ["locationId","tenantId","hierarchyNodeId","name","serviceType","timezone","locale","createdAt"],
"properties": {
"locationId": { "type": "string", "pattern": "^loc_..." },
"hierarchyNodeId": { "type": "string" },
"name": { "type": "string" },
"serviceType": { "enum": ["OUTPATIENT","INPATIENT","EMERGENCY","ICU","DIAGNOSTIC"] },
"capacity": { "type": "integer", "minimum": 0 },
"timezone": { "type": "string" },
"locale": { "type": "string" }
} }

3.4 facility.bed.status_changed.v1

{ "required": ["bedId","tenantId","locationId","fromStatus","toStatus","changedAt","changedBy"],
"properties": {
"bedId": { "type": "string", "pattern": "^bed_..." },
"locationId": { "type": "string" },
"fromStatus": { "enum": ["AVAILABLE","RESERVED","OCCUPIED","CLEANING","MAINTENANCE","OUT_OF_SERVICE"] },
"toStatus": { "enum": ["AVAILABLE","RESERVED","OCCUPIED","CLEANING","MAINTENANCE","OUT_OF_SERVICE"] },
"patientId": { "type": "string" },
"changedAt": { "type": "string", "format": "date-time" },
"changedBy": { "type": "string" }
} }

3.5 facility.provider_membership.assigned.v1

{ "required": ["membershipId","tenantId","providerId","nodeId","primary","effectiveFrom"],
"properties": {
"membershipId": { "type": "string", "pattern": "^pnm_..." },
"providerId": { "type": "string" },
"nodeId": { "type": "string" },
"primary": { "type": "boolean" },
"effectiveFrom": { "type": "string", "format": "date" },
"effectiveTo": { "type": "string", "format": "date" }
} }

3.6 Example envelope

{
"eventId": "01HN2K...", "eventType": "facility.bed.status_changed.v1",
"eventVersion": 1, "occurredAt": "2026-04-17T09:20:00Z",
"tenantId": "ten_01H...", "traceId": "c2f5...",
"payload": { "bedId": "bed_01H...", "fromStatus":"OCCUPIED", "toStatus":"CLEANING", "changedBy":"usr_01H...", "changedAt":"2026-04-17T09:20:00Z" }
}

4. Consumed Events

EventProducerHandler
tenant.tenant.created.v1tenant-serviceOnTenantCreatedPolicy — seed profile + root node
tenant.tenant.archived.v1tenant-serviceDeactivate nodes under tenant
provider_directory.practitioner.created.v1provider-directory-serviceAllow subsequent membership writes
gdpr.subject_request.received.v1platformParticipate — no PII stored, ack-only

5. Outbox / Inbox

ConcernImplementation
PublicationTransactional outbox table facility.outbox; relay to NATS
Consumptionfacility.inbox keyed on eventId; idempotent handlers
Publication SLO< 2s p95 from commit → NATS ack

6. Versioning

  • Additive changes → same major version, incremented minor in docs only.
  • Breaking changes → new subject version (v2); dual-publish 30d window.