config

package
v0.0.0-...-ddef314 Latest Latest
Warning

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

Go to latest
Published: May 6, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package config provides a declarative configuration system for modules. Modules define their configuration needs using Go structs with tags, and the admin UI automatically generates forms for editing them.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetFieldValue

func GetFieldValue(cfg any, fieldName string) any

GetFieldValue uses reflection to get a field value from a config struct.

func GetStringValue

func GetStringValue(cfg any, fieldName string) string

GetStringValue returns a field's value as a string.

func HasValue

func HasValue(cfg any, fieldName string) bool

HasValue returns true if the field has a non-zero value.

Types

type ArrayField

type ArrayField struct {
	Name      string  // Go struct field name
	JSONName  string  // JSON field name
	Label     string  // Display label (e.g., "Printers")
	ItemLabel string  // Label for each item (e.g., "Printer")
	Help      string  // Help text
	KeyField  string  // Field name used for secret preservation matching
	MinItems  int     // Minimum required items
	MaxItems  int     // Maximum allowed items (0 = unlimited)
	Hidden    bool    // If true, generic UI omits this field — module renders its own.
	Fields    []Field // Fields within each array item
	GoType    reflect.Type
}

ArrayField represents a parsed dynamic array field.

type ArrayFieldDef

type ArrayFieldDef struct {
	FieldName string // The struct field name
	Label     string // Display label (e.g., "Printers")
	ItemLabel string // Item label (e.g., "Printer")
	Help      string // Help text
	KeyField  string // Field name used for secret preservation matching
	MinItems  int
	MaxItems  int

	// Hidden suppresses the generic auto-generated array editor for this
	// field. The module is expected to provide its own UI (e.g. via
	// Spec.ExtraContent and dedicated routes). Persistence still works
	// through the normal store — saves of the parent config preserve the
	// existing array contents because no form fields are emitted.
	Hidden bool
}

ArrayFieldDef defines a dynamic array field.

type Event

type Event struct {
	ID         int64
	Created    time.Time
	Module     string
	MemberID   *int64
	EventType  string
	EntityID   string
	EntityName string
	Success    bool
	Details    string
}

Event represents an event log entry for display.

type Field

type Field struct {
	Name        string       // Go struct field name
	JSONName    string       // JSON/form field name (from json tag or lowercased)
	Label       string       // Display label
	Help        string       // Help text shown below field
	Type        FieldType    // Input type
	Secret      bool         // If true, value is masked and preserved on empty submit
	Required    bool         // If true, field cannot be empty
	Default     string       // Default value (as string)
	Min         *int         // For numbers: minimum value
	Max         *int         // For numbers: maximum value
	Options     []Option     // For select fields: available options
	Placeholder string       // Input placeholder text
	Rows        int          // For textarea: number of rows
	Section     string       // Section name this field belongs to
	GoType      reflect.Type // The underlying Go type
}

Field represents a single configuration field with metadata.

type FieldType

type FieldType string

FieldType defines the UI input type for a config field.

const (
	FieldTypeText     FieldType = "text"
	FieldTypePassword FieldType = "password" // Masked input, secret preservation
	FieldTypeNumber   FieldType = "number"
	FieldTypeTextarea FieldType = "textarea"
	FieldTypeSelect   FieldType = "select"
	FieldTypeBool     FieldType = "bool"
	FieldTypeColor    FieldType = "color" // Color picker with hex input
)

Supported FieldType values, each corresponding to a UI input control rendered by the config admin pages.

type Loader

type Loader[T any] struct {
	// contains filtered or unexported fields
}

Loader provides typed config loading for modules.

func NewLoader

func NewLoader[T any](store *Store, module string) *Loader[T]

NewLoader creates a typed config loader for a module.

func (*Loader[T]) Load

func (l *Loader[T]) Load(ctx context.Context) (*T, error)

Load retrieves the current config.

func (*Loader[T]) LoadWithVersion

func (l *Loader[T]) LoadWithVersion(ctx context.Context) (*T, int, error)

LoadWithVersion retrieves the current config and its version.

type Option

