settings

package
v0.0.0-...-04478d6 Latest Latest
Warning

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

Go to latest
Published: May 10, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrCustomSettingNotFound is returned when a custom setting is not found
	ErrCustomSettingNotFound = errors.New("custom setting not found")
	// ErrCustomSettingPermissionDenied is returned when user lacks permission to modify a setting
	ErrCustomSettingPermissionDenied = errors.New("permission denied for this custom setting")
	// ErrCustomSettingInvalidKey is returned when the key format is invalid
	ErrCustomSettingInvalidKey = errors.New("invalid custom setting key format")
	// ErrCustomSettingDuplicate is returned when a setting with the same key already exists
	ErrCustomSettingDuplicate = errors.New("custom setting with this key already exists")
)
View Source
var (
	// ErrSecretNotFound is returned when a secret setting is not found
	ErrSecretNotFound = errors.New("secret setting not found")
	// ErrDecryptionFailed is returned when decryption fails
	ErrDecryptionFailed = errors.New("failed to decrypt secret")
)
View Source
var (
	ErrNotOverridable     = errors.New("setting is not overridable at tenant level")
	ErrTenantRequired     = errors.New("tenant context required")
	ErrSecretKeyRequired  = errors.New("encryption key required for secret settings")
	ErrInvalidSettingPath = errors.New("invalid setting path")
)

Errors for unified settings service

View Source
var ErrSettingNotFound = errors.New("setting not found")

ErrSettingNotFound is returned when a setting is not found

Functions

func CanEditSetting

func CanEditSetting(editableBy []string, userRole string) bool

CanEditSetting checks if the given role can edit a specific setting

func ValidateKey

func ValidateKey(key string) error

ValidateKey validates the custom setting key format Keys should follow a pattern like "custom.*" to avoid conflicts

Types

type CreateCustomSettingRequest

type CreateCustomSettingRequest struct {
	Key         string                 `json:"key"`
	Value       map[string]interface{} `json:"value"`
	ValueType   string                 `json:"value_type"`
	Description string                 `json:"description,omitempty"`
	EditableBy  []string               `json:"editable_by,omitempty"`
	Metadata    map[string]interface{} `json:"metadata,omitempty"`
	IsSecret    bool                   `json:"is_secret,omitempty"`
}

CreateCustomSettingRequest represents the request to create a custom setting

type CreateSecretSettingRequest

type CreateSecretSettingRequest struct {
	Key         string `json:"key"`
	Value       string `json:"value"`
	Description string `json:"description,omitempty"`
}

CreateSecretSettingRequest represents the request to create a secret setting

type CreateUserSettingRequest

type CreateUserSettingRequest struct {
	Key         string                 `json:"key"`
	Value       map[string]interface{} `json:"value"`
	Description string                 `json:"description,omitempty"`
}

CreateUserSettingRequest represents the request to create a user setting

type CustomSetting

type CustomSetting struct {
	ID          uuid.UUID              `json:"id"`
	Key         string                 `json:"key"`
	Value       map[string]interface{} `json:"value"`
	ValueType   string                 `json:"value_type"`
	Description string                 `json:"description,omitempty"`
	EditableBy  []string               `json:"editable_by"`
	Metadata    map[string]interface{} `json:"metadata,omitempty"`
	CreatedBy   *uuid.UUID             `json:"created_by,omitempty"`
	UpdatedBy   *uuid.UUID             `json:"updated_by,omitempty"`
	CreatedAt   time.Time              `json:"created_at"`
	UpdatedAt   time.Time              `json:"updated_at"`
}

CustomSetting represents a custom admin-managed configuration setting

type CustomSettingsService

type CustomSettingsService struct {
	database.TenantAware
	// contains filtered or unexported fields
}

CustomSettingsService handles custom admin-managed settings

func NewCustomSettingsService

func NewCustomSettingsService(db *database.Connection, encryptionKey string) *CustomSettingsService

NewCustomSettingsService creates a new custom settings service

func (*CustomSettingsService) CreateSecretSetting

func (s *CustomSettingsService) CreateSecretSetting(ctx context.Context, req CreateSecretSettingRequest, userID *uuid.UUID, createdBy uuid.UUID) (*SecretSettingMetadata, error)

CreateSecretSetting creates a new encrypted secret setting For user-specific secrets, pass userID. For system secrets, pass nil.

func (*CustomSettingsService) CreateSecretSettingWithTx

func (s *CustomSettingsService) CreateSecretSettingWithTx(ctx context.Context, tx Querier, req CreateSecretSettingRequest, userID *uuid.UUID, createdBy uuid.UUID) (*SecretSettingMetadata, error)

