Skip to main content

Notification Gateway and Compatibility

Summary

The gateway declares one toggled proxy route for the /api/notifications prefix and one permanently registered shadow route for /notifications. The legacy monolith retains ten authorized notification operations. The native and legacy contracts differ, so the module is Transitional.

Audience

Engineers, architects, DevOps engineers, QA, support and security reviewers.

Gateway routing

Feature toggle

The gateway resolves a boolean from an environment-style key first, then a configuration section key, defaulting to false. When false — the default — notification traffic stays on the monolith. Flipping it off is the documented rollback.

The toggle governs a single owned prefix: notifications. The notification-templates prefix is not in the owned-prefix set, so monolith template traffic is unaffected by the toggle.

Route configuration

The prefix routes are generated from a shared prefix list. Each produces a route whose identifier combines the resolved cluster with the prefix, matching /api/{prefix}/{**catch-all}, and whose cluster is selected by the toggles. The notification prefix resolves to the notification-service cluster only when the notification toggle is on.

Verified path caveat. These generated prefix routes declare no path transform. The route matches /api/notifications/** and forwards the path unchanged. The native service, however, maps its routes at /notifications/* and /notification-templates/* — it maps nothing under /api. Toggling the route to the notification-service cluster therefore forwards paths that the native service does not map. Other services in the same file that require rewriting receive an explicit prefix-removal transform; the notification prefix route does not.

Whether the toggle-on path is intended to be accompanied by a transform, by native /api routes, or by a different alignment strategy is classified Requires confirmation. No runtime behavior is asserted here.

Shadow route

A separate route, identified as the notification-service shadow, is registered unconditionally against the notification-service cluster and matches /notifications/{**catch-all}. It declares no transform, which aligns exactly with the native route prefix. This is the path that reaches the native surface without rewriting.

Unlike several other services in the same file, the notification shadow route uses the bare resource prefix rather than a distinct service-named prefix, so it shares a namespace with the monolith's own paths at the gateway.

Route-source header

The gateway computes a route-source value from the request path and the toggles. Paths beginning with the notifications prefix resolve to the shadow source value; paths beginning with the /api/notifications prefix resolve to either the notification-service value or the monolith value depending on the toggle. This value is intended for diagnosis of which backend a request was directed to.

Legacy compatibility surface

The monolith retains two authorized controllers. Both declare [Authorize] and resolve the caller from the email claim on the principal.

Notifications controller — six operations. It reads from two tables and merges them into one projection, tagging each row with a source discriminator so the caller can distinguish current rows from legacy rows. The read action honours that discriminator to decide which table to update, and ownership is enforced by matching the row's user against the resolved caller. Identifiers are integers.

Template controller — four operations keyed by an event key string rather than an identifier, with an update, a preview and a reset to a built-in definition default. Templates expose separate in-app and email fields and a scoped-override flag.

Contract divergence

AspectNative surfaceCompatibility surface
Identifier typeGUIDInteger
Template keyTemplate key plus channel plus versionEvent key
Template modelSubject and body per channel, versionedTitle, message, email subject and email body on one row
ChannelsIn-app, email, SMS, WhatsAppIn-app and email flags
Read stateStatus value with a read timestampBoolean flag
AuthenticationNone declaredRequired
TenantExplicit string valueImplicit through the resolved user

The two surfaces are not interchangeable, and no adapter reconciles them in the reviewed source. There is no native compatibility endpoint that reproduces a monolith-shaped notification contract — unlike several other extracted modules in this platform, Notification has no /api/... compatibility layer inside the service.

Portal consumption

The client portal calls the monolith paths for the notification list, unread count, read and read-all actions, and calls the monolith template path for template administration. An operations dashboard additionally reads the native statistics, failed-queue and audit paths. The self-service notification view is served by the gateway aggregation route.

Classification

Transitional.

Requires confirmation

Path alignment for the toggle-on route, which surface is canonical, whether the template prefix is intended to remain untoggled, and the migration plan between the two contracts require confirmation.

See Also

Keywords

  • Notification API
  • Gateway and Compatibility
  • Draft API documentation

Source References

  • microservices/src/gateway-api/Program.cs
  • microservices/src/gateway-api/EssEndpoints.cs
  • Controllers/NotificationsController.cs
  • Controllers/NotificationTemplatesController.cs
  • UI/salary-ui/apps/client-hrms-portal/src/components/AppLayout.tsx
  • UI/salary-ui/apps/client-hrms-portal/src/dashboard/dashboardApi.ts

Revision Information

  • Status: Draft
  • Last reviewed: 2026-07-21
  • Review cycle: Quarterly