configapp

package
v0.1.13 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 39 Imported by: 0

Documentation

Overview

Package configapp is the configuration service of the admin plane: the scanned catalog, schema scans and scan batches, plans and their previews, plan templates, pending work and administrators' MCP tokens. It checks who may do what (the signed-in principal on the context, with its permissions and datasources) and holds every business rule; the admin API (GraphQL) and the configuration MCP endpoint only adapt their requests and results.

Index

Constants

View Source
const (
	ItemEntity   = "entity"
	ItemRole     = "role"
	ItemUser     = "user"
	ItemSettings = "settings"
)

The kinds of workspace items, as the console names its changes.

View Source
const (
	ScanStatePending  = "PENDING"
	ScanStateRunning  = "RUNNING"
	ScanStateDone     = "DONE"
	ScanStateFailed   = "FAILED"
	ScanStateCanceled = "CANCELED"
)

The states of a scan job (GraphQL ScanState), as scanjobs names them.

View Source
const (
	// No entity reads the table.
	TableStatusNew = "NEW"
	// An entity of the workspace reads it, not yet published.
	TableStatusWorkspace = "WORKSPACE"
	// A published entity reads it.
	TableStatusPublished = "PUBLISHED"
)

How a scanned table stands to the configuration (GraphQL TableStatus).

View Source
const RequestScanTimeout = 30 * time.Second

RequestScanTimeout bounds the reads that answer within their request: tableComments and schemaList.

Variables

View Source
var ErrPlanChanged = errors.New("the plan is not the one previewed, or its preview expired and what it evaluates " +
	"to changed since (a publish, a workspace edit or a new scan): preview it again")

ErrPlanChanged: a plan is not the one its preview ID names, or changed while it was checked.

View Source
var ErrWorkspaceChanged = workspace.ErrChanged

ErrWorkspaceChanged: the workspace was written since it was read.

View Source
var ErrWorkspaceContent = errors.New("workspace items are not a configuration")

ErrWorkspaceContent is a workspace whose items do not read as configuration (an agent wrote a section of the wrong shape): what it would configure cannot be told, as a validation of it reports.

View Source
var Schema = mergeSchema(EntityItem{}, RoleItem{}, UserItem{})

Schema is how the configuration's values merge, read off the item types (see mergeSchema): fields and relationships keyed by name, grants by the entity they name; optional text, and switches off unless set, unset when empty or false (an empty token hash: no token).

Functions

func DecodePlan

func DecodePlan(v any) (configplan.Plan, error)

DecodePlan reads a plan from its JSON value.

func LoadCatalog

func LoadCatalog(
	ctx context.Context,
	in introspect.Introspector,
	schemas []string,
	withDefault bool,
) (introspect.Catalog, error)

LoadCatalog loads a catalog that matches names the way the database compares them, as assembly does.

func NormalizeJSON

func NormalizeJSON(v any) any

NormalizeJSON turns json.Number values (GraphQL variables decode numbers so) into int64 or float64, so YAML encodes them as numbers, not strings.

func ParseID

func ParseID(id string) (int64, error)

ParseID reads a revision ID.

Types

type Against

type Against struct {
	Workspace bool
	Revision  *string
}

Against is the configuration a read is about: the caller's workspace (the published configuration until they write it), a revision, or, the zero Against, the published revision. The console reads its workspace; agents read the published configuration unless they plan (see PreviewInWorkspace).

type AppliedPlan

type AppliedPlan struct {
	Items   []WorkspaceRef `json:"items"`
	Comment string         `json:"comment,omitempty"`
}

AppliedPlan is what applying a plan wrote.

type ApplyRequest

type ApplyRequest struct {
	Plan   configplan.Plan
	PlanID string
	Review bool
	// Confirmed are the IDs of the exceptions to confirm reported to the
	// administrator: every one of them.
	Confirmed []string
	Comment   string
	// Agent names the agent (its token) applying the plan; empty: the
	// administrator, in the console.
	Agent string
}

ApplyRequest applies a plan to the caller's workspace.

type Built

type Built struct {
	Base    revision.Revision
	Spec    *config.Spec
	Config  *config.Config
	Payload []byte
}

Built is a merged, validated and normalized configuration.

type CatalogCounts

type CatalogCounts struct {
	All       int `json:"all"`
	New       int `json:"new"`
	Workspace int `json:"workspace"`
	Published int `json:"published"`
	Drift     int `json:"drift"`
}

type CatalogCoverage

type CatalogCoverage struct {
	Datasource string `json:"datasource"`
	// Schemas scanned.
	Scanned int `json:"scanned"`
	// Schemas listed; null when never listed.
	Listed *int `json:"listed,omitempty"`
	// Listed schemas never scanned.
	Unscanned []string `json:"unscanned"`
	// When the oldest scanned schema was scanned; null when none.
	OldestScan *time.Time `json:"oldestScan,omitempty"`
}

What has been scanned of a datasource.

type CatalogFilter

type CatalogFilter struct {
	// Datasources to search; empty: all.
	Datasources []string `json:"datasources,omitempty"`
	// Glob patterns (* and ?) on schema names.
	Schemas []string `json:"schemas,omitempty"`
	// Glob patterns on table names.
	Tables []string `json:"tables,omitempty"`
	// A part of the table name or its comment.
	Search *string  `json:"search,omitempty"`
	Status []string `json:"status,omitempty"`
	// Only configured tables whose columns and fields differ.
	Drift *bool `json:"drift,omitempty"`
}
type CatalogLinks struct {
	Outgoing []TableLink `json:"outgoing"`
	Incoming []TableLink `json:"incoming"`
}

type CatalogPage

type CatalogPage struct {
	// Tables matching the filter.
	Total  int          `json:"total"`
	Tables []CatalogRow `json:"tables"`
	// Tables by status, matching every condition but the status.
	Counts   *CatalogCounts    `json:"counts"`
	Coverage []CatalogCoverage `json:"coverage"`
}

type CatalogRow

type CatalogRow struct {
	// datasource.schema.table: the ID an entity named like the table would have.
	Ref         string `json:"ref"`
	Datasource  string `json:"datasource"`
	Schema      string `json:"schema"`
	Table       string `json:"table"`
	Description string `json:"description"`
	View        bool   `json:"view"`
	Columns     int    `json:"columns"`
	// Foreign keys of the table, and of other scanned tables referencing it.
	ForeignKeys  int `json:"foreignKeys"`
	ReferencedBy int `json:"referencedBy"`
	// Whether a key identifies a row.
	HasKey      bool   `json:"hasKey"`
	SideEffects bool   `json:"sideEffects"`
	Status      string `json:"status"`
	// The entity that reads the table.
	Entity *string `json:"entity,omitempty"`
	// Columns without a field, and fields without a column.
	Added   []string `json:"added"`
	Missing []string `json:"missing"`
	// When the table's schema was scanned.
	ScannedAt *time.Time `json:"scannedAt,omitempty"`
}

type CommitInput

type CommitInput struct {
	Version           int     `json:"version"`
	ExpectedPublished string  `json:"expectedPublished"`
	Comment           *string `json:"comment,omitempty"`
	RestartRequired   *bool   `json:"restartRequired,omitempty"`
}

CommitInput commits the workspace at the version reviewed.

type Draft

type Draft struct {
	Base string
	Edit configedit.Edit
}

Draft is a configuration being edited: a base revision with sections replaced.

type EntityItem

type EntityItem struct {
	Name          string             `json:"name"`
	Source        *string            `json:"source,omitempty"`
	Datasource    *string            `json:"datasource,omitempty"`
	Schema        *string            `json:"schema,omitempty"`
	Kind          *string            `json:"kind,omitempty"`
	Description   *string            `json:"description,omitempty"`
	PrimaryKey    []string           `json:"primaryKey"`
	UniqueKeys    [][]string         `json:"uniqueKeys"`
	Fields        []FieldItem        `json:"fields"                 merge:"key=name"`
	Relationships []RelationshipItem `json:"relationships"          merge:"key=name"`
	TenantPolicy  any                `json:"tenantPolicy,omitempty"`
	LegacyAccess  any                `json:"legacyAccess,omitempty"`
	Mcp           *EntityMCPItem     `json:"mcp,omitempty"`
	Params        []string           `json:"params"`
	Affects       []string           `json:"affects"`
	AllowCascade  *bool              `json:"allowCascade,omitempty" merge:"unset"`
}

EntityItem is an entity. Lists are always written (empty when unset); legacyAccess holds the entity-level roles, fieldACL and rowPolicies.

func EntityItemOf

func EntityItemOf(e config.EntityConfig) EntityItem

EntityItemOf is the item of an entity built in code (a candidate).

type EntityMCPItem

type EntityMCPItem struct {
	DmlTools         *bool `json:"dmlTools,omitempty"`
	CustomTool       *bool `json:"customTool,omitempty"       merge:"unset"`
	TrustedProcedure *bool `json:"trustedProcedure,omitempty" merge:"unset"`
}

EntityMCPItem are an entity's MCP flags; an unset dmlTools defaults on.

type FieldItem

type FieldItem struct {
	Name        string  `json:"name"`
	Alias       *string `json:"alias,omitempty"`
	Description *string `json:"description,omitempty"`
	Mask        *string `json:"mask,omitempty"`
	Exclude     *bool   `json:"exclude,omitempty"     merge:"unset"`
}

FieldItem is a field of an entity.

type FieldReference

type FieldReference struct {
	Field string  `json:"field"`
	Kind  string  `json:"kind"`
	Name  string  `json:"name"`
	Via   *string `json:"via,omitempty"`
}

FieldReference is a place in the workspace naming a field of an entity: a role or user (Via fields: a grant lists it, which removing the field takes care of; rows: a grant filters by it, to fix first), or an entity's relationship, primaryKey, uniqueKey or tenantPolicy (Name its ID).

type GrantItem

type GrantItem struct {
	Entity           string   `json:"entity"`
	Actions          []string `json:"actions"`
	FieldsRestricted *bool    `json:"fieldsRestricted,omitempty"`
	ReadFields       []string `json:"readFields"`
	WriteFields      []string `json:"writeFields"`
	Rows             any      `json:"rows,omitempty"`
}

