Skip to main content

04 — Event Catalog

Status: ✅ Draft
Prerequisite: TD2, 01 — Service Decomposition
Next: 05 — Event Schemas

Complete inventory of all event types on the platform — every event Core publishes and every event modules publish. For each event: who produces it, who consumes it, what triggers it, and what its retention and replay requirements are.

Payload schemas (field-level definitions) are in 05 — Event Schemas. This document is the catalog — what exists and why. Doc 05 is the schema — exactly what each event contains.


1. Event Naming Convention

All event types follow domain.action dot notation. Lowercase. No abbreviations.

registration.confirmed
allocation.waitlisted
miqaat.phase.changed
capacity.imbalance.detected

Rules:

  • domain — the owning module or Core engine (e.g. registration, allocation, rbac, miqaat)
  • action — past tense verb describing the state change that occurred (e.g. confirmed, changed, detected)
  • No future tense (registration.willConfirm is wrong — events describe what happened, not what will happen)
  • No underscores in the event type name — use dots only

Module teams register their event types with the Domain Event Schema Registry before publishing. The registered name becomes the contract identifier.


2. Standard Envelope (Reference)

Every event on the platform uses the same envelope, confirmed in TD2. The payload field is what varies per event type. Full schema is in 05 — Event Schemas.

{
"eventId": "uuid-v4",
"eventType": "registration.confirmed",
"schemaVersion": "1.0",
"timestamp": "2026-07-15T10:30:00Z",
"idempotencyKey": "uuid-v4",
"sourceModule": "ams",
"miqaatId": "MQ-1447-KHI",
"itsId": "ITS-1234567",
"correlationId": "uuid-v4",
"payload": { }
}

3. Core-Published Events

Core engines publish decision events when they complete an action that the rest of the platform needs to react to. These are Core-to-platform broadcasts — not module-to-module events.

Contract IDs C-020 to C-026 are assigned to these events (from TD3 Section 6).


miqaat.created · C-020a

ItemDetail
ProducerMiqaat Lifecycle Engine
ContractC-020a
Fire conditionA new Miqaat is created in Platform Admin and assigned a miqaatId for the first time
Who subscribesConfig Cascade Engine (seeds default config for new Miqaat) · All modules (to learn a new Miqaat is available) · Audit Log Backbone
Why modules careModules need to know a new Miqaat exists so they can begin their own setup workflows and display it in Miqaat pickers
RetentionLong — platform lifecycle record
Replay requirementYes — Config Cascade must be able to replay this to rebuild its state

miqaat.phase.changed · C-020

ItemDetail
ProducerMiqaat Lifecycle Engine
ContractC-020
Fire conditionA Miqaat transitions from one phase to the next (e.g. setupregistration_open, registration_openregistration_closed, operationalclosed)
Who subscribesAll modules (phase change affects what operations are permitted) · Config Cascade Engine · Rule Engine · Allocation Engine · Audit Log Backbone
Why modules careModules gate their own features on Miqaat phase — registration UI opens on registration_open, passes are printed on operational, etc. Modules listen to this event and react rather than polling Core for phase
RetentionLong — all phase changes are lifecycle records
Replay requirementYes — modules that go down during a phase transition must replay to get current state

miqaat.archived · C-020b

ItemDetail
ProducerMiqaat Lifecycle Engine
ContractC-020b
Fire conditionA Miqaat is archived — all operations are closed, records are sealed
Who subscribesAll modules · Audit Log Backbone
Why modules careModules must close all open workflows, disable write operations, and switch to read-only mode for archived Miqaat data
RetentionPermanent — archive event is part of the Miqaat's immutable record
Replay requirementYes

allocation.confirmed · C-021

