Skip to main content
Version: 1.2

19. FAQ

Q: If I don't create a NotificationEventConfiguration row for my new event, will notifications still send? A: Yes — with no configuration row, every channel is treated as enabled by default. You only need a configuration row to restrict channels for an event, or to explicitly opt an event into WhatsApp (which defaults false, unlike every other channel). See §9.4.

Q: Why did my dispatch not send on a channel I expected? A: The two most common reasons are (1) no AppNotificationTemplate exists for that EventKey + Channel + language, which fails silently by design, or (2) the channel is explicitly disabled in NotificationEventConfiguration. See Chapter 18 §18.1.

Q: Can I send a notification to a phone number or email directly, without a RecipientUserId? A: DispatchNotificationRequest requires a RecipientUserId for template-driven dispatch, but supports an optional RecipientPhone override for WhatsApp specifically (bypassing the user's stored phone, if different). For fully ad-hoc, non-templated sends, DirectCommunicationRequest exists as a separate, lower-level contract (channel + explicit RecipientEmail/RecipientPhone/RecipientUserId + raw subject/body) — see §5.1.

Q: What's the difference between NotificationDeliveryStatus and NotificationDeliveryState? A: NotificationDeliveryStatus (Pending/Sent/Failed/Retrying, ErpCompat-renamed to NotificationStatus) is the legacy status used by TenantNotificationLog (Chapter 13). NotificationDeliveryState (Pending/Processing/Succeeded/RetryScheduled/Retrying/Failed/DeadLetter/ Cancelled/Expired) is the current state machine used by NotificationDeliveryAttempt and NotificationRetryQueue (Chapter 12). They are not interchangeable — do not assume the same integer value means the same thing in both.

Q: Is WhatsApp routed through the same provider-abstraction/failover layer as Email/SMS/Push? A: No. WhatsApp is dispatched inline and directly by WhatsAppNotificationSender (ERP-owned), not through INotificationChannelProviderResolver. See §7.3 and §5.3.

Q: Can I subscribe an external system to be called when a notification is delivered (an outbound webhook)? A: Not today. "Webhooks" in this framework mean exclusively the inbound Meta → Shumoul delivery-status callback for WhatsApp. There is no customer-configurable outbound webhook subscription mechanism. See §9.11.3.

Q: Why do some campaign permissions (Execute, Approve) exist but no endpoint checks them? A: They are defined in PermissionConstants but not wired to any current controller action — likely reserved for a future manual-trigger/approval-gate feature on campaigns. Don't build integrations assuming they're enforced anywhere today. See Chapter 14.

Q: Is the legacy MultiTenancyApi notification stack ever going away? A: Not in the near term — it is classified "Stack B", confirmed live, and explicitly not scheduled for migration into the Notification Framework packages, due to its entity coupling to MultiTenancyApi-specific services. See §9.13.

Q: Some legacy topic-management endpoints have no enforced permission check — is that intentional? A: No — every [MustHavePermission] attribute on NotificationTopicsController and NotificationTopicSubscribersController is commented out in source, meaning those actions are effectively gated only by whatever bare [Authorize]/[AllowAnonymous] remains. This is documented as a real gap, not an intended design choice — see §9.13.3–9.13.4.

Q: How do I know which channels a specific event key is configured to use, right now, for my tenant? A: GET NotificationEventConfigurations/GetDetails/{id} (look it up by EventKey via GetDropdownList first) — see §9.4. If no row exists, all channels are enabled by default.

Q: Does deleting an AppNotification from a user's inbox affect analytics or delivery history? A: No — it only soft-deletes that user's inbox record. NotificationDeliveryAttempt, NotificationDeliveryReceipt, and analytics aggregates are entirely separate tables and are unaffected. See Chapter 13.

Q: Why does NotificationHistoryController live under GroupName = "identity" instead of "notifications" like every other controller? A: No documented reason was found — likely a historical artifact from when this controller was added, predating the framework's "notifications"/"notifications.campaigns"/"notifications.receipts" grouping convention. Flagged as-is rather than guessed at.

Q: Where do I go to report a bug or gap found in this documentation itself? A: This document is derived directly from source as of 2026-07-04 — if source has since changed, treat this document as out of date on that specific point and prefer current source. See Appendix § Verification Notes.