type Option struct {
	Value string
	Label string
}

Option represents a select field option.

type ParsedSpec

type ParsedSpec struct {
	Spec
	Sections    []Section    // Parsed sections with fields populated
	ArrayFields []ArrayField // Parsed array field definitions
}

ParsedSpec is a Spec with all fields parsed from struct tags.

type Registry

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

Registry holds all registered configuration specs.

func NewRegistry

func NewRegistry(db *sql.DB) *Registry

NewRegistry creates a new configuration registry.

func (*Registry) Get

func (r *Registry) Get(module string) (*ParsedSpec, bool)

Get returns a module's parsed config spec.

func (*Registry) List

func (r *Registry) List() []*ParsedSpec

List returns all registered specs sorted by Order then Title.

func (*Registry) Modules

func (r *Registry) Modules() []string

Modules returns all registered module names in registration order.

func (*Registry) MustRegister

func (r *Registry) MustRegister(spec Spec)

MustRegister registers a spec and panics on error.

func (*Registry) Register

func (r *Registry) Register(spec Spec) error

Register adds a module's config spec to the registry. It parses the struct tags and validates the spec.

type Section

type Section struct {
	Name        string          // Section identifier
	Title       string          // Display title
	Description templ.Component // Section description/help text (rendered as HTML)
	Fields      []Field         // Fields in this section
}

Section groups related fields together in the UI.

type SectionDef

type SectionDef struct {
	Name        string          // Section identifier
	Title       string          // Display title
	Description templ.Component // Help text for the section (rendered as HTML)
	Fields      []string        // Optional: explicit field names (in order) belonging to this section
}

SectionDef defines a section in the Spec.

type Spec

type Spec struct {
	// Module identifier (used in database table naming and URL paths)
	Module string

	// Display title for the admin UI
	Title string

	// Description/help text shown at the top of the config page (rendered as HTML)
	Description templ.Component

	// Type is a zero value of the config struct.
	// Must be a struct or pointer to struct.
	Type any

	// Sections defines how fields are grouped.
	// If empty, fields are assigned to sections based on their `section` tag.
	Sections []SectionDef

	// ArrayFields defines fields that are dynamic arrays.
	// These require special form handling (add/remove items).
	ArrayFields []ArrayFieldDef

	// InfoContent is an optional component for read-only informational content.
	// Used for pages like the Fob API documentation.
	InfoContent templ.Component

	// ReadOnly means this config page is informational only (no form).
	ReadOnly bool

	// ExtraContent is an optional component rendered below the config card.
	// Use this to embed additional management UI (e.g., webhook CRUD) on
	// the same page as the module's configuration. The function is called
	// during page rendering so it can fetch dynamic data.
	ExtraContent func(ctx context.Context) templ.Component

	// Category groups this config into a sidebar section (e.g. "Integrations").
	// Empty string means the item appears in the default "Configuration" section.
	Category string

	// Order controls display order in the config sidebar (lower = first).
	Order int

	// TableName overrides the default table name ({Module}_config).
	// Use this when the config is stored in a table with a non-standard name.
	TableName string
}

Spec defines a module's configuration specification.

type Store

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

Store provides config persistence operations.

func NewStore

func NewStore(db *sql.DB, registry *Registry) *Store

NewStore creates a new config store.

func (*Store) Load

func (s *Store) Load(ctx context.Context, module string) (any, int, error)

Load retrieves the current config for a module. Returns a pointer to the config struct with values populated, the version number, and any error. If no config exists, returns a zero value with defaults applied.

func (*Store) ParseFormIntoConfig

func (s *Store) ParseFormIntoConfig(r *http.Request, module string) (any, error)

ParseFormIntoConfig parses an HTTP form into a config struct.

func (*Store) Save

func (s *Store) Save(ctx context.Context, module string, config any, preserveSecrets bool) error

Save stores the config, replacing any existing row. If preserveSecrets is true, empty secret fields will keep their existing values.

type Validatable

type Validatable interface {
	Validate() error
}

Validatable is implemented by config structs that need custom validation.

Jump to

Keyboard shortcuts

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