# `schemas/options` ## Purpose Zod schema for plugin options accepted by `createNotificationsPlugin()` plus the nested APN configuration shape (`ApnConfigSchema`). Every field carries a default so consumers can call the factory with no arguments and still receive a fully-resolved `NotificationsPluginConfig`. Invalid input surfaces a single `NotificationsPluginError` with `code === INVALID_CONFIG` and the `ZodError` as `cause`. ## Features - `basePath` defaults to `/notifications`; `pushBasePath` defaults to `/push` — both mount independently so hosts can split the surface behind different auth gates. - `enablePush` flag gates the APN service registration. When the flag is `false` the plugin still mounts `/notifications` but the `/push/*` routes return `503` for delivery endpoints. - `apn` accepts either certificate / key / pfx pairs or a token bundle (`{ key, keyId, teamId }`). Boundary validation happens here; cross-field validation (exactly-one-auth-method) happens later in the APN service. - `autoCleanOldDays` controls the optional retention job (`0` disables cleanup); `maxBulkRecipients` caps the size of `POST /push/send-bulk`. ## Usage: Basic ```ts import { createNotificationsPlugin } from "@suaveplan/api-plugin-notifications"; const plugin = createNotificationsPlugin({ basePath: "/v1/notifications", enablePush: true, apn: { token: { key: "/keys/AuthKey_ABC.p8", keyId: "ABC", teamId: "TEAM" }, defaultTopic: "com.example.app", production: true, }, }); ``` ## Usage: Advanced `z.input` is exported as `NotificationsPluginConfigInput` so callers can use it to type their own deployment-config files: ```ts import type { NotificationsPluginConfigInput } from "@suaveplan/api-plugin-notifications"; interface DeploymentConfig { plugins: { notifications: NotificationsPluginConfigInput }; } ``` ## API Reference - `ApnConfigSchema` / `ApnConfig` - `NotificationsPluginOptionsSchema` - `NotificationsPluginConfig` — `z.infer<...>` - `NotificationsPluginConfigInput` — `z.input<...>` ## Implementation Notes The schema does not enforce "exactly one of cert/key/pfx/token" at the boundary because some deployments pass `passphrase` alone (when the key file already lives on disk and is referenced by path). The APN service's `validateConfig()` method enforces the cross-field rule and throws `APN_CONFIG_MISSING` / `APN_CONFIG_INVALID` at `initialize()` time so the error surfaces with a stable code and full telemetry context.