ItemDetail
ProducerAllocation Engine
ContractC-021
Fire conditionAn allocation request is accepted and a seat/slot is confirmed for the Mumin
Who subscribesThe requesting module (e.g. AMS, Istefadah Registration) · Notification Dispatch Engine (to trigger confirmation message) · Audit Log Backbone · HR Bank (if the allocation is tied to a khidmat role)
Why modules careThe module that submitted the allocation request needs to update its own records to reflect the confirmed state and trigger downstream workflows (e.g. pass generation, welcome communication)
RetentionLong — allocation records are platform history
Replay requirementYes — critical for state reconstruction after an outage

allocation.waitlisted · C-022

ItemDetail
ProducerAllocation Engine
ContractC-022
Fire conditionAn allocation request is received but no seat/slot is available — the Mumin is placed on the waitlist
Who subscribesThe requesting module · Notification Dispatch Engine (to trigger waitlist notification) · Audit Log Backbone
Why modules careModule needs to update its own records to reflect waitlist status and communicate it to the Mumin
RetentionLong
Replay requirementYes

allocation.released · C-022a

ItemDetail
ProducerAllocation Engine
ContractC-022a
Fire conditionA confirmed allocation is released (cancelled by the Mumin, revoked by an operator, or freed up due to Miqaat capacity change) — next person on the waitlist is promoted
Who subscribesThe holding module · Notification Dispatch Engine · Audit Log Backbone
Why modules careModule must update its records, revoke pass if already issued, and acknowledge the waitlist promotion flow
RetentionLong
Replay requirementYes

capacity.imbalance.detected · C-023

ItemDetail
ProducerCapacity Balance Engine
ContractC-023
Fire conditionCapacity figures received from modules (via capacity.configured events) are out of acceptable ratio — e.g. Vaaz venue significantly exceeds Mawaid or Kitchen capacity
Who subscribesPlatform Admin dashboard · Audit Log Backbone
Why modules carePlatform Admin surfaces this as a pre-go-live alert. Modules with misconfigured capacity may receive follow-up from the ops team. Not a direct module consumer — this is an operational alert for the Core ops team.
RetentionMedium — relevant until the Miqaat is operational and balanced
Replay requirementNo

eligibility.status.changed · C-024

ItemDetail
ProducerEligibility Engine
ContractC-024
Fire conditionA Mumin's eligibility status for a given Miqaat and rule set changes — either from eligible to ineligible or from ineligible to eligible (e.g. after a rule change or new data from ITS sync)
Who subscribesThe module that triggered the eligibility check · Allocation Engine (if eligibility gates allocation) · Notification Dispatch Engine · Audit Log Backbone
Why modules careA Mumin whose eligibility status changes after registration has been submitted requires the module to act (revoke, notify, escalate)
RetentionLong — eligibility changes are audit-sensitive
Replay requirementYes

role.assigned · C-025

ItemDetail
ProducerRBAC Engine
ContractC-025
Fire conditionA role is assigned to an itsId for a given Miqaat scope in Platform Admin
Who subscribesThe affected module (if it needs to unlock features for this role) · Notification Dispatch Engine (to notify the person) · Audit Log Backbone
Why modules careSome modules conditionally unlock UI features or workflows when a user holds a specific role. Listening to role.assigned lets them react without polling RBAC.
RetentionLong — role changes are audit records
Replay requirementYes

role.revoked · C-026

ItemDetail
ProducerRBAC Engine
ContractC-026
Fire conditionA role is revoked from an itsId in Platform Admin
Who subscribesAll modules holding cached role state for this itsId · Notification Dispatch Engine · Audit Log Backbone
Why modules careModules must not serve UI features or approve actions for a role that has been revoked. This event is the signal to invalidate any local role cache.
RetentionLong
Replay requirementYes

4. Module-Published Events

Business modules are the primary event publishers. Every significant state change in a module is published as an event. The module owns the event type and its schema.

Events are listed by domain group — registration, volunteer management, accommodation, scanning, payment, and operational. Within each group: event type, publishing module, Core subscribers, and fire condition.


4.1 Registration Events

