Documentation
¶
Overview ¶
Package postgres implements notify's durable inbox on a host-owned PostgreSQL pool. Hosts explicitly migrate before use and authorize every recipient. It starts no workers, sends no messages and never owns the host's pool.
Index ¶
- func Migrate(ctx context.Context, pool *pgxpool.Pool, schema string) error
- func MigrateDB(ctx context.Context, db *sql.DB, schema string) error
- func Validate(ctx context.Context, pool *pgxpool.Pool, schema string) error
- type Config
- type LegacyScope
- type LegacyVisibility
- type Store
- func (s *Store) AppErasedRecipients(ctx context.Context, audience notify.Audience, appID string, ...) ([]notify.Recipient, error)
- func (s *Store) Apply(ctx context.Context, mutations []notify.Mutation) error
- func (s *Store) ApplyTx(ctx context.Context, tx pgx.Tx, mutations []notify.Mutation) error
- func (s *Store) ClassifyLegacyOrigins(ctx context.Context, mappings []LegacyVisibility) (int64, error)
- func (s *Store) EraseAppRecipient(ctx context.Context, r notify.Recipient, appID string, ...) error
- func (s *Store) EraseRecipient(ctx context.Context, r notify.Recipient) error
- func (s *Store) EraseRecipientTx(ctx context.Context, tx pgx.Tx, r notify.Recipient) error
- func (s *Store) Get(ctx context.Context, r notify.Recipient, id string) (notify.Item, error)
- func (s *Store) GetRecipients(ctx context.Context, rs []notify.Recipient, id string) (notify.Item, error)
- func (s *Store) List(ctx context.Context, r notify.Recipient, o notify.ListOptions) (notify.Page, error)
- func (s *Store) ListRecipients(ctx context.Context, recipients []notify.Recipient, o notify.ListOptions) (notify.Page, error)
- func (s *Store) MergeFrom(ctx context.Context, sources []LegacyScope) error
- func (s *Store) Publish(ctx context.Context, in notify.Input) (notify.Item, error)
- func (s *Store) PublishTx(ctx context.Context, tx pgx.Tx, in notify.Input) (notify.Item, error)
- func (s *Store) SetDismissed(ctx context.Context, r notify.Recipient, id string, dismissed bool) (notify.Item, error)
- func (s *Store) SetDismissedRecipients(ctx context.Context, rs []notify.Recipient, id string, dismissed bool) (notify.Item, error)
- func (s *Store) SetRead(ctx context.Context, r notify.Recipient, id string, read bool) (notify.Item, error)
- func (s *Store) SetReadRecipients(ctx context.Context, rs []notify.Recipient, id string, read bool) (notify.Item, error)
- func (s *Store) Transition(ctx context.Context, r notify.Recipient, id string, revision int64, ...) (notify.Item, error)
- func (s *Store) TransitionTx(ctx context.Context, tx pgx.Tx, r notify.Recipient, id string, revision int64, ...) (notify.Item, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Migrate ¶
Migrate applies this library's versioned migrations in a transaction. The host creates the schema and supplies a pool with DDL permission.
Types ¶
type Config ¶
type Config struct {
Schema, Scope string
// Origins, when non-nil, restricts reads and receipt mutations to exact
// producer namespaces. nil retains the unrestricted legacy behavior.
// Publication and account erasure cover the whole shared store.
Origins []notify.OriginScope
// AppView is the trusted application presentation boundary. It is distinct
// from producer provenance. Do not combine with the legacy Origins filter.
AppView *notify.AppView
}
Config binds a store to one local application/tenant scope in a migrated schema.
type LegacyScope ¶
LegacyScope identifies an existing, migrated inbox in the same database.
type LegacyVisibility ¶
type LegacyVisibility struct {
Origin notify.OriginScope
Visibility notify.Visibility
AppID string
}
LegacyVisibility is an explicit migration claim about one producer scope. It does not alter the producer identity or relabel already classified rows.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store retains notices and actionable items. Scope and recipients are data isolation boundaries; authorization remains with the host.
func (*Store) AppErasedRecipients ¶
func (s *Store) AppErasedRecipients(ctx context.Context, audience notify.Audience, appID string, legacy notify.OriginScope, after string, limit int) ([]notify.Recipient, error)
AppErasedRecipients pages permanent account/app fences for trusted restore reconciliation. Only this app's explicit and native legacy fences join the whole-account tombstones. The caller must finish replay before serving.
func (*Store) ApplyTx ¶
ApplyTx joins the caller's transaction. Its savepoint makes the whole batch atomic even if the caller handles an error and commits other work in tx.
func (*Store) ClassifyLegacyOrigins ¶
func (s *Store) ClassifyLegacyOrigins(ctx context.Context, mappings []LegacyVisibility) (int64, error)
ClassifyLegacyOrigins labels only currently unclassified receipts. Run with writers stopped after verifying each producer scope's ownership. A conflicting explicit classification aborts the whole operation; read/archive state and IDs survive. Versioned unclassified rows require exact source-state adoption; relabeling them would invalidate producer replay. Normal Publish replay never performs this migration implicitly.
func (*Store) EraseAppRecipient ¶
func (s *Store) EraseAppRecipient(ctx context.Context, r notify.Recipient, appID string, legacy notify.OriginScope) error
EraseAppRecipient permanently erases one app's receipts, including its explicitly identified legacy native origin. Tenant-wide notices and other apps survive. This is an erasure boundary, not an inbox dismiss/reset action. IDs and origin come from trusted deployment configuration, never a request.
func (*Store) EraseRecipient ¶
EraseRecipient deletes an inbox and permanently fences delayed publications. This is account erasure, not the operation for dismissing one item.
func (*Store) EraseRecipientTx ¶
EraseRecipientTx joins account erasure in the host's transaction.
func (*Store) GetRecipients ¶
func (s *Store) GetRecipients(ctx context.Context, rs []notify.Recipient, id string) (notify.Item, error)
GetRecipients reads a receipt only when its recipient is in the host's fresh authorized set. An absent or newly unlinked recipient reads as not found.
func (*Store) List ¶
func (s *Store) List(ctx context.Context, r notify.Recipient, o notify.ListOptions) (notify.Page, error)
List reads one authorized recipient's inbox, newest first. Restart scans from an empty cursor to discover late commits; cursors are not delivery watermarks.
func (*Store) ListRecipients ¶
func (s *Store) ListRecipients(ctx context.Context, recipients []notify.Recipient, o notify.ListOptions) (notify.Page, error)
ListRecipients reads only the recipients the host authorized for this request. Filtering happens in SQL before pagination, so an unlinked recipient consumes no page slots. Empty recipients returns an empty page. Cursors bind the normalized recipient set and filters; restart paging after access changes.
func (*Store) MergeFrom ¶
func (s *Store) MergeFrom(ctx context.Context, sources []LegacyScope) error
MergeFrom consolidates legacy inboxes into this store without changing the sources. Run this maintenance operation with source and destination writers stopped, then switch all writers to the destination. It is not a boot hook.
Duplicate origins retain one receipt, read/archive timestamps from either copy, and the most recently updated workflow state. Erasure wins over every copy. The destination's existing ID survives; otherwise the first source ID survives. A conflicting ID for a different origin aborts the transaction. Reads and receipt changes use this store's origin filter after the merge; the merge itself copies every origin in the explicitly named scopes.
func (*Store) Publish ¶
Publish inserts once per origin and recipient. Retries preserve content and every local read/workflow transition, including after a crash before an ack.
func (*Store) PublishTx ¶
PublishTx joins the domain change's transaction. The transaction must reach the same database as the store; the caller commits or rolls it back.
func (*Store) SetDismissed ¶
func (s *Store) SetDismissed(ctx context.Context, r notify.Recipient, id string, dismissed bool) (notify.Item, error)
SetDismissed archives or restores a recipient's receipt, independently of read state and domain/workflow resolution.
func (*Store) SetDismissedRecipients ¶
func (s *Store) SetDismissedRecipients(ctx context.Context, rs []notify.Recipient, id string, dismissed bool) (notify.Item, error)
SetDismissedRecipients changes only a receipt in the host's currently authorized set. Retried dismissal preserves its original timestamp.
func (*Store) SetRead ¶
func (s *Store) SetRead(ctx context.Context, r notify.Recipient, id string, read bool) (notify.Item, error)
SetRead changes only local read state. It never resolves an actionable item.
func (*Store) SetReadRecipients ¶
func (s *Store) SetReadRecipients(ctx context.Context, rs []notify.Recipient, id string, read bool) (notify.Item, error)
SetReadRecipients updates authorized receipt state and returns the canonical item/revision. Reading does not dismiss the receipt or resolve a workflow.
func (*Store) Transition ¶
func (s *Store) Transition(ctx context.Context, r notify.Recipient, id string, revision int64, status notify.Status) (notify.Item, error)
Transition changes workflow state under optimistic concurrency. The caller must perform/authorize any domain action first, or use TransitionTx in the same transaction as that action. General notices cannot become work items.