Help us shape the future of Go! Take the 2026 Go Developer Survey

notification

package
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 18, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

Notification module

modules/notification tells somebody something, in the application and optionally by mail. Rows are addressed to a person, so the two routes under /api/v1/notification/notifications are scoped by the principal rather than by a permission, and the manifest declares neither permissions nor a navigation entry; a subscription delivers the mail-marked rows through the composed Mailer. Without a mail host the rows are still recorded and the mails are logged, which is what a development machine wants.

Compose it with notification.Deps{Recipients, Mailer, Hosts, Secure}: SMTP is the production mailer for config.example.yaml's mail section (password through PLATFORMKIT_MAIL_PASSWORD) and NewMailbox() the in-memory one. Consumers import contracts/ and its fake, never internal/; mail templates live in internal/templates.

Documentation

Overview

Package notification is the module manifest: telling somebody something, in the application and optionally by mail.

It is the shape every module follows, with one deliberate omission: there is no rest.Spec. A Spec's list route is the whole tenant, and these rows are addressed to a person — every caller's list is a different list — so the two routes are written by hand and scoped by the principal rather than by a permission. See internal/handler.go.

Index

Constants

This section is empty.

Variables

View Source
var Migrations = db.MigrationSource{
	Owner:  "notification",
	Files:  db.Sub(schema, "migrations"),
	Adopts: []db.Adoption{{Owner: "platformkit", Versions: []int64{11}}},
}

Migrations is this module's SQL as one source — the notifications table — owned as "notification". The manifest hands the kernel the same files and adoption, and a test composes the schema it needs beside the foundation: dbtest.Schema(t, notification.Migrations).

The files keep the version numbers they had when the foundation applied them under its own name, so an installation migrated before this module owned its SQL is adopted by checksum rather than migrated again (see db.Adoption and docs/adr/0011). New files continue from the highest number.

SMTP is the production Mailer for a configured server. main wires it, or the in-memory Mailbox when there is none, so the choice is visible in the file that composes the application.

Functions

func Module

func Module(deps Deps) (contracts.Service, module.Module)

Types

type Deps

type Deps struct {
	// Recipients turns a user id into an email address. The interface is
	// declared in this module's contracts/ and satisfied by an adapter over the
	// user module in apps/platformkit: the app adapts, so notification never
	// names user. A nil lookup writes every row and sends no mail.
	Recipients contracts.RecipientLookup

	// Mailer sends the rendered message, in the worker.
	Mailer contracts.Mailer

	// Hosts turns the tenant an event belongs to into the host its people reach
	// the application at, which is what a notice's link has to become for a mail
	// client. It is declared in this module's contracts/ and satisfied by an
	// adapter over the tenant module in apps/platformkit, the same way
	// Recipients is satisfied over the user module.
	Hosts contracts.HostLookup

	// Secure says the application is reached over https, which is the scheme a
	// mailed link is built with. It is one bool rather than a host because it is
	// the same decision the session cookie's Secure flag is: a laptop reached at
	// a local name gets http, and everything else gets https.
	Secure bool
}

Deps is what this module cannot make for itself.

type Mail

type Mail = internal.Mail

Mail is one outgoing mail server. It has the same shape as config.Mail, so main converts one to the other in a line.

type Mailbox

type Mailbox struct {
	// contains filtered or unexported fields
}

Mailbox is contracts.Mailer over a slice. It keeps every message and logs each one, so a development machine can read what would have been sent and a test can assert on it.

It lives in the module and not in notificationtest, and the reason is a link rather than a taste. A deployment with no mail server wires this, so it is production code by use; notificationtest also holds a conformance suite, which imports "testing", and a package is linked whole — so the reference binary used to carry the testing package, its flag registrations and its init, because of where one struct sat. The test suite still uses this one: what a test wants and what an unconfigured deployment wants is the same thing, which is somewhere for a message to go that is not a mail server.

func NewMailbox

func NewMailbox() *Mailbox

NewMailbox returns an empty mailbox.

func (*Mailbox) Send

func (m *Mailbox) Send(ctx context.Context, msg contracts.Message) error

Send records the message. It never fails: a mailbox that could refuse would be exercising the outbox's retry ladder rather than whatever is under test.

func (*Mailbox) Sent

func (m *Mailbox) Sent() []contracts.Message

Sent is every message so far, in order.

Directories

Path Synopsis
Package contracts is everything another module, an app or a test may know about notifications: the entity, the notice, the events, the two interfaces this module needs somebody else to satisfy, and the Service.
Package contracts is everything another module, an app or a test may know about notifications: the entity, the notice, the events, the two interfaces this module needs somebody else to satisfy, and the Service.
Package internal is every implementation of the notification module.
Package internal is every implementation of the notification module.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL