settings

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package settings persists values through registered, typed key declarations. Form presentation is separate from the value codec and grants no access rights.

Index

Constants

View Source
const (
	MigrationOrigin          migrate.Origin  = "foundry.settings"
	CreateSettings           migrate.ID      = "000001_create_settings"
	AddPresentationOwnership migrate.ID      = "000002_add_presentation_ownership"
	Introduced               migrate.Version = "v0.1.0"
)
View Source
const (
	DefaultPageSize = 100
	// MaxLoadBytes bounds the stored JSON retained by one List, Load or LoadGroup.
	// ListPage never fails on aggregate size: it ends a page early instead.
	MaxLoadBytes = 64 << 20
)
View Source
const MaxCacheTTL = time.Hour

MaxCacheTTL bounds how long a process may serve a cached setting. It is also the upper bound on staleness after a write made by another process.

Variables

This section is empty.

Functions

func Migrations

func Migrations() []migrate.Definition

Migrations returns the settings table history. Rows existing before presentation ownership keep their stored presentation (declared=false); ResetPresentation hands a row back to its declaration explicitly.

Types

type Batch

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

Batch is an immutable snapshot of selected settings. Values decode afresh on each access. Later writes do not change an existing Batch.

func Load

func Load(ctx context.Context, m *Manager, keys ...Selection) (Batch, error)

Load reads the selected registered keys with at most one query. Cached keys are served from the manager's cache; the others are read in one snapshot and may populate it. The retained JSON is bounded by MaxLoadBytes.

func LoadGroup

func LoadGroup(ctx context.Context, m *Manager, group Group) (Batch, error)

LoadGroup loads every registered key whose declared presentation group is group, including keys without a stored row, which read as absent. Membership follows declarations so typed code sees a stable set of keys.

func (Batch) Format

func (Batch) Format(s fmt.State, _ rune)

Format writes a fixed label without exposing batch data.

type Cursor

type Cursor struct {
	Group Group
	Order int32
	Name  Name
}

Cursor is the position after which ListPage continues: the group, sort order and name of the last record already returned. The zero Cursor starts at the beginning. It is a position, not a capability or a consistent snapshot.

func After

func After(r Record) Cursor

After returns the cursor that continues after record r.

func (Cursor) IsZero

func (c Cursor) IsZero() bool

IsZero reports whether the cursor is empty.

type Filter

type Filter struct {
	Group      Group
	Prefix     string
	PublicOnly bool
}

Filter selects settings by group, name prefix, and public visibility.

type Group

type Group string

Group identifies a settings presentation group.

func Groups

func Groups(ctx context.Context, m *Manager) ([]Group, error)

Groups lists the stored presentation groups of registered settings, ordered as List orders them. It reads presentation columns only, never values.

type Key

type Key[V any] struct {
	// contains filtered or unexported fields
}

Key is a typed, versioned setting declaration.

func Define

func Define[V any](name Name, version Version, codec contract.JSON[V], presentation Presentation) Key[V]

Define creates a typed setting key, retaining presentation normalization errors for validation.

func (Key[V]) Configure

func (k Key[V]) Configure(ctx context.Context, m *Manager, p Presentation) error

Configure explicitly takes ownership of the persisted presentation. Later declaration changes no longer replace it until ResetPresentation is called.

func (Key[V]) Create

func (k Key[V]) Create(ctx context.Context, m *Manager, input V) error

Create creates the setting through the manager's write operation.

func (Key[V]) Decode

func (k Key[V]) Decode(ctx context.Context, r Record) (V, error)

Decode decodes a record whose name and version match this validated key.

func (Key[V]) Ensure

func (k Key[V]) Ensure(ctx context.Context, m *Manager, input V) error

Ensure creates a missing setting using its descriptor's presentation. An existing value remains unchanged, including its version. A presentation still owned by the declaration is refreshed from it; one changed by Configure stays.

func (Key[V]) EnsureIn

func (k Key[V]) EnsureIn(ctx context.Context, tx *database.Tx, m *Manager, input V) error

EnsureIn applies Ensure within the caller's transaction through a savepoint. Parent rollback includes initialization and declaration-owned presentation changes.

func (Key[V]) Find

func (k Key[V]) Find(ctx context.Context, m *Manager) (value.Optional[Record], error)

Find reads one setting. With Options.Cache it is served from the manager's cache until the entry expires or a write through this manager invalidates it.

func (Key[V]) Format

func (Key[V]) Format(s fmt.State, _ rune)

Format writes a fixed label without exposing the setting key.

func (Key[V]) From

func (k Key[V]) From(ctx context.Context, b Batch) (value.Optional[V], error)