Event TypePublisherCore SubscribersFire Condition
registration.submittedAMS, Istefadah RegistrationAudit LogA Mumin submits a registration form — not yet confirmed
registration.confirmedAMS, Istefadah RegistrationEligibility Engine · HR Bank · Audit LogRegistration is accepted and confirmed (after eligibility and allocation checks pass)
registration.cancelledAMS, Istefadah RegistrationAllocation Engine · Audit LogA registration is cancelled by the Mumin or an operator
registration.rejectedAMS, Istefadah RegistrationAudit LogA registration is rejected (e.g. eligibility failure after submission)

AMS is the primary publisher for community/safar-level registrations. Istefadah Registration module publishes for Istefadah-specific registrations. Both modules publish to the same event types — the sourceModule field distinguishes the publisher.


4.2 Attendance Events

Event TypePublisherCore SubscribersFire Condition
attendance.recordedAMS, Istefadah Registration, ScanningEligibility Engine (for prior attendance rules) · HR Bank · Audit LogAttendance for a session or day is recorded for a Mumin
attendance.checked_inJamaat Scan, Kiosk, ScanningAudit LogA Mumin checks in at a venue or session via scanning or kiosk
attendance.checked_outJamaat Scan, Kiosk, ScanningAudit LogA Mumin checks out (where applicable)

4.3 Volunteer & Khidmat Events

Event TypePublisherCore SubscribersFire Condition
volunteer.appliedVMSAudit LogA Mumin applies to volunteer for a khidmat role
volunteer.assignedVMSHR Bank · Audit LogA Mumin is assigned to a volunteer role
volunteer.approvedVMSAudit LogA volunteer assignment is approved by an authorised coordinator
volunteer.releasedVMSHR Bank · Audit LogA volunteer is released from their assigned role
khidmat.assignedVMSHR Bank · Audit LogA khidmat (service role) is formally assigned — HR Bank uses this to build the cross-Miqaat history record
khidmat.completedVMSHR Bank · Audit LogKhidmat is confirmed as completed — HR Bank writes the history record

Why khidmat.assigned and volunteer.assigned are separate: volunteer.assigned is an operational state within VMS (the person is rostered). khidmat.assigned is the formal platform-level record that HR Bank cares about — it may fire later, after confirmation, and carries additional context about the role type and Miqaat scope.


4.4 Accommodation Events

Event TypePublisherCore SubscribersFire Condition
accommodation.allocatedAccommodation moduleAudit LogA Mumin is allocated to accommodation (Bethak, room, hotel)
accommodation.releasedAccommodation moduleAudit LogAccommodation allocation is released
capacity.configuredAccommodation, Venue, Mawaid, Kitchen modulesCapacity Balance Engine · Audit LogA module finalises its capacity figure for the Miqaat — triggers Capacity Balance Engine to check ratios

capacity.configured is special — it is published by multiple modules (venue, food, accommodation, kitchen) and is the primary trigger for the Capacity Balance Engine. Each module publishes once when its capacity is finalised, and again if the figure changes. The Capacity Balance Engine aggregates across all of them.


4.5 Pass & Scanning Events

Event TypePublisherCore SubscribersFire Condition
pass.generatedPass module, Scanning moduleAudit LogA Miqaat pass is generated for a Mumin
pass.printedScanning, KioskAudit LogA physical pass is printed — triggers the point of no return in pass issuance
pass.revokedPass module, Platform AdminAudit LogA pass is revoked (allocation cancelled, rule violation, operator action)
checkpoint.scannedJamaat Scan, Scanning, KioskAudit LogA pass or ID is scanned at a checkpoint — records movement/entry
sharaf.photo.capturedSharaf Photos moduleAudit LogA Sharaf photo is captured for a Mumin (Ashara Mubaraka context)

4.6 Payment Events

Event TypePublisherCore SubscribersFire Condition
payment.receivedPayment moduleEligibility Engine · Audit LogPayment is confirmed received and cleared
payment.failedPayment moduleAudit LogA payment attempt fails
payment.refundedPayment moduleAudit LogA payment is refunded

