integration

package
v0.39.0 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ErrCodeContractNotFound      = 2600
	ErrCodeContractDisabled      = 2601
	ErrCodeSystemNotFound        = 2602
	ErrCodeSystemDisabled        = 2603
	ErrCodeAdapterNotFound       = 2604
	ErrCodeAdapterDisabled       = 2605
	ErrCodeRouteNotFound         = 2606
	ErrCodeTargetAmbiguous       = 2607
	ErrCodeInputInvalid          = 2608
	ErrCodeOutputInvalid         = 2609
	ErrCodeUpstreamFailed        = 2610
	ErrCodeTransportFailed       = 2611
	ErrCodeInvocationTimeout     = 2612
	ErrCodeScriptFailed          = 2613
	ErrCodeUnknownAuthScheme     = 2614
	ErrCodeInvalidSchema         = 2615
	ErrCodeInvalidScript         = 2616
	ErrCodeInvalidAuthParams     = 2617
	ErrCodeInvalidRouteRef       = 2618
	ErrCodeInvalidBaseURL        = 2619
	ErrCodeInvalidDataSource     = 2620
	ErrCodeInvalidDirection      = 2621
	ErrCodeInboundAuthFailed     = 2622
	ErrCodeInboundHandlerMissing = 2623
	ErrCodeInvocationCanceled    = 2624
	ErrCodeInvalidEnvelope       = 2625
	ErrCodeInvalidLabel          = 2626
)

Response codes for integration API errors (2600-2699).

View Source
const MaskedSecret = "******"

MaskedSecret is the placeholder management APIs return in place of a sensitive auth parameter value. An update submitting the placeholder keeps the stored value unchanged.

View Source
const SensitiveAll = "*"

SensitiveAll is the SensitiveParams wildcard marking every parameter of a scheme sensitive, for schemes whose parameter names are not known statically (the built-in script and multi-pair header/query schemes use it).

Variables

View Source
var (
	ErrContractNotFound = result.Err(
		i18n.T("integration_contract_not_found"),
		result.WithCode(ErrCodeContractNotFound),
	)
	ErrContractDisabled = result.Err(
		i18n.T("integration_contract_disabled"),
		result.WithCode(ErrCodeContractDisabled),
	)
	ErrSystemNotFound = result.Err(
		i18n.T("integration_system_not_found"),
		result.WithCode(ErrCodeSystemNotFound),
	)
	ErrSystemDisabled = result.Err(
		i18n.T("integration_system_disabled"),
		result.WithCode(ErrCodeSystemDisabled),
	)
	ErrAdapterNotFound = result.Err(
		i18n.T("integration_adapter_not_found"),
		result.WithCode(ErrCodeAdapterNotFound),
	)
	ErrAdapterDisabled = result.Err(
		i18n.T("integration_adapter_disabled"),
		result.WithCode(ErrCodeAdapterDisabled),
	)
	ErrRouteNotFound = result.Err(
		i18n.T("integration_route_not_found"),
		result.WithCode(ErrCodeRouteNotFound),
	)
	// ErrTargetAmbiguous rejects an invocation passing both WithSystem and
	// WithRoute — the two target selectors are mutually exclusive.
	ErrTargetAmbiguous = result.Err(
		i18n.T("integration_target_ambiguous"),
		result.WithCode(ErrCodeTargetAmbiguous),
	)
	// ErrTransportFailed marks a wire call that never completed. Sentinel
	// (not a factory) because the transport detail belongs in logs, not in
	// the API response.
	ErrTransportFailed = result.Err(
		i18n.T("integration_transport_failed"),
		result.WithCode(ErrCodeTransportFailed),
	)
	ErrInvocationTimeout = result.Err(
		i18n.T("integration_invocation_timeout"),
		result.WithCode(ErrCodeInvocationTimeout),
	)
	// ErrInvocationCanceled marks an invocation interrupted by its caller's
	// cancellation — the caller is typically no longer listening.
	ErrInvocationCanceled = result.Err(
		i18n.T("integration_invocation_canceled"),
		result.WithCode(ErrCodeInvocationCanceled),
	)
	// ErrInvalidRouteRef rejects a route referencing a missing contract or
	// system at save time.
	ErrInvalidRouteRef = result.Err(
		i18n.T("integration_invalid_route_ref"),
		result.WithCode(ErrCodeInvalidRouteRef),
	)
	// ErrInvalidBaseURL rejects a system base URL that does not parse as an
	// absolute URL at save time.
	ErrInvalidBaseURL = result.Err(
		i18n.T("integration_invalid_base_url"),
		result.WithCode(ErrCodeInvalidBaseURL),
	)
)