GrantItem is a grant of a role or user; actions are upper case (READ). Without fieldsRestricted, read or write fields restrict the grant.

type Imports

type Imports struct {
	Datasource    string
	DefaultSchema string
	// Source is the token of the database the tables were read from.
	Source string
	Tables []configplan.Candidate
}

Imports are the scanned tables of a datasource with the entity proposed for each.

type Introspection

type Introspection func(
	ctx context.Context, datasource string, database config.DatabaseConfig, fn func(introspect.Introspector) error,
) error

Introspection runs fn with the introspector of datasource, reading the database that database (its configuration) names: what is read is what the caller took from its configuration, even before the runtime applies it.

type McpToken

type McpToken struct {
	ID        string    `json:"id"`
	Name      string    `json:"name"`
	CreatedAt time.Time `json:"createdAt"`
	// null: never expires.
	ExpiresAt  *time.Time `json:"expiresAt,omitempty"`
	LastUsedAt *time.Time `json:"lastUsedAt,omitempty"`
	// The datasources it reaches; null: every one.
	Datasources []string `json:"datasources,omitempty"`
	// Refused: created read only, which is no longer offered; generate a new one.
	Retired bool `json:"retired"`
}

type McpTokenInput

type McpTokenInput struct {
	// Names the client, unique among the administrator's tokens.
	Name string `json:"name"`
	// Days until it expires; null or 0 never.
	ExpiresInDays *int `json:"expiresInDays,omitempty"`
	// Limits it to these datasources; null: every one.
	Datasources []string `json:"datasources,omitempty"`
}

type McpTokenSecret

type McpTokenSecret struct {
	// Shown only once.
	Token string    `json:"token"`
	Info  *McpToken `json:"info"`
}

type PendingDraft

type PendingDraft struct {
	Revision revision.Revision
	BasedOn  int64
}

PendingDraft is a draft with the revision it builds on: the first up its parents that is not a draft (0: none).

type PendingPlan

type PendingPlan struct {
	// Changes when the report does: a new situation opens again.
	Key      string        `json:"key"`
	Template *PlanTemplate `json:"template"`
	Report   *PlanReport   `json:"report"`
	State    *PendingState `json:"state,omitempty"`
}

type PendingState

type PendingState struct {
	Key string `json:"key"`
	// open, snoozed or ignored; a snooze that ended reads open.
	Status    string     `json:"status"`
	Owner     *string    `json:"owner,omitempty"`
	Reason    *string    `json:"reason,omitempty"`
	Until     *time.Time `json:"until,omitempty"`
	UpdatedBy string     `json:"updatedBy"`
	UpdatedAt time.Time  `json:"updatedAt"`
}

type PendingStateInput

type PendingStateInput struct {
	// The item's key, as PendingWork gives it.
	Key string `json:"key"`
	// open, snoozed or ignored.
	Status string  `json:"status"`
	Owner  *string `json:"owner,omitempty"`
	Reason *string `json:"reason,omitempty"`
	// When a snoozed item opens again.
	Until *time.Time `json:"until,omitempty"`
}

type PendingTable

type PendingTable struct {
	// Changes when the differences do.
	Key     string        `json:"key"`
	Ref     string        `json:"ref"`
	Entity  string        `json:"entity"`
	Added   []string      `json:"added"`
	Missing []string      `json:"missing"`
	State   *PendingState `json:"state,omitempty"`
}

type PendingWork

type PendingWork struct {
	// Recurring templates whose plan would change the configuration or has rules it cannot apply.
	Plans []PendingPlan `json:"plans"`
	// Tables whose fields differ from their columns.
	DriftTables      []PendingTable `json:"driftTables"`
	Drift            int            `json:"drift"`
	NewTables        int            `json:"newTables"`
	UnscannedSchemas int            `json:"unscannedSchemas"`
	// Datasources whose schemas were never listed: what they hold is unknown.
	UnlistedDatasources []string `json:"unlistedDatasources"`
}

type PlanChange

type PlanChange struct {
	// import, createRole, grant, exclude, mask, syncAdd or syncRemove.
	Kind      string   `json:"kind"`
	Principal *string  `json:"principal,omitempty"`
	Actions   []string `json:"actions"`
	Mask      *string  `json:"mask,omitempty"`
	// Fields a field change touches.
	Fields   int      `json:"fields"`
	Entities []string `json:"entities"`
}

type PlanException

type PlanException struct {
	// Identifies the exception within its plan: a draft is saved with each exception to confirm
	// confirmed by its ID.
	ID string `json:"id"`
	// renamed, noKey, sideEffects, relationshipDropped, qualified, unknownUser,
	// noFields, referenced, denied or review.
	Kind string `json:"kind"`
	// block (the proposal cannot be taken), confirm (taking it needs the
	// exception acknowledged) or info.
	Level string `json:"level"`
	// Not only informative: level is block or confirm.
	Warning bool `json:"warning"`
	// The table, when excluding it is a way out.
	Ref    *string `json:"ref,omitempty"`
	Entity *string `json:"entity,omitempty"`
	Detail *string `json:"detail,omitempty"`
}

type PlanObjects

type PlanObjects struct {
	Datasource string `json:"datasource"`
	Schema     string `json:"schema"`
	Tables     int    `json:"tables"`
	Imported   int    `json:"imported"`
	Changed    int    `json:"changed"`
}

type PlanReport

type PlanReport struct {
	Matched    int                `json:"matched"`
	Excluded   int                `json:"excluded"`
	Objects    []PlanObjects      `json:"objects"`
	Changes    []PlanChange       `json:"changes"`
	Exceptions []PlanException    `json:"exceptions"`
	Unscanned  []UnscannedSchemas `json:"unscanned"`
	// When the tables in scope were scanned, oldest and newest.
	ScannedFrom *time.Time `json:"scannedFrom,omitempty"`
	ScannedTo   *time.Time `json:"scannedTo,omitempty"`
}

type PlanStore

type PlanStore interface {
	PlanTemplates(ctx context.Context) ([]configstore.PlanTemplate, error)
	PlanTemplateVersions(ctx context.Context, name string) ([]configstore.PlanTemplate, error)
	PutPlanTemplate(ctx context.Context, t configstore.PlanTemplate, expected int) (configstore.PlanTemplate, error)
	DeletePlanTemplate(ctx context.Context, name string) error
	AdminTokens(ctx context.Context, username string) ([]configstore.AdminToken, error)
	AdminTokenByHash(ctx context.Context, hash string) (configstore.AdminToken, bool, error)
	CreateAdminToken(ctx context.Context, t configstore.AdminToken) (configstore.AdminToken, error)
	DeleteAdminToken(ctx context.Context, username, id string) error
	TouchAdminToken(ctx context.Context, id string, at time.Time) error
	PendingStates(ctx context.Context) ([]configstore.PendingState, error)
	PendingLog(ctx context.Context, key string) ([]configstore.PendingState, error)
	PutPendingState(ctx context.Context, p configstore.PendingState) (configstore.PendingState, error)
	workspace.Store
}

PlanStore keeps plan templates, the administrators' tokens for the configuration MCP endpoint and the state of pending work, outside configuration revisions.

type PlanTemplate

type PlanTemplate struct {
	Name string `json:"name"`
	Plan any    `json:"plan"`
	// Its new matches are pending after each scan.
	Recurring bool `json:"recurring"`
	// Bumped by every save.
	Version int `json:"version"`
	// Who saved this version.
	Author    string    `json:"author"`
	UpdatedAt time.Time `json:"updatedAt"`
}

type PlanTemplateInput

type PlanTemplateInput struct {
	// 1 to 64 characters.
	Name string `json:"name"`
	Plan any    `json:"plan"`
	// Report its new matches as pending.
	Recurring bool `json:"recurring"`
	// The version edited; null creates a template, failing when the name is
	// taken. Another administrator's save meanwhile fails with CONFLICT.
	ExpectedVersion *int `json:"expectedVersion,omitempty"`
}

type Preview

type Preview struct {
	// PlanID identifies the plan with what it was evaluated against.
	PlanID   string
	Plan     configplan.Plan
	Review   bool
	Proposal configplan.Proposal
	// Base is the configuration the plan applies to.
	Base       *config.Config
	Report     *PlanReport
	Validation *Validation
	// contains filtered or unexported fields
}

Preview is a plan evaluated against a configuration.

type RelationshipItem

type RelationshipItem struct {
	Name        string `json:"name"`
	Target      string `json:"target"`
	Cardinality string `json:"cardinality"`
	JoinOn      any    `json:"joinOn"`
}

RelationshipItem is a relationship of an entity.

type RoleItem

type RoleItem struct {
	Name        string      `json:"name"`
	Description *string     `json:"description,omitempty"`
	Grants      []GrantItem `json:"grants"                merge:"key=entity"`
}

RoleItem is a role.

type ScanBatch

type ScanBatch struct {
	ID         string `json:"id"`
	Datasource string `json:"datasource"`
	// running, done or canceled.
	State    string `json:"state"`
	Total    int    `json:"total"`
	Done     int    `json:"done"`
	Failed   int    `json:"failed"`
	Canceled int    `json:"canceled"`
	// Schemas waiting or scanning.
	Pending    int             `json:"pending"`
	Items      []ScanBatchItem `json:"items"`
	StartedBy  string          `json:"startedBy"`
	StartedAt  time.Time       `json:"startedAt"`
	FinishedAt *time.Time      `json:"finishedAt,omitempty"`
}

type ScanBatchInput

type ScanBatchInput struct {
	Datasource string   `json:"datasource"`
	Schemas    []string `json:"schemas"`
	// Names the request: sent again with the same key, it gets the batch it started.
	RequestKey *string `json:"requestKey,omitempty"`
}

type ScanBatchItem

type ScanBatchItem struct {
	Schema string `json:"schema"`
	// pending, running, done, failed or canceled.
	State string  `json:"state"`
	Error *string `json:"error,omitempty"`
}

type ScanJob

type ScanJob struct {
	ID         string `json:"id"`
	Datasource string `json:"datasource"`
	State      string `json:"state"`
	// Why the scan failed or stopped.
	Error *string `json:"error,omitempty"`
}

type Scans

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