CreateSecretSettingWithTx creates a new encrypted secret setting using a transaction

func (*CustomSettingsService) CreateSetting

func (s *CustomSettingsService) CreateSetting(ctx context.Context, req CreateCustomSettingRequest, createdBy uuid.UUID) (*CustomSetting, error)

CreateSetting creates a new custom setting

func (*CustomSettingsService) CreateUserSetting

func (s *CustomSettingsService) CreateUserSetting(ctx context.Context, userID uuid.UUID, req CreateUserSettingRequest) (*UserSetting, error)

CreateUserSetting creates a new non-encrypted user setting

func (*CustomSettingsService) DeleteSecretSetting

func (s *CustomSettingsService) DeleteSecretSetting(ctx context.Context, key string, userID *uuid.UUID) error

DeleteSecretSetting removes a secret setting

func (*CustomSettingsService) DeleteSecretSettingWithTx

func (s *CustomSettingsService) DeleteSecretSettingWithTx(ctx context.Context, tx Querier, key string, userID *uuid.UUID) error

DeleteSecretSettingWithTx removes a secret setting using a transaction

func (*CustomSettingsService) DeleteSetting

func (s *CustomSettingsService) DeleteSetting(ctx context.Context, key string, userRole string) error

DeleteSetting removes a custom setting by key

func (*CustomSettingsService) DeleteUserSetting

func (s *CustomSettingsService) DeleteUserSetting(ctx context.Context, userID uuid.UUID, key string) error

DeleteUserSetting removes a user's setting

func (*CustomSettingsService) DeleteUserSettingWithTx

func (s *CustomSettingsService) DeleteUserSettingWithTx(ctx context.Context, tx Querier, userID uuid.UUID, key string) error

DeleteUserSettingWithTx removes a user's setting using a transaction

func (*CustomSettingsService) GetSecretSettingMetadata

func (s *CustomSettingsService) GetSecretSettingMetadata(ctx context.Context, key string, userID *uuid.UUID) (*SecretSettingMetadata, error)

GetSecretSettingMetadata retrieves metadata for a secret setting (never returns the value)

func (*CustomSettingsService) GetSecretSettingMetadataWithTx

func (s *CustomSettingsService) GetSecretSettingMetadataWithTx(ctx context.Context, tx Querier, key string, userID *uuid.UUID) (*SecretSettingMetadata, error)

GetSecretSettingMetadataWithTx retrieves metadata for a secret setting using a transaction

func (*CustomSettingsService) GetSetting

func (s *CustomSettingsService) GetSetting(ctx context.Context, key string) (*CustomSetting, error)

GetSetting retrieves a custom setting by key

func (*CustomSettingsService) GetSystemSetting

func (s *CustomSettingsService) GetSystemSetting(ctx context.Context, key string) (*CustomSetting, error)

GetSystemSetting retrieves a system-level setting (user_id IS NULL) This is for public/system settings that any authenticated user can read

func (*CustomSettingsService) GetSystemSettingWithTx

func (s *CustomSettingsService) GetSystemSettingWithTx(ctx context.Context, tx Querier, key string) (*CustomSetting, error)

GetSystemSettingWithTx retrieves a system-level setting using a transaction

func (*CustomSettingsService) GetUserOwnSetting

func (s *CustomSettingsService) GetUserOwnSetting(ctx context.Context, userID uuid.UUID, key string) (*UserSetting, error)

GetUserOwnSetting retrieves a user's own setting only (no fallback)

func (*CustomSettingsService) GetUserOwnSettingWithTx

func (s *CustomSettingsService) GetUserOwnSettingWithTx(ctx context.Context, tx Querier, userID uuid.UUID, key string) (*UserSetting, error)

GetUserOwnSettingWithTx retrieves a user's own setting using a transaction

func (*CustomSettingsService) GetUserSettingWithFallback

func (s *CustomSettingsService) GetUserSettingWithFallback(ctx context.Context, userID uuid.UUID, key string) (*UserSettingWithSource, error)

GetUserSettingWithFallback retrieves a setting with user -> system fallback Returns the value and whether it came from user or system

func (*CustomSettingsService) GetUserSettingWithFallbackWithTx

func (s *CustomSettingsService) GetUserSettingWithFallbackWithTx(ctx context.Context, tx Querier, userID uuid.UUID, key string) (*UserSettingWithSource, error)

GetUserSettingWithFallbackWithTx retrieves a setting with user -> system fallback using a transaction

func (*CustomSettingsService) ListSecretSettings

func (s *CustomSettingsService) ListSecretSettings(ctx context.Context, userID *uuid.UUID) ([]SecretSettingMetadata, error)

