engine

package
v0.0.0-...-b75b351 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2026 License: LGPL-2.1 Imports: 28 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefineBuiltinActions

func DefineBuiltinActions(engine it.DynamicResourceEngine, only ...it.CrudAction) error

DefineBuiltinActions registers the CRUD actions every resource gets for free. The registry calls it right after constructing an engine.

An empty `only` defines all of them; a non-empty list defines just those, so that an engine can be created without the actions its resource has no business exposing. An action left out has no REST route and is refused by the resource service.

They declare no ParamSchema: the crud helpers the service delegates to already validate the params against the resource schema, inject the service fields, check the unique constraints and enforce the etag on update. Declaring a schema here would validate twice. A module that needs a pipeline-level schema on a built-in can still add one with ModifyAction; the second validation is idempotent on already-sanitized params.

func NewDynamicResourceEngine

func NewDynamicResourceEngine(param NewEngineParam) it.DynamicResourceEngine

func NewDynamicResourceRepository

func NewDynamicResourceRepository(param NewRepositoryParam) it.DynamicResourceRepository

func NewDynamicResourceService

func NewDynamicResourceService(param NewServiceParam) it.DynamicResourceService

func NewDynamicRestApi

func NewDynamicRestApi(engine it.DynamicResourceEngine) it.DynamicRestApi

func WithComputedFields

func WithComputedFields(
	base it.DynamicResourceService, sourceSearch SourceSearchFn, invokeFunction FunctionInvokeFn,
	defaultSearchFields []string,
) it.DynamicResourceService

WithComputedFields decorates a resource service so declared computed fields evaluate on every read and reject every write — the generic replacement for the per-module Search/GetById/GetOne overrides modules used to hand-roll for virtual fields. Wrapping is unconditional and costs nothing for a schema without computed fields: the eval planner returns nil and every call passes straight through.

defaultSearchFields must be the same list the wrapped service falls back to when a search names no fields — otherwise a defaulted listing evaluates the wrong set of computed fields and reads operands the projection never selected.

func WithdrawOrgScoping

func WithdrawOrgScoping(engine it.DynamicResourceEngine) error

WithdrawOrgScoping opts every action currently defined on the engine out of org scoping.

It exists for a resource whose org_id is *optional*, where NULL means "global" or "domain-scoped" rather than "belongs to no org" - iam_role and iam_entitlement are the two in the tree. Requiring ?org_id= on those would make every domain-scoped row unreachable, which is a silent under-grant rather than a visible error.

Call it after the module has defined its own actions, so that those are covered too. It is deliberately all-or-nothing: a resource that needs scoping on some actions and not others should say so per action, where the reason can be written down next to the exception.

Types

type DynamicResourceEngineImpl

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

DynamicResourceEngineImpl is the generic CRUD machinery of one resource. It owns the action definitions and the three subengines that carry them out.

func (*DynamicResourceEngineImpl) Action

func (this *DynamicResourceEngineImpl) Action(actionName string) (it.DynamicActionDefinition, bool)

func (*DynamicResourceEngineImpl) ActionNames

func (this *DynamicResourceEngineImpl) ActionNames() []string

func (*DynamicResourceEngineImpl) AssertComputedFunctionsDefined

func (this *DynamicResourceEngineImpl) AssertComputedFunctionsDefined() error

AssertComputedFunctionsDefined matches the schema's declarations against what was registered.

It reports every missing function at once rather than the first, so a module adding several fields fixes them in one pass instead of rediscovering them one boot at a time.

func (*DynamicResourceEngineImpl) ComputedFieldFunction

func (this *DynamicResourceEngineImpl) ComputedFieldFunction(name string) (it.ComputedFieldFn, bool)

func (*DynamicResourceEngineImpl) DefaultPermissionScope

func (this *DynamicResourceEngineImpl) DefaultPermissionScope() requestguard.ResourceScope

func (*DynamicResourceEngineImpl) DefineAction

func (this *DynamicResourceEngineImpl) DefineAction(definition it.DynamicActionDefinition) error

DefineAction registers a new action, rejecting duplicates so that two modules cannot silently overwrite each other's behavior. Use ModifyAction to change an existing one.

func (*DynamicResourceEngineImpl) DefineComputedFieldFunction

func (this *DynamicResourceEngineImpl) DefineComputedFieldFunction(
	name string, fn it.ComputedFieldFn,
) error

DefineComputedFieldFunction registers the implementation of a "function"-kind computed field, rejecting duplicates for the same reason DefineAction does: two modules must not silently overwrite each other's behaviour.

func (*DynamicResourceEngineImpl) ExecuteAction

func (this *DynamicResourceEngineImpl) ExecuteAction(
	ctx corectx.Context, actionName string, params dmodel.DynamicFields,
) (result *it.ActionResult, err error)

ExecuteAction runs the full pipeline of the named action.

A violation the caller can fix (missing permission, invalid params, missing record) comes back as ClientErrors inside the result, never as a Go error, so that the REST layer answers 400 rather than 500. A Go error means the request could not be processed.

func (*DynamicResourceEngineImpl) ModifyAction

func (this *DynamicResourceEngineImpl) ModifyAction(delta it.DynamicActionDelta) error

ModifyAction overrides the provided fields of an existing action, leaving the rest intact.

func (*DynamicResourceEngineImpl) ResourceName

func (this *DynamicResourceEngineImpl) ResourceName() string

func (*DynamicResourceEngineImpl) ResourceRepository

func (this *DynamicResourceEngineImpl) ResourceRepository() it.DynamicResourceRepository

func (*DynamicResourceEngineImpl) ResourceService

func (this *DynamicResourceEngineImpl) ResourceService() it.DynamicResourceService

func (*DynamicResourceEngineImpl) RestApi

func (*DynamicResourceEngineImpl) RoutePath

func (this *DynamicResourceEngineImpl) RoutePath() string

func (*DynamicResourceEngineImpl) Schema

func (*DynamicResourceEngineImpl) SetDefaultPermissionScope

func (this *DynamicResourceEngineImpl) SetDefaultPermissionScope(scope requestguard.ResourceScope)

func (*DynamicResourceEngineImpl) SetResourceRepository

func (this *DynamicResourceEngineImpl) SetResourceRepository(repository it.DynamicResourceRepository)

func (*DynamicResourceEngineImpl) SetResourceService

func (this *DynamicResourceEngineImpl) SetResourceService(service it.DynamicResourceService)

func (*DynamicResourceEngineImpl) SetRestApi

func (this *DynamicResourceEngineImpl) SetRestApi(restApi it.DynamicRestApi)

func (*DynamicResourceEngineImpl) SetRoutePath

func (this *DynamicResourceEngineImpl) SetRoutePath(path string)

type DynamicResourceRepositoryImpl

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

DynamicResourceRepositoryImpl is the schema-agnostic counterpart of the hand-written repositories such as iam's UserDynamicRepository: it delegates to the same baserepo helpers, but speaks DynamicFields instead of a typed domain model.

func (*DynamicResourceRepositoryImpl) BeginTransaction

func (*DynamicResourceRepositoryImpl) DeleteOne

func (*DynamicResourceRepositoryImpl) Exists

func (*DynamicResourceRepositoryImpl) FindByKeys

FindByKeys fetches the single record identified by the given keys, reading every column of the schema.

func (*DynamicResourceRepositoryImpl) GetBaseRepo

func (*DynamicResourceRepositoryImpl) GetOne

func (*DynamicResourceRepositoryImpl) Insert

func (*DynamicResourceRepositoryImpl) Search

func (*DynamicResourceRepositoryImpl) Update

type DynamicResourceServiceImpl

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

DynamicResourceServiceImpl is the schema-agnostic merge of what a feature module splits between its application service and its domain service, minus the permission checks, which the engine pipeline performs before calling in here.

A module extends it by embedding it in its own service struct and installing that struct with Engine.SetResourceService.

func (*DynamicResourceServiceImpl) Create

func (*DynamicResourceServiceImpl) Delete

func (*DynamicResourceServiceImpl) Exists

func (*DynamicResourceServiceImpl) GetById

func (*DynamicResourceServiceImpl) GetOne

GetOne fetches one record by any unique key present in params. Every param that names a schema column is used as an equality condition, so callers must pass only key fields.

func (*DynamicResourceServiceImpl) Repository

Repository exposes the repository to embedding services.

func (*DynamicResourceServiceImpl) Schema

func (*DynamicResourceServiceImpl) Search

func (*DynamicResourceServiceImpl) SetArchived

func (*DynamicResourceServiceImpl) Update

type DynamicRestApiImpl

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

DynamicRestApiImpl exposes one resource over HTTP. Every endpoint goes through Engine.ExecuteAction rather than calling the service directly, so that a permission check always runs and a ModifyAction override takes effect on the REST surface too.

func (*DynamicRestApiImpl) RegisterRoutes

func (this *DynamicRestApiImpl) RegisterRoutes(route *echo.Group, middlewares ...echo.MiddlewareFunc)

RegisterRoutes adds every REST-exposed action of the resource to the given group. An action opts in by declaring an ActionType, which decides the HTTP method, and a RestPath relative to the resource base.

The order matters: echo matches in registration order, so the literal "meta/schema" and "exists" paths must be registered before the ":id" patterns that would swallow them. routableActions sorts by specificity so that holds without hand-written ordering.

type FunctionInvokeFn

type FunctionInvokeFn func(
	ctx corectx.Context, schemaName string, functionName string, fieldName string,
	rows []dmodel.DynamicFields,
) ([]any, error)

FunctionInvokeFn runs a registered computed-field function over a page of rows. Supplied by the registry, which knows how to reach the engine holding the function registry — the same indirection SourceSearchFn uses to reach another engine's repository.

type NewEngineParam

type NewEngineParam struct {
	Schema     *dmodel.ModelSchema
	Repository it.DynamicResourceRepository
	Service    it.DynamicResourceService
}

NewEngineParam carries what an engine needs at construction time.

type NewRepositoryParam

type NewRepositoryParam struct {
	Client        orm.DbClient
	ConfigSvc     config.ConfigService
	QueryBuilder  orm.QueryBuilder
	Logger        logging.LoggerService
	NewBaseRepoFn dyn.NewBaseDynamicRepositoryFn
	Schema        *dmodel.ModelSchema
}

NewRepositoryParam carries the core services a repository needs. The registry fills it once and reuses it for every engine it builds.

type NewServiceParam

type NewServiceParam struct {
	Schema     *dmodel.ModelSchema
	Repository it.DynamicResourceRepository

	// DefaultFields is returned by a search that specifies neither fields nor a resolvable
	// view. When empty, every column of the schema is returned.
	DefaultFields []string

	// CrudActions is the engine's action allow-list. Empty means every action is supported.
	CrudActions []it.CrudAction

	// ActionLookup resolves an action definition at call time, which is how the service
	// reaches the validator hooks a module attached with ModifyAction. The service is built
	// before the engine that will own it exists, so the lookup has to be deferred - the same
	// reason invokeComputedFunction defers its own.
	ActionLookup func(actionName string) (it.DynamicActionDefinition, bool)
}

NewServiceParam carries what a resource service needs to work.

type SourceSearchFn

type SourceSearchFn func(
	ctx corectx.Context, schemaName string, keyColumn string, keys []any, fields []string,
) ([]dmodel.DynamicFields, error)

SourceSearchFn fetches rows of another resource for a batched related-field read. Supplied by the registry, which knows how to reach every engine's repository.

Jump to

Keyboard shortcuts

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