Predefined integration API errors. These are business errors and keep the default HTTP 200 status; the failure is carried by the body code.

View Source
var ErrInboundAuthFailed = result.Err(
	i18n.T("integration_inbound_auth_failed"),
	result.WithCode(ErrCodeInboundAuthFailed),
	result.WithStatus(fiber.StatusUnauthorized),
)

ErrInboundAuthFailed denies an inbound delivery that failed verification. It is deliberately uniform — missing configuration, missing credentials, and wrong credentials all yield it; the distinction stays server-side.

View Source
var ErrInboundHandlerMissing = result.Err(
	i18n.T("integration_inbound_handler_missing"),
	result.WithCode(ErrCodeInboundHandlerMissing),
	result.WithStatus(fiber.StatusNotImplemented),
)

ErrInboundHandlerMissing marks an inbound contract no registered handler serves — a deployment fault, not a caller error.

View Source
var ErrInvalidDirection = result.Err(
	i18n.T("integration_invalid_direction"),
	result.WithCode(ErrCodeInvalidDirection),
)

ErrInvalidDirection rejects an adapter direction outside the known flows.

View Source
var ErrInvalidLabel = result.Err(
	i18n.T("integration_invalid_label"),
	result.WithCode(ErrCodeInvalidLabel),
)

ErrInvalidLabel rejects a contract label whose key would silently escape the label equality filter (dots read as JSON path nesting) or whose key or value exceeds the size bounds.

Functions

func Call

func Call[T any](ctx context.Context, inv Invoker, contract string, input any, opts ...InvokeOption) (T, error)

Call is the typed convenience wrapper over Invoker.Invoke: it decodes the standard model into T.

func ErrInputInvalid

func ErrInputInvalid(detail string) result.Error

ErrInputInvalid reports input rejected by the contract's input schema.

func ErrInvalidAuthParams

func ErrInvalidAuthParams(detail string) result.Error

ErrInvalidAuthParams reports an auth configuration a scheme refused: rejected at save-time validation, or failing at runtime when the outbound client is assembled or a request is signed.

func ErrInvalidDataSource

func ErrInvalidDataSource(detail string) result.Error

ErrInvalidDataSource rejects a system data source configuration that is incomplete or whose credential cannot be processed.

func ErrInvalidEnvelope

func ErrInvalidEnvelope(detail string) result.Error

ErrInvalidEnvelope rejects an outbound envelope configuration: a script that does not compile, an envelope defining no script, or one on a system without an HTTP transport.

func ErrInvalidSchema

func ErrInvalidSchema(detail string) result.Error

ErrInvalidSchema rejects a contract schema that does not parse or resolve as a self-contained JSON Schema at save time.

func ErrInvalidScript

func ErrInvalidScript(detail string) result.Error

ErrInvalidScript rejects an adapter script that does not compile at save time.

func ErrOutputInvalid

func ErrOutputInvalid(detail string) result.Error

ErrOutputInvalid reports a script return value rejected by the contract's output schema.

func ErrScriptFailed

func ErrScriptFailed(detail string) result.Error

ErrScriptFailed reports an adapter script that threw or failed to compile.

func ErrUnknownAuthScheme

func ErrUnknownAuthScheme(scheme string) result.Error

ErrUnknownAuthScheme rejects a system whose auth references a scheme no registered OutboundAuthScheme reports as its name.

func ErrUpstreamFailed

func ErrUpstreamFailed(message string) result.Error

ErrUpstreamFailed reports a failure the external system itself signaled, carrying the message the adapter script surfaced via errors.upstream.

Types

type Adapter