ListSecretSettings retrieves metadata for all secret settings (never returns values)

func (*CustomSettingsService) ListSecretSettingsWithTx

func (s *CustomSettingsService) ListSecretSettingsWithTx(ctx context.Context, tx Querier, userID *uuid.UUID) ([]SecretSettingMetadata, error)

ListSecretSettingsWithTx retrieves metadata for all secret settings using a transaction

func (*CustomSettingsService) ListSettings

func (s *CustomSettingsService) ListSettings(ctx context.Context, userRole string) ([]CustomSetting, error)

ListSettings retrieves all custom settings, optionally filtered by user role permissions

func (*CustomSettingsService) ListUserOwnSettings

func (s *CustomSettingsService) ListUserOwnSettings(ctx context.Context, userID uuid.UUID) ([]UserSetting, error)

ListUserOwnSettings retrieves all non-encrypted settings for a user

func (*CustomSettingsService) ListUserOwnSettingsWithTx

func (s *CustomSettingsService) ListUserOwnSettingsWithTx(ctx context.Context, tx Querier, userID uuid.UUID) ([]UserSetting, error)

ListUserOwnSettingsWithTx retrieves all non-encrypted settings for a user using a transaction

func (*CustomSettingsService) UpdateSecretSetting

func (s *CustomSettingsService) UpdateSecretSetting(ctx context.Context, key string, req UpdateSecretSettingRequest, userID *uuid.UUID, updatedBy uuid.UUID) (*SecretSettingMetadata, error)

UpdateSecretSetting updates an existing secret setting

func (*CustomSettingsService) UpdateSecretSettingWithTx

func (s *CustomSettingsService) UpdateSecretSettingWithTx(ctx context.Context, tx Querier, key string, req UpdateSecretSettingRequest, userID *uuid.UUID, updatedBy uuid.UUID) (*SecretSettingMetadata, error)

UpdateSecretSettingWithTx updates an existing secret setting using a transaction

func (*CustomSettingsService) UpdateSetting

func (s *CustomSettingsService) UpdateSetting(ctx context.Context, key string, req UpdateCustomSettingRequest, updatedBy uuid.UUID, userRole string) (*CustomSetting, error)

UpdateSetting updates an existing custom setting

func (*CustomSettingsService) UpdateUserSetting

func (s *CustomSettingsService) UpdateUserSetting(ctx context.Context, userID uuid.UUID, key string, req UpdateUserSettingRequest) (*UserSetting, error)

UpdateUserSetting updates an existing user setting

func (*CustomSettingsService) UpsertUserSetting

func (s *CustomSettingsService) UpsertUserSetting(ctx context.Context, userID uuid.UUID, req CreateUserSettingRequest) (*UserSetting, error)

UpsertUserSetting creates or updates a user setting

func (*CustomSettingsService) UpsertUserSettingWithTx

func (s *CustomSettingsService) UpsertUserSettingWithTx(ctx context.Context, tx Querier, userID uuid.UUID, req CreateUserSettingRequest) (*UserSetting, error)

UpsertUserSettingWithTx creates or updates a user setting using a transaction

type InstanceSettings

type InstanceSettings struct {
	Settings            map[string]any `json:"settings"`
	OverridableSettings []string       `json:"overridable_settings,omitempty"`
	CreatedAt           time.Time      `json:"created_at"`
	UpdatedAt           time.Time      `json:"updated_at"`
}

InstanceSettings represents instance-level configuration

type Querier

type Querier interface {
	QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row
	Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error)
	Exec(ctx context.Context, sql string, args ...interface{}) (pgconn.CommandTag, error)
}

Querier is an interface that both *database.Connection and pgx.Tx implement

type ResolvedSetting

type ResolvedSetting struct {
	Value         any    `json:"value,omitempty"`
	Source        string `json:"source"` // "config", "instance", "tenant", "default"
	IsSecret      bool   `json:"is_secret,omitempty"`
	IsOverridable bool   `json:"is_overridable,omitempty"`
	IsReadOnly    bool   `json:"is_read_only,omitempty"` // True if from config file (cannot be changed in dashboard)
	DataType      string `json:"data_type,omitempty"`    // "string", "number", "boolean", "object", "array"
}

ResolvedSetting represents a setting with its source information

type SecretSettingMetadata

