Documentation
¶
Overview ¶
Package notifywire assembles the notification substrate for the HTTP composition root: the delivery handle, the branded templates, the review and connection alerts, and the portal's notifier and self-scoped preference routes.
It was extracted from internal/httpserver (#1759) when that package reached its size budget. The seam is a real one: everything here takes a *platform.Platform and returns an assembled subsystem handle, and nothing in it touches a mux, a route or a middleware, which is what the composition root itself is about.
Index ¶
- Constants
- func APIConnectionExists(reg *registry.Registry) func(context.Context, string) bool
- func BuildNotifications(p *platform.Platform, brand Brand) *notifydelivery.Handle
- func BuildReviewAlert(p *platform.Platform, notify *notifydelivery.Handle) *reviewalert.Checker
- func ChannelUpstream(reg *registry.Registry) notifypost.UpstreamFunc
- func ConnAlertSettings(p *platform.Platform) connalert.SettingsStore
- func ConnAlertStore(p *platform.Platform) *connalert.PostgresStore
- func ReviewAlertSettings(p *platform.Platform, target reviewalert.Target) reviewalert.SettingsStore
- func WireConnRevocationAlert(p *platform.Platform, notify *notifydelivery.Handle) *connalert.Escalator
- func WirePortalNotifications(deps *portal.Deps, p *platform.Platform, notify *notifydelivery.Handle, ...)
- type Brand
Constants ¶
const PortalToolkitKind = "portal"
PortalToolkitKind is the registry kind of the asset-portal toolkit.
Variables ¶
This section is empty.
Functions ¶
func APIConnectionExists ¶ added in v1.134.0
APIConnectionExists reports whether a live api toolkit serves a connection. The admin channel form uses it to warn about a channel naming a connection nothing serves, which is otherwise a channel that looks configured and fails only when something is sent to it.
func BuildNotifications ¶
func BuildNotifications(p *platform.Platform, brand Brand) *notifydelivery.Handle
BuildNotifications assembles the email-notification substrate from the platform's database, encryptor, and the brand supplied. Returns nil when the feature is unavailable (no platform, no database) or disabled by config; every consumer of the handle is nil-safe.
func BuildReviewAlert ¶
func BuildReviewAlert(p *platform.Platform, notify *notifydelivery.Handle) *reviewalert.Checker
BuildReviewAlert assembles the scheduled knowledge review-queue staleness check. Returns nil (a no-op checker) when anything it needs is absent: no database, notifications off, no knowledge insight store -- an alert with nowhere to send is not an alert.
func ChannelUpstream ¶ added in v1.134.0
func ChannelUpstream(reg *registry.Registry) notifypost.UpstreamFunc
ChannelUpstream resolves the api connection a chat or webhook channel delivers through to its authorized transport (#1720).
The registry is walked per send rather than snapshotted, for the reason the api browser's locator walks it per request: a connection added or re-keyed through the admin API is reachable without a restart, and a channel holding a transport built at startup would keep posting with a credential the operator has already rotated.
Returns nil when there is no registry to walk, which leaves the three HTTP channel kinds undeliverable rather than silently failing per send.
func ConnAlertSettings ¶
func ConnAlertSettings(p *platform.Platform) connalert.SettingsStore
ConnAlertSettings narrows the store to the half the admin settings surface needs, or nil when the alert cannot exist here. A nil result unmounts the admin routes: an operator must not be able to name recipients for an alert nothing will ever send. The explicit nil check keeps a typed nil out of the interface.
func ConnAlertStore ¶
func ConnAlertStore(p *platform.Platform) *connalert.PostgresStore
ConnAlertStore builds the connection-revocation alert's persistence (#1694), or nil when the alert cannot exist in this deployment: no database, or notifications turned off in YAML. Like the review alert's store it is stateless over the pool, so the admin API and the sweep each build one rather than sharing a handle whose lifecycle it does not have.
func ReviewAlertSettings ¶
func ReviewAlertSettings(p *platform.Platform, target reviewalert.Target) reviewalert.SettingsStore
ReviewAlertSettings narrows one queue's store to the half the admin settings surface needs, or nil when the alert cannot exist here. A nil result unmounts the admin routes, matching what the SMTP section already does in the same states: an operator must not be able to configure an alert nothing will ever send. The explicit nil check keeps a typed nil out of the interface.
func WireConnRevocationAlert ¶
func WireConnRevocationAlert(p *platform.Platform, notify *notifydelivery.Handle) *connalert.Escalator
WireConnRevocationAlert tells the auth-event writer where to announce a discarded credential (#1694), and returns the sweep that escalates one nobody has acted on. Both are nil when the alert cannot exist here.
The writer is built with the token store, long before the notification substrate exists, so the sink is attached here rather than at construction. It is the one dependency every connoauth.Source already carries, which is why the announcement rides it instead of being threaded a second time through every toolkit that wires OAuth.
func WirePortalNotifications ¶
func WirePortalNotifications(deps *portal.Deps, p *platform.Platform, notify *notifydelivery.Handle, audience *mention.Audience)
WirePortalNotifications attaches the notification substrate to the portal dependency set: the share/thread trigger bridge and the self-scoped preference routes. A nil handle leaves both unset (feature unavailable).
The mention audience is supplied rather than built here: the composition root builds one and hands the same one to every surface that resolves a mention.
Types ¶
type Brand ¶
type Brand struct {
// Name is the deployment's brand name, already resolved through its
// fallbacks.
Name string
// UnsubscribeURL builds the no-login opt-out link for an address, or nil
// when the endpoint cannot be served.
UnsubscribeURL func(email string) string
}
Brand is what an email says it is from and where its footer links go. The composition root resolves both -- the brand name has fallbacks that belong to the portal's config, and the unsubscribe link needs the browser-session signing key -- so they arrive here rather than being derived twice.