widgets

package
v0.49.1 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2026 License: MIT Imports: 5 Imported by: 1

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrFeatureDisabled = errors.New("widgets: feature disabled")

	ErrDefinitionNameRequired          = errors.New("widgets: definition name required")
	ErrDefinitionSchemaRequired        = errors.New("widgets: definition schema required")
	ErrDefinitionSchemaInvalid         = errors.New("widgets: definition schema invalid")
	ErrDefinitionExists                = errors.New("widgets: definition already exists")
	ErrDefinitionDefaultsInvalid       = errors.New("widgets: defaults contain unknown fields")
	ErrDefinitionInUse                 = errors.New("widgets: definition has active instances")
	ErrDefinitionSoftDeleteUnsupported = errors.New("widgets: soft delete not supported for definitions")

	ErrInstanceDefinitionRequired    = errors.New("widgets: definition id required")
	ErrInstanceCreatorRequired       = errors.New("widgets: created_by is required")
	ErrInstanceUpdaterRequired       = errors.New("widgets: updated_by is required")
	ErrInstanceIDRequired            = errors.New("widgets: instance id required")
	ErrInstancePositionInvalid       = errors.New("widgets: position cannot be negative")
	ErrInstanceConfigurationInvalid  = errors.New("widgets: configuration contains unknown fields")
	ErrInstanceScheduleInvalid       = errors.New("widgets: publish_on must be before unpublish_on")
	ErrVisibilityRulesInvalid        = errors.New("widgets: visibility_rules contains unsupported keys")
	ErrVisibilityScheduleInvalid     = errors.New("widgets: visibility schedule timestamps must be RFC3339")
	ErrInstanceSoftDeleteUnsupported = errors.New("widgets: soft delete not supported for instances")

	ErrTranslationContentRequired = errors.New("widgets: translation content required")
	ErrTranslationLocaleRequired  = errors.New("widgets: translation locale required")
	ErrTranslationExists          = errors.New("widgets: translation already exists for locale")
	ErrTranslationNotFound        = errors.New("widgets: translation not found")

	ErrAreaCodeRequired           = errors.New("widgets: area code required")
	ErrAreaCodeInvalid            = errors.New("widgets: area code must contain letters, numbers, dot, or underscore")
	ErrAreaNameRequired           = errors.New("widgets: area name required")
	ErrAreaDefinitionExists       = errors.New("widgets: area code already exists")
	ErrAreaDefinitionNotFound     = errors.New("widgets: area definition not found")
	ErrAreaFeatureDisabled        = errors.New("widgets: area repositories not configured")
	ErrAreaInstanceRequired       = errors.New("widgets: instance id required")
	ErrAreaPlacementExists        = errors.New("widgets: widget already assigned to area for locale")
	ErrAreaPlacementPosition      = errors.New("widgets: placement position must be zero or positive")
	ErrAreaPlacementNotFound      = errors.New("widgets: placement not found")
	ErrAreaWidgetOrderMismatch    = errors.New("widgets: reorder input must include every placement")
	ErrVisibilityLocaleRestricted = errors.New("widgets: locale not permitted for widget")
)

Functions

This section is empty.

Types

type AddTranslationInput added in v0.32.0

type AddTranslationInput struct {
	InstanceID uuid.UUID
	LocaleID   uuid.UUID
	Content    map[string]any
}

AddTranslationInput describes the payload to add localized widget content.

type AreaDefinition

type AreaDefinition struct {
	bun.BaseModel `bun:"table:widget_area_definitions,alias:wad"`

	ID          uuid.UUID  `bun:",pk,type:uuid" json:"id"`
	Code        string     `bun:"code,notnull,unique" json:"code"`
	Name        string     `bun:"name,notnull" json:"name"`
	Description *string    `bun:"description" json:"description,omitempty"`
	Scope       AreaScope  `bun:"scope,notnull,default:'global'" json:"scope"`
	ThemeID     *uuid.UUID `bun:"theme_id,type:uuid" json:"theme_id,omitempty"`
	TemplateID  *uuid.UUID `bun:"template_id,type:uuid" json:"template_id,omitempty"`
	CreatedAt   time.Time  `bun:"created_at,nullzero,default:current_timestamp" json:"created_at"`
	UpdatedAt   time.Time  `bun:"updated_at,nullzero,default:current_timestamp" json:"updated_at"`
}

AreaDefinition documents a named region where widgets can be rendered.

type AreaPlacement

