Runtime contracts
Low-level policy, result, adapter and pipeline APIs for custom runtimes and third-party adapters.
Most apps should use defineAdmin, createFlowpanel, and the generated UI.
This page documents the lower-level @flowpanel/core contracts for adapter
authors, custom framework integrations and security-sensitive extensions.
import {
accessAllows,
assertWritableInput,
authorizeOperation,
bindAdapterScope,
resolveScopeApplier,
errorResult,
filterReadableProjection,
reportUnexpectedError,
resolveOperationAccess,
resultResponse,
FLOWPANEL_ERROR_STATUS,
type AccessContext,
type AccessRule,
type AdminDefinition,
type AdminPaths,
type AdminPathsInput,
type AnyResourceConfig,
type AdapterScopeContext,
type BoundAdapterScope,
type ErrorContext,
type FieldAccess,
type FieldAccessMap,
type FieldWriteContext,
type FlowpanelErrorCode,
type FlowpanelResult,
type FlowpanelResultError,
type FlowpanelResultMeta,
type FlowpanelWarning,
type FlowpanelWarningCode,
type JsonValue,
type ResourceAccess,
type ResourceOperation,
} from "@flowpanel/core";Definitions and paths
AdminDefinition<Resources> is the immutable public input accepted by
defineAdmin; AnyResourceConfig is its generic resource constraint.
AdminPathsInput is the partial { admin, api } input and AdminPaths is the
normalized resolved pair. Both paths have a leading slash and no trailing
slash.
Application code normally relies on inference and never writes these types explicitly. They are useful when a factory returns a definition:
function companyAdmin(): AdminDefinition {
return {
adapter,
auth,
paths: { admin: "/ops", api: "/api/ops" },
};
}Access and field policy
AccessRule is a boolean, role string, role list, or predicate receiving
AccessContext (session, role, scope). ResourceAccess maps those rules
to the four ResourceOperation values: read, create, update, delete.
accessAllows(rule, context)evaluates one normalized rule.resolveOperationAccess(access, requireRole, operation)applies precedence: the operation-specific rule wins, then the compatibilityrequireRole.authorizeOperation(rule, context)throws the safe access error when the resolved rule rejects the request.
FieldAccess<Row> adds read, write and sensitive policy. A
FieldAccessMap<Row> maps it by field name; write predicates receive
FieldWriteContext<Row> with both the current row and submitted input.
filterReadableProjection(fields, policy, context)removes fields the caller may not read before the adapter query is built.assertWritableInput(input, knownFields, policy, context)rejects unknown, sensitive or forbidden writes. It does not silently drop them.
Bound adapter scope
A tenant policy crosses the runtime/adapter boundary as an opaque
BoundAdapterScope. Create it with bindAdapterScope(apply). Adapters must
apply it to list, get, update and delete operations and fail closed when a
resource requires scope but no binding is present.
resolveScopeApplier(ctx) is that fail-closed rule, shared by the first-party
adapters: it returns the bound predicate, null when the resource declares
none, and throws FlowpanelAccessError when one is required but missing. An
adapter that resolves scope by hand must refuse the query in the same case.
Post-commit effects
Post-commit audit, realtime or revalidation failures do not turn a committed
mutation into a false failure. They appear as a FlowpanelWarning in result
metadata; FlowpanelWarningCode is audit_failed, realtime_failed, or
revalidation_failed.
Result envelope
Every protected controller and v1 JSON CRUD endpoint returns
FlowpanelResult<T>:
type FlowpanelResult<T> =
| { ok: true; data: T; meta: FlowpanelResultMeta }
| { ok: false; error: FlowpanelResultError };FlowpanelResultMeta carries the request id and optional warnings.
FlowpanelResultError carries a stable FlowpanelErrorCode, a safe message,
optional field errors and request id. FLOWPANEL_ERROR_STATUS is the canonical
code-to-HTTP-status table.
errorResult(error, requestId)converts known errors to the envelope and redacts unexpected failures tointernal.resultResponse(result)produces a JSONResponsewith the canonical status.reportUnexpectedError(error, context, onError)invokeshooks.onErrorat most once for the same error object.ErrorContextincludes request, operation, actor, IP and user-agent diagnostics but no submitted secrets.
These helpers are public for runtime authors. Ordinary actions should throw a
documented FlowPanel error or return an ActionResult, then let the built-in
runtime normalize it.
Generated-UI form, drawer, action, import, restore and SSE routes predate the
v1 client protocol and keep their compact, route-specific response shapes for
compatibility. Use createFlowpanelClient or protected controllers when a
custom surface needs the structured envelope above.