@suaveplan/api-plugin-notifications - Notifications plugin for @suaveplan/api. Ships SurrealDB-backed NotificationRepository + DeviceTokenRepository, /notifications and /push Hono OpenAPI route groups, an APN service with injectable transport (no hardcoded network library), an event-bus integration via ctx.eventBus, 18 NOTIFICATIONS_PLUGIN_* error codes, and 6 OTel counters. Server-tier — runs in Bun and Node.
SurrealDB-backed notifications + push plugin for @suaveplan/api.
Ships a NotificationRepository + DeviceTokenRepository pair, an
ApnService with a pluggable transport contract (no hardcoded
@parse/node-apn dependency), eleven /notifications/* Hono OpenAPI
routes, five /push/* routes, an opt-in multi-channel
NotificationDispatcher (apn + email) wired on top of
@suaveplan/notification-channel, @suaveplan/emailer, and
@suaveplan/delivery-tracking, twenty-two NOTIFICATIONS_PLUGIN_*
error codes, and eight OTel counters.
Server-tier — runs in Bun and Node.
Documentation tree
- apn-channel — Adapts the in-package
ApnServiceto the@suaveplan/notification-channelDeliveryChannelinterface so `Notificatio…- apn-channel — Adapts the in-package
ApnServiceto the@suaveplan/notification-channelDeliveryChannelinterface so `Notificatio…
- apn-channel — Adapts the in-package
- email-channel — Adapts
@suaveplan/emailer'sEmailServiceto the@suaveplan/notification-channelDeliveryChannelinterface so `N…- email-channel — Adapts
@suaveplan/emailer'sEmailServiceto the@suaveplan/notification-channelDeliveryChannelinterface so `N…
- email-channel — Adapts
- idempotency-adapter — Defines the narrow contract that lets
NotificationDispatcherdelegate per-call deduplication to a caller-supplied imp…- idempotency-adapter — Defines the narrow contract that lets
NotificationDispatcherdelegate per-call deduplication to a caller-supplied imp…
- idempotency-adapter — Defines the narrow contract that lets
- notification-dispatcher — Top-level orchestrator that lets callers send one notification through whichever delivery channel they pick (APN, email…
- notification-dispatcher — Top-level orchestrator that lets callers send one notification through whichever delivery channel they pick (APN, email…
- error-codes — Stable error-code registry for
@suaveplan/api-plugin-notifications. The module exports a frozen `NOTIFICATIONS_PLUGIN…- error-codes — Stable error-code registry for
@suaveplan/api-plugin-notifications. The module exports a frozen `NOTIFICATIONS_PLUGIN…
- error-codes — Stable error-code registry for
- otel — OpenTelemetry instrument bundle for
@suaveplan/api-plugin-notifications. The module exposes a lazy, memoised factory…- instruments — OpenTelemetry instrument bundle for
@suaveplan/api-plugin-notifications. The module exposes a lazy, memoised factory…
- instruments — OpenTelemetry instrument bundle for
- plugin — Plugin descriptor factory for
@suaveplan/api-plugin-notifications. Composes everything in the package — Zod-validated…- plugin — Plugin descriptor factory for
@suaveplan/api-plugin-notifications. Composes everything in the package — Zod-validated…
- plugin — Plugin descriptor factory for
- device-token-repository — SurrealDB-backed repository for the
device_tokentable. Owns every SurrealQL statement the plugin issues against devi…- device-token-repository — SurrealDB-backed repository for the
device_tokentable. Owns every SurrealQL statement the plugin issues against devi…
- device-token-repository — SurrealDB-backed repository for the
- notification-repository — SurrealDB-backed repository for the
notificationtable. Owns every SurrealQL statement the plugin issues against noti…- notification-repository — SurrealDB-backed repository for the
notificationtable. Owns every SurrealQL statement the plugin issues against noti…
- notification-repository — SurrealDB-backed repository for the
- notifications-routes — Hono OpenAPI route module exposing the
/notifications/*surface. Eleven endpoints cover list / unread-count / create…- notifications-routes — Hono OpenAPI route module exposing the
/notifications/*surface. Eleven endpoints cover list / unread-count / create…
- notifications-routes — Hono OpenAPI route module exposing the
- push-routes — Hono OpenAPI route module exposing the
/push/*surface for device- token registration and APN delivery. Five endpoint…- push-routes — Hono OpenAPI route module exposing the
/push/*surface for device- token registration and APN delivery. Five endpoint…
- push-routes — Hono OpenAPI route module exposing the
- dispatch-schemas — Defines the Zod boundary for the
NotificationDispatchersurface. The dispatcher fans a single call out to whichever d… - notification-schemas — Zod boundary schemas for the notification entity and every wire surface the plugin exposes — list / get / create / upda…
- options — Zod schema for plugin options accepted by
createNotificationsPlugin()plus the nested APN configuration shape (`ApnCo… - push-schemas — Zod boundary schemas for the
/push/*route group and the device-token entity stored in SurrealDB. Schemas describe bo… - services — Module-augmentation file that declares three new service slots on
@suaveplan/api-plugin/service-registry's `ServiceRe…- apn-service — Apple Push Notification delivery service. Validates an
ApnConfigat construction-time, builds a pluggable `ApnTranspo…- apn-service — Apple Push Notification delivery service. Validates an
ApnConfigat construction-time, builds a pluggable `ApnTranspo…
- apn-service — Apple Push Notification delivery service. Validates an
- registry-augmentation — Module-augmentation file that declares three new service slots on
@suaveplan/api-plugin/service-registry's `ServiceRe…
- apn-service — Apple Push Notification delivery service. Validates an
- apn-transport — Pluggable transport contract for Apple Push Notification delivery. The plugin never depends on a concrete APN client li…
- apn-transport — Pluggable transport contract for Apple Push Notification delivery. The plugin never depends on a concrete APN client li…
- types — Public type aliases for cross-module wiring: the typed event-bus payload map (
NotificationsPluginEvents), the discrim…- types — Public type aliases for cross-module wiring: the typed event-bus payload map (
NotificationsPluginEvents), the discrim…
- types — Public type aliases for cross-module wiring: the typed event-bus payload map (
Modules
src/error-codes/error-codes.mdsrc/otel/instruments.mdsrc/plugin/plugin.mdsrc/repositories/notification-repository/notification-repository.mdsrc/repositories/device-token-repository/device-token-repository.mdsrc/routes/notifications-routes/notifications-routes.mdsrc/routes/push-routes/push-routes.mdsrc/schemas/options.mdsrc/schemas/notification-schemas.mdsrc/schemas/push-schemas.mdsrc/services/apn-service/apn-service.mdsrc/services/registry-augmentation.mdsrc/transport/apn-transport/apn-transport.mdsrc/types/types.mdsrc/channels/apn-channel/apn-channel.mdsrc/channels/email-channel/email-channel.mdsrc/dispatcher/notification-dispatcher/notification-dispatcher.mdsrc/dispatcher/idempotency-adapter/idempotency-adapter.mdsrc/schemas/dispatch-schemas.md
Usage
import { createNotificationsPlugin } from "@suaveplan/api-plugin-notifications";
await api.loadPlugin(
createNotificationsPlugin({
basePath: "/v1/notifications",
pushBasePath: "/v1/push",
enablePush: true,
apn: {
token: { key: "/keys/AuthKey.p8", keyId: "K", teamId: "T" },
defaultTopic: "com.example.app",
production: true,
},
})
);
Pluggable APN transport
Production hosts inject a node-apn-backed ApnTransport; tests use
the deterministic MemoryApnTransport:
import { ApnService, type ApnTransport } from "@suaveplan/api-plugin-notifications";
const transport: ApnTransport = makeNodeApnTransport(provider);
const service = new ApnService({ config, transport });
See src/transport/apn-transport/apn-transport.md for the full
contract.