type AreaPlacement struct {
	bun.BaseModel `bun:"table:widget_area_placements,alias:wap"`

	ID         uuid.UUID      `bun:",pk,type:uuid" json:"id"`
	AreaCode   string         `bun:"area_code,notnull" json:"area_code"`
	LocaleID   *uuid.UUID     `bun:"locale_id,type:uuid" json:"locale_id,omitempty"`
	InstanceID uuid.UUID      `bun:"instance_id,notnull,type:uuid" json:"instance_id"`
	Position   int            `bun:"position,notnull,default:0" json:"position"`
	Metadata   map[string]any `bun:"metadata,type:jsonb" json:"metadata,omitempty"`
	CreatedAt  time.Time      `bun:"created_at,nullzero,default:current_timestamp" json:"created_at"`
	UpdatedAt  time.Time      `bun:"updated_at,nullzero,default:current_timestamp" json:"updated_at"`

	Instance *Instance `bun:"rel:belongs-to,join:instance_id=id" json:"instance,omitempty"`
}

AreaPlacement binds a widget instance to an area with optional locale-specific ordering.

type AreaScope

type AreaScope string

AreaScope identifies how broadly an area definition applies.

const (
	// AreaScopeGlobal registers an area that applies across the entire site.
	AreaScopeGlobal AreaScope = "global"
	// AreaScopeTheme registers an area that is scoped to a specific theme.
	AreaScopeTheme AreaScope = "theme"
	// AreaScopeTemplate registers an area scoped to a specific template.
	AreaScopeTemplate AreaScope = "template"
	// AreaScopePage registers an area intended for a specific page surface.
	AreaScopePage AreaScope = "page"
)

type AreaWidgetOrder added in v0.32.0

type AreaWidgetOrder struct {
	PlacementID uuid.UUID
	Position    int
}

AreaWidgetOrder describes the desired order for a placement.

type AssignWidgetToAreaInput added in v0.32.0

type AssignWidgetToAreaInput struct {
	AreaCode   string
	LocaleID   *uuid.UUID
	InstanceID uuid.UUID
	Position   *int
	Metadata   map[string]any
}

AssignWidgetToAreaInput describes how to bind a widget instance to an area.

type CreateInstanceInput added in v0.32.0

type CreateInstanceInput struct {
	DefinitionID    uuid.UUID
	BlockInstanceID *uuid.UUID
	AreaCode        *string
	Placement       map[string]any
	Configuration   map[string]any
	VisibilityRules map[string]any
	PublishOn       *time.Time
	UnpublishOn     *time.Time
	Position        int
	CreatedBy       uuid.UUID
	UpdatedBy       uuid.UUID
}

CreateInstanceInput defines the payload required to create a widget instance.

type Definition

type Definition struct {
	bun.BaseModel `bun:"table:widget_definitions,alias:wd"`

	ID          uuid.UUID      `bun:",pk,type:uuid" json:"id"`
	Name        string         `bun:"name,notnull,unique" json:"name"`
	Description *string        `bun:"description" json:"description,omitempty"`
	Schema      map[string]any `bun:"schema,type:jsonb,notnull" json:"schema"`
	Defaults    map[string]any `bun:"defaults,type:jsonb" json:"defaults,omitempty"`
	Category    *string        `bun:"category" json:"category,omitempty"`
	Icon        *string        `bun:"icon" json:"icon,omitempty"`
	DeletedAt   *time.Time     `bun:"deleted_at,nullzero" json:"deleted_at,omitempty"`
	CreatedAt   time.Time      `bun:"created_at,nullzero,default:current_timestamp" json:"created_at"`
	UpdatedAt   time.Time      `bun:"updated_at,nullzero,default:current_timestamp" json:"updated_at"`

	// Instances is populated when loading widget definitions with eager relations.
	Instances []*Instance `bun:"rel:has-many,join:id=definition_id" json:"instances,omitempty"`
}

Definition captures a widget type, its configuration schema, and default values.

type DefinitionSyncResult added in v0.49.0

type DefinitionSyncResult struct {
	Definition *Definition          `json:"definition"`
	Status     DefinitionSyncStatus `json:"status"`
}

DefinitionSyncResult reports the current definition plus the sync outcome.

type DefinitionSyncStatus added in v0.49.0

type DefinitionSyncStatus string

DefinitionSyncStatus describes how a sync operation affected persistent state.

const (
	DefinitionSyncStatusCreated   DefinitionSyncStatus = "created"
	DefinitionSyncStatusUpdated   DefinitionSyncStatus = "updated"
	DefinitionSyncStatusUnchanged DefinitionSyncStatus = "unchanged"
)

type DeleteDefinitionRequest added in v0.32.0

type DeleteDefinitionRequest struct {
	ID         uuid.UUID
	HardDelete bool
}

DeleteDefinitionRequest controls hard-delete behavior for widget definitions.

