first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -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.