Files
skills/docs/api-stack/api/api-plugin-notifications/src/plugin/plugin.md
2026-05-29 08:20:56 +01:00

3.0 KiB

plugin/plugin

(no submodules)

Purpose

Plugin descriptor factory for @suaveplan/api-plugin-notifications. Composes everything in the package — Zod-validated options, SurrealDB-backed NotificationRepository and DeviceTokenRepository, the optional ApnService, the two route modules, and the OTel instrument bundle — into a single PluginDescriptor<NotificationsPluginConfig> that hosts mount via @suaveplan/api-plugin's standard lifecycle.

Features

  • Boundary Zod validation — invalid options throw NotificationsPluginError(INVALID_CONFIG) with the ZodError attached as cause.
  • Two-phase lifecycle: onInit registers repositories and the APN service in the host's ServiceRegistry; onReady mounts both route trees and refuses double-mount with ROUTE_PREFIX_COLLISION.
  • Event-bus integration — emits notifications:initialized and notifications:ready on the shared ctx.eventBus so siblings observe lifecycle transitions. Route-level events flow through a single forwarder callback that the route modules call via emitEvent.
  • Optional APN — enablePush: false (default) skips APN construction; enablePush: true without config.apn throws APN_CONFIG_MISSING at boot.
  • Graceful close — onClose shuts down the APN transport (if any) and clears the repository references so the GC can collect them.

Usage: Basic

import { createNotificationsPlugin } from "@suaveplan/api-plugin-notifications";

await api.loadPlugin(createNotificationsPlugin());

Usage: Advanced

Enable push delivery with a token-auth APN config and a custom mount prefix:

await api.loadPlugin(
    createNotificationsPlugin({
        basePath: "/v1/notifications",
        pushBasePath: "/v1/push",
        enablePush: true,
        apn: {
            token: {
                key: "/keys/AuthKey_ABC.p8",
                keyId: "ABC",
                teamId: "TEAM",
            },
            defaultTopic: "com.example.app",
            production: true,
        },
        maxBulkRecipients: 500,
        autoCleanOldDays: 14,
    })
);

API Reference

  • createNotificationsPlugin(options?: NotificationsPluginConfigInput) → PluginDescriptor<NotificationsPluginConfig>
  • Lifecycle hooks: onInit(ctx), onReady(ctx), onClose().
  • Service slots registered: notificationRepository, deviceTokenRepository, apnService (only when enablePush).
  • Event-bus emissions: notifications:initialized, notifications:ready, plus every event in NotificationsPluginEvents.

Implementation Notes

The plugin name is "notifications". Dependencies are ["database"] — onInit will refuse to boot without an @suaveplan/api-plugin-database-registered db slot. The plugin calls ctx.eventBus.emit(event.type, event.payload) from a single forwarder callback rather than dragging the eventBus reference into every route handler. This matches the api-plugin-events pattern and means route handlers stay testable in isolation.