Provider Directory Service — Event Schemas
Status: populated Owner: TBD Last updated: 2026-04-17 Companion: 04 Event-Driven · NAMING
1. Subject Naming
All events published on stream PROVIDER_DIRECTORY with subjects provider_directory.{aggregate}.{event}.v{N}.
| Attribute | Value |
|---|---|
| Stream | PROVIDER_DIRECTORY |
| Retention class | config (180d hot; 7y archive for credentials) |
| Partition key | tenantId + practitionerId |
| Envelope | EventEnvelope (F01) |
2. Produced Events
| Event | Aggregate |
|---|---|
provider_directory.practitioner.created.v1 | Practitioner |
provider_directory.practitioner.updated.v1 | Practitioner |
provider_directory.practitioner.suspended.v1 | Practitioner |
provider_directory.practitioner.reinstated.v1 | Practitioner |
provider_directory.practitioner.deactivated.v1 | Practitioner |
provider_directory.credential.added.v1 | Credential |
provider_directory.credential.updated.v1 | Credential |
provider_directory.credential.revoked.v1 | Credential |
provider_directory.credential.expiring.v1 | Credential (scheduled 60/30/7 days) |
provider_directory.credential.expired.v1 | Credential |
provider_directory.role.assigned.v1 | Role |
provider_directory.role.revoked.v1 | Role |
provider_directory.healthcare_service.created.v1 | HealthcareService |
provider_directory.healthcare_service.updated.v1 | HealthcareService |
provider_directory.endpoint.registered.v1 | Endpoint |
provider_directory.endpoint.updated.v1 | Endpoint |
provider_directory.endpoint.health_changed.v1 | Endpoint |
3. Schemas
3.1 provider_directory.practitioner.created.v1
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "schemas://provider_directory/practitioner/created/v1",
"type": "object", "additionalProperties": false,
"required": ["practitionerId","tenantId","kind","official_name","identifiers","status","createdAt"],
"properties": {
"practitionerId": { "type": "string", "pattern": "^prc_..." },
"tenantId": { "type": "string", "pattern": "^ten_..." },
"userId": { "type": "string", "pattern": "^usr_..." },
"kind": { "enum": ["physician","nurse","midwife","pharmacist","dentist","technician","therapist","other"] },
"official_name": { "type": "object",
"required": ["family","given","scriptCode"],
"properties": { "family": {"type":"string"}, "given": {"type":"array","items":{"type":"string"}}, "scriptCode":{"type":"string"} } },
"identifiers": {
"type": "array",
"items": { "type":"object","required":["system","value","authority"],
"properties": { "system":{"type":"string"}, "value":{"type":"string"}, "authority":{"type":"string"} } }
},
"status": { "enum": ["active","suspended","deactivated"] },
"createdAt": { "type": "string", "format": "date-time" }
}
}
3.2 provider_directory.credential.added.v1
{ "required": ["credentialId","practitionerId","tenantId","type","number","issuingAuthority","issuedAt","status"],
"properties": {
"credentialId": { "type":"string","pattern":"^crd_..." },
"type": { "enum": ["license","certification","degree"] },
"number": { "type":"string" },
"issuingAuthority": { "type":"string" },
"issuedAt": { "type":"string","format":"date" },
"expiresAt": { "type":"string","format":"date" },
"status": { "enum":["active","expired","suspended","revoked"] }
} }
3.3 provider_directory.credential.expiring.v1
{ "required": ["credentialId","practitionerId","expiresAt","daysUntilExpiry"],
"properties": {
"expiresAt": { "type":"string","format":"date" },
"daysUntilExpiry": { "type":"integer","enum":[60,30,7] }
} }
3.4 provider_directory.role.assigned.v1
{ "required": ["roleId","practitionerId","tenantId","role","active","periodStart"],
"properties": {
"roleId": { "type":"string","pattern":"^prr_..." },
"hierarchyNodeId": { "type":"string" },
"healthcareServiceId": { "type":"string" },
"role": { "type":"string" },
"privileges": { "type":"array","items":{"type":"string"} },
"periodStart": { "type":"string","format":"date" },
"periodEnd": { "type":"string","format":"date" }
} }
3.5 provider_directory.endpoint.health_changed.v1
{ "required": ["endpointId","tenantId","previous","current","observedAt"],
"properties": {
"previous": { "enum": ["active","inactive","error","deprecated"] },
"current": { "enum": ["active","inactive","error","deprecated"] },
"latencyMs": { "type":"integer","minimum":0 }
} }
4. Consumed Events
| Event | Producer | Handler |
|---|---|---|
identity.user.registered.v1 | identity-service | OnUserRegisteredPolicy (JIT shadow) |
facility.provider_membership.assigned.v1 | facility-service | Update cached scope summary |
facility.provider_membership.revoked.v1 | facility-service | Update cached scope summary |
tenant.tenant.created.v1 | tenant-service | Seed default specialty catalog |
gdpr.subject_request.received.v1 | platform | Participate |
5. Outbox / Inbox
| Concern | Implementation |
|---|---|
| Publication | provider_directory.outbox + NATS relay |
| Consumption | provider_directory.inbox keyed on eventId |
| Publication SLO | ≤ 2s p95 |
6. Versioning
Same as platform convention — additive in-place, breaking = new vN + 30d dual-publish.