type Adapter struct {
	orm.BaseModel `bun:"table:itg_adapter,alias:iad"`
	orm.FullAuditedModel

	SystemID   string `json:"systemId" bun:"system_id"`
	ContractID string `json:"contractId" bun:"contract_id"`
	// Direction selects the flow the script implements; an empty value is
	// normalized to outbound at save time.
	Direction Direction `json:"direction" bun:"direction"`
	Script    string    `json:"script" bun:"script"`
	// TimeoutMs overrides the script run timeout for this adapter; zero
	// inherits vef.integration.run_timeout. The system's TimeoutMs bounds
	// individual HTTP calls — a different axis.
	TimeoutMs int  `json:"timeoutMs" bun:"timeout_ms"`
	IsEnabled bool `json:"isEnabled" bun:"is_enabled"`
}

Adapter binds one system to one contract: its script translates between the system's wire format and the contract's standard models. A system implements a contract with exactly one adapter per direction.

type Contract

type Contract struct {
	orm.BaseModel `bun:"table:itg_contract,alias:ic"`
	orm.FullAuditedModel

	Code        string  `json:"code" bun:"code"`
	Name        string  `json:"name" bun:"name"`
	Description *string `json:"description" bun:"description,nullzero"`
	// Labels are host-owned selection metadata (e.g. which business scenes may
	// offer this contract for dynamic binding); the engine stores and filters
	// them but never interprets them. Key charset and sizes are enforced by
	// ValidateContract at save time.
	Labels map[string]string `json:"labels,omitempty" bun:"labels,type:jsonb,nullzero"`
	// InputSchema is the self-contained JSON Schema (draft 2020-12) the
	// invocation input is validated against; empty skips input validation.
	InputSchema json.RawMessage `json:"inputSchema" bun:"input_schema,type:jsonb,nullzero"`
	// OutputSchema is the self-contained JSON Schema the adapter script's
	// return value is validated against; empty skips output validation.
	OutputSchema json.RawMessage `json:"outputSchema" bun:"output_schema,type:jsonb,nullzero"`
	IsEnabled    bool            `json:"isEnabled" bun:"is_enabled"`
}

Contract defines a standard integration operation: the business-side input and output models every provider adapter must honor. Business code programs against contracts; provider differences stay inside adapter scripts.

type DataSourceConfig

type DataSourceConfig struct {
	Kind config.DBKind `json:"kind"`
	// Mode gates script write access to this database; empty means read-only.
	Mode        DataSourceMode `json:"mode,omitempty"`
	Host        string         `json:"host,omitempty"`
	Port        uint16         `json:"port,omitempty"`
	User        string         `json:"user,omitempty"`
	Password    string         `json:"password,omitempty"`
	Database    string         `json:"database,omitempty"`
	Schema      string         `json:"schema,omitempty"`
	Path        string         `json:"path,omitempty"`
	SSLMode     config.SSLMode `json:"sslMode,omitempty"`
	SSLRootCert string         `json:"sslRootCert,omitempty"`
}

DataSourceConfig describes a system's direct database connection. It mirrors config.DataSourceConfig with JSON tags for jsonb storage and the management API; ToConfig converts it for the datasource registry.

func (*DataSourceConfig) ToConfig

ToConfig converts the connection settings into the framework's data source configuration. Script write access is enforced at the sql library layer (per Mode), so the connection-level SQL guard is left off.

type DataSourceMode

type DataSourceMode string

DataSourceMode declares how far adapter scripts may go against a system's database: read-only querying (the default) or full read-write exchange for systems whose integration surface is a writable database.

const (
	// DataSourceModeReadOnly restricts scripts to sql.queryList; sql.execute throws.
	// An empty mode resolves to this default.
	DataSourceModeReadOnly DataSourceMode = "read_only"
	// DataSourceModeReadWrite additionally enables sql.execute, letting scripts
	// write back into the system's database.
	DataSourceModeReadWrite DataSourceMode = "read_write"
)

func (DataSourceMode) AllowsWrite

func (m DataSourceMode) AllowsWrite() bool

AllowsWrite reports whether scripts may mutate the system's database.

func (DataSourceMode) IsValid

func (m DataSourceMode) IsValid() bool

IsValid reports whether the mode is empty (defaulting to read-only) or one of the known modes.

type Direction

type Direction string

Direction distinguishes the two integration flows an adapter can implement: outbound (business code invokes the external system) and inbound (the external system calls in through an inbound gateway).

