Skip to content

Commit f8ecd72

Browse files
committed
feat(spec)!: resolve the notification-vocabulary dual sources — ./ui Notification(Config) removed, ./system NotificationConfig removed, ./api keeps the bare names (#4610)
The four #4535-C3 baseline rows were the #4411 trap on the notification vocabulary: Notification(Schema) had a second declaration in ./ui diverging from ./api, and NotificationConfig(Schema) had two declarations (./system vs ./ui) that shared nothing but the name. Import-statement-level scan across framework, cloud and objectui: - ./api Notification(Schema) is the live REST inbox-row contract: embedded in ListNotificationsResponseSchema, part of NotificationProtocol, implemented by @objectstack/client, served by the runtime notifications domain, and mirrored by contracts' InboxNotification (ADR-0030: the bell reads this shape). - ./ui Notification(Schema) — a toast/banner instance shape — had zero importers outside its own unit test; objectui pins only the presentation enums (NotificationType/Position/ActionSchema), which stay. - ./system NotificationConfig(Schema) — a channel+template+recipients+ schedule+retryPolicy+tracking wrapper — had zero importers, is wired into no parent schema, predates ADR-0030's accepted delivery model (NotificationService.emit / NotifyConfigSchema / sys_* objects), and advertised unenforced capability (#3197 dead-letter channels). - ./ui NotificationConfig(Schema) — a toaster global config — had zero importers. Disposal (route 1, dead-side delete, v17 major window): the ./ui pair and BOTH NotificationConfig declarations removed; ./api is the sole owner of the bare Notification(Schema) names and NotificationConfig left the export surface entirely. Compile-time pins (typeof import conditional type, #4581 pattern) keep the bare names out of ./ui and ./system; the surviving ./api declaration is already covered by api/protocol.test.ts. dual-source-exports.baseline.json: exactly the 4 named rows removed (28 -> 24). json-schema.manifest: system/NotificationConfig, ui/Notification and ui/NotificationConfig retired deliberately; their 25 authorable-surface rows hand-deleted per the #4458/#4568/#4581/#4603 precedent. api-surface + reference docs regenerated via check:generated --fix (2 proved stale; the api/notification.mdx page folds into api/protocol.mdx where the declaration lives). docs-import-surface baseline (#4595): untouched. Changeset: @objectstack/spec major with FROM -> TO migration lines. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M9uWvoEp9CoLzYjNExj9sL
1 parent a2cd18a commit f8ecd72

14 files changed

Lines changed: 137 additions & 726 deletions
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
"@objectstack/spec": major
3+
---
4+
5+
feat(spec)!: the notification vocabulary has one owner per name — `@objectstack/spec/ui` no longer exports `Notification(Schema)` / `NotificationConfig(Schema)`, and `@objectstack/spec/system` no longer exports `NotificationConfig(Schema)` (#4610)
6+
7+
The names `Notification` / `NotificationSchema` (`./api` vs `./ui`) and
8+
`NotificationConfig` / `NotificationConfigSchema` (`./system` vs `./ui`)
9+
each resolved to **two different declarations** depending on the import
10+
path — the #4411 dual-source trap. Resolution (three-repo,
11+
import-statement-level consumer scan: framework, cloud, objectui):
12+
13+
- **Removed** `NotificationSchema` / `Notification` from
14+
`@objectstack/spec/ui`. This was a toast/banner "notification instance"
15+
shape (`type`/`severity`/`message`/`duration`/`actions`/`position` + ARIA
16+
props) with **zero importers** in all three repos — objectui's toaster
17+
never adopted it. The live contract is `./api`'s `Notification(Schema)`:
18+
the REST inbox row (`id`/`type`/`title`/`body`/`read`/`data`/`actionUrl`/
19+
`createdAt`) embedded in `ListNotificationsResponseSchema`, served by
20+
`/api/v1/notifications`, implemented by `@objectstack/client`, and
21+
mirrored by `InboxNotification` in `@objectstack/spec/contracts`
22+
(ADR-0030: the bell reads this shape).
23+
- FROM `import { NotificationSchema, type Notification } from '@objectstack/spec/ui'`
24+
TO `import { NotificationSchema, type Notification } from '@objectstack/spec/api'`.
25+
**Shape change**: the api row is an inbox record, not a presentation
26+
config — the ui shape's `severity` / `duration` / `dismissible` /
27+
`actions` / `position` / ARIA fields do not exist there. For the
28+
presentation vocabulary keep using the ui enums, which are unchanged:
29+
`NotificationTypeSchema`, `NotificationSeveritySchema`,
30+
`NotificationPositionSchema`, `NotificationActionSchema` (+ their
31+
types) still live in `@objectstack/spec/ui`.
32+
- **Removed** `NotificationConfigSchema` / `NotificationConfig` from **both**
33+
`@objectstack/spec/system` and `@objectstack/spec/ui` — the bare name left
34+
the spec export surface entirely. Both declarations had zero importers in
35+
all three repos and were wired into no parent schema. The system side (a
36+
channel + template + recipients + schedule + retryPolicy + tracking
37+
"unified notification management protocol") predates ADR-0030's accepted
38+
delivery architecture and advertised capability the runtime does not
39+
deliver (its channel enum's `push`/`slack`/`teams`/`webhook` dead-letter,
40+
#3197; nothing reads `schedule`/`retryPolicy`/`tracking`). The ui side (a
41+
toaster global config: `defaultPosition`/`defaultDuration`/`maxVisible`/
42+
`stackDirection`/`pauseOnHover`) was never adopted by objectui.
43+
- FROM `import { NotificationConfigSchema } from '@objectstack/spec/system'` (or `.../ui`) →
44+
TO: no direct replacement. The live delivery vocabulary is
45+
`NotificationService.emit` (`INotificationService`,
46+
`@objectstack/spec/contracts`), the `notify` flow node
47+
(`NotifyConfigSchema`, `@objectstack/spec/automation`) and the
48+
`sys_notification*` platform objects; per-user delivery preferences are
49+
`NotificationPreferences(Schema)` in `@objectstack/spec/api`.
50+
- `@objectstack/spec/api`'s `Notification(Schema)` and
51+
`NotificationPreferences(Schema)` are **unchanged**; `./api` is now the
52+
sole owner of the bare `Notification(Schema)` names. Imports from `./api`
53+
need no migration. `@objectstack/spec/system`'s `NotificationChannel(Schema)`,
54+
`EmailTemplate(Schema)`, `SMSTemplate(Schema)`, `PushNotification(Schema)`
55+
and `InAppNotification(Schema)` are **unchanged**.
56+
57+
`dual-source-exports.baseline.json` shrinks by exactly these 4 rows (28 → 24,
58+
#4535 C3).

content/docs/references/api/meta.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
"export",
3333
"identity",
3434
"metadata",
35-
"notification",
3635
"package-api",
3736
"package-registry",
3837
"plugin-rest-api",

content/docs/references/api/notification.mdx

Lines changed: 0 additions & 37 deletions
This file was deleted.

content/docs/references/api/protocol.mdx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ validation. Each entry is a canonical `ActionDescriptorSchema`.
2020
## TypeScript Usage
2121

2222
```typescript
23-
import { AiAgentCapabilitiesSchema, AiAgentChatRequestSchema, AiAgentSummarySchema, AiAgentsResponseSchema, AiChatRequestSchema, AiChatResponseSchema, AiCompleteRequestSchema, AiConversationSchema, AiMessageSchema, AiModelsResponseSchema, AiPendingActionSchema, AiPendingActionStatusSchema, AiStreamChunkSchema, ApproveAiPendingActionResponseSchema, AutomationActionsResponseSchema, AutomationTriggerRequestSchema, AutomationTriggerResponseSchema, BatchDataRequestSchema, BatchDataResponseSchema, CheckPermissionRequestSchema, CheckPermissionResponseSchema, CreateAiConversationRequestSchema, CreateDataRequestSchema, CreateDataResponseSchema, CreateManyDataRequestSchema, CreateManyDataResponseSchema, CreateViewRequestSchema, CreateViewResponseSchema, DeleteDataRequestSchema, DeleteDataResponseSchema, DeleteManyDataRequestSchema, DeleteManyDataResponseSchema, DeleteMetaItemRequestSchema, DeleteMetaItemResponseSchema, DeleteViewRequestSchema, DeleteViewResponseSchema, FindDataRequestSchema, FindDataResponseSchema, GetDataRequestSchema, GetDataResponseSchema, GetDiscoveryRequestSchema, GetDiscoveryResponseSchema, GetEffectivePermissionsRequestSchema, GetEffectivePermissionsResponseSchema, GetFieldLabelsRequestSchema, GetFieldLabelsResponseSchema, GetLocalesRequestSchema, GetLocalesResponseSchema, GetMetaItemCachedRequestSchema, GetMetaItemCachedResponseSchema, GetMetaItemRequestSchema, GetMetaItemResponseSchema, GetMetaItemsRequestSchema, GetMetaItemsResponseSchema, GetMetaTypesRequestSchema, GetMetaTypesResponseSchema, GetNotificationPreferencesRequestSchema, GetNotificationPreferencesResponseSchema, GetObjectPermissionsRequestSchema, GetObjectPermissionsResponseSchema, GetPresenceRequestSchema, GetPresenceResponseSchema, GetTranslationsRequestSchema, GetTranslationsResponseSchema, GetUiViewRequestSchema, GetUiViewResponseSchema, GetViewRequestSchema, GetViewResponseSchema, HttpFindQueryParamsSchema, ListAiConversationsRequestSchema, ListAiConversationsResponseSchema, ListAiPendingActionsRequestSchema, ListAiPendingActionsResponseSchema, ListNotificationsRequestSchema, ListNotificationsResponseSchema, ListViewsRequestSchema, ListViewsResponseSchema, MarkAllNotificationsReadRequestSchema, MarkAllNotificationsReadResponseSchema, MarkNotificationsReadRequestSchema, MarkNotificationsReadResponseSchema, NotificationPreferencesSchema, RealtimeConnectRequestSchema, RealtimeConnectResponseSchema, RealtimeDisconnectRequestSchema, RealtimeDisconnectResponseSchema, RealtimeSubscribeRequestSchema, RealtimeSubscribeResponseSchema, RealtimeUnsubscribeRequestSchema, RealtimeUnsubscribeResponseSchema, RegisterDeviceRequestSchema, RegisterDeviceResponseSchema, RejectAiPendingActionResponseSchema, SaveMetaItemRequestSchema, SaveMetaItemResponseSchema, SetPresenceRequestSchema, SetPresenceResponseSchema, UnregisterDeviceRequestSchema, UnregisterDeviceResponseSchema, UpdateAiConversationRequestSchema, UpdateDataRequestSchema, UpdateDataResponseSchema, UpdateManyDataRequestSchema, UpdateManyDataResponseSchema, UpdateNotificationPreferencesRequestSchema, UpdateNotificationPreferencesResponseSchema, UpdateViewRequestSchema, UpdateViewResponseSchema } from '@objectstack/spec/api';
24-
import type { AiAgentCapabilities, AiAgentChatRequest, AiAgentSummary, AiAgentsResponse, AiChatRequest, AiChatResponse, AiCompleteRequest, AiConversation, AiMessage, AiModelsResponse, AiPendingAction, AiPendingActionStatus, AiStreamChunk, ApproveAiPendingActionResponse, AutomationActionsResponse, AutomationTriggerRequest, AutomationTriggerResponse, BatchDataRequest, BatchDataResponse, CheckPermissionRequest, CheckPermissionResponse, CreateAiConversationRequest, CreateDataRequest, CreateDataResponse, CreateManyDataRequest, CreateManyDataResponse, CreateViewRequest, CreateViewResponse, DeleteDataRequest, DeleteDataResponse, DeleteManyDataRequest, DeleteManyDataResponse, DeleteMetaItemRequest, DeleteMetaItemResponse, DeleteViewRequest, DeleteViewResponse, FindDataRequest, FindDataResponse, GetDataRequest, GetDataResponse, GetDiscoveryRequest, GetDiscoveryResponse, GetEffectivePermissionsRequest, GetEffectivePermissionsResponse, GetFieldLabelsRequest, GetFieldLabelsResponse, GetLocalesRequest, GetLocalesResponse, GetMetaItemCachedRequest, GetMetaItemCachedResponse, GetMetaItemRequest, GetMetaItemResponse, GetMetaItemsRequest, GetMetaItemsResponse, GetMetaTypesRequest, GetMetaTypesResponse, GetNotificationPreferencesRequest, GetNotificationPreferencesResponse, GetObjectPermissionsRequest, GetObjectPermissionsResponse, GetPresenceRequest, GetPresenceResponse, GetTranslationsRequest, GetTranslationsResponse, GetUiViewRequest, GetUiViewResponse, GetViewRequest, GetViewResponse, ListAiConversationsRequest, ListAiConversationsResponse, ListAiPendingActionsRequest, ListAiPendingActionsResponse, ListNotificationsRequest, ListNotificationsResponse, ListViewsRequest, ListViewsResponse, MarkAllNotificationsReadRequest, MarkAllNotificationsReadResponse, MarkNotificationsReadRequest, MarkNotificationsReadResponse, NotificationPreferences, RealtimeConnectRequest, RealtimeConnectResponse, RealtimeDisconnectRequest, RealtimeDisconnectResponse, RealtimeSubscribeRequest, RealtimeSubscribeResponse, RealtimeUnsubscribeRequest, RealtimeUnsubscribeResponse, RegisterDeviceRequest, RegisterDeviceResponse, RejectAiPendingActionResponse, SaveMetaItemRequest, SaveMetaItemResponse, SetPresenceRequest, SetPresenceResponse, UnregisterDeviceRequest, UnregisterDeviceResponse, UpdateAiConversationRequest, UpdateDataRequest, UpdateDataResponse, UpdateManyDataRequest, UpdateManyDataResponse, UpdateNotificationPreferencesRequest, UpdateNotificationPreferencesResponse, UpdateViewRequest, UpdateViewResponse } from '@objectstack/spec/api';
23+
import { AiAgentCapabilitiesSchema, AiAgentChatRequestSchema, AiAgentSummarySchema, AiAgentsResponseSchema, AiChatRequestSchema, AiChatResponseSchema, AiCompleteRequestSchema, AiConversationSchema, AiMessageSchema, AiModelsResponseSchema, AiPendingActionSchema, AiPendingActionStatusSchema, AiStreamChunkSchema, ApproveAiPendingActionResponseSchema, AutomationActionsResponseSchema, AutomationTriggerRequestSchema, AutomationTriggerResponseSchema, BatchDataRequestSchema, BatchDataResponseSchema, CheckPermissionRequestSchema, CheckPermissionResponseSchema, CreateAiConversationRequestSchema, CreateDataRequestSchema, CreateDataResponseSchema, CreateManyDataRequestSchema, CreateManyDataResponseSchema, CreateViewRequestSchema, CreateViewResponseSchema, DeleteDataRequestSchema, DeleteDataResponseSchema, DeleteManyDataRequestSchema, DeleteManyDataResponseSchema, DeleteMetaItemRequestSchema, DeleteMetaItemResponseSchema, DeleteViewRequestSchema, DeleteViewResponseSchema, FindDataRequestSchema, FindDataResponseSchema, GetDataRequestSchema, GetDataResponseSchema, GetDiscoveryRequestSchema, GetDiscoveryResponseSchema, GetEffectivePermissionsRequestSchema, GetEffectivePermissionsResponseSchema, GetFieldLabelsRequestSchema, GetFieldLabelsResponseSchema, GetLocalesRequestSchema, GetLocalesResponseSchema, GetMetaItemCachedRequestSchema, GetMetaItemCachedResponseSchema, GetMetaItemRequestSchema, GetMetaItemResponseSchema, GetMetaItemsRequestSchema, GetMetaItemsResponseSchema, GetMetaTypesRequestSchema, GetMetaTypesResponseSchema, GetNotificationPreferencesRequestSchema, GetNotificationPreferencesResponseSchema, GetObjectPermissionsRequestSchema, GetObjectPermissionsResponseSchema, GetPresenceRequestSchema, GetPresenceResponseSchema, GetTranslationsRequestSchema, GetTranslationsResponseSchema, GetUiViewRequestSchema, GetUiViewResponseSchema, GetViewRequestSchema, GetViewResponseSchema, HttpFindQueryParamsSchema, ListAiConversationsRequestSchema, ListAiConversationsResponseSchema, ListAiPendingActionsRequestSchema, ListAiPendingActionsResponseSchema, ListNotificationsRequestSchema, ListNotificationsResponseSchema, ListViewsRequestSchema, ListViewsResponseSchema, MarkAllNotificationsReadRequestSchema, MarkAllNotificationsReadResponseSchema, MarkNotificationsReadRequestSchema, MarkNotificationsReadResponseSchema, NotificationSchema, NotificationPreferencesSchema, RealtimeConnectRequestSchema, RealtimeConnectResponseSchema, RealtimeDisconnectRequestSchema, RealtimeDisconnectResponseSchema, RealtimeSubscribeRequestSchema, RealtimeSubscribeResponseSchema, RealtimeUnsubscribeRequestSchema, RealtimeUnsubscribeResponseSchema, RegisterDeviceRequestSchema, RegisterDeviceResponseSchema, RejectAiPendingActionResponseSchema, SaveMetaItemRequestSchema, SaveMetaItemResponseSchema, SetPresenceRequestSchema, SetPresenceResponseSchema, UnregisterDeviceRequestSchema, UnregisterDeviceResponseSchema, UpdateAiConversationRequestSchema, UpdateDataRequestSchema, UpdateDataResponseSchema, UpdateManyDataRequestSchema, UpdateManyDataResponseSchema, UpdateNotificationPreferencesRequestSchema, UpdateNotificationPreferencesResponseSchema, UpdateViewRequestSchema, UpdateViewResponseSchema } from '@objectstack/spec/api';
24+
import type { AiAgentCapabilities, AiAgentChatRequest, AiAgentSummary, AiAgentsResponse, AiChatRequest, AiChatResponse, AiCompleteRequest, AiConversation, AiMessage, AiModelsResponse, AiPendingAction, AiPendingActionStatus, AiStreamChunk, ApproveAiPendingActionResponse, AutomationActionsResponse, AutomationTriggerRequest, AutomationTriggerResponse, BatchDataRequest, BatchDataResponse, CheckPermissionRequest, CheckPermissionResponse, CreateAiConversationRequest, CreateDataRequest, CreateDataResponse, CreateManyDataRequest, CreateManyDataResponse, CreateViewRequest, CreateViewResponse, DeleteDataRequest, DeleteDataResponse, DeleteManyDataRequest, DeleteManyDataResponse, DeleteMetaItemRequest, DeleteMetaItemResponse, DeleteViewRequest, DeleteViewResponse, FindDataRequest, FindDataResponse, GetDataRequest, GetDataResponse, GetDiscoveryRequest, GetDiscoveryResponse, GetEffectivePermissionsRequest, GetEffectivePermissionsResponse, GetFieldLabelsRequest, GetFieldLabelsResponse, GetLocalesRequest, GetLocalesResponse, GetMetaItemCachedRequest, GetMetaItemCachedResponse, GetMetaItemRequest, GetMetaItemResponse, GetMetaItemsRequest, GetMetaItemsResponse, GetMetaTypesRequest, GetMetaTypesResponse, GetNotificationPreferencesRequest, GetNotificationPreferencesResponse, GetObjectPermissionsRequest, GetObjectPermissionsResponse, GetPresenceRequest, GetPresenceResponse, GetTranslationsRequest, GetTranslationsResponse, GetUiViewRequest, GetUiViewResponse, GetViewRequest, GetViewResponse, ListAiConversationsRequest, ListAiConversationsResponse, ListAiPendingActionsRequest, ListAiPendingActionsResponse, ListNotificationsRequest, ListNotificationsResponse, ListViewsRequest, ListViewsResponse, MarkAllNotificationsReadRequest, MarkAllNotificationsReadResponse, MarkNotificationsReadRequest, MarkNotificationsReadResponse, Notification, NotificationPreferences, RealtimeConnectRequest, RealtimeConnectResponse, RealtimeDisconnectRequest, RealtimeDisconnectResponse, RealtimeSubscribeRequest, RealtimeSubscribeResponse, RealtimeUnsubscribeRequest, RealtimeUnsubscribeResponse, RegisterDeviceRequest, RegisterDeviceResponse, RejectAiPendingActionResponse, SaveMetaItemRequest, SaveMetaItemResponse, SetPresenceRequest, SetPresenceResponse, UnregisterDeviceRequest, UnregisterDeviceResponse, UpdateAiConversationRequest, UpdateDataRequest, UpdateDataResponse, UpdateManyDataRequest, UpdateManyDataResponse, UpdateNotificationPreferencesRequest, UpdateNotificationPreferencesResponse, UpdateViewRequest, UpdateViewResponse } from '@objectstack/spec/api';
2525

2626
// Validate data
2727
const result = AiAgentCapabilitiesSchema.parse(data);
@@ -1092,6 +1092,24 @@ const result = AiAgentCapabilitiesSchema.parse(data);
10921092
| **readCount** | `number` || Number of notifications marked as read |
10931093

10941094

1095+
---
1096+
1097+
## Notification
1098+
1099+
### Properties
1100+
1101+
| Property | Type | Required | Description |
1102+
| :--- | :--- | :--- | :--- |
1103+
| **id** | `string` || Notification ID |
1104+
| **type** | `string` || Notification type |
1105+
| **title** | `string` || Notification title |
1106+
| **body** | `string` || Notification body text |
1107+
| **read** | `boolean` || Whether notification has been read |
1108+
| **data** | `Record<string, any>` | optional | Additional notification data |
1109+
| **actionUrl** | `string` | optional | URL to navigate to when clicked |
1110+
| **createdAt** | `string` || When notification was created |
1111+
1112+
10951113
---
10961114

10971115
## NotificationPreferences

content/docs/references/system/notification.mdx

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ Supports variables for personalization and file attachments.
5050
## TypeScript Usage
5151

5252
```typescript
53-
import { EmailTemplateSchema, InAppNotificationSchema, NotificationChannelSchema, NotificationConfigSchema, PushNotificationSchema, SMSTemplateSchema } from '@objectstack/spec/system';
54-
import type { EmailTemplate, InAppNotification, NotificationChannel, NotificationConfig, PushNotification, SMSTemplate } from '@objectstack/spec/system';
53+
import { EmailTemplateSchema, InAppNotificationSchema, NotificationChannelSchema, PushNotificationSchema, SMSTemplateSchema } from '@objectstack/spec/system';
54+
import type { EmailTemplate, InAppNotification, NotificationChannel, PushNotification, SMSTemplate } from '@objectstack/spec/system';
5555

5656
// Validate data
5757
const result = EmailTemplateSchema.parse(data);
@@ -106,24 +106,6 @@ Notification delivery channel (implemented today: inbox, email, sms — push/sla
106106
* `webhook`
107107

108108

109-
---
110-
111-
## NotificationConfig
112-
113-
### Properties
114-
115-
| Property | Type | Required | Description |
116-
| :--- | :--- | :--- | :--- |
117-
| **id** | `string` || Notification ID |
118-
| **name** | `string` || Notification name |
119-
| **channel** | `Enum<'email' \| 'sms' \| 'push' \| 'in-app' \| 'slack' \| 'teams' \| 'webhook'>` || Notification channel |
120-
| **template** | `{ id: string; subject: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }; body: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }; bodyType?: Enum<'text' \| 'html' \| 'markdown'>; … } \| { id: string; message: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }; maxLength?: number; variables?: string[] } \| { title: string; body: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }; icon?: string; badge?: number; … } \| { title: string; message: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }; type: Enum<'info' \| 'success' \| 'warning' \| 'error'>; actionUrl?: string; … }` || Notification template |
121-
| **recipients** | `{ to: string[]; cc?: string[]; bcc?: string[] }` || Recipients |
122-
| **schedule** | `{ type: Enum<'immediate' \| 'delayed' \| 'scheduled'>; delay?: number; scheduledAt?: number }` | optional | Scheduling |
123-
| **retryPolicy** | `{ enabled?: boolean; maxRetries?: number; backoffStrategy: Enum<'exponential' \| 'linear' \| 'fixed'> }` | optional | Retry policy |
124-
| **tracking** | `{ trackOpens?: boolean; trackClicks?: boolean; trackDelivery?: boolean }` | optional | Tracking configuration |
125-
126-
127109
---
128110

129111
## PushNotification

0 commit comments

Comments
 (0)