first commit
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# `plugin/plugin`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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
|
||||
|
||||
```ts
|
||||
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:
|
||||
|
||||
```ts
|
||||
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.
|
||||
Reference in New Issue
Block a user