Config Service — Event Schemas
Status: populated Owner: TBD Last updated: 2026-04-18 Companion: Service Template · 03 platform-services · 04 event-driven-architecture
1. Envelope
All events follow CloudEvents 1.0 specification.
| Field | Value |
|---|---|
specversion | "1.0" |
source | "ghasi/config-service" |
datacontenttype | "application/json" |
subject (NATS subject) | config.{aggregate}.{event}.v{N} |
Subject pattern per NAMING.md: {service}.{aggregate}.{event}.v{N}
Service domain: config
2. Events Produced
2.1 NATS Subject Map
| Subject | JetStream Stream | Retention | Produced when |
|---|---|---|---|
config.feature.created.v1 | cfg-feature-events | 7 years | Feature definition created |
config.feature.updated.v1 | cfg-feature-events | 7 years | Feature definition updated |
config.role.created.v1 | cfg-role-events | 7 years | Role definition created |
config.role.updated.v1 | cfg-role-events | 7 years | Role definition updated |
config.role.deleted.v1 | cfg-role-events | 7 years | Role soft-deleted |
config.role_grant.created.v1 | cfg-role-events | 7 years | Role feature grant created |
config.role_grant.updated.v1 | cfg-role-events | 7 years | Role feature grant updated |
config.ui_definition.created.v1 | cfg-ui-events | 7 years | UI element definition created |
config.ui_definition.updated.v1 | cfg-ui-events | 7 years | UI element definition updated |
config.user_override.created.v1 | cfg-override-events | 7 years | User node override created |
config.user_override.deleted.v1 | cfg-override-events | 7 years | User node override soft-deleted |
config.design_token.updated.v1 | cfg-token-events | 7 years | Design token value changed |
config.config.cache_busted.v1 | cfg-ops-events | 7 days | Cache eviction completed |
2.2 config.feature.created.v1
{
"specversion": "1.0",
"type": "config.feature.created.v1",
"source": "ghasi/config-service",
"id": "feat_01JRXXXX",
"time": "2026-04-18T09:00:00Z",
"datacontenttype": "application/json",
"data": {
"featureId": "feat_01JRXXXX",
"featureKey": "ViewMedications",
"moduleKey": "CLIN-MEDS",
"tenantId": "ten_afg_moph_001",
"allowedActions": ["medication:read"],
"dataScopeType": "sameFacility",
"createdBy": "usr_tenantadmin001"
}
}
2.3 config.feature.updated.v1
{
"data": {
"featureId": "feat_01JRXXXX",
"featureKey": "ViewMedications",
"tenantId": "ten_afg_moph_001",
"changes": {
"before": { "allowedActions": ["medication:read"] },
"after": { "allowedActions": ["medication:read", "medication:list"] }
},
"updatedBy": "usr_tenantadmin001"
}
}
2.4 config.role.created.v1
{
"data": {
"roleId": "role_01JRXXXX",
"roleKey": "ClinicalStaff",
"tenantId": "ten_afg_moph_001",
"isAbstract": true,
"isSystem": false,
"createdBy": "usr_superadmin001"
}
}
2.5 config.role.updated.v1
{
"data": {
"roleId": "role_01JRXXXX",
"roleKey": "ClinicalStaff",
"tenantId": "ten_afg_moph_001",
"changes": {
"before": { "displayName": "Clinical Staff" },
"after": { "displayName": "Clinical Staff (Expanded)" }
},
"updatedBy": "usr_superadmin001"
}
}
2.6 config.role.deleted.v1
{
"data": {
"roleId": "role_01JRXXXX",
"roleKey": "WARD_REGISTRAR",
"tenantId": "ten_afg_moph_001",
"deletedBy": "usr_tenantadmin001"
}
}
2.7 config.role_grant.created.v1
{
"data": {
"grantId": "grant_01JRXXXX",
"roleKey": "NURSE",
"tenantId": "ten_afg_moph_001",
"featureKey": "ManageClinicalNotes",
"grantedActions": ["note:read", "note:write"],
"deniedActions": ["note:sign"],
"createdBy": "usr_superadmin001"
}
}
2.8 config.ui_definition.created.v1
{
"data": {
"elementId": "uid_01JRXXXX",
"elementKey": "add-medication-btn",
"elementType": "element",
"featureKey": "ViewMedications",
"tenantId": "ten_afg_moph_001",
"actionBinding": "medication:write",
"defaultProps": { "visible": true, "interactable": true },
"createdBy": "usr_superadmin001"
}
}
2.9 config.user_override.created.v1
{
"data": {
"overrideId": "ovr_01JRXXXX",
"tenantId": "ten_afg_moph_001",
"userId": "usr_nurse_nargis",
"nodeId": "cfgn_01JRXXXX",
"featureKey": "ViewMedications",
"action": "medication:write",
"effect": "allow",
"justification": "Night dispensing protocol — SDK Ward A emergency authorization",
"effectiveFrom": "2026-01-01",
"effectiveTo": "2026-12-31",
"grantedBy": "usr_tenantadmin001"
}
}
2.10 config.design_token.updated.v1
{
"data": {
"tokenId": "tok_01JRXXXX",
"tenantId": "ten_afg_moph_001",
"scopeType": "tenant",
"tokenKey": "brand.primary",
"before": "#003399",
"after": "#006600",
"locale": null,
"updatedBy": "usr_tenantadmin001"
}
}
2.11 config.config.cache_busted.v1
{
"data": {
"cacheKeyPattern": "cfg:ten_afg_moph_001:*:*:CLIN-MEDS:ViewMedications",
"reason": "feature.updated",
"triggeringEventId": "feat_01JRXXXX",
"tenantId": "ten_afg_moph_001"
}
}
3. Events Consumed
| Subject consumed | Source | Action taken |
|---|---|---|
config.feature.updated.v1 (self) | config-service | Evict feature resolution cache keys |
config.role.*.v1 (self) | config-service | Evict role BFS expansion cache |
config.role_grant.*.v1 (self) | config-service | Evict role BFS expansion cache |
config.ui_definition.*.v1 (self) | config-service | Evict UI config cache |
config.user_override.*.v1 (self) | config-service | Evict user resolution + UI cache |
config.design_token.updated.v1 (self) | config-service | Evict token cache |
tenant.tenant.updated.v1 | tenant-service | Refresh tenant root config node |
4. Consumer Reaction Map
| Event | Consumer | Reaction |
|---|---|---|
config.feature.* | config-service (self) | Evict cfg:{tenantId}:*:*:{moduleKey}:{featureKey} |
config.role.* | config-service (self) | Evict cfg:roles:{tenantId}:{roleKey}:expanded; cascade |
config.role_grant.* | config-service (self) | Evict role BFS cache for affected role |
config.ui_definition.* | config-service (self) | Evict cfg:ui:{tenantId}:*:{featureKey} |
config.user_override.* | config-service (self) | Evict cfg:{tenantId}:{userId}:* |
config.design_token.updated.v1 | Frontend SDK | Re-fetch tokens; re-apply MUI ThemeProvider |
| All events | audit-service | Persist audit record (7-year retention) |
5. Dead Letter Queue
DLQ subject: config.dlq
| Condition | Retry | Post-retry |
|---|---|---|
| Redis eviction failure | 3 retries, 1 s/2 s/4 s exponential backoff | Alert on 3rd failure |
| 5 NACKs from consumer | NATS JetStream moves to DLQ | Alert if DLQ depth > 10 |
| Schema validation failure | No retry | Manual review; log event ID |
DLQ consumer: emits CRITICAL log, publishes safety-net config.config.cache_busted.v1 for affected tenant. Replay requires operator acknowledgement.