Scans runs schema scans on a bounded pool of workers and keeps what each scan found, per schema, in a catalog store until the next scan of that schema: coming back to the console, restarting or reaching another replica does not scan again. Decoded schemas are cached per process and read again when the store holds a newer scan.

func NewScans

func NewScans(opts scanjobs.Options, store catalog.Store) *Scans

NewScans returns scans that run on opts.Bus (see scanjobs.Options), keeping them in store (in memory when nil); Close stops them.

func (*Scans) Close

func (s *Scans) Close()

Close cancels the scans and batches and stops the workers.

func (*Scans) WatchBatches

func (s *Scans) WatchBatches(runner func(ctx context.Context, datasource string) (scanRunner, error))

WatchBatches takes over the batches other processes stopped running, now and then, until the scans close. runner says how to scan a datasource as configured now.

type SchemaInfo

type SchemaInfo struct {
	Name string `json:"name"`
	// When its tables were last scanned; null when never.
	ScannedAt *time.Time `json:"scannedAt,omitempty"`
	// How many tables the last scan found; null when never scanned.
	Tables *int `json:"tables,omitempty"`
}

type SchemaList

type SchemaList struct {
	Datasource string `json:"datasource"`
	// Every user schema; when the database cannot list them, one named "" for its
	// default schema, which a scan without schemas reads.
	Schemas []SchemaInfo `json:"schemas"`
	// Where unqualified names resolve; null when unknown.
	DefaultSchema *string   `json:"defaultSchema,omitempty"`
	ListedAt      time.Time `json:"listedAt"`
	// Identifies the database the datasource reads (its driver and read
	// connection); results of another source are stale.
	Source string `json:"source"`
}

type ScopeCondition

type ScopeCondition struct {
	// datasources, schemas, tables, search, status, drift or refs.
	Name string `json:"name"`
	// The condition as written.
	Value   string `json:"value"`
	Matched int    `json:"matched"`
}

type ScopeStats

type ScopeStats struct {
	Total int `json:"total"`
	// The first matching tables.
	Samples []CatalogRow `json:"samples"`
	// Every condition of the scope with how many tables it selects alone.
	Conditions []ScopeCondition `json:"conditions"`
}

type Sections

type Sections struct {
	Entities []EntityItem   `json:"entities"`
	Roles    []RoleItem     `json:"roles"`
	Users    []UserItem     `json:"users"`
	Settings map[string]any `json:"settings"`
}

Sections are a configuration as a workspace holds it, item by item: each entity, role and user, and the settings (every other top-level section). Their JSON is what the workspace stores and the console edits; the admin API's input types (EntityInput, RoleInput, UserInput) have the same shape. A nil list or settings is a section left out (an edit keeps the base's).

func SectionsOf

func SectionsOf(spec *config.Spec) (Sections, error)

SectionsOf are the sections of what a configuration says: an unset value is not in its item (lists are written empty).

func SectionsOfConfig

func SectionsOfConfig(cfg *config.Config) (Sections, error)