Eligibility Engine subscribes to payment.received because payment clearance can gate registration eligibility in some Miqaat types (e.g. Vajebaat payment must be confirmed before Istefadah eligibility resolves).


4.7 Communications Events

Event TypePublisherCore SubscribersFire Condition
broadcast.sentBroadcast moduleAudit LogA broadcast message is dispatched to a group audience
notification.deliveredNotification Dispatch EngineAudit LogA Notification Dispatch delivery is confirmed by the channel
notification.failedNotification Dispatch EngineAudit LogA delivery attempt fails after all retries are exhausted

Broadcast vs Notification: Confirmed in Day 4 sessions — Broadcast (bulk, Jamaat-wide, role-targeted) is a separate engine from Notification Dispatch (individual, transactional, triggered by module events). They have separate event types.


4.8 Safar & Miqaat Management Events

Event TypePublisherCore SubscribersFire Condition
safar.createdSafar Management moduleAudit LogA new Safar record is created in ITS (community record — distinct from a Core miqaat.created event)
safar.updatedSafar Management moduleAudit LogSafar record is updated
grouping.assignedGrouping module (Istefadah)Audit LogA Mumin is assigned to a group/bethak for the Miqaat
timetable.publishedTimetable moduleAudit LogA Miqaat timetable is published — visible to all modules and attendees
helpline.ticket.raisedHelpline moduleAudit LogA helpline ticket is raised during the Miqaat
helpline.ticket.resolvedHelpline moduleAudit LogA helpline ticket is resolved

4.9 Vendor & Procurement Events

Event TypePublisherCore SubscribersFire Condition
indent.raisedAny module with procurement workflowVendor Registry · Audit LogA procurement indent is raised by a module
indent.approvedAny module with procurement workflowAudit LogAn indent is approved in the module's workflow
indent.rejectedAny module with procurement workflowAudit LogAn indent is rejected

Vendor Registry subscribes to indent.raised to track procurement activity against the budget envelope and to flag cross-event vendor conflicts.


4.10 Nikah & Rasm Events

Event TypePublisherCore SubscribersFire Condition
nikah.application.submittedNikah moduleAudit LogA Nikah application is submitted
nikah.approvedNikah moduleAudit LogNikah application approved
rasm.saifee.recordedRasm-e-Saifee moduleAudit LogA Rasm-e-Saifee ceremony is recorded
misaaq.recordedMisaaq moduleAudit LogA Misaaq commitment is recorded — triggers eligibility updates in some rule sets

misaaq.recorded may feed the Eligibility Engine in some Miqaat rule configurations — a Mumin who has not yet taken Misaaq may be ineligible for certain Istefadah slots.


5. Producer → Consumer Map

Full cross-reference of every event type and its subscribers.

Core engine as consumer

Event TypeCore Engine SubscriberReason
capacity.configuredCapacity Balance EngineTriggers ratio check across all modules
khidmat.assignedHR BankBuild cross-Miqaat khidmat record
khidmat.completedHR BankMark khidmat as completed in history
volunteer.assignedHR BankCross-reference with khidmat record
volunteer.releasedHR BankUpdate history if khidmat was in progress
registration.confirmedEligibility EngineUpdates eligibility state for attendance-based rules in future Miqaats
attendance.recordedEligibility EnginePrior attendance rule family — records attendance count
payment.receivedEligibility EnginePayment-gate rule family — clears payment block on eligibility
misaaq.recordedEligibility EngineMisaaq rule family — clears eligibility block
indent.raisedVendor RegistryBudget envelope tracking; conflict detection
miqaat.createdConfig Cascade EngineSeeds default config for new Miqaat
All eventsAudit Log BackboneImmutable platform-wide audit record

Core engine as publisher — module consumer