type DeleteInstanceRequest added in v0.32.0

type DeleteInstanceRequest struct {
	InstanceID uuid.UUID
	DeletedBy  uuid.UUID
	HardDelete bool
}

DeleteInstanceRequest controls hard-delete behavior for widget instances.

type DeleteTranslationRequest added in v0.32.0

type DeleteTranslationRequest struct {
	InstanceID uuid.UUID
	LocaleID   uuid.UUID
}

DeleteTranslationRequest removes a localized widget translation.

type Instance

type Instance struct {
	bun.BaseModel `bun:"table:widget_instances,alias:wi"`

	ID              uuid.UUID      `bun:",pk,type:uuid" json:"id"`
	DefinitionID    uuid.UUID      `bun:"definition_id,notnull,type:uuid" json:"definition_id"`
	BlockInstanceID *uuid.UUID     `bun:"block_instance_id,type:uuid" json:"block_instance_id,omitempty"`
	AreaCode        *string        `bun:"area_code" json:"area_code,omitempty"`
	Placement       map[string]any `bun:"placement_metadata,type:jsonb" json:"placement,omitempty"`
	Configuration   map[string]any `bun:"configuration,type:jsonb,notnull,default:'{}'::jsonb" json:"configuration"`
	VisibilityRules map[string]any `bun:"visibility_rules,type:jsonb" json:"visibility_rules,omitempty"`
	PublishOn       *time.Time     `bun:"publish_on" json:"publish_on,omitempty"`
	UnpublishOn     *time.Time     `bun:"unpublish_on" json:"unpublish_on,omitempty"`
	Position        int            `bun:"position,notnull,default:0" json:"position"`
	CreatedBy       uuid.UUID      `bun:"created_by,notnull,type:uuid" json:"created_by"`
	UpdatedBy       uuid.UUID      `bun:"updated_by,notnull,type:uuid" json:"updated_by"`
	DeletedAt       *time.Time     `bun:"deleted_at,nullzero" json:"deleted_at,omitempty"`
	CreatedAt       time.Time      `bun:"created_at,nullzero,default:current_timestamp" json:"created_at"`
	UpdatedAt       time.Time      `bun:"updated_at,nullzero,default:current_timestamp" json:"updated_at"`

	Definition   *Definition    `bun:"rel:belongs-to,join:definition_id=id" json:"definition,omitempty"`
	Translations []*Translation `bun:"rel:has-many,join:id=widget_instance_id" json:"translations,omitempty"`
}

Instance represents a concrete placement of a widget definition.

type RegisterAreaDefinitionInput added in v0.32.0

type RegisterAreaDefinitionInput struct {
	Code        string
	Name        string
	Description *string
	Scope       AreaScope
	ThemeID     *uuid.UUID
	TemplateID  *uuid.UUID
}

RegisterAreaDefinitionInput captures metadata for a widget area.

type RegisterDefinitionInput added in v0.32.0

type RegisterDefinitionInput struct {
	Name        string
	Description *string
	Schema      map[string]any
	Defaults    map[string]any
	Category    *string
	Icon        *string
}

RegisterDefinitionInput captures the information required to register a widget definition.

type RemoveWidgetFromAreaInput added in v0.32.0

type RemoveWidgetFromAreaInput struct {
	AreaCode   string
	LocaleID   *uuid.UUID
	InstanceID uuid.UUID
}

RemoveWidgetFromAreaInput removes a widget instance from an area/locale combination.

type ReorderAreaWidgetsInput added in v0.32.0

type ReorderAreaWidgetsInput struct {
	AreaCode string
	LocaleID *uuid.UUID
	Items    []AreaWidgetOrder
}

ReorderAreaWidgetsInput updates ordering for widget placements within an area.

type ResolveAreaInput added in v0.32.0

type ResolveAreaInput struct {
	AreaCode          string
	LocaleID          *uuid.UUID
	FallbackLocaleIDs []uuid.UUID
	Audience          []string
	Segments          []string
	Now               time.Time
}

ResolveAreaInput controls how area widgets are resolved for rendering.

type ResolvedWidget

type ResolvedWidget struct {
	Instance *Instance `json:"instance"`
	// Config is the fully resolved payload hosts should render. It starts from
	// the base widget instance configuration and overlays the first matching
	// translation in the requested locale/fallback chain.
	Config map[string]any `json:"config,omitempty"`
	// ResolvedTranslation identifies the translation that produced Config when a
	// locale-specific or fallback translation matched.
	ResolvedTranslation *Translation `json:"resolved_translation,omitempty"`
	// ResolvedLocaleID records which locale from the requested resolution chain
	// produced the final localized Config when a translation match was found.
	ResolvedLocaleID *uuid.UUID     `json:"resolved_locale_id,omitempty"`
	Placement        *AreaPlacement `json:"placement"`
}

