20. Appendix
20.1 Enums
| Enum | Values | Namespace (native) |
|---|---|---|
NotificationChannel | Email=1, Sms=2, Push=3, InApp=4, SignalR=5, WhatsApp=6 | Shumoul.Notification.Contracts |
NotificationDeliveryChannel | Email=1, Sms=2, Push=3, InApp=4, SignalR=5 (no WhatsApp) | Shumoul.Framework.Application.Notifications |
DevicePlatform | Android=1, Ios=2, Web=3 | Shumoul.Notification.Contracts |
SaaSNotificationType | BusinessNotification=0, Registration=1, ProvisioningCompleted=2, SubscriptionActivated=3, SubscriptionRenewed=4, SubscriptionUpgraded=5, SubscriptionPaused=6, SubscriptionReactivated=7, SubscriptionExpired=8, ExpiryReminder=9 | Shumoul.Notification.Contracts |
NotificationDeliveryStatus (ErpCompat: NotificationStatus) | Pending=0, Sent=1, Failed=2, Retrying=3 | Shumoul.Notification.Contracts |
NotificationDeliveryState | Pending=0, Processing=1, Succeeded=2, RetryScheduled=3, Retrying=4, Failed=5, DeadLetter=6, Cancelled=7, Expired=8 | Shumoul.Notification.Contracts |
NotificationFailureType | Unknown=0, Temporary=1, Permanent=2, Timeout=3, RateLimit=4, NetworkFailure=5, AuthenticationFailure=6, InvalidRecipient=7, QuotaExceeded=8 | Shumoul.Notification.Contracts |
RetryStrategy | None=0, Fixed=1, ExponentialBackoff=2, Linear=3, Immediate=4 | Shumoul.Notification.Contracts |
NotificationDeadLetterStatus | Pending=0, Requeued=1, Cancelled=2 | Shumoul.Notification.Contracts |
SaaSNotificationScheduleStatus | Pending=0, New=1, Canceled=2 | Shumoul.Notification.Contracts |
NotificationReceiptStatus | Unknown=0, Sent=1, Delivered=2, Read=3, Opened=4, Clicked=5, Failed=6, Rejected=7, Expired=8, Bounced=9, Unsubscribed=10 | Shumoul.Notification.Contracts.Receipts |
ProviderHealthState | Unknown=0, Healthy=1, Degraded=2, Unavailable=3 | Shumoul.Notification.Contracts.Providers |
CampaignType | OneTime=1, Scheduled=2, Recurring=3, Workflow=4, Drip=5, Reminder=6 | Shumoul.Notification.Contracts.Campaigns |
CampaignStatus | Draft=0, Scheduled=1, Running=2, Paused=3, Completed=4, Cancelled=5, Failed=6 | Shumoul.Notification.Contracts.Campaigns |
CampaignExecutionStatus | Pending=0, Running=1, Succeeded=2, Failed=3, Skipped=4, Cancelled=5 | Shumoul.Notification.Contracts.Campaigns |
RecurrenceType | OneTime=0, Hourly=1, Daily=2, Weekly=3, Monthly=4, Yearly=5, Cron=6, CustomInterval=7 | Shumoul.Notification.Contracts.Campaigns |
DelayUnit (ErpCompat: CampaignDelayUnit) | Seconds=0, Minutes=1, Hours=2, Days=3, Weeks=4, Months=5 | Shumoul.Notification.Contracts.Campaigns |
WorkflowStepTrigger | Always=0, OnDeliverySucceeded=1, OnDeliveryFailed=2, OnRetryExhausted=3, OnCustomEvent=4 | Shumoul.Notification.Contracts.Campaigns |
AudienceSourceType | SpecificUsers=0, Roles=1, Subscribers=2, TenantUsers=3, QueryResult=4, DynamicQuery=5 | Shumoul.Notification.Contracts.Campaigns |
Every enum above also exists under Shumoul.Domain.Enums.Notifications via the ErpCompat namespace shim
(same values, same names, except where a rename is noted) — see §5.1.
20.2 DTOs
The complete field-level DTO reference is embedded per-endpoint throughout Chapter 9 rather than repeated here. Quick index by concern:
| Concern | Where documented |
|---|---|
AppNotification* DTOs | §9.1, §9.2 |
DeviceToken* DTOs | §9.3 |
NotificationEventConfiguration* DTOs | §9.4 |
NotificationDeliveryPolicy* DTOs | §9.5 |
NotificationRetryQueue* DTOs | §9.6 |
NotificationDeadLetter* DTOs | §9.7 |
| Analytics DTOs (9 types) | §9.8 |
NotificationCampaign* DTOs (campaign + step + audience + execution) | §9.9, §9.10 |
NotificationDeliveryReceipt* / webhook DTOs | §9.11 |
TenantNotificationLog* DTOs (legacy) | §9.12 |
DispatchNotificationRequest, DirectCommunicationRequest, ChannelDeliveryResult, ChannelDispatchContext | §5.1, §6, §8.4 |
Validators that exist today: AppNotificationTemplateValidator, AppNotificationValidator (validates a
generic DeleteDto, not an AppNotification-specific shape), NotificationEventConfigurationValidator. No
validator exists for DeviceTokenEditDto, NotificationDeliveryPolicyEditDto,
NotificationCampaignEditDto, or any retry-queue/dead-letter/receipt DTO — noted per-endpoint where relevant.
20.3 Terminology / Glossary
| Term | Meaning |
|---|---|
| EventKey | A string identifying a business event (e.g. PurchaseInvoicePosted) that templates and event configurations are keyed by |
| Channel | One of Email, SMS, WhatsApp, Push, SignalR, InApp |
| Dispatch | The act of an ERP business service requesting a notification be sent for an event |
| Delivery Attempt | One append-only record of a single try to deliver on one channel |
| Retry Queue | A scheduled future retry of a previously failed, retryable delivery attempt |
| Dead Letter | A terminal record of a delivery that exhausted retries or failed permanently |
| Delivery Receipt | A provider-reported, asynchronous confirmation of delivery status (currently WhatsApp/Meta only) |
| Campaign | A scheduled/recurring/multi-step bulk-notification entity targeting a resolved audience |
| Workflow (in campaign context) | A CampaignType = Workflow campaign whose steps have conditional triggers (WorkflowStepTrigger) |
| Provider | A concrete integration with a specific vendor (e.g. ZohoEmailProvider, FourJawalySmsProvider, MetaWhatsAppProvider) |
| Channel Provider | The unified INotificationChannelProvider dispatch-layer wrapper around a channel (may itself use multiple underlying providers) |
| ErpCompat | The namespace-shim layer letting ERP code import framework enums/DTOs under classic Shumoul.Domain/Shumoul.Application namespaces |
| Golden Reference | The platform's certification tier for a fully extracted, standalone, versioned framework module |
20.4 Reference links
| Resource | Location |
|---|---|
| Architecture Standards | docs/ARCHITECTURE/STANDARDS/ (this repo) |
| ADR-002 (entity base class deviation) | docs/ARCHITECTURE/adr/ADR-002-notification-entity-base-class-deviation.md |
| Legacy Cleanup Readiness | docs/ARCHITECTURE/LEGACY_CLEANUP_READINESS.md |
| TenantNotificationLog retention decision | docs/NOTIFICATION_PHASE3_TENANTNOTIFICATIONLOG_DECISION.md |
| Legacy assets verification | NOTIFICATION_FRAMEWORK_LEGACY_ASSETS_VERIFICATION_REPORT.md (repo root) |
| Phase reports (historical, superseded on the points noted in §3.6) | docs/NOTIFICATION_FRAMEWORK_PHASE4*.md |
| WhatsApp SignalR events | docs/WHATSAPP_SIGNALR_EVENTS.md |
| Platform environment variables | docs/PLATFORM_ENVIRONMENT_VARIABLES.md |
| Platform secrets runbook | docs/PLATFORM_SECRETS_RUNBOOK.md |
| Branding assets | docs/assets/branding/ |
20.5 Verification Notes
Every fact in this documentation was checked against source as of 2026-07-04. Where verification could not be completed to the same standard as the rest of the document, it is flagged here rather than silently treated as certain:
NotificationAnalyticsSummaryDtoand sibling analytics DTO field names (§9.8) were derived from the endpoints' XML doc comments and general naming conventions rather than a field-by-field source read — verify exact property names against the liveShumoul.Notification.Contracts.ErpCompat.DTOssource before binding a strongly-typed client against them.- The exact SignalR hub mapping path (the URL clients connect to) was not independently re-confirmed in
this pass — confirm the exact route via your environment's MultiTenancyApi
Program.cs/Startup.csMapHub<NotificationHub>()call before hardcoding a client URL. - SMS provider configuration key names (§15.5)
were not found in the tracked
appsettings.json— confirmed absent from that file, but the actual environment-variable names used in production were not independently verified. - Total endpoint/action counts in §9.1 (91 active + 29 legacy = 120) were derived by direct enumeration during this documentation pass; re-count if controllers are added or removed after 2026-07-04.
- Three of six originally-planned research passes for this documentation initiative hit an account-level session usage limit partway through and were completed via direct, narrower follow-up reads instead of the original broad-sweep approach — the SignalR/push/device-token, channels/templates/configuration, and deployment/testing chapters reflect that narrower-but-still-source-verified research path.
If you find a discrepancy between this documentation and current source, trust current source and treat
this document as needing an update — see the branding/versioning note in
docs/assets/branding/README.md for how documentation updates should be
sequenced relative to content changes.