# What is this?

Inovus Notifications is a standalone in-app notification service. Think of it as a shared mailbox that any Inovus product can write into, and that every signed-in user can read from.


# The problem it solves

Most products eventually need something like:

“Tell this user that their review is ready — and let them see it later in a bell dropdown, mark it read, or click through.”

Without a shared service, every app invents its own table, its own webhook, its own half-broken polling, and its own security shortcuts. That’s what V1 looked like inside Video Library: it worked for one app, then became hard to reuse safely.

V2 is that capability extracted into one place — so Assess, Video Library, and future apps share one inbox model, one auth story, and one npm client.


# What you get

Capability In plain English
Publish A backend (or privileged caller) creates a notification for a user
Inbox That user lists their notifications, newest first
Badge Cheap unread count for the bell icon
Lifecycle Mark one/all read, mark unread, delete
Idempotency Safe retries via dedupeKey (no double notifications)
Live-ish updates Client polls ~every 30s with cheap 304 Not Modified responses
Typed client @inovus-medical/notifications handles tokens, retries, and polling

# What it is not

Being clear about boundaries saves a lot of confusion:

Not this service Where it lives instead
Toast / snackbar UI (“Saved!” for 3 seconds) Your app’s toast library
Bell dropdown styling / Totum branding Your app’s UI components
Click-to-navigate routing Your app reads actionUrl and navigates
Email, SMS, or push notifications Out of scope (for now)
Instant WebSocket “realtime” Honest polling (~30s by default)
User login / Cognito pools You already have those — we verify the tokens

Tip: If all you need is a temporary success banner after a button click, use a toast. If the user should still see the message after refreshing the page, use this service.


# Mental model

Every notification is a small record addressed to one user:

┌─────────────────────────────────────────────┐
│  Notification                               │
│  • who:     userGuid (Cognito sub)          │
│  • what:    title + body                    │
│  • tone:    severity (info/success/…)       │
│  • where:   optional actionUrl              │
│  • from:    source (derived from the token) │
│  • dedupe:  optional dedupeKey              │
│  • state:   read / unread                   │
└─────────────────────────────────────────────┘

Users only ever see their own inbox. Publishers can write to any user (with the right token). Regular users can also create a notification for themselves via a safe self-publish path (handy for “job finished in this browser” style flows).


# Who talks to whom?

sequenceDiagram
  participant Job as Backend job
  participant API as Notifications API
  participant DB as Database
  participant App as Browser app
  participant User as End user

  Job->>API: POST /v1/notifications (M2M token)
  API->>DB: store row for userGuid
  API-->>Job: 201 created

  User->>App: opens app / looks at bell
  App->>API: GET /v1/notifications (user token)
  API->>DB: list for token.sub
  API-->>App: items + unreadCount
  App-->>User: render bell UI

# Roles (very important)

Role Who What they can do
User Anyone with a valid Cognito access token Read/manage own inbox; optionally self-publish to themselves
Publisher M2M app client (scope) or user in a publisher group Publish notifications to any user

Regular end users do not need publisher privileges just to see the bell. That’s intentional.


# Is this for me?

Yes, if you:

  • Need persistent in-app notifications across one or more Inovus apps
  • Already authenticate users with Cognito
  • Want retries and polling handled for you

Maybe later / not yet, if you:

  • Only need ephemeral toasts
  • Need true push/SSE latency under a second (polling is the current design)
  • Need email/SMS channels

When you’re ready to try it in code, continue to Getting started. To understand the pieces first, see Components.