@molecule/api-notification-center-database
Provider bond · notifications · API (Node) · v1.0.2 · Apache-2.0
Database-backed notification center provider for molecule.dev
npm install @molecule/api-notification-center-databasenpm · Source on GitHub · Implements @molecule/api-notification-center
How it works
@molecule/api-notification-center-database is a provider bond on the API (Node) side: it implements the notifications core interface (@molecule/api-notification-center) with a concrete vendor or library behind it.
Your code calls the core; you wire this provider once at startup. Swapping vendors later is one line in that wiring, not a rewrite.
import { setProvider } from '@molecule/api-notification-center'
import { createProvider } from '@molecule/api-notification-center-database'
// Bond at startup (requires @molecule/api-database to be bonded)
setProvider(createProvider())
// Or with custom table names
setProvider(
createProvider({
tableName: 'user_notifications',
preferencesTableName: 'user_notification_prefs',
}),
)Works with: @molecule/api-database, @molecule/api-notification-center
Reference
Database-backed notification center provider for molecule.dev.
Implements the @molecule/api-notification-center interface using the
bonded @molecule/api-database DataStore for persistence.
Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit
src/index.tsJSDoc, not this file.
Quick Start
import { setProvider } from '@molecule/api-notification-center'
import { createProvider } from '@molecule/api-notification-center-database'
// Bond at startup (requires @molecule/api-database to be bonded)
setProvider(createProvider())
// Or with custom table names
setProvider(
createProvider({
tableName: 'user_notifications',
preferencesTableName: 'user_notification_prefs',
}),
)
Type
provider
Installation
npm install @molecule/api-notification-center-database @molecule/api-database @molecule/api-notification-center
API
Interfaces
DatabaseNotificationCenterConfig
Configuration for the database-backed notification center provider.
interface DatabaseNotificationCenterConfig {
/** Table name for notifications. Defaults to `'notifications'`. */
tableName?: string
/** Table name for notification preferences. Defaults to `'notification_preferences'`. */
preferencesTableName?: string
}
Functions
createProvider(config)
Creates a database-backed NotificationCenterProvider.
Requires a DataStore to be bonded via @molecule/api-database before use.
function createProvider(config?: DatabaseNotificationCenterConfig): NotificationCenterProvider
config— Database notification center configuration.
Returns: A fully initialised NotificationCenterProvider backed by the bonded DataStore.
Core Interface
Implements @molecule/api-notification-center interface.
Injection Notes
Requirements
Peer dependencies:
@molecule/api-database^1.0.1@molecule/api-notification-center^1.0.1
Runtime Dependencies
-
@molecule/api-database -
@molecule/api-notification-center -
The tables must already exist — nothing auto-creates them. Add a migration for
notifications(or yourtableName) with columns:id(uuid/text, PK),user_id(text),type(text),title(text),body(text),read(boolean — 0/1 integers fine on SQLite/MySQL),data(text, JSON-serialized, nullable),channels(text, JSON-serialized, nullable),created_at(timestamp). Index(user_id, read)and(user_id, created_at)for the list/count paths. Andnotification_preferences(orpreferencesTableName):id(uuid/ text, PK),user_id(text, unique),email/push/sms(boolean),channels(text, JSON-serialized). -
Bond the
@molecule/api-databaseDataStore first — every method callsgetStore()and throws without it. -
sendBulk()inserts sequentially (onecreateper entry, no transaction) — a mid-batch failure leaves earlier rows written. -
getAll()defaults tolimit: 50, newest first; drive pagination from the returnedtotal, notitems.length.
E2E Tests
Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual bell/feed and notification triggers, and check every box off one by one. A box you can't check is an integration bug to fix — not a skip:
- An event that should notify a user (a mention, invite, comment, a
finished job — whatever this app defines) creates an in-app notification
that appears in THAT user's bell/feed with the correct type, title, body,
and any link/target carried in
data. Sending here writes only the in-app record — do not expect it to also arrive by email/push. - The unread badge (from
getUnreadCount) increments when a new notification arrives and equals the number of unread items shown in the feed. - Marking one read (
markRead) flips that item to read and drops the badge by one; mark-all-read (markAllRead) shows every item as read and the badge as zero — and BOTH changes persist across a full reload (they are stored, not client-only state). - Real-time: if the app wires a live channel (SSE/websocket), a notification sent while the feed is open appears WITHOUT a manual reload and the badge updates live; with no live channel, confirm the new notification shows on the next feed load / poll.
- Clicking a notification navigates to its target (the link/id in
data) and, where that is the intended behavior, marks it read. - Clearing/deleting one (
deleteNotification) removes it from the feed and it does NOT reappear on reload (it is deleted from the store, not just hidden client-side). - Scoping — a user sees ONLY their own feed:
getAllreturns just the authenticated user's items, a notification created for user A never shows for user B, and no route returns or mutates another user's notification by id (markRead/deleteNotificationon someone else's id must no-op and return false, never touch that row). Handlers pass the AUTHENTICATED user's id — never a client-supplieduserId.