const (
	// DirectionOutbound marks a script translating contract input into calls
	// on the external system and its responses into the contract output.
	DirectionOutbound Direction = "outbound"
	// DirectionInbound marks a script translating a request the external
	// system initiated into a contract dispatch and the dispatch result into
	// the reply the system expects.
	DirectionInbound Direction = "inbound"
)

func (Direction) IsValid

func (d Direction) IsValid() bool

IsValid reports whether the direction is one of the two known flows.

type FailureKind

type FailureKind string

FailureKind classifies why an invocation failed. It is the single vocabulary shared by invocation logs, statistics, and API errors; an empty value means success.

const (
	// FailureInputInvalid marks input rejected by the contract's input schema
	// before the adapter script ran.
	FailureInputInvalid FailureKind = "input_invalid"
	// FailureOutputInvalid marks a script return value rejected by the
	// contract's output schema — the adapter mapped the response incorrectly.
	FailureOutputInvalid FailureKind = "output_invalid"
	// FailureUpstream marks a failure reported by the external system, which
	// the adapter script surfaced via errors.upstream(...).
	FailureUpstream FailureKind = "upstream"
	// FailureTransport marks a wire call that never completed: connection
	// refused, TLS failure, or an upstream that stopped responding.
	FailureTransport FailureKind = "transport"
	// FailureTimeout marks an invocation that exceeded its run timeout.
	FailureTimeout FailureKind = "timeout"
	// FailureCanceled marks an invocation interrupted because its caller
	// canceled — the caller walked away, not a fault of the upstream, the
	// adapter, or the deadline.
	FailureCanceled FailureKind = "canceled"
	// FailureScript marks a failure of the adapter script itself — an
	// uncaught exception or a compile error; a bug in the adapter, not in
	// the upstream.
	FailureScript FailureKind = "script"
	// FailureConfig marks an invocation the system/adapter configuration
	// prevented from executing: an auth scheme that is no longer registered
	// or a credential that cannot be decrypted.
	FailureConfig FailureKind = "config"
	// FailureAuth marks an inbound delivery rejected by the system's inbound
	// auth verification — the caller could not prove it is the system.
	FailureAuth FailureKind = "auth"
	// FailureHandler marks an inbound delivery whose business handler
	// returned an error after a successful dispatch — a business failure, not
	// an adapter or external-system fault.
	FailureHandler FailureKind = "handler"
)

type HTTPExchange

type HTTPExchange struct {
	Method          string            `json:"method"`
	URL             string            `json:"url"`
	RequestHeaders  map[string]string `json:"requestHeaders,omitempty"`
	RequestBody     string            `json:"requestBody,omitempty"`
	Status          int               `json:"status,omitempty"`
	ResponseHeaders map[string]string `json:"responseHeaders,omitempty"`
	ResponseBody    string            `json:"responseBody,omitempty"`
	DurationMs      int64             `json:"durationMs"`
	Error           string            `json:"error,omitempty"`
}

HTTPExchange is one wire exchange captured while an adapter script ran, shared by invocation logs and the dry-run trace. Bodies and header values are masked and truncated per vef.integration.log before they land here.

type InboundAuthConfig

type InboundAuthConfig struct {
	Scheme string            `json:"scheme"`
	Params map[string]string `json:"params,omitempty"`
	// Script is the custom verification body for the "script" scheme: it runs
	// in a runtime with no IO capabilities, sees request and params, and
	// grants access by returning a truthy value.
	Script string `json:"script,omitempty"`
}

InboundAuthConfig selects the InboundAuthScheme verifying calls on a system's inbound endpoints and carries its parameters. Values of the parameters named by the scheme's SensitiveParams are stored encrypted and masked in management API responses.

type InboundAuthScheme

type InboundAuthScheme interface {
	// Name identifies the scheme referenced by a system's inboundAuth.scheme.
	Name() string
	// Verify authenticates the request against the system's inbound auth
	// configuration. The config arrives with sensitive parameters decrypted;
	// their values must never be logged. Any returned error denies the
	// delivery — its message stays server-side and is never echoed to the
	// caller.
	Verify(ctx context.Context, req *InboundRequest, auth *InboundAuthConfig) error
	// SensitiveParams names the parameters whose values are stored encrypted
	// and masked in management API responses; the SensitiveAll wildcard marks
	// every parameter sensitive.
	SensitiveParams() []string
}

