Patient Portal Service — Event Schemas
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services · 02 DDD
1. Overview
Transport: NATS JetStream via @ghasi/nats-client
Envelope: CloudEvents v1.0
Stream: PATIENT_PORTAL
Retention: All events carry tenantId; retention class varies by event type.
2. Published Events
2.1 portal.account.created.v1
NATS subject: PATIENT_PORTAL.account.created
Retention: 7 days
Trigger: New portal account registered and linked to patient identity.
{
"specversion": "1.0",
"id": "01JXXX",
"source": "ghasi/patient-portal",
"type": "portal.account.created.v1",
"datacontenttype": "application/json",
"time": "2026-04-18T10:00:00Z",
"tenantid": "TENANT_01J",
"data": {
"accountId": "pact_01JXXX",
"patientId": "pat_01JXXX",
"status": "pending_verification"
}
}
2.2 portal.account.suspended.v1
NATS subject: PATIENT_PORTAL.account.suspended
Retention: 30 days
Trigger: Admin suspends portal account.
{
"data": {
"accountId": "pact_01JXXX",
"patientId": "pat_01JXXX",
"actorId": "usr_01JYYY",
"reason": "Suspicious access pattern"
}
}
2.3 portal.account.closed.v1
NATS subject: PATIENT_PORTAL.account.closed
Retention: 90 days
Trigger: Account deletion request confirmed after retention check.
{
"data": {
"accountId": "pact_01JXXX",
"patientId": "pat_01JXXX",
"closedAt": "2026-04-18T12:00:00Z"
}
}
2.4 portal.login.v1
NATS subject: PATIENT_PORTAL.login
Retention: 30 days
Trigger: Successful patient authentication.
{
"data": {
"accountId": "pact_01JXXX",
"patientId": "pat_01JXXX",
"mfaUsed": true,
"channel": "web"
}
}
2.5 portal.result.viewed.v1
NATS subject: PATIENT_PORTAL.result.viewed
Retention: 90 days
Trigger: Patient views a lab or radiology result.
{
"data": {
"accountId": "pact_01JXXX",
"patientId": "pat_01JXXX",
"resourceType": "Observation",
"resourceId": "obs_01JXXX",
"actingAsProxy": false,
"occurredAt": "2026-04-18T10:00:00Z"
}
}
2.6 portal.appointment.requested.v1
NATS subject: PATIENT_PORTAL.appointment.requested
Retention: 30 days
Trigger: Patient submits an appointment request.
{
"data": {
"accountId": "pact_01JXXX",
"patientId": "pat_01JXXX",
"requestId": "apptreq_01JXXX",
"preferredProviderId": "prov_01JXXX",
"preferredFacilityId": "fac_01JXXX",
"requestedStart": "2026-05-01T09:00:00Z"
}
}
2.7 portal.demographics.update.requested.v1
NATS subject: PATIENT_PORTAL.demographics.update.requested
Retention: 90 days
Trigger: Patient submits a demographic update request.
{
"data": {
"accountId": "pact_01JXXX",
"patientId": "pat_01JXXX",
"requestId": "demreq_01JXXX",
"requestedAt": "2026-04-18T10:00:00Z"
}
}
2.8 portal.proxy.delegation.granted.v1
NATS subject: PATIENT_PORTAL.proxy.delegation.granted
Retention: 90 days
Trigger: Patient grants proxy/caregiver access.
{
"data": {
"delegationId": "pdel_01JXXX",
"grantorPatientId": "pat_01JXXX",
"proxyPortalAccountId": "pact_01JYYY",
"relationshipType": "parent",
"scope": ["read:record", "read:results"],
"validFrom": "2026-04-18",
"validTo": "2027-04-18"
}
}
2.9 portal.proxy.delegation.revoked.v1
NATS subject: PATIENT_PORTAL.proxy.delegation.revoked
Retention: 90 days
{
"data": {
"delegationId": "pdel_01JXXX",
"actorId": "pact_01JXXX",
"revokedAt": "2026-04-18T12:00:00Z"
}
}
2.10 portal.export.requested.v1
NATS subject: PATIENT_PORTAL.export.requested
Retention: 30 days
{
"data": {
"exportJobId": "expjob_01JXXX",
"accountId": "pact_01JXXX",
"patientId": "pat_01JXXX",
"includeResources": ["Patient","Condition","Observation","MedicationRequest"],
"from": "2020-01-01",
"to": "2026-04-18"
}
}
3. Consumed Events
| Subject | Source Service | Why Consumed |
|---|---|---|
IDENTITY.patient.registered.v1 | identity-service | Auto-create portal account for new patient |
SCHEDULING.appointment.status.updated.v1 | scheduling-service | Push notification to patient (appointment confirmed/cancelled) |
LABORATORY.result.released.v1 | laboratory-service | Push notification to patient (new result available) |
RADIOLOGY.report.released.v1 | radiology-service | Push notification to patient (imaging report ready) |
TENANT.tenant.activated.v1 | tenant-service | Provision default portal configuration for new tenant |
4. Outbox Relay
All published events are written to the outbox table atomically within the triggering transaction and then relayed to NATS JetStream by the OutboxRelayWorker. This prevents dual-write failure and guarantees at-least-once delivery. Consumers must implement idempotent processing.