Files
2026-05-27 23:29:53 +01:00

3.1 KiB

OpenSpec Change: enterprise-api-plugin-notifications

  • Change ID: enterprise-api-plugin-notifications
  • Package: @suaveplan/api-plugin-notifications
  • Category: api/comms
  • Target path: api/comms/api-plugin-notifications
  • Status: PROPOSED
  • Date: 2026-04-24
  • Reference spec: /mnt/s/web/suaveplan/enterprise/api-plugin-notifications.md

Summary

Deliver @suaveplan/api-plugin-notifications on the genesis branch from scratch at enterprise quality. Multi-channel notification delivery plugin: in-app (stored + delivered over SSE), email (via pluggable EmailProvider), SMS (via pluggable SmsProvider), and push (Web Push). Template rendering via @suaveplan/templates. User preference management (per-channel opt-in/out). Delivery tracking with retry via @suaveplan/retry. Routes under /notifications. Per-table SurrealQL. Typed bus events: notification:sent, notification:failed, notification:read.


Available workspace deps on genesis

Package Role
@suaveplan/api (workspace:^) definePlugin
@suaveplan/api-shared (workspace:^) Helpers
@suaveplan/api-plugin-auth (workspace:^) requireAuth
@suaveplan/api-plugin-database (workspace:^) SurrealDB
@suaveplan/templates (workspace:^) Notification template rendering
@suaveplan/suppression (workspace:^) Email/SMS suppression
@suaveplan/retry (workspace:^) Delivery retry
@suaveplan/events (workspace:^) Event bus
@suaveplan/error (workspace:^) NotificationError hierarchy
@suaveplan/rate-limiter (workspace:^) Send rate limits
hono + @hono/zod-openapi + zod Routes
@opentelemetry/api OTel

Public API surface

function createNotificationsPlugin(config?: NotificationsPluginConfig): PluginDescriptor

interface NotificationService {
  send(notification: SendNotificationInput): Promise<NotificationRecord>
  markRead(notificationId: string, userId: string): Promise<void>
  listNotifications(userId: string, query: NotificationQuery): Promise<NotificationRecord[]>
  getUnreadCount(userId: string): Promise<number>
  updatePreferences(userId: string, prefs: NotificationPreferences): Promise<void>
  getPreferences(userId: string): Promise<NotificationPreferences>
}

Error codes

type NotificationErrorCode =
  | "NOTIFICATION_NOT_FOUND"
  | "NOTIFICATION_CHANNEL_DISABLED"
  | "NOTIFICATION_SUPPRESSED"
  | "NOTIFICATION_DELIVERY_FAILED"
  | "NOTIFICATION_TEMPLATE_NOT_FOUND"

File layout

api/comms/api-plugin-notifications/
  package.json  tsconfig.json  vitest.config.ts
  surql/ (notification, notification_preference tables)
  src/
    index.ts  events.ts  types/  errors/
    adapters/email.port.ts  adapters/sms.port.ts  adapters/push.port.ts
    services/notification/  services/preferences/  services/delivery/
    routes/notifications/
  tests/integration.test.ts

Impact

Prerequisites: @suaveplan/api, @suaveplan/api-plugin-auth, @suaveplan/api-plugin-database, @suaveplan/templates, @suaveplan/suppression, @suaveplan/retry.