Event TypeCore PublisherWho Typically Subscribes
miqaat.createdMiqaat LifecycleAll modules (Miqaat picker, setup workflows)
miqaat.phase.changedMiqaat LifecycleAll modules (feature gating on phase)
miqaat.archivedMiqaat LifecycleAll modules (switch to read-only)
allocation.confirmedAllocation EngineRequesting module · Pass module · Notification Dispatch
allocation.waitlistedAllocation EngineRequesting module · Notification Dispatch
allocation.releasedAllocation EngineRequesting module · Pass module
eligibility.status.changedEligibility EngineRequesting module · Allocation Engine
capacity.imbalance.detectedCapacity BalancePlatform Admin only
role.assignedRBAC EngineAffected module · Notification Dispatch
role.revokedRBAC EngineAll modules (cache invalidation)

6. Event Retention and Replay

Retention tiers

TierRetentionEvent types
PermanentNever deletedmiqaat.created · miqaat.archived · role.assigned · role.revoked · allocation.confirmed · khidmat.completed · registration.confirmed · all audit-sensitive events
LongUntil 1 year post Miqaat archive (TBC — security session)Most operational events — miqaat.phase.changed · allocation.waitlisted · attendance.recorded · pass.generated · pass.printed · payment.received
MediumUntil Miqaat closes (TBC)capacity.configured · capacity.imbalance.detected · checkpoint.scanned · helpline.ticket.*

Retention periods marked TBC are subject to the Dedicated Security session outcome (data residency, compliance, and audit retention policy).

Replay requirements

Must support replay (consumer goes down and needs to catch up):

  • All Core-engine subscribers — Eligibility Engine, HR Bank, Capacity Balance Engine must be able to replay from a given offset
  • All modules subscribing to miqaat.phase.changed and role.revoked — state changes that affect feature gating

Replay is at-least-once delivery. Consumers must use idempotencyKey in the event envelope to detect and safely ignore duplicate delivery. Exactly-once is not a platform guarantee — this shifts the idempotency responsibility to consumers.


7. Event Bus Operational Requirements

Confirmed in TD2. Included here for completeness.

RequirementDetail
DurabilityEvents must not be dropped on publish. Durable storage required — no in-memory-only bus
Replay from offsetConsumers must be able to replay from any point in the event stream — required for recovery after module downtime during peak windows
At-least-once deliveryPlatform assumes at-least-once. Consumers handle idempotency.
Consumer groupsMultiple modules may subscribe to the same event type independently. Each gets its own copy and manages its own offset.
Dead Letter Queue (DLQ)Events that exceed retry limits land in a DLQ. Visible in Platform Admin Event Bus Health. Core team inspects, retries, or discards.
Topic-level ACLsModule credentials only grant access to their registered event type topics. A module cannot read another module's topics unless explicitly subscribed.
Schema version mismatch alertsPlatform Admin surfaces alerts when a consumer is receiving events in a schema version it has not declared support for

Bus technology: Under analysis — decision confirmed before Phase 1 infrastructure provisioning. Pattern B and the event envelope are confirmed regardless of technology.


8. Subscription Management

A module declares its event subscriptions in its System Definition Document before build begins. Core provisions bus-level topic access based on those declarations at onboarding.

A module's bus credentials grant access only to the topics it declared. If requirements change:

  1. Module team updates their System Definition Document
  2. Core team reviews and provisions the additional subscription in Platform Admin
  3. Module team is notified when access is provisioned

Modules cannot self-provision new subscriptions. This prevents data leakage — a module cannot read another module's operational events by guessing topic names.


9. Open Questions

QuestionBlocked On
Exact retention periods per tierDedicated Security session (data residency + compliance)
Event bus technology selectionInfrastructure session + TD2 analysis
Whether capacity.configured fires once (finalization) or can be updatedBusiness / module design session
misaaq.recorded → Eligibility Engine subscription — which rule sets does this apply to?Business session (module-specific rule configuration)
Historical event migration — what happens to events from pre-Core Miqaats?Migration planning session
Module-specific event types for AMS + 11 remaining modulesRemaining discovery sessions