InboundAuthScheme verifies that an inbound request truly originates from the system it targets, using the system's stored inbound auth configuration. Built-in schemes cover the common cases; applications register their own via vef.ProvideIntegrationInboundAuthScheme, and a scheme whose name matches a built-in replaces it.

type InboundHandler

type InboundHandler interface {
	// Contract returns the code of the contract the handler serves.
	Contract() string
	// Handle processes one schema-validated dispatch and returns the standard
	// output. A returned error is classified as FailureHandler; adapter
	// scripts may catch it to shape the external-facing reply.
	Handle(ctx context.Context, input any) (any, error)
}

InboundHandler is the business-side receiver of one inbound contract: it consumes the standard input an inbound adapter script dispatched and returns the standard output, both validated against the contract's schemas. Register implementations with vef.ProvideIntegrationInboundHandler — one handler per contract code. Handlers must be idempotent: external systems deliver at-least-once.

func NewInboundHandler

func NewInboundHandler[I, O any](contract string, handle func(ctx context.Context, input I) (O, error)) InboundHandler

NewInboundHandler adapts a typed function to an InboundHandler: the schema-validated input is decoded into I through a JSON round-trip before the function runs.

type InboundRequest

type InboundRequest struct {
	SystemCode   string
	ContractCode string
	// Protocol names the gateway that received the call (e.g. "http").
	Protocol string
	Method   string
	Path     string
	Headers  map[string]string
	Query    map[string]string
	// Body is the raw request payload.
	Body []byte
	// ClientAddr is the network peer address, for IP-based verification.
	ClientAddr string
}

InboundRequest is the protocol-neutral envelope an inbound gateway builds from one call an external system initiated. SystemCode and ContractCode identify the target the gateway resolved (for HTTP, from the URL path). Headers carries the protocol's named metadata with lowercased keys — HTTP headers verbatim; a non-HTTP gateway maps its protocol's equivalent (an MLLP gateway could project MSH fields). Method, Path, and Query are HTTP-native and stay empty where the protocol has no counterpart.

type InvocationLog

type InvocationLog struct {
	orm.BaseModel `bun:"table:itg_invocation_log,alias:il"`
	orm.CreationAuditedModel

	SystemCode   string `json:"systemCode" bun:"system_code"`
	ContractCode string `json:"contractCode" bun:"contract_code"`
	// Direction records which flow produced the entry: outbound invocations
	// or inbound deliveries.
	Direction Direction `json:"direction" bun:"direction"`
	// FailureKind is empty for a successful invocation.
	FailureKind FailureKind     `json:"failureKind" bun:"failure_kind"`
	DurationMs  int64           `json:"durationMs" bun:"duration_ms"`
	Input       json.RawMessage `json:"input" bun:"input,type:jsonb,nullzero"`
	Output      json.RawMessage `json:"output" bun:"output,type:jsonb,nullzero"`
	HTTPTrace   []HTTPExchange  `json:"httpTrace" bun:"http_trace,type:jsonb,nullzero"`
	Error       *string         `json:"error" bun:"error,nullzero"`
	RequestID   string          `json:"requestId" bun:"request_id"`
}

InvocationLog is one recorded invocation: its classification, timing, and the masked, size-capped captures selected by vef.integration.log.

type InvocationStats

type InvocationStats struct {
	System        string                `json:"system"`
	Contract      string                `json:"contract"`
	Direction     Direction             `json:"direction"`
	Calls         int64                 `json:"calls"`
	Successes     int64                 `json:"successes"`
	Failures      map[FailureKind]int64 `json:"failures,omitempty"`
	AvgDurationMs int64                 `json:"avgDurationMs"`
	MaxDurationMs int64                 `json:"maxDurationMs"`
	LastError     string                `json:"lastError,omitempty"`
	LastErrorAt   time.Time             `json:"lastErrorAt,omitzero"`
}

InvocationStats aggregates the invocations of one (system, contract, direction) tuple on this node since process start. Inbound deliveries rejected by verification aggregate under an empty Contract — the contract code is unvalidated caller input at rejection time.

type InvokeConfig

type InvokeConfig struct {
	// SystemCode targets a system directly, bypassing route resolution.
	SystemCode string
	// RouteKey selects the system through the RouteResolver; empty is the
	// default route.
	RouteKey string
	// Timeout overrides the adapter/system call timeout when positive.
	Timeout time.Duration
	// CacheTTL caches the validated output for the given duration when
	// positive; invocations are never cached otherwise.
	CacheTTL time.Duration
}

InvokeConfig collects the settings resolved from InvokeOptions. It is consumed by the Invoker implementation; applications use the With* options instead of constructing it directly.

func NewInvokeConfig

func NewInvokeConfig(opts ...InvokeOption) InvokeConfig

NewInvokeConfig resolves opts into an InvokeConfig.

type InvokeOption

type InvokeOption func(*InvokeConfig)

InvokeOption customizes a single invocation.

func WithCache

func WithCache(ttl time.Duration) InvokeOption

WithCache caches the validated output for ttl, keyed by system, contract, and input. Caching is per invocation site and off by default — opt in only where the business tolerates data of that age.

func WithRoute

func WithRoute(key string) InvokeOption

WithRoute selects the system by resolving key through the RouteResolver. Mutually exclusive with WithSystem.

func WithSystem

func WithSystem(code string) InvokeOption

WithSystem targets the system with the given code directly. Mutually exclusive with WithRoute.

func WithTimeout

func WithTimeout(d time.Duration) InvokeOption

WithTimeout overrides the adapter/system call timeout for this invocation.

type Invoker

type Invoker interface {
	// Invoke executes the named contract with input against the system
	// selected by WithSystem, or resolved through the RouteResolver from the
	// WithRoute key (no target option resolves the empty route key, i.e. the
	// default route). The input is validated against the contract's input
	// schema before the script runs and the script's return value against
	// the output schema after, so the Result always carries a valid standard
	// model.
	Invoke(ctx context.Context, contract string, input any, opts ...InvokeOption) (*Result, error)
}

Invoker executes integration calls: it resolves the target system, runs the bound adapter script, and returns the contract's standard model. Business code depends on contracts only — never on a concrete provider.

type OutboundAuthConfig

type OutboundAuthConfig struct {
	Scheme string            `json:"scheme"`
	Params map[string]string `json:"params,omitempty"`
	// Script is the custom signing body for the "script" scheme: it runs per
	// request in a runtime with no IO capabilities, sees the built request and
	// the decrypted params, and returns the credential headers to add.
	Script string `json:"script,omitempty"`
}

OutboundAuthConfig selects the OutboundAuthScheme authenticating a system's outbound calls and carries its parameters. Values of the parameters named by the scheme's SensitiveParams are stored encrypted and masked in management API responses.

type OutboundAuthScheme

type OutboundAuthScheme interface {
	// Name identifies the scheme referenced by a system's outboundAuth.scheme.
	Name() string
	// Apply validates cfg and returns the client options implementing the
	// scheme. Cfg is never nil and its params arrive decrypted; sensitive
	// values must never be logged.
	Apply(cfg *OutboundAuthConfig) ([]httpx.Option, error)
	// SensitiveParams names the parameters whose values are stored encrypted
	// and masked in management API responses; the SensitiveAll wildcard marks
	// every parameter sensitive.
	SensitiveParams() []string
}

OutboundAuthScheme turns a system's declarative outbound auth configuration into httpx options (credentials, signing hooks) applied to every outbound request of that system. Built-in schemes cover the common cases; applications register their own via vef.ProvideIntegrationOutboundAuthScheme, and a scheme whose name matches a built-in replaces it.

type OutboundEnvelopeConfig

type OutboundEnvelopeConfig struct {
	// Request is the wrap script: it receives the request the adapter issued
	// as `request` ({ method, path, headers, query, body }) and returns the
	// request to put on the wire — fields it omits keep the adapter's values.
	Request string `json:"request,omitempty"`
	// Response is the unwrap script: it receives the completed HTTP response
	// as `response` (the fetch Response shape) and whatever it returns is
	// what the adapter's call yields — typically the payload stripped of the
	// vendor envelope. Vendor-level error codes belong here: throw
	// errors.upstream(msg) to classify the failure as upstream once for the
	// whole system.
	Response string `json:"response,omitempty"`
}

OutboundEnvelopeConfig holds a system's envelope scripts: the common wire structure most external APIs repeat on every endpoint ({code, msg, data} responses, signed request wrappers, SOAP envelopes) is wrapped and unwrapped once at the system level instead of in every adapter. Either script may be empty, leaving that side untouched (save-time validation requires at least one); adapters bypass both per call with the { envelope: false } request option (deviant endpoints such as file downloads or health checks).

type Result

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

Result is the validated outcome of an invocation.

func NewResult

func NewResult(output any, system string, duration time.Duration, cached bool) *Result

NewResult assembles a Result. It exists for the framework's Invoker implementation; applications only read Results.

func (*Result) Cached

func (r *Result) Cached() bool

Cached reports whether the output came from the response cache.

func (*Result) Decode

func (r *Result) Decode(v any) error

Decode unmarshals the output into v through a JSON round-trip.

func (*Result) Duration

func (r *Result) Duration() time.Duration

Duration returns the wall time of the invocation.

func (*Result) Output

func (r *Result) Output() any

Output returns the standard model the adapter script produced, already validated against the contract's output schema.

func (*Result) System

func (r *Result) System() string

System returns the code of the system that served the invocation.

type RetryPolicy

type RetryPolicy struct {
	// MaxAttempts is the total number of attempts, the first call included.
	MaxAttempts int `json:"maxAttempts"`
	// InitialBackoffMs is the base delay before the first retry; zero applies
	// the httpx default.
	InitialBackoffMs int64 `json:"initialBackoffMs,omitempty"`
	// MaxBackoffMs caps the delay between attempts; zero applies the httpx
	// default.
	MaxBackoffMs int64 `json:"maxBackoffMs,omitempty"`
}

RetryPolicy is the declarative retry configuration for a system's outbound calls. It rides on the httpx default retry policy: idempotent methods only, retried on transport errors and 429/502/503/504 responses.

type Route

type Route struct {
	orm.BaseModel `bun:"table:itg_route,alias:irt"`
	orm.FullAuditedModel

	RouteKey   string `json:"routeKey" bun:"route_key"`
	ContractID string `json:"contractId" bun:"contract_id"`
	SystemID   string `json:"systemId" bun:"system_id"`
	IsEnabled  bool   `json:"isEnabled" bun:"is_enabled"`
}

Route maps a route key (tenant, branch, hospital area) to the system serving a contract. ContractID scopes the rule to one contract, empty applies to every contract; a row with an empty RouteKey is the default route. Exact (key, contract) matches win over contract-wildcard matches.

type RouteDiagnostics

type RouteDiagnostics struct {
	Findings []RouteFinding `json:"findings"`
}

RouteDiagnostics is the point-in-time report of the routing table's configuration gaps. It is computed on demand — a diagnostic pull, not a background monitor.

type RouteFinding

type RouteFinding struct {
	Kind         RouteFindingKind `json:"kind"`
	RouteID      string           `json:"routeId,omitempty"`
	RouteKey     string           `json:"routeKey"`
	ContractCode string           `json:"contractCode,omitempty"`
	ContractName string           `json:"contractName,omitempty"`
	SystemCode   string           `json:"systemCode,omitempty"`
	SystemName   string           `json:"systemName,omitempty"`
}

RouteFinding is one diagnostic finding. RouteKey is always meaningful ("" is the default route); the entity references identify the involved route, contract, and system by code and display name so a UI needs no extra lookups.

type RouteFindingKind

type RouteFindingKind string

RouteFindingKind classifies one routing diagnostic finding. Like FailureKind it is a typed vocabulary shared with management UIs, which render and translate findings by kind — extend it consciously and keep the React side in lockstep.

const (
	// RouteFindingDanglingAdapter marks a contract-scoped route whose target
	// system has no enabled adapter for that contract: invoking the contract
	// through this rule fails with ErrAdapterNotFound.
	RouteFindingDanglingAdapter RouteFindingKind = "dangling_adapter"
	// RouteFindingWildcardGap marks an enabled contract a wildcard (or
	// default) route cannot serve because its target system has no enabled
	// adapter for it. Informational: not every contract is invoked through
	// every key.
	RouteFindingWildcardGap RouteFindingKind = "wildcard_gap"
	// RouteFindingDisabledSystem marks an enabled route targeting a disabled
	// system: invocations through it fail with ErrSystemDisabled.
	RouteFindingDisabledSystem RouteFindingKind = "disabled_system"
	// RouteFindingDisabledContract marks an enabled route scoped to a
	// disabled contract: the rule can never match a successful invocation.
	RouteFindingDisabledContract RouteFindingKind = "disabled_contract"
	// RouteFindingUncoveredContract marks an enabled contract that resolves
	// to no rule under a route key present in the routing table: invoking it
	// with that key fails with ErrRouteNotFound. Informational when the key
	// intentionally routes a subset of contracts.
	RouteFindingUncoveredContract RouteFindingKind = "uncovered_contract"
)

type RouteResolver

type RouteResolver interface {
	// Resolve returns the code of the system serving contract for routeKey.
	// A key matching no rule fails with ErrRouteNotFound.
	Resolve(ctx context.Context, contract, routeKey string) (string, error)
}

RouteResolver maps a route key (tenant, branch, hospital area) to the code of the system that should serve a contract. The framework default resolves through the itg_route table — exact (key, contract) rules win over contract-wildcard rules, and the empty key is the default route; replace it via fx.Decorate when routing lives elsewhere (a tenant registry, a config center).

type StatsInspector

type StatsInspector interface {
	// Stats returns a snapshot of invocation statistics, one entry per
	// (system, contract, direction) tuple observed since process start,
	// ordered by system, contract, then direction.
	Stats() []InvocationStats
}

StatsInspector exposes per-node invocation statistics. The monitor module consumes it as an optional dependency (absent when the integration module is not enabled), mirroring event.StreamInspector.

type System

type System struct {
	orm.BaseModel `bun:"table:itg_system,alias:isy"`
	orm.FullAuditedModel

	Code    string `json:"code" bun:"code"`
	Name    string `json:"name" bun:"name"`
	BaseURL string `json:"baseUrl" bun:"base_url"`
	// OutboundAuth selects how the framework authenticates against this
	// system's HTTP endpoints; nil sends requests unauthenticated.
	OutboundAuth *OutboundAuthConfig `json:"outboundAuth" bun:"outbound_auth,type:jsonb,nullzero"`
	// OutboundEnvelope wraps every outbound HTTP call of the system in its
	// common wire structure, so adapter scripts translate business payloads
	// only; nil sends adapter requests untouched.
	OutboundEnvelope *OutboundEnvelopeConfig `json:"outboundEnvelope" bun:"outbound_envelope,type:jsonb,nullzero"`
	// InboundAuth selects how calls arriving on this system's inbound
	// endpoints are proven to originate from the system itself; a system
	// without it refuses inbound delivery entirely (fail closed — the "none"
	// scheme opens it up deliberately).
	InboundAuth *InboundAuthConfig `json:"inboundAuth" bun:"inbound_auth,type:jsonb,nullzero"`
	// DataSource is the system's direct database connection (external views /
	// exchange tables). Its password is stored encrypted and masked in
	// management API responses.
	DataSource *DataSourceConfig `json:"dataSource" bun:"data_source,type:jsonb,nullzero"`
	// Params are non-sensitive, system-specific values (branch codes,
	// version flags) exposed to adapter scripts as system.params.
	Params map[string]string `json:"params" bun:"params,type:jsonb,nullzero"`
	// TimeoutMs bounds each HTTP call against the system; zero applies the
	// framework default.
	TimeoutMs int          `json:"timeoutMs" bun:"timeout_ms"`
	Retry     *RetryPolicy `json:"retry" bun:"retry,type:jsonb,nullzero"`
	IsEnabled bool         `json:"isEnabled" bun:"is_enabled"`
}

System is one external system instance: where it lives and how to authenticate against it. BaseURL enables the scoped http library, DataSource enables the scoped sql library (read-only unless its Mode says otherwise); a system may carry both. Connection-level settings (TimeoutMs, Retry) bound every HTTP call its adapters make.

Jump to

Keyboard shortcuts

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