From decodes this key from a Batch without I/O. A key that was not selected for the batch is an error rather than a silently missing value.

func (Key[V]) FromOr

func (k Key[V]) FromOr(ctx context.Context, b Batch, fallback V) (V, error)

FromOr applies GetOr's fallback rules to a Batch value.

func (Key[V]) Get

func (k Key[V]) Get(ctx context.Context, m *Manager) (value.Optional[V], error)

Get finds and decodes the setting, returning an absent optional when missing.

func (Key[V]) GetOr

func (k Key[V]) GetOr(ctx context.Context, m *Manager, fallback V) (V, error)

GetOr uses a validated, independently decoded fallback only when no row exists. Invalid stored values or versions never silently become defaults. With Options.Cache, repeated calls are served from the manager's cache.

func (Key[V]) Name

func (k Key[V]) Name() Name

Name returns the setting name, or an empty name for an undefined key.

func (Key[V]) Registration

func (k Key[V]) Registration() Registration

Registration returns a registration with default options.

func (Key[V]) RegistrationWith

func (k Key[V]) RegistrationWith(options Options[V]) Registration

RegistrationWith returns a registration with cache and upgrade options, copying the upgrade slice.

func (Key[V]) Remove

func (k Key[V]) Remove(ctx context.Context, m *Manager) (bool, error)

Remove removes the setting and reports whether a row was deleted, invalidating its cache around the write.

func (Key[V]) ResetPresentation

func (k Key[V]) ResetPresentation(ctx context.Context, m *Manager) error

ResetPresentation restores the declared presentation and returns its ownership to the declaration, so Ensure and Reconcile keep it current.

func (Key[V]) Set

func (k Key[V]) Set(ctx context.Context, m *Manager, input V) error

Set updates the setting through the manager's write operation.

func (Key[V]) SetIn

func (k Key[V]) SetIn(ctx context.Context, tx *database.Tx, m *Manager, input V) error

SetIn updates the setting in the supplied nonnil transaction.

func (Key[V]) Upsert

func (k Key[V]) Upsert(ctx context.Context, m *Manager, input V) error

Upsert atomically creates or replaces the value/version. Existing presentation is preserved; Configure changes presentation explicitly.

func (Key[V]) UpsertIn

func (k Key[V]) UpsertIn(ctx context.Context, tx *database.Tx, m *Manager, input V) error

UpsertIn creates or updates the setting in the supplied nonnil transaction.

func (Key[V]) Validate

func (k Key[V]) Validate() error

Validate checks the definition, name, version, presentation, and value codec.

func (Key[V]) Version

func (k Key[V]) Version() Version

Version returns the setting version, or zero for an undefined key.

type Kind

type Kind string

Kind identifies a setting's presentation kind.

const (
	Text          Kind = "text"
	Textarea      Kind = "textarea"
	Number        Kind = "number"
	Boolean       Kind = "boolean"
	Select        Kind = "select"
	Multiselect   Kind = "multiselect"
	Email         Kind = "email"
	URL           Kind = "url"
	Color         Kind = "color"
	Date          Kind = "date"
	Datetime      Kind = "datetime"
	File          Kind = "file"
	Image         Kind = "image"
	JSON          Kind = "json"
	Password      Kind = "password"
	Code          Kind = "code"
	MaxKeys            = 1000
	MaxValueBytes      = extensionvalue.MaxBytes
	MaxBatchBytes      = extensionvalue.MaxBatchBytes
)

func (Kind) Validate

func (k Kind) Validate() error

Validate checks that the setting presentation kind is supported.

type Manager

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

Manager borrows the extension Store, which owns admission and shutdown. Its optional read cache is owned by this manager instance only.

func New

func New(store *extensions.Store, keys ...Registration) (*Manager, error)

New validates and registers setting keys against an extension store, rejecting duplicate names.

func (*Manager) Invalidate

func (m *Manager) Invalidate(keys ...Selection) error

Invalidate drops cached reads for the given keys in this manager. Writes made through the manager do this automatically; call it after changing a setting by other means, such as a migration or another process's notification.

func (*Manager) Validate

func (m *Manager) Validate() error

Validate checks that the manager and its extension store are initialized.

type Name

type Name string

Name identifies a setting declaration.

type Options

type Options[V any] struct {
	Cache    time.Duration
	Upgrades []Upgrade[V]
}

Options adds optional registration behavior. The zero value is Registration().

Cache enables the manager's per-process read cache for this key: Get, GetOr, Find and Load serve a validated snapshot for at most Cache, then read again. Writes through the same manager invalidate the entry immediately and again after commit. Other processes observe a write after at most Cache. Zero disables caching; the maximum is MaxCacheTTL.

Upgrades declare conversions for values stored by earlier versions.

