@quanticjs/notification-bff
v8.4.1
Published
Server-authoritative BFF proxy to the standalone notification engine — per-app scoping or shell (unified) mode.
Readme
@quanticjs/notification-bff
Server-authoritative BFF proxy to the standalone notification engine. Replaces the
hand-rolled NotificationController + engine client that each app used to copy
(and drift on). One module, two modes.
Usage
// app.module.ts — a normal app: the bell shows only THIS app's notifications
import { NotificationProxyModule } from '@quanticjs/notification-bff';
@Module({
imports: [
NotificationProxyModule.forRoot({ appId: 'delivery-hub' }),
],
})
export class AppModule {}// the shell/portal: the bell shows the user's notifications across ALL apps
NotificationProxyModule.forRoot({ appId: 'shell', unified: true })Mounts GET/POST/PUT /notifications* under the app's global prefix (e.g.
/api/notifications), proxying to the engine at
NOTIFICATION_ENGINE_URL (default http://notification-engine:3000).
Scoping & security
Two independent scopes apply to every feed read/mutation:
| Scope | Source | Enforced by |
|---|---|---|
| User | the verified bearer token (requireCurrentUser()) | the engine — always; a caller can only ever see their own notifications |
| App | this module's config | the BFF — server-authoritative |
App scope:
- Per-app (
{ appId }): stampsappId=<appId>onlist/unread-count/read-all, and strips any client-suppliedappId— the browser is not a security boundary and cannot widen (or be tricked into narrowing) its scope. - Shell (
{ unified: true }): sends noappId, so the engine returns the user's notifications across every app. There is no reliance on an implicit "null appId" — unified mode simply omits the app filter; the user filter still applies. ProvideappId: 'shell'alongside as an identity label.
There is no unscoped default: forRoot({}) throws at boot, so an app can
never accidentally serve every application's notifications. The shell scope must
be opted into explicitly.
config/* and preferences endpoints are proxied unscoped (they are
app-agnostic / engine-enforced for admin).
