Notification FAQ
Summary
Twenty-one questions, each answered only from verified implementation. Where the honest answer is that something does not exist, that is the answer given.
Audience
Employees, administrators, support, QA, engineers, product owners and implementation partners.
Reference Content
The verified reference material for this topic is set out in the sections below.
Delivery and channels
Which channels actually deliver? In-app writes a real inbox row. Email delivers only when the SMTP provider is configured; the default provider writes to the log instead. SMS and WhatsApp are placeholders that record a simulated delivery and log a line stating no real provider is configured.
Why did an email not arrive? Most likely the email provider is the console default, in which case the content was written to the log and never sent. Otherwise check the message status and its attempt records for the provider error.
Which events send email? All but one. Every consumed event defaults to in-app and email, except the payroll-frozen event which defaults to in-app only.
Can channels be changed per event? Yes, through a configuration map keyed by event type. It is bound at startup, so a change needs a restart. There is no UI for it.
Does the service know whether an email was opened or a message was seen? No. It records only that a send attempt succeeded against the provider. Read state exists for in-app notifications only, and is set when the user opens or marks the item.
Notifications not arriving
How do I find out why a notification did not arrive? Query the audit trail by event identifier. It records thirteen stages including the negative outcomes — duplicate, stale, template missing, suppressed and delivery failed.
What does a no-recipient outcome mean? Usually that the event payload did not deserialize into the expected shape, or its key identifier was empty. For most events the payload contract is a copy held inside the notification service, so publisher field changes surface this way.
Why would a notification be skipped as stale? The event's occurrence timestamp is older than the configured staleness window, which defaults to 168 hours. Setting the window to zero disables the check.
Which modules raise notifications? Employee, Leave, Payroll, Document, Platform, Expense, Asset, Performance, Training and Helpdesk — 42 event types. Workflow, Recruitment, Attendance, Organization, Onboarding and Identity raise none.
Retry
How many times is delivery retried? Three by default, in process, with exponential backoff from a 200-millisecond base. All attempts happen within one delivery.
Is a failed notification retried later automatically? No. There is no scheduled re-drive and no retry queue. Re-driving is manual, one message at a time.
The console said a retry was queued — was it? No. The retry runs synchronously; the wording is inaccurate. The console also does not refresh afterwards, so the row stays listed until reloaded.
Templates
Where do I edit notification wording? It depends which implementation produced it. The template administration screen edits the legacy model. The extracted service's versioned templates have no editing UI and are changed through its API.
Why is part of a message blank? Rendering is tolerant — an unknown or mis-typed placeholder renders as blank rather than failing. Blanks usually mean a placeholder name mismatch or missing payload data.
Are default templates provided? Yes. 87 built-in global template rows across 44 template keys are seeded at startup when missing. Seeding never overwrites an existing row.
Can a tenant override a template? Yes. A tenant-specific row takes precedence over the global default for the same key and channel, and the highest active version wins.
Preferences
Can an employee turn a notification off? No. There is no preferences UI anywhere, and no API to manage preferences. The service enforces opt-out rows at dispatch time, but nothing can create them except direct database access.
Operations
Does a healthy health endpoint mean notifications are flowing? No. Health checks are registered but no individual check is added, so a healthy response confirms only that the HTTP host is responding. A service disconnected from the broker for hours still reports healthy.
How do I know the service is consuming? The consumer's bound-to-queue log line is the only positive signal. A recurring connect-failure warning means consumption has stopped.
Are old notifications cleaned up? No. Nothing deletes any row from any notification table. Messages, attempts, audit rows and the idempotency ledger all grow without bound.
Is there alerting? No. No alert rule, threshold or notification-on-failure exists in the repository. Monitoring is read-on-demand.
Classification
Transitional — answers reflect current verified behavior.
Requires confirmation
Production provider selection, retention policy and preference management plans require confirmation.
Related Articles
See Also
Keywords
- Notification database
- FAQ
- Draft database documentation
Source References
microservices/src/notification-service/Application/EventNotificationResolver.csmicroservices/src/notification-service/Application/NotificationDispatcher.csmicroservices/src/notification-service/Api/NotificationEndpoints.csmicroservices/src/notification-service/Application/NotificationOptions.csmicroservices/src/notification-service/Seed/DefaultTemplateSeeder.csmicroservices/src/notification-service/Application/TemplateEngine.csmicroservices/src/notification-service/Application/PreferenceEvaluator.csmicroservices/src/notification-service/Messaging/NotificationEventConsumer.csmicroservices/src/notification-service/Program.cs
Revision Information
- Status: Draft
- Last reviewed: 2026-07-21
- Review cycle: Quarterly