ResolvedWidget pairs a widget instance with its placement metadata.

type Service added in v0.32.0

type Service interface {
	RegisterDefinition(ctx context.Context, input RegisterDefinitionInput) (*Definition, error)
	SyncDefinition(ctx context.Context, input RegisterDefinitionInput) (*DefinitionSyncResult, error)
	GetDefinition(ctx context.Context, id uuid.UUID) (*Definition, error)
	ListDefinitions(ctx context.Context) ([]*Definition, error)
	DeleteDefinition(ctx context.Context, req DeleteDefinitionRequest) error
	SyncRegistry(ctx context.Context) error

	CreateInstance(ctx context.Context, input CreateInstanceInput) (*Instance, error)
	UpdateInstance(ctx context.Context, input UpdateInstanceInput) (*Instance, error)
	GetInstance(ctx context.Context, id uuid.UUID) (*Instance, error)
	ListInstancesByDefinition(ctx context.Context, definitionID uuid.UUID) ([]*Instance, error)
	ListInstancesByArea(ctx context.Context, areaCode string) ([]*Instance, error)
	ListAllInstances(ctx context.Context) ([]*Instance, error)
	DeleteInstance(ctx context.Context, req DeleteInstanceRequest) error

	AddTranslation(ctx context.Context, input AddTranslationInput) (*Translation, error)
	UpdateTranslation(ctx context.Context, input UpdateTranslationInput) (*Translation, error)
	GetTranslation(ctx context.Context, instanceID uuid.UUID, localeID uuid.UUID) (*Translation, error)
	DeleteTranslation(ctx context.Context, req DeleteTranslationRequest) error

	RegisterAreaDefinition(ctx context.Context, input RegisterAreaDefinitionInput) (*AreaDefinition, error)
	ListAreaDefinitions(ctx context.Context) ([]*AreaDefinition, error)
	AssignWidgetToArea(ctx context.Context, input AssignWidgetToAreaInput) ([]*AreaPlacement, error)
	RemoveWidgetFromArea(ctx context.Context, input RemoveWidgetFromAreaInput) error
	ReorderAreaWidgets(ctx context.Context, input ReorderAreaWidgetsInput) ([]*AreaPlacement, error)
	ResolveArea(ctx context.Context, input ResolveAreaInput) ([]*ResolvedWidget, error)
	EvaluateVisibility(ctx context.Context, instance *Instance, input VisibilityContext) (bool, error)
}

Service exposes widget management capabilities to external consumers.

type Translation

type Translation struct {
	bun.BaseModel `bun:"table:widget_translations,alias:wt"`

	ID               uuid.UUID      `bun:",pk,type:uuid" json:"id"`
	WidgetInstanceID uuid.UUID      `bun:"widget_instance_id,notnull,type:uuid" json:"widget_instance_id"`
	LocaleID         uuid.UUID      `bun:"locale_id,notnull,type:uuid" json:"locale_id"`
	Content          map[string]any `bun:"content,type:jsonb,notnull" json:"content"`
	DeletedAt        *time.Time     `bun:"deleted_at,nullzero" json:"deleted_at,omitempty"`
	CreatedAt        time.Time      `bun:"created_at,nullzero,default:current_timestamp" json:"created_at"`
	UpdatedAt        time.Time      `bun:"updated_at,nullzero,default:current_timestamp" json:"updated_at"`

	Instance *Instance `bun:"rel:belongs-to,join:widget_instance_id=id" json:"instance,omitempty"`
}

Translation stores localized data for a widget instance.

type UpdateInstanceInput added in v0.32.0

type UpdateInstanceInput struct {
	InstanceID      uuid.UUID
	Configuration   map[string]any
	VisibilityRules map[string]any
	Placement       map[string]any
	PublishOn       *time.Time
	UnpublishOn     *time.Time
	Position        *int
	UpdatedBy       uuid.UUID
	AreaCode        *string
}

UpdateInstanceInput defines mutable fields for a widget instance.

type UpdateTranslationInput added in v0.32.0

type UpdateTranslationInput struct {
	InstanceID uuid.UUID
	LocaleID   uuid.UUID
	Content    map[string]any
}

UpdateTranslationInput updates the localized widget content.

type VisibilityContext added in v0.32.0

type VisibilityContext struct {
	Now         time.Time
	LocaleID    *uuid.UUID
	Audience    []string
	Segments    []string
	CustomRules map[string]any
}

VisibilityContext provides ambient information for visibility evaluation.

Jump to

Keyboard shortcuts

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