Documentation
¶
Overview ¶
Package notifylayer is the notify tool: the one route a person in a session, a managed script and the portal all send to a channel through.
It holds no transport and no queue. A send is an enqueue onto the existing notification queue, delivered by the existing worker, so an upstream outage is a retry rather than a failed tool call. What this package owns is the surface: which channels a caller may reach, what a document may be, and what an asset becomes when it is published.
Authorization is the channel's connection, not a new dimension. A channel the caller's persona cannot reach the connection of is not listed and cannot be sent to, which is the same rule a tool call against that connection already obeys.
Index ¶
Constants ¶
const ToolName = "notify"
ToolName is the MCP tool name, exported for composition roots that bind UI apps to it and for the platform's tool inventory.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AssetReader ¶
type AssetReader interface {
// Get returns one asset by id.
Get(ctx context.Context, id string) (*portaldomain.Asset, error)
// Content returns the asset's stored bytes at its current version.
Content(ctx context.Context, asset *portaldomain.Asset) ([]byte, error)
}
AssetReader is the portal read path publish needs: the asset record and its stored content. It is an interface so this package depends on reading an asset rather than on the portal's storage.
type Config ¶
type Config struct {
// Channels lists and resolves the operator's channels. nil leaves the
// tool unregistered: there is nothing to send to.
Channels notification.ChannelStore
// Enqueuer writes the queue row a send becomes. nil leaves the tool
// unregistered, because a listed channel that cannot be sent to is worse
// than no tool at all.
Enqueuer *notification.Enqueuer
// Scope decides whether a caller's persona reaches a channel's
// connection. nil denies every channel that names one, which is the
// fail-closed answer the action path already gives.
Scope *connscope.Scope
// Assets reads the asset publish turns into a document. nil leaves the
// publish action refusing, and list and send unaffected.
Assets AssetReader
// Access decides whether the caller may read the asset they named. nil
// leaves the publish action refusing: a deployment that cannot check
// entitlement must not publish on the strength of an id.
Access Entitlement
// PortalURL is the deployment's public base URL, used to build the link
// a published document carries. Empty omits the link.
PortalURL string
// AdminPersona is the persona name whose reach is unrestricted, as it is
// everywhere else in the product. Empty means no persona is lifted.
AdminPersona string
}
Config wires the tool to the stores it reads and the queue it writes.
type Entitlement ¶
type Entitlement interface {
// CanRead reports whether the identified caller may read the asset.
CanRead(ctx context.Context, asset *portaldomain.Asset, userID, email string) bool
}
Entitlement reports whether a caller may read an asset. It is the portal's existing access core, narrowed to the one question publish asks.
type Handle ¶
type Handle struct {
// contains filtered or unexported fields
}
Handle is the registered tool.
func New ¶
New builds the handle, or nil when the deployment cannot send at all.
The two required pieces are the channel records and the queue. Either missing means there is no feature here: a tool that lists destinations it cannot write to would advertise a capability the deployment does not have, which is the shape the vaporware gates exist to refuse.
func (*Handle) RegisterTool ¶
RegisterTool registers notify on the server. A nil handle registers nothing, which is how a deployment with no channels advertises no tool.