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.