Skip to main content

stacks-notifications

Use when implementing notifications in Stacks — multi-channel notifications (email, SMS, push, chat, database), the database notification driver with read/unread tracking, notification factories (useEmail, useSMS, useChat, useDatabase), or notification configuration. Covers @stacksjs/notifications and config/notification.ts.

Informations de source

Dépôt
stacksjs/postline
Dernière activité de la source
3 août 2026 à 19:34
Langue détectée de SKILL.md
anglais
Étoiles
2
Forks
0

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
stacks-notifications
description
Use when implementing notifications in Stacks — multi-channel notifications (email, SMS, push, chat, database), the database notification driver with read/unread tracking, notification factories (useEmail, useSMS, useChat, useDatabase), or notification configuration. Covers @stacksjs/notifications and config/notification.ts.
license
MIT
compatibility
Bun >= 1.3.0, TypeScript
allowed-tools
Read Edit Write Bash Grep Glob
# Stacks Notifications Multi-channel notification system with 5 channel types: email, SMS, chat, push, and database. ## Key Paths - Core package: `storage/framework/core/notifications/src/` - Main entry: `storage/framework/core/notifications/src/index.ts` - Drivers: `storage/framework/core/notifications/src/drivers/` - Database driver: `storage/framework/core/notifications/src/drivers/database.ts` - Configuration: `config/notification.ts` - Notification model: `storage/framework/defaults/app/Models/Notification.ts` ## Package Exports ```typescript import { useChat, useEmail, useSMS, useDatabase, useNotification, notification, DatabaseNotificationDriver, } from '@stacksjs/notifications' // Types import type { CreateNotificationOptions, DatabaseNotification } from '@stacksjs/notifications' ``` ## Channel Factories Each factory returns the underlying driver module for that channel. ```typescript // Email -- defaults to 'mailtrap', returns @stacksjs/email driver const emailDriver = useEmail('ses') const emailDriver = useEmail('sendgrid') const emailDriver = useEmail('mailgun') const emailDriver = useEmail('mailtrap') const emailDriver = useEmail('smtp') // SMS -- defaults to 'twilio', returns @stacksjs/sms driver const smsDriver = useSMS('twilio') const smsDriver = useSMS('vonage') // Chat -- defaults to 'slack', returns @stacksjs/chat driver const chatDriver = useChat('slack') const chatDriver = useChat('discord') const chatDriver = useChat('teams') // Database -- returns DatabaseNotificationDriver object const dbDriver = useDatabase() // Auto-detect by type -- dispatches to the correct factory const driver = useNotification('email', 'ses') const driver = useNotification('sms', 'twilio') const driver = useNotification('chat', 'slack') const driver = useNotification('database') // Default (uses config.default, falls back to 'email' + 'mailtrap') const driver = notification() ``` `useNotification()` reads `config/notification.ts` for the default type. If no default is set, it throws `'No default notification type set in config/notification.ts'`. The channel drivers are re-exports from their respective packages: - `email` driver: `@stacksjs/email` - `sms` driver: `@stacksjs/sms` - `chat` driver: `@stacksjs/chat` - `push` driver: `@stacksjs/push` ## Database Notification Driver The `DatabaseNotificationDriver` provides CRUD operations for notifications stored in the `notifications` database table using Kysely query builder. ### Send a Notification ```typescript const db = useDatabase() const notification = await db.send({ userId: 1, type: 'order.shipped', data: { orderId: 42, trackingNumber: 'ABC123' }, }) // Returns the created DatabaseNotification with auto-generated id, timestamps ``` `send()` inserts a row into the `notifications` table with: - `user_id` from `options.userId` - `type` from `options.type` - `data` -- JSON.stringify'd from `options.data` - `read_at` set to `null` - `created_at` and `updated_at` set to current ISO timestamp ### Query Notifications ```typescript // All notifications for a user, ordered by created_at desc const all = await db.getUserNotifications(userId) // Only unread (where read_at is null), ordered by created_at desc const unread = await db.getUnreadNotifications(userId) // Count of unread notifications const count = await db.unreadCount(userId) ``` ### Mark as Read ```typescript // Mark a single notification as read (sets read_at to current timestamp) await db.markAsRead(notificationId) // Mark all unread notifications for a user as read await db.markAllAsRead(userId) ``` `markAllAsRead()` only updates rows where `read_at` is null. ### Delete Notifications ```typescript // Delete a single notification by ID await db.deleteNotification(notificationId) // Delete all notifications for a user await db.deleteAllNotifications(userId) ``` ### DatabaseNotification Interface ```typescript interface DatabaseNotification { id: number user_id: number type: string // e.g., 'order.shipped', 'payment.received' data: string // JSON stringified -- parse with JSON.parse() when reading read_at: string | null // ISO timestamp or null if unread created_at: string // ISO timestamp updated_at: string | null // ISO timestamp } ``` ### CreateNotificationOptions Interface ```typescript interface CreateNotificationOptions { userId: number type: string data: Record<string, any> } ``` ## Notification Model Fields The Notification model at `storage/framework/defaults/app/Models/Notification.ts` maps the database notification inbox used by `DatabaseNotificationDriver`: - `user_id` comes from the `belongsTo: ['User']` relationship - `type` is an application event name such as `order.shipped` - `data` is a JSON string containing the notification payload - `readAt` maps to the nullable `read_at` column - `created_at` and `updated_at` come from `useTimestamps` The model uses `useApi` for its CRUD API and seeds 30 records by default. It must stay aligned with `notificationsTableSql()` in `storage/framework/core/database/src/notification-tables.ts`. Outbound transport attempts belong in a separate delivery-log model and table. Do not add email, SMS, or provider-specific delivery columns to the inbox model. ## CLI Commands - `buddy make:notification [name]` -- scaffold a new notification ## config/notification.ts ```typescript import type { NotificationConfig } from '@stacksjs/types' export default { default: 'email', } satisfies NotificationConfig ``` The `default` field controls which channel type `useNotification()` and `notification()` use when no type is specified. Valid values: `'email'`, `'sms'`, `'chat'`, `'database'`. ## Architecture The notifications package is a thin aggregation layer. Each channel delegates to its own dedicated package: - **Email channel** (`useEmail`) -- re-exports `@stacksjs/email` (configured via `config/email.ts`) - **SMS channel** (`useSMS`) -- re-exports `@stacksjs/sms` (configured via `config/sms.ts`) - **Chat channel** (`useChat`) -- re-exports `@stacksjs/chat` (configured via `config/services.ts`) - **Push channel** -- re-exports `@stacksjs/push` - **Database channel** (`useDatabase`) -- built-in driver using `@stacksjs/database` The driver modules (`drivers/email.ts`, `drivers/sms.ts`, etc.) are single-line re-exports: `export * as email from '@stacksjs/email'`, `export * as sms from '@stacksjs/sms'`, etc. ## Gotchas - The `data` field in database notifications is stored as a JSON string -- always `JSON.parse()` when reading - `read_at` is `null` for unread notifications -- use this to filter unread - The database driver uses Kysely's query builder with `as any` type casts on table/column names since the notifications table is dynamically referenced - Channel-specific configuration (SMTP credentials, Twilio keys, Slack tokens) lives in each channel's own config file, not in `config/notification.ts` - `useNotification()` throws if `config.default` is not set in `config/notification.ts` - The `notification()` function (without arguments) is a shorthand for `useNotification()` with defaults - The `nexmo` driver is a legacy alias for `vonage` in the SMS drivers index
Voir sur GitHub