type SecretSettingMetadata struct {
	ID          uuid.UUID  `json:"id"`
	Key         string     `json:"key"`
	Description string     `json:"description,omitempty"`
	UserID      *uuid.UUID `json:"user_id,omitempty"`
	CreatedBy   *uuid.UUID `json:"created_by,omitempty"`
	UpdatedBy   *uuid.UUID `json:"updated_by,omitempty"`
	CreatedAt   time.Time  `json:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
}

SecretSettingMetadata represents metadata for a secret setting (value is never exposed)

type SecretsService

type SecretsService struct {
	database.TenantAware
	// contains filtered or unexported fields
}

SecretsService provides server-side access to encrypted secret settings. This service should ONLY be used internally by edge functions, background jobs, and custom handlers. It should NEVER be exposed via API endpoints.

func NewSecretsService

func NewSecretsService(db *database.Connection, encryptionKey string) *SecretsService

NewSecretsService creates a new secrets service for server-side decryption

func (*SecretsService) DeleteSystemSecret

func (s *SecretsService) DeleteSystemSecret(ctx context.Context, key string) error

DeleteSystemSecret removes a system-level secret setting.

func (*SecretsService) DeleteUserSecret

func (s *SecretsService) DeleteUserSecret(ctx context.Context, userID uuid.UUID, key string) error

DeleteUserSecret removes a user-specific secret setting.

func (*SecretsService) GetAllSystemSettings

func (s *SecretsService) GetAllSystemSettings(ctx context.Context) (map[string]string, error)

GetAllSystemSettings retrieves all system-level settings (both secrets and non-secrets). Returns a map of key -> value. Secrets are decrypted.

func (*SecretsService) GetAllUserSettings

func (s *SecretsService) GetAllUserSettings(ctx context.Context, userID uuid.UUID) (map[string]string, error)

GetAllUserSettings retrieves all settings for a user (both secrets and non-secrets). Returns a map of key -> value. Secrets are decrypted.

func (*SecretsService) GetSettingWithFallback

func (s *SecretsService) GetSettingWithFallback(ctx context.Context, userID *uuid.UUID, key string) (string, bool, error)

GetSettingWithFallback retrieves a setting with user -> system fallback. Returns the value and a boolean indicating if found.

func (*SecretsService) GetSystemSecret

func (s *SecretsService) GetSystemSecret(ctx context.Context, key string) (string, error)

GetSystemSecret retrieves and decrypts a system-level secret setting. This should only be called from server-side code (handlers, jobs, edge functions).

func (*SecretsService) GetSystemSecrets

func (s *SecretsService) GetSystemSecrets(ctx context.Context) (map[string]string, error)

GetSystemSecrets retrieves all decrypted system-level secrets. This is used for injecting secrets into edge functions as environment variables.

func (*SecretsService) GetSystemSetting

func (s *SecretsService) GetSystemSetting(ctx context.Context, key string) (string, error)

GetSystemSetting retrieves a system-level setting (secret or non-secret). For secrets, returns the decrypted value. For non-secrets, returns the JSON value as string.

func (*SecretsService) GetUserSecret

func (s *SecretsService) GetUserSecret(ctx context.Context, userID uuid.UUID, key string) (string, error)

GetUserSecret retrieves and decrypts a user's secret setting. This should only be called from server-side code (handlers, jobs, edge functions).

func (*SecretsService) GetUserSecrets

func (s *SecretsService) GetUserSecrets(ctx context.Context, userID uuid.UUID) (map[string]string, error)

GetUserSecrets retrieves all decrypted secrets for a user. This is used for injecting secrets into edge functions as environment variables.

func (*SecretsService) GetUserSetting

func (s *SecretsService) GetUserSetting(ctx context.Context, userID uuid.UUID, key string) (string, error)

GetUserSetting retrieves a user's setting (secret or non-secret). For secrets, returns the decrypted value. For non-secrets, returns the JSON value as string.

func (*SecretsService) SetSystemSecret

func (s *SecretsService) SetSystemSecret(ctx context.Context, key, value, description string) error

SetSystemSecret creates or updates a system-level secret setting. This encrypts the value and stores it in the database.

func (*SecretsService) SetUserSecret

func (s *SecretsService) SetUserSecret(ctx context.Context, userID uuid.UUID, key, value, description string) error

SetUserSecret creates or updates a user-specific secret setting. This encrypts the value with a user-derived key and stores it in the database.

type TenantSettings

type TenantSettings struct {
	TenantID  string         `json:"tenant_id"`
	Settings  map[string]any `json:"settings"`
	CreatedAt time.Time      `json:"created_at"`
	UpdatedAt time.Time      `json:"updated_at"`
}

TenantSettings represents tenant-specific overrides

type UnifiedService

type UnifiedService struct {
	database.TenantAware
	// contains filtered or unexported fields
}

UnifiedService provides settings resolution with tenant/instance/config fallback

func NewUnifiedService

func NewUnifiedService(db *database.Connection, cfg *config.Config, encryptionKey string) *UnifiedService

NewUnifiedService creates a new unified settings service

func (*UnifiedService) DecryptSecret

func (s *UnifiedService) DecryptSecret(encryptedValue string) (string, error)

DecryptSecret decrypts an encrypted secret value

func (*UnifiedService) DeleteTenantSetting

func (s *UnifiedService) DeleteTenantSetting(ctx context.Context, tenantID, path string) error

DeleteTenantSetting removes a tenant-specific setting

func (*UnifiedService) GetInstanceSettings

func (s *UnifiedService) GetInstanceSettings(ctx context.Context) (*InstanceSettings, error)

GetInstanceSettings returns all instance-level settings

func (*UnifiedService) GetTenantSettings

func (s *UnifiedService) GetTenantSettings(ctx context.Context, tenantID string) (*TenantSettings, error)

GetTenantSettings returns all tenant-specific settings

func (*UnifiedService) InvalidateCache

func (s *UnifiedService) InvalidateCache(tenantID, path string)

InvalidateCache clears cache entries

func (*UnifiedService) IsSettingOverridable

func (s *UnifiedService) IsSettingOverridable(ctx context.Context, path string) (bool, error)

IsSettingOverridable checks if a setting can be overridden at tenant level

func (*UnifiedService) ResolveSetting

func (s *UnifiedService) ResolveSetting(ctx context.Context, tenantID, path string, isDefaultTenant bool, tenantSlug ...string) (*ResolvedSetting, error)

ResolveSetting resolves a setting using the cascade: tenant -> instance -> config. For the default tenant (isDefaultTenant=true), the full cascade applies:

tenant DB → instance DB → config (YAML/env) → hardcoded default.

For non-default tenants, the config layer is skipped:

tenant DB → instance DB → hardcoded default.

func (*UnifiedService) ResolveSettingWithDefault

func (s *UnifiedService) ResolveSettingWithDefault(ctx context.Context, tenantID, path string, defaultValue any, isDefaultTenant bool, tenantSlug ...string) (*ResolvedSetting, error)

ResolveSettingWithDefault resolves a setting with a default fallback

func (*UnifiedService) SetInstanceSetting

func (s *UnifiedService) SetInstanceSetting(ctx context.Context, path string, value any, isSecret bool) error

SetInstanceSetting sets an instance-level setting value

func (*UnifiedService) SetOverridableSettings

func (s *UnifiedService) SetOverridableSettings(ctx context.Context, paths []string) error

SetOverridableSettings sets which settings can be overridden at tenant level

func (*UnifiedService) SetTenantConfigLoader

func (s *UnifiedService) SetTenantConfigLoader(loader *config.TenantConfigLoader)

SetTenantConfigLoader sets the tenant configuration loader for per-tenant config resolution

func (*UnifiedService) SetTenantSetting

func (s *UnifiedService) SetTenantSetting(ctx context.Context, tenantID, path string, value any, isSecret bool) error

SetTenantSetting sets a tenant-specific setting value

type UpdateCustomSettingRequest

type UpdateCustomSettingRequest struct {
	Value       map[string]interface{} `json:"value"`
	Description *string                `json:"description,omitempty"`
	EditableBy  []string               `json:"editable_by,omitempty"`
	Metadata    map[string]interface{} `json:"metadata,omitempty"`
}

UpdateCustomSettingRequest represents the request to update a custom setting

type UpdateSecretSettingRequest

type UpdateSecretSettingRequest struct {
	Value       *string `json:"value,omitempty"`
	Description *string `json:"description,omitempty"`
}

UpdateSecretSettingRequest represents the request to update a secret setting

type UpdateUserSettingRequest

type UpdateUserSettingRequest struct {
	Value       map[string]interface{} `json:"value"`
	Description *string                `json:"description,omitempty"`
}

UpdateUserSettingRequest represents the request to update a user setting

type UserSetting

type UserSetting struct {
	ID          uuid.UUID              `json:"id"`
	Key         string                 `json:"key"`
	Value       map[string]interface{} `json:"value"`
	Description string                 `json:"description,omitempty"`
	UserID      uuid.UUID              `json:"user_id"`
	CreatedAt   time.Time              `json:"created_at"`
	UpdatedAt   time.Time              `json:"updated_at"`
}

UserSetting represents a user's non-encrypted setting

type UserSettingWithSource

type UserSettingWithSource struct {
	Key    string                 `json:"key"`
	Value  map[string]interface{} `json:"value"`
	Source string                 `json:"source"` // "user" or "system"
}

UserSettingWithSource represents a setting with its source (user or system)

Jump to

Keyboard shortcuts

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