SectionsOfConfig are the sections of a configuration built in code (a plan's outcome), as SectionsOf has them: a zero value is unset.

func SectionsOfPayload

func SectionsOfPayload(payload []byte) (Sections, error)

SectionsOfPayload are the sections of a stored payload.

func (Sections) Edit

func (s Sections) Edit() (configedit.Edit, error)

Edit is s as an edit of a base configuration, saying what the items say: the sections s holds replace the base's, empty text and lists, and switches off unless set, are left unset (they mean the same), and a user's token is the one its item holds (none without a hash).

type Service

type Service struct {
	Store      revision.Store
	Introspect Introspection
	// Scans runs schema scans in the background and keeps their results;
	// nil refuses them.
	Scans *Scans
	// Plans keeps plan templates, MCP tokens and pending states; nil refuses
	// them.
	Plans PlanStore
	// Capabilities reports the serving snapshot's capabilities; nil reports
	// none.
	Capabilities func() bootstrap.EntityCapabilities
	// contains filtered or unexported fields
}

Service is the configuration service. It holds no per-request state.

func (*Service) ApplyPlan

func (r *Service) ApplyPlan(ctx context.Context, in ApplyRequest) (*AppliedPlan, error)

ApplyPlan writes a previewed plan (see applicable) into the caller's workspace: the items it changes, as the console writes them, with a note of the agent (if one applies it) and its comment. The console's "add to the workspace" and an agent's plan_apply both come here. A plan that changes nothing, does not validate or has blocking exceptions fails.

func (*Service) BuildDraft

func (r *Service) BuildDraft(ctx context.Context, d Draft) (Built, error)

BuildDraft applies d to its base revision through configedit, the same chain as `store import`: decode, defaults, validation, store secret rule and the deterministic encoding.

func (*Service) CancelScanBatch

func (r *Service) CancelScanBatch(ctx context.Context, id string) (*ScanBatch, error)

CancelScanBatch asks the owner of a batch to stop; this process stops at once a batch it runs.

func (*Service) Catalog

func (r *Service) Catalog(
	ctx context.Context, f CatalogFilter, against Against, offset, limit int,
) (*CatalogPage, error)

Catalog pages through the scanned tables matching f, against the configuration against is.

func (r *Service) CatalogLinks(ctx context.Context, ref string, against Against) (*CatalogLinks, error)

CatalogLinks lists the foreign keys of a table and those referencing it, among the scanned tables of its datasource, with the entities reading the other tables.

func (*Service) CatalogRefs

func (r *Service) CatalogRefs(ctx context.Context, f CatalogFilter, against Against) ([]string, error)

CatalogRefs lists the refs of every table matching f.

func (*Service) CatalogTable

func (r *Service) CatalogTable(ctx context.Context, ref string, against Against) (*configplan.Candidate, error)

CatalogTable is one scanned table in full, with the entity proposed for it; nil when no scanned table has the ref.

func (*Service) CheckpointWorkspace

func (r *Service) CheckpointWorkspace(ctx context.Context, comment *string) (revision.Revision, error)

CheckpointWorkspace saves the caller's workspace as a draft to share.

func (*Service) CommitWorkspace

func (r *Service) CommitWorkspace(ctx context.Context, in CommitInput) (revision.Revision, error)

CommitWorkspace publishes the caller's workspace at the version reviewed.

func (*Service) CreateMcpToken

func (r *Service) CreateMcpToken(ctx context.Context, in McpTokenInput) (*McpTokenSecret, error)

CreateMcpToken creates a token of the caller for one client; the token is returned once.

func (*Service) DeletePlanTemplate

func (r *Service) DeletePlanTemplate(ctx context.Context, name string) (bool, error)

DeletePlanTemplate deletes a template with its versions.

func (*Service) Diff

func (r *Service) Diff(ctx context.Context, from string, to Against) (string, error)

Diff is the unified diff, secrets redacted, from a revision to the configuration to is.

func (*Service) DiscardDraft

func (r *Service) DiscardDraft(ctx context.Context, id string) (revision.Revision, error)

DiscardDraft discards a draft, saved by anyone, an agent included: it stays in the history and is never published.

func (*Service) Drafts

func (r *Service) Drafts(ctx context.Context) ([]PendingDraft, error)

Drafts lists every draft, newest first, with what each builds on, worked out over the whole history.

func (*Service) EditWorkspace

func (r *Service) EditWorkspace(ctx context.Context, in WorkspaceEditInput) (*Workspace, error)

EditWorkspace writes items of the caller's workspace (see workspaceops.WriteItems: an item written meanwhile merges).

func (*Service) FieldReferences

func (r *Service) FieldReferences(ctx context.Context, entity string) ([]FieldReference, error)

FieldReferences are the places the caller's workspace names the fields of the entity with ID entity, by field: roles and users first, a grant's row filter before its field lists.

func (*Service) McpTokens

func (r *Service) McpTokens(ctx context.Context) ([]McpToken, error)

McpTokens lists the caller's tokens.

func (*Service) MergeDraft

func (r *Service) MergeDraft(ctx context.Context, id string) (*Workspace, error)

MergeDraft takes draft id into the caller's workspace.

func (*Service) Ops

func (r *Service) Ops() revisionops.Service

Ops returns the revision operations shared with the `store` CLI.

func (*Service) Pending

func (r *Service) Pending(ctx context.Context, against Against) (*PendingWork, error)

Pending evaluates every recurring template, reporting each that would change the configuration or has rules it cannot apply, lists the tables whose fields differ, and counts the tables not imported and the schemas never scanned. A principal limited to some datasources sees what is about them only: their tables and the templates whose scope names only them.

func (*Service) PendingLog

func (r *Service) PendingLog(ctx context.Context, key string) ([]PendingState, error)

PendingLog lists what was set of a pending item, newest first.

func (*Service) PlanScope

func (r *Service) PlanScope(ctx context.Context, scope configplan.Scope, against Against) (*ScopeStats, error)

PlanScope counts what a scope selects, and each of its conditions alone.

func (*Service) PlanTemplateVersions

func (r *Service) PlanTemplateVersions(ctx context.Context, name string) ([]PlanTemplate, error)

PlanTemplateVersions lists the versions of a template, newest first.

func (*Service) PlanTemplates

func (r *Service) PlanTemplates(ctx context.Context) ([]PlanTemplate, error)

PlanTemplates lists the plan templates; a principal limited to some datasources sees those whose scope names only them.

func (*Service) PreviewInWorkspace

func (r *Service) PreviewInWorkspace(ctx context.Context, p configplan.Plan, review bool) (*Preview, error)

PreviewInWorkspace previews a plan against the caller's workspace, as an agent working for them does.

func (*Service) PreviewPlan

func (r *Service) PreviewPlan(ctx context.Context, p configplan.Plan, against Against, review bool) (*Preview, error)

PreviewPlan evaluates a plan against the configuration against is, as a review of a recurring template's proposal when review is set, and keeps the result for its maker.

func (*Service) Previewed

func (r *Service) Previewed(ctx context.Context, planID string) (*Preview, error)

Previewed returns a preview its caller made, while it is kept.

func (*Service) ResetWorkspace

func (r *Service) ResetWorkspace(ctx context.Context, to string) (*Workspace, error)

ResetWorkspace makes the caller's workspace revision to as it is.

func (*Service) ResolveConflict

func (r *Service) ResolveConflict(ctx context.Context, id string, theirs bool) (*Workspace, error)

ResolveConflict resolves a conflict of the caller's workspace.

func (*Service) RestartChanges

func (r *Service) RestartChanges(ctx context.Context, next *config.Config) ([]string, error)

RestartChanges compares a configuration with the published one.

func (*Service) RetryScanBatch

func (r *Service) RetryScanBatch(ctx context.Context, id string) (*ScanBatch, error)

RetryScanBatch scans again, as a new batch, what failed or was canceled in a batch.

func (*Service) Revision

func (r *Service) Revision(ctx context.Context, id string) (revision.Revision, error)

Revision returns the revision with an ID.

func (*Service) Revisions

func (r *Service) Revisions(ctx context.Context, limit int) ([]revision.Revision, error)

Revisions lists revisions, newest first, without their payloads.

func (*Service) RevokeMcpToken

func (r *Service) RevokeMcpToken(ctx context.Context, id string) (bool, error)

RevokeMcpToken revokes one of the caller's tokens.

func (*Service) SavePlanTemplate

func (r *Service) SavePlanTemplate(ctx context.Context, in PlanTemplateInput) (*PlanTemplate, error)

SavePlanTemplate creates a template, or saves a new version of one while it is still at in.ExpectedVersion.

func (*Service) ScanBatches

func (r *Service) ScanBatches(ctx context.Context, datasource string) ([]ScanBatch, error)

ScanBatches lists the recent batches of datasource, running ones first.

func (*Service) SchemaList

func (r *Service) SchemaList(ctx context.Context, datasource string, refresh bool) (*SchemaList, error)

SchemaList lists the schemas of datasource with what was scanned of each; the list is read from the database once, and again on refresh.

func (*Service) SchemaScan

func (r *Service) SchemaScan(ctx context.Context, id string, cancel bool) (*ScanJob, error)

SchemaScan reads a scan, or cancels it.

func (*Service) SchemaTables

func (r *Service) SchemaTables(ctx context.Context, datasource string, schemas []string) (*Imports, error)

SchemaTables returns the tables of the kept ones of schemas (nil: all).

func (*Service) SelectConfig

func (r *Service) SelectConfig(ctx context.Context, against Against) (*config.Config, error)

SelectConfig is the configuration against is.

func (*Service) SetPendingState

func (r *Service) SetPendingState(ctx context.Context, in PendingStateInput) (*PendingState, error)

SetPendingState records who handles a pending item and how.

func (*Service) Simulate

func (r *Service) Simulate(ctx context.Context, in SimulateRequest) (*Simulation, error)

Simulate evaluates one authorization offline.

func (*Service) StartScanBatch

func (r *Service) StartScanBatch(ctx context.Context, in ScanBatchInput) (*ScanBatch, error)

StartScanBatch scans schemas of a datasource on the server, a few at a time; the same request sent again (by its key) gets the batch it started.

func (*Service) StartSchemaScan

func (r *Service) StartSchemaScan(ctx context.Context, datasource string, schemas []string) (*ScanJob, error)

StartSchemaScan queues a scan of schemas of datasource (none: every schema it lists, or its default one) and keeps what it finds.

func (*Service) UpdateWorkspace

func (r *Service) UpdateWorkspace(ctx context.Context, to string) (*Workspace, error)

UpdateWorkspace moves the caller's workspace onto revision to.

func (*Service) Validate

func (r *Service) Validate(ctx context.Context, against Against) (*Validation, error)

Validate builds a draft and reports whether it validates, what of it needs a restart and what the serving connections cannot do.

func (*Service) WatchScanBatches

func (r *Service) WatchScanBatches()

WatchScanBatches takes over the scan batches of processes that stopped.

func (*Service) Workspace

func (r *Service) Workspace(ctx context.Context) (*Workspace, error)

Workspace is the caller's workspace; nil when nothing is published.

func (*Service) WorkspaceLog

func (r *Service) WorkspaceLog(ctx context.Context, limit *int) ([]WorkspaceLogEntry, error)

WorkspaceLog is the caller's workspace log, newest first.

type SimulateRequest

type SimulateRequest struct {
	// Against selects the configuration.
	Against Against
	// User is a configured user name, or role:<name>.
	User, Entity, Action string
	Fields               []string
	Subject              map[string]any
}

SimulateRequest is one authorization to evaluate.

type Simulation

type Simulation struct {
	Allowed bool     `json:"allowed"`
	Reason  string   `json:"reason"`
	Fields  []string `json:"fields"`
	// Effective row filter in rowPolicies JSON form; null means every row.
	RowFilter any      `json:"rowFilter,omitempty"`
	Grants    []string `json:"grants"`
	// Set when no single grant covers the requested fields.
	FieldScopes [][]string `json:"fieldScopes,omitempty"`
}

Simulation is one authorization evaluated offline.

type Simulator

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

Simulator evaluates the authorizations of one user or role of a configuration, without touching any database.

func NewSimulator

func NewSimulator(cfg *config.Config, who string, subject map[string]any) (*Simulator, error)

NewSimulator evaluates who, a configured user name or "role:<name>", in cfg; subject supplies attributes the user does not set.

func (*Simulator) Evaluate

func (s *Simulator) Evaluate(ctx context.Context, entityName, action string, fields []string) (*Simulation, error)

Evaluate evaluates action (read, aggregate, create, update, delete or execute) on an entity, for fields (none: the default projection).

type TableLink struct {
	// The other table.
	Ref  string `json:"ref"`
	Name string `json:"name"`
	// Columns of the referencing table, and the referenced ones.
	Columns    []string `json:"columns"`
	RefColumns []string `json:"refColumns"`
	// The entity reading the other table, if any.
	Entity *string `json:"entity,omitempty"`
}

A foreign key between two scanned tables.

type UnscannedSchemas

type UnscannedSchemas struct {
	Datasource string   `json:"datasource"`
	Schemas    []string `json:"schemas"`
}

type UserItem

type UserItem struct {
	Name        string      `json:"name"`
	Description *string     `json:"description,omitempty"`
	Roles       []string    `json:"roles"`
	Grants      []GrantItem `json:"grants"                merge:"key=entity"`
	Subject     any         `json:"subject,omitempty"`
	Disabled    *bool       `json:"disabled,omitempty"    merge:"unset"`
	TokenHash   *string     `json:"tokenHash,omitempty"`
}

UserItem is a user, its token included: one without a token hash has none.

type Validation

type Validation struct {
	Ok          bool    `json:"ok"`
	Error       *string `json:"error,omitempty"`
	ContentHash *string `json:"contentHash,omitempty"`
	// Changes against the published revision that need a restart.
	RestartRequired []string `json:"restartRequired"`
	// Grants the routed datasource connections cannot run (they do not block publishing).
	Warnings []string `json:"warnings"`
}

type Workspace

type Workspace struct {
	// The revision it builds on.
	Base    string `json:"base"`
	Version int    `json:"version"`
	// The console's sections (entities, roles, users, settings).
	Sections  any                 `json:"sections"`
	Conflicts []WorkspaceConflict `json:"conflicts"`
	// Where changes came from: plans agents applied, drafts taken in.
	Notes []WorkspaceNote `json:"notes"`
	// Drafts taken in or saved from it (not to offer it for review), and the
	// draft it holds as it is (saved from it, nothing changed since).
	Taken      []string   `json:"taken"`
	Checkpoint *string    `json:"checkpoint,omitempty"`
	UpdatedAt  *time.Time `json:"updatedAt,omitempty"`
	// The administrator, or agent:<token name>.
	UpdatedBy string `json:"updatedBy"`
}

Workspace is an administrator's workspace as it stands: the one copy of their unpublished work, written by them (in any console) and their agents.

type WorkspaceConflict

type WorkspaceConflict struct {
	ID   string `json:"id"`
	Kind string `json:"kind"`
	Key  string `json:"key"`
	// Where in the item, e.g. fields[email].mask; empty: the whole item.
	Path string `json:"path"`
	// The values (null when removed: MineGone, TheirsGone).
	Mine       any  `json:"mine,omitempty"`
	MineGone   bool `json:"mineGone"`
	Theirs     any  `json:"theirs,omitempty"`
	TheirsGone bool `json:"theirsGone"`
	// published (a newer revision), draft (one taken in) or workspace (a
	// write made meanwhile, by another console or an agent).
	Source string  `json:"source"`
	FromID *string `json:"fromId,omitempty"`
	FromBy *string `json:"fromBy,omitempty"`
}

WorkspaceConflict is a value the workspace and another side changed differently; the workspace keeps its value until resolved.

type WorkspaceEditInput

type WorkspaceEditInput struct {
	Items []WorkspaceItemInput `json:"items"`
}

WorkspaceEditInput writes items of the workspace.

type WorkspaceItemInput

type WorkspaceItemInput struct {
	Kind        string  `json:"kind"`
	Key         string  `json:"key"`
	Value       any     `json:"value,omitempty"`
	Previous    any     `json:"previous,omitempty"`
	RenamedFrom *string `json:"renamedFrom,omitempty"`
}

WorkspaceItemInput writes one item: its value (null removes it) and the value its writer read (null: absent). An item written meanwhile merges. RenamedFrom is the key of the item of the same kind (an entity or a role) it was renamed or moved from, which it replaces; references follow it.

type WorkspaceLogEntry

type WorkspaceLogEntry struct {
	Version int       `json:"version"`
	At      time.Time `json:"at"`
	By      string    `json:"by"`
	// edit, apply, update, reset, merge, resolve, checkpoint or commit.
	Op    string         `json:"op"`
	Items []WorkspaceRef `json:"items"`
	Note  *string        `json:"note,omitempty"`
}

WorkspaceLogEntry is a write of a workspace.

type WorkspaceNote

type WorkspaceNote struct {
	// agent or draft.
	Source string `json:"source"`
	By     string `json:"by"`
	Text   string `json:"text"`
}

WorkspaceNote says where changes came from.

type WorkspaceRef

type WorkspaceRef struct {
	Kind string `json:"kind"`
	Key  string `json:"key"`
}

WorkspaceRef names an item: entity (by ID), role or user (by name), or settings.

Jump to

Keyboard shortcuts

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