Skip to main content
Version: 0.5.x

Introduction​

The notification capability has three entries:

EntryUserDescription
services.Notifications()Source plugin standard capabilityBatch-reads visible notification message views
services.Admin().Notifications()Trusted source pluginSends notifications, deletes notifications, deletes by business source
service: notificationsDynamic pluginReads message views and sends governed notifications through the notifications service

The latest root capability catalog does not have a services.Notify() method. Source plugins that need to send notifications should use management commands, because sending messages produces host write and delivery side effects.

Capability Phase: Runtime

Supported Plugin Types: Source plugins, Dynamic plugins

Capability Design​

Data Model​

TypeFieldDescription
SendInputRecipientsTarget user identifier set
SendInputSourceType, SourceIDBusiness source type and source record identifier
SendInputTitle, ContentNotification title and content
SendInputCategoryInbox category; falls back to other when unspecified
SendInputSenderUserIDOptional sender; adapter can use CapabilityContext operator when omitted
SendResultMessageID, DeliveryCountCreated message identifier and delivery count

Built-in source types include notice and plugin; the generic category fallback value is other.

Read-Write Separation Design​

The notification capability follows a read-write separation pattern: standard Notifications() provides read-only view capabilities, while Admin().Notifications() provides governed write commands. Sending is a governed write command because it produces host write and delivery side effects.

Localization and Sending​

Notification content requires plugins to handle localization themselves. Before sending, the i18n capability can be used to resolve copy. The notification capability itself is not responsible for template rendering.

Interface Definitions​

Source Plugin Interface​

EntryMethodDescription
Notifications()BatchGetBatch-reads visible notification message views
Notifications()BatchGetBySourceBatch-reads visible notification messages by business source
Notifications()EnsureVisibleValidates that target notification message set is visible to the current call context
Admin().Notifications()SendSends a governed notification
Admin().Notifications()DeleteDeletes visible notification messages
Admin().Notifications()DeleteBySourceDeletes notifications by business source

Dynamic Plugin Interface​

Dynamic plugins declare authorized methods through hostServices.notifications:

Dynamic MethodDescription
messages.batch_getBatch-reads visible notification message views
messages.batch_get_by_sourceBatch-reads visible notification messages by business source
messages.visible.ensureValidates that target notification message set is visible to the current call context
messages.sendSends a governed notification

Capability Usage​

Source Plugin Usage​

Source plugins read notification views through services.Notifications(), explicitly passing the domain-required CapabilityContext:

// Batch-read notification messages
result, err := services.Notifications().BatchGet(ctx, capabilityCtx, messageIDs)

// Batch-read notification messages by business source
sourceResult, err := services.Notifications().BatchGetBySource(ctx, capabilityCtx, notifycap.BatchGetBySourceInput{
SourceType: notifycap.SourceTypePlugin,
SourceIDs: []string{reportID1, reportID2},
})

// Validate notification message visibility
err := services.Notifications().EnsureVisible(ctx, capabilityCtx, messageIDs)

Trusted source plugins sending and managing notifications:

// Send notification
result, err := services.Admin().Notifications().Send(ctx, capabilityCtx, notifycap.SendInput{
Recipients: []string{userID},
SourceType: notifycap.SourceTypePlugin,
SourceID: reportID,
Title: "Report Generation Complete",
Content: "Your report has been generated, please check",
Category: notifycap.CategoryCode("report"),
})

// Delete notification messages
err := services.Admin().Notifications().Delete(ctx, capabilityCtx, messageIDs)

// Delete notifications by business source
err := services.Admin().Notifications().DeleteBySource(ctx, capabilityCtx, notifycap.SourceTypePlugin, []string{reportID})

Dynamic Plugin Usage​

Dynamic plugins declare the notifications service and authorized methods in plugin.yaml:

hostServices:
- service: notifications
methods:
- messages.batch_get
- messages.batch_get_by_source
- messages.visible.ensure
- messages.send
resources:
- ref: inbox:business-alert

messages.send is a resource-type method and must declare resources[].ref. The host can use this to restrict the message scenarios or categories a plugin can send. Usage on the dynamic plugin side:

notifySvc := pluginbridge.Default().Notifications()

// Batch-read notification messages
result, err := notifySvc.BatchGet(ctx, capabilityCtx, messageIDs)

// Batch-read notification messages by business source
sourceResult, err := notifySvc.BatchGetBySource(ctx, capabilityCtx, notifycap.BatchGetBySourceInput{
SourceType: notifycap.SourceTypePlugin,
SourceIDs: []string{reportID1, reportID2},
})

// Send notification
sendResult, err := notifySvc.Send(ctx, capabilityCtx, notifycap.SendInput{
Recipients: []string{userID},
SourceType: notifycap.SourceTypePlugin,
SourceID: taskID,
Title: "Task Complete",
Content: "Your export task has been completed",
Category: notifycap.CategoryCode("report"),
})

Design Constraints​

  • Standard capability is read-only. Notifications() is for reading views, not for sending.
  • Sending is a governed write command. Source plugins send notifications via Admin().Notifications().Send; dynamic plugins via notifications.messages.send.
  • Deletion is governed by visibility and source. Both DeleteMessages and DeleteBySource should check target visibility in the host domain adapter.
  • Notification content should be self-localized. The i18n capability can be used to resolve copy before sending; the notification capability is not responsible for template rendering.