type Page

type Page struct {
	Records []Record
	Next    Cursor
}

Page is one bounded ListPage result. Next is zero after the last page.

func ListPage

func ListPage(ctx context.Context, m *Manager, filter Filter, after Cursor, limit int) (Page, error)

ListPage returns up to limit registered settings (DefaultPageSize when zero, at most MaxKeys) ordered by group, sort order and name, after the cursor. A page also ends early rather than retain more than MaxBatchBytes of JSON, so large settings never make the listing fail; continue with Page.Next. Each page is one bounded query in its own read snapshot.

type Presentation

type Presentation struct {
	Kind        Kind
	Group       Group
	Label       string
	Description string
	Order       int32
	Public      bool
	Parameters  value.JSON[json.RawMessage]
}

Presentation describes an administrative form. Password is only a masked widget; settings storage does not encrypt values. Parameters are explicitly dynamic JSON object data for the application's chosen widget.

func (Presentation) Validate

func (p Presentation) Validate() error

Validate validates the presentation kind, group, bounded text, and JSON object parameters.

type Reconciliation

type Reconciliation struct {
	// Upgraded values were rewritten from an earlier version by a declared upgrade.
	Upgraded []Name
	// Presented presentations still owned by their declaration were refreshed.
	Presented []Name
	// Incompatible rows have a newer version, or an older version without a
	// declared upgrade. Their presence fails Reconcile without any write.
	Incompatible []Name
}

Reconciliation reports what Reconcile changed, or which stored settings it could not accept. Names are registered setting names only, never values.

func Reconcile

func Reconcile(ctx context.Context, m *Manager) (Reconciliation, error)

Reconcile brings stored settings in line with their registrations in one transaction: declared upgrades are applied and declaration-owned presentations are refreshed. Run it after migrations whenever a deployment changes setting versions or presentation, for example while starting serve and worker processes, and treat an error as a startup failure. An incompatible version fails with fault.Conflict, lists the settings in Incompatible and writes nothing, instead of letting every later Get fail. It reads presentation columns first and loads one value at a time for upgrades.

type Record

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

Record's explicit dynamic export prevents accidental serialization of a private setting when an administrative record is logged or returned by HTTP.

func List

func List(ctx context.Context, m *Manager, filter Filter) ([]Record, error)

List returns this manager's registered settings ordered by group, sort order and name by reading consecutive ListPage pages; pages are separate snapshots. Prefix is a literal string, not SQL LIKE syntax. PublicOnly is explicit; callers still own endpoint authorization. The complete result retains at most MaxLoadBytes of JSON; use ListPage for larger administrative listings.

func (Record) Configured

func (r Record) Configured() bool

Configured reports whether Configure took ownership of the presentation, so declaration changes no longer replace it.

func (Record) CreatedAt

func (r Record) CreatedAt() temporal.DateTime

CreatedAt returns the record creation timestamp.

func (Record) DynamicValue

func (r Record) DynamicValue() (json.RawMessage, error)

DynamicValue decodes the stored value as raw JSON.

func (Record) Format

func (Record) Format(s fmt.State, _ rune)

Format writes a fixed label without exposing the record.

func (Record) MarshalJSON

func (Record) MarshalJSON() ([]byte, error)

MarshalJSON rejects direct JSON serialization of the record.

func (Record) Name

func (r Record) Name() Name

Name returns the record's setting name.

func (Record) Presentation

func (r Record) Presentation() Presentation

Presentation returns the record's presentation metadata.

func (Record) UpdatedAt

func (r Record) UpdatedAt() temporal.DateTime

UpdatedAt returns the record update timestamp.

func (Record) Version

func (r Record) Version() Version

Version returns the record's schema version.

type Registration

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

Registration holds a setting's registry identity, presentation, codec validation, and upgrade callbacks.

type Selection

type Selection interface {
	// contains filtered or unexported methods
}

Selection names one registered key for a batched read. Key implements it; the declaration identity, not a lookalike name, selects the stored row.

type Upgrade

type Upgrade[V any] struct {
	// contains filtered or unexported fields
}

Upgrade converts a value persisted by an earlier declaration version. It is declared next to the key and applied by reads and by Reconcile.

func UpgradeFrom

func UpgradeFrom[Old, V any](from Version, previous contract.JSON[Old], convert func(context.Context, Old) (V, error)) Upgrade[V]

UpgradeFrom decodes a stored value of an earlier version with that version's codec, then converts it. The result is re-encoded and validated by the current codec. convert is application code: it must be deterministic and must not perform I/O; panics are contained and reported as failures.

type Version

type Version uint32

Version identifies a persisted setting schema version.

Jump to

Keyboard shortcuts

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