Move docs/ package mirror into document-navigator plugin

Relocate the ~6k-file docs tree from the repo root into
plugins/document-navigator/docs/ so the plugin is self-contained and
portable. docs/superpowers/ (specs and plans) stays at the repo root.

Moved via cp+rm rather than git mv because directory rename() fails with
EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the
identical-content files at commit time.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-30 01:10:00 +01:00
parent fe3fedf42e
commit 9bf56a806b
6022 changed files with 12437 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
# @suaveplan/notification-channel - Multi-channel notification router with templates, sliding-window rate limiting, retry + dead-letter, scheduler, preferences, hooks, OpenTelemetry instrumentation, and Zod-validated boundaries. Universal: runs unchanged in Bun, Node, and the browser.
Multi-channel notification router with templates, sliding-window rate limiting, retry + dead-letter, scheduler, preferences, hooks, OpenTelemetry instrumentation, and Zod-validated boundaries. Universal: runs unchanged in Bun, Node, and the browser.
<!-- begin:auto-docs -->
## Documentation tree
- [delivery-channel](./src/channels/delivery-channel.md) — `delivery-channel.ts` defines the structural contract every concrete delivery channel implements. The contract is inten…
- [email-channel](./src/channels/email-channel.md) — `email-channel.ts` ships the `EmailChannel` `DeliveryChannel` implementation. The class is provider-neutral: the integr…
- [in-app-channel](./src/channels/in-app-channel.md) — `in-app-channel.ts` ships the `InAppChannel` implementation that stores notifications for an in-app inbox / unread badg…
- [push-channel](./src/channels/push-channel.md) — `push-channel.ts` ships the `PushChannel` implementation that delivers notifications via the Web Push Protocol (RFC 803…
- [sms-channel](./src/channels/sms-channel.md) — `sms-channel.ts` ships the `SmsChannel` `DeliveryChannel` implementation. Like the email channel, it is provider-neutra…
- [webhook-channel](./src/channels/webhook-channel.md) — `webhook-channel.ts` ships the `WebhookChannel` implementation that POSTs notifications to an arbitrary HTTPS endpoint.…
- [digest](./src/digest/digest-channel.md) — `digest-channel.ts` ships the `DigestChannel` implementation that batches notifications into periodic summaries deliver…
- [digest-channel](./src/digest/digest-channel.md) — `digest-channel.ts` ships the `DigestChannel` implementation that batches notifications into periodic summaries deliver…
- [error-codes](./src/error-codes/error-codes.md) — `error-codes.ts` is the single source of truth for every error the `@suaveplan/notification-channel` package can throw.…
- [error-codes](./src/error-codes/error-codes.md) — `error-codes.ts` is the single source of truth for every error the `@suaveplan/notification-channel` package can throw.…
- [error-mapping](./src/error-mapping/error-mapping.md) — `error-mapping.ts` is the canonical place every reason code in `NOTIFICATION_CHANNEL_CODES` is paired with its typed su…
- [error-mapping](./src/error-mapping/error-mapping.md) — `error-mapping.ts` is the canonical place every reason code in `NOTIFICATION_CHANNEL_CODES` is paired with its typed su…
- [fakes](./src/fakes/fake-fetch.md) — `fake-fetch.ts` ships the `FakeFetch` test double — a `FetchLike` that consumes scripted responses from a FIFO queue an…
- [fake-fetch](./src/fakes/fake-fetch.md) — `fake-fetch.ts` ships the `FakeFetch` test double — a `FetchLike` that consumes scripted responses from a FIFO queue an…
- [hooks](./src/hooks/hooks.md) — `hooks.ts` exposes a small typed hook bus that runs before `NotificationRouter` commits a notification to a channel. Th…
- [hooks](./src/hooks/hooks.md) — `hooks.ts` exposes a small typed hook bus that runs before `NotificationRouter` commits a notification to a channel. Th…
- [otel](./src/otel/metrics.md) — `otel/metrics.ts` registers the package's four OpenTelemetry instruments on a meter named `@suaveplan/notification-chan…
- [metrics](./src/otel/metrics.md) — `otel/metrics.ts` registers the package's four OpenTelemetry instruments on a meter named `@suaveplan/notification-chan…
- [preferences](./src/preferences/preference-manager.md) — `preference-manager.ts` ships the `PreferenceManager` class that answers, at every send-time, "should this notification…
- [preference-manager](./src/preferences/preference-manager.md) — `preference-manager.ts` ships the `PreferenceManager` class that answers, at every send-time, "should this notification…
- [rate-limiter](./src/rate-limiter/channel-rate-limiter.md) — `channel-rate-limiter.ts` ships the `ChannelRateLimiter` class — a per-channel + per-user sliding-window rate limiter.…
- [channel-rate-limiter](./src/rate-limiter/channel-rate-limiter.md) — `channel-rate-limiter.ts` ships the `ChannelRateLimiter` class — a per-channel + per-user sliding-window rate limiter.…
- [retry](./src/retry/delivery-retry.md) — `delivery-retry.ts` ships the `DeliveryRetry` wrapper that retries a `DeliveryChannel.send` call with exponential backo…
- [delivery-retry](./src/retry/delivery-retry.md) — `delivery-retry.ts` ships the `DeliveryRetry` wrapper that retries a `DeliveryChannel.send` call with exponential backo…
- [router](./src/router/notification-router.md) — `notification-router.ts` ships the `NotificationRouter` class — the primary entrypoint a consumer talks to. It resolves…
- [notification-router](./src/router/notification-router.md) — `notification-router.ts` ships the `NotificationRouter` class — the primary entrypoint a consumer talks to. It resolves…
- [scheduler](./src/scheduler/notification-scheduler.md) — `notification-scheduler.ts` ships the `NotificationScheduler` class for scheduling notifications for future delivery. T…
- [notification-scheduler](./src/scheduler/notification-scheduler.md) — `notification-scheduler.ts` ships the `NotificationScheduler` class for scheduling notifications for future delivery. T…
- [schemas](./src/schemas/schemas.md) — `schemas.ts` exposes a Zod schema for every public option bundle in the package so callers can validate untrusted input…
- [schemas](./src/schemas/schemas.md) — `schemas.ts` exposes a Zod schema for every public option bundle in the package so callers can validate untrusted input…
- [templates](./src/templates/template-engine.md) — `template-engine.ts` ships the `TemplateEngine` registry that turns named templates into channel-specific rendered outp…
- [template-engine](./src/templates/template-engine.md) — `template-engine.ts` ships the `TemplateEngine` registry that turns named templates into channel-specific rendered outp…
<!-- end:auto-docs -->
## Install
```bash
bun add @suaveplan/notification-channel
```
## Quick start
```ts
import {
EmailChannel,
NotificationRouter,
} from "@suaveplan/notification-channel";
const email = new EmailChannel({
from: "noreply@example.com",
sendFn: async (msg) => ({ messageId: await provider.send(msg) }),
});
const router = new NotificationRouter({
channels: [{ channel: "email", enabled: true, rateLimit: 100 }],
defaultChannel: "email",
deliveryChannels: [email],
});
router.on("notification.failed", (n) => audit.record(n));
await router.send({
recipient: "user@example.com",
body: "Welcome to Suaveplan",
subject: "Welcome",
});
```
## Surface
- **Five sending channels** — `EmailChannel`, `SmsChannel`, `PushChannel`, `InAppChannel`, `WebhookChannel`.
- **One aggregating channel** — `DigestChannel` (wraps any sending channel).
- **Router** — `NotificationRouter` with templates, routing rules, lifecycle events, OTel meters.
- **Composables** — `ChannelRateLimiter`, `DeliveryRetry`, `NotificationScheduler`, `PreferenceManager`, `TemplateEngine`.
- **Hooks** — `notification:routing` pre-routing pipeline (`onNotificationRouting`).
- **Errors** — stable `NOTIFICATION_CHANNEL_CODES` registry with eleven reasons.
- **Test double** — `FakeFetch` for deterministic `FetchLike` injection.
- **OpenTelemetry** — four instruments under the `@suaveplan/notification-channel` meter.
## Modules
- [`error-codes`](./src/error-codes.md) — `NOTIFICATION_CHANNEL_CODES` + typed error subclasses.
- [`hooks/hooks`](./src/hooks/hooks.md) — generic hook bus + `notification:routing` pipeline.
- [`schemas/schemas`](./src/schemas/schemas.md) — Zod schemas for every public option bundle.
- [`channels/delivery-channel`](./src/channels/delivery-channel.md) — common transport contract.
- [`channels/email-channel`](./src/channels/email-channel.md) — email delivery.
- [`channels/sms-channel`](./src/channels/sms-channel.md) — SMS delivery.
- [`channels/push-channel`](./src/channels/push-channel.md) — Web Push delivery (RFC 8030).
- [`channels/in-app-channel`](./src/channels/in-app-channel.md) — in-app inbox delivery.
- [`channels/webhook-channel`](./src/channels/webhook-channel.md) — HTTP webhook delivery.
- [`digest/digest-channel`](./src/digest/digest-channel.md) — digest / summary delivery.
- [`templates/template-engine`](./src/templates/template-engine.md) — template registry + renderer.
- [`rate-limiter/channel-rate-limiter`](./src/rate-limiter/channel-rate-limiter.md) — sliding-window rate limits.
- [`retry/delivery-retry`](./src/retry/delivery-retry.md) — retry wrapper + dead-letter queue.
- [`scheduler/notification-scheduler`](./src/scheduler/notification-scheduler.md) — future-delivery scheduler.
- [`preferences/preference-manager`](./src/preferences/preference-manager.md) — opt-in/out + quiet hours.
- [`router/notification-router`](./src/router/notification-router.md) — primary multi-channel router.
- [`otel/metrics`](./src/otel/metrics.md) — OpenTelemetry instruments.
- [`fakes/fake-fetch`](./src/fakes/fake-fetch.md) — deterministic `FetchLike` test double.
## Architecture
Every dependency is injectable: `Clock` and `FetchLike` come from `@suaveplan/types`, the storage adapter behind `PreferenceManager` is caller-supplied, and every channel takes a `sendFn` callback so the package never bundles a specific provider SDK. The router uses `EventBus<NotificationEventMap>` so lifecycle events flow through the same typed-pub/sub primitive as the rest of the project.
The 11-code `defineCodes("NOTIFICATION_CHANNEL", […])` registry preserves literal-typed unions through the public surface, so an exhaustive `switch (err.code)` reports unhandled codes at type-check time. OpenTelemetry meters fire on every router send and every dead-letter event so dashboards reflect real production behaviour out of the box.
## License
MIT