Documentation
¶
Overview ¶
Package notify implements outbound notification channels for grant request lifecycle events. Today this is Slack-only and outbound-only — no inbound webhooks, no interactive buttons. The admin sees the post in Slack, follows the link to the dbbat UI, and decides there.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrChannelMissing = errors.New("DBB_SLACK_NOTIFY_BOT_TOKEN set without DBB_SLACK_NOTIFY_CHANNEL")
ErrChannelMissing is returned by NewSlackNotifier when a bot token is set but no channel is configured.
var ErrPublicURLMissing = errors.New("DBB_SLACK_NOTIFY_BOT_TOKEN set without DBB_PUBLIC_URL")
ErrPublicURLMissing is returned by NewSlackNotifier when a bot token is set but no public URL is configured.
Functions ¶
This section is empty.
Types ¶
type GrantAction ¶
type GrantAction string
GrantAction names the lifecycle event a notification refers to.
const ( GrantActionCreated GrantAction = "created" GrantActionApproved GrantAction = "approved" GrantActionDenied GrantAction = "denied" GrantActionCancelled GrantAction = "cancelled" //nolint:misspell // matches DB lifecycle value )
Lifecycle actions a notification can describe. The cancel value matches the DB CHECK constraint spelling.
type GrantRequestEvent ¶
type GrantRequestEvent struct {
Action GrantAction
Request *store.GrantRequest
Definition *store.GrantDefinition
Database *store.Database
Requester *store.User
// Decider is set when Action is approved/denied/canceled.
Decider *store.User
}
GrantRequestEvent carries the data the notifier needs to render a message. Fields besides Request are looked up by the API handler before firing — denormalizing here keeps the notifier free of store lookups (so a slow DB doesn't block Slack and vice-versa).
type SlackNotifier ¶
type SlackNotifier struct {
// contains filtered or unexported fields
}
SlackNotifier posts Block Kit messages to a configured channel for grant request lifecycle events. A nil notifier is a graceful no-op (returned from NewSlackNotifier when the bot token is unset).
func NewSlackNotifier ¶
func NewSlackNotifier(cfg config.SlackNotifyConfig, publicURL string, persister SlackPersister, log *slog.Logger) (*SlackNotifier, error)
NewSlackNotifier returns a configured notifier or nil when the feature is disabled. A startup error fires only when notification is enabled but dependent fields are missing — silent disable is intentional for deployments that just don't want it.
func (*SlackNotifier) NotifyGrantRequest ¶
func (n *SlackNotifier) NotifyGrantRequest(ctx context.Context, ev GrantRequestEvent)
NotifyGrantRequest posts a fresh message on creation and chat.update's the existing message on subsequent lifecycle events. All errors are logged and swallowed — notifications are best-effort and must never fail the API request that triggered them.
type SlackPersister ¶
type SlackPersister interface {
SetGrantRequestSlackMessage(ctx context.Context, uid uuid.UUID, channel, ts string) error
}
SlackPersister is the slice of the store API the notifier uses to remember which Slack message corresponds to a request, so it can chat.update on follow-ups.