Skip to main content

Approval API Reference

Everything exported from the root of @vef-framework-react/approval, grouped as in the source: permissions, plugins, API hooks, runtime components, types, and re-exports. Page components and their props are covered in Pages.

QueryFunction<TData, TParams> and MutationFunction<TData, TParams> are the framework's keyed function shapes from @vef-framework-react/core (each carries a stable .key for TanStack Query). PaginatedQueryParams<TSearch> is the ProTable query shape from @vef-framework-react/components (search fields plus symbol-keyed pagination). ApiResult<T> is the standard response envelope.

Permissions​

APPROVAL_PERMISSIONS​

const — permission codes for the approval engine management API, mirroring the backend RequiredPermission strings verbatim. Every management page defaults its gates to the matching entry and accepts overrides through its permissions prop. The self-service approval/my resource carries no codes — its operations are user-scoped server-side. See Permissions for the general model.

Group.keyCodeGates
category.queryapproval.category.queryCategory tree query
category.createapproval.category.createCreate category
category.updateapproval.category.updateUpdate category
category.deleteapproval.category.deleteDelete category
flow.queryapproval.flow.queryFlow list / versions / graph / initiators queries
flow.createapproval.flow.createCreate flow
flow.updateapproval.flow.updateUpdate flow, toggle activation
flow.deployapproval.flow.deployDeploy a designed definition as a new draft version
flow.publishapproval.flow.publishPublish a draft version
instance.queryapproval.instance.queryAdmin cross-user instance list
instance.detailapproval.instance.detailAdmin instance detail (incl. action logs)
instance.startapproval.instance.startStart instance (self-service start is additionally initiator-gated)
instance.withdrawapproval.instance.withdrawWithdraw a running instance
instance.resubmitapproval.instance.resubmitResubmit a returned instance
instance.ccapproval.instance.ccAdd carbon copies
instance.terminateapproval.instance.terminateAdmin terminate
task.queryapproval.task.queryAdmin cross-user task list
task.processapproval.task.processProcess a task (approve / reject / transfer / rollback / handle)
task.addAssigneeapproval.task.add_assigneeAdd assignees to a task
task.removeAssigneeapproval.task.remove_assigneeRemove a peer assignee's task
task.urgeapproval.task.urgeUrge a pending task
task.reassignapproval.task.reassignAdmin reassign
actionLog.queryapproval.action_log.queryAudit-trail query
metrics.queryapproval.metrics.queryEngine metrics
binding.queryapproval.binding.queryBusiness-projection list
binding.retryapproval.binding.retryRetry a failed projection
delegation.queryapproval.delegation.queryDelegation list
delegation.createapproval.delegation.createCreate delegation
delegation.updateapproval.delegation.updateUpdate delegation
delegation.deleteapproval.delegation.deleteDelete delegation

Type exports: ApprovalPermissions (typeof APPROVAL_PERMISSIONS) and one alias per group — CategoryPermissionCodes, FlowPermissionCodes, InstancePermissionCodes, TaskPermissionCodes, ActionLogPermissionCodes, MetricsPermissionCodes, BindingPermissionCodes, DelegationPermissionCodes (each ApprovalPermissions["<group>"]).

Plugins and provider​

ApprovalPlugins​

Host-integration points shared by every approval page and component. Wrap the approval routes in one ApprovalProvider and every picker, registry, and renderer below is resolved from it — pages never take these as props.

FieldTypeDefaultDescription
pickersPartial<Record<string, FC<PickerProps>>>—Pickers that resolve concrete ids, keyed by rule kind. Lookup falls back to the kind's selection mode, so the built-in user / role / department pickers also serve custom kinds that select the same thing. A kind left unset degrades to a plain id-tags input.
tenantsTenantOption[]—The tenants a shared flow's rules can pick people from, each { value, label }. A shared flow is offered to every tenant and routes work to people of other tenants than the one that starts it, so the designer picks a tenant first and hands it to the user / department picker as PickerProps.tenantId; roles and host catalogs are not per tenant. Without it a shared flow picks people through the plain pickers.
registriesDeviceRegistriescreateApprovalRegistries()Form field registries for rendering and designing approval forms. Defaults to the approval profile from approval-form-bridge, which excludes the field types the backend parser rejects.
globalSubjectsFormFieldDefinition[]—Host-defined global subjects the flow designer's condition editor offers alongside the built-in applicant attributes — resolved server-side from Instance.Globals at instance start.
formGlobalsFormGlobalDefinition[]—The host globals the backend exposes to approval forms (its globals resolver implementing FormGlobalsExposer), declared so the form designer offers them as $globals.<key> system variables beside the built-in $applicant attributes. Keep the keys in lockstep with the resolver's FormGlobalKeys — see Form system variables.
dataSourceResolverDataSourceResolver—Resolves a form's remote data-source requests into options, in every form render and in the form designer's preview; without it every remote source in an approval form resolves to an empty list.
dataSourceApisDataSourceApi[]—The host's catalog of option APIs: the form designer's remote data sources lead with a picker over it instead of a hand-typed endpoint and field mapping. A pick is stored as the request itself, so dataSourceResolver must serve every endpoint listed — see Offering an API catalog.
codeSetsCodeSetDescriptor[]—The host's catalog of data dictionaries: the form designer's 数据字典 option source offers a searchable picker over it instead of a typed key. A pick stores the key alone; forms load their dictionaries through the application's AppContext.codeSetQueryFn, which must serve every key listed — see Data dictionaries.
evaluatorsLinkageEvaluatorsbuilt-in JavaScript evaluatorOverrides expression / script evaluation for form linkage and bound data-source parameters (the built-in one has $form / $vars / $applicant / $globals in scope), and supplies dispatchEffect for alert / api_call / navigate.
renderBusinessRef(businessRef: string) => ReactNodeplain textRenders an instance's opaque business reference as a host-navigable element (a link to the business record, a drawer trigger, …).

ApprovalProviderProps​

PropTypeDefaultDescription
pluginsApprovalPlugins—The plugin set to provide. Optional: without it every point falls back to its default.
childrenReactNode—Subtree that resolves the plugins.

ApprovalProvider​

(props: ApprovalProviderProps) => JSX.Element — provides the approval plugin set to every page and component beneath it. The default form registries are created once per mount (registries are stateful class instances, so the context value never churns field registrations across re-renders); pass registries to override them wholesale.

ResolvedApprovalPlugins​

interface ResolvedApprovalPlugins extends ApprovalPlugins { registries: DeviceRegistries } — the plugin set after defaulting: registries are always present.

useApprovalPlugins​

() => ResolvedApprovalPlugins — resolves the approval plugin set. Usable without a provider — every integration point then falls back to its built-in default (fresh default registries per mount, no pickers, no global subjects, plain-text business refs).

toEditorPlugins​

(plugins: ResolvedApprovalPlugins, formFields: FormFieldDefinition[], kindOptions?: KindOptions) => EditorPlugins — projects the approval plugin set into the flow designer's EditorPlugins shape (pickers, globalSubjects), layers the deploy-derived formFields on top, and passes the application's kind catalog (kindOptions.assignees / kindOptions.ccs, from approval/flow.list_kind_options) as assigneeKinds / ccKinds; while it is still loading the editor falls back to its built-in kinds.

FormGlobalDefinition​

interface FormGlobalDefinition { key: string; label: string } — one host global an approval form may read: key exactly as the host's globals resolver produces it, label its display name in the designer (e.g. "聘任职称"). The value comes from the backend, which ships only the keys its resolver names through FormGlobalsExposer.

API hooks​

All hooks memoize their function set per ApiClient and post to API_PATH with createApiRequest(resource, operation, params) envelopes.

Query plumbing​

ExportSignatureDescription
API_PATHconst "/api"The framework RPC endpoint every approval call posts to.
toPagedParams<TSearch extends AnyObject>(queryParams: PaginatedQueryParams<TSearch>) => Omit<PaginatedQueryParams<TSearch>, typeof SYMBOL_PAGINATION> & { page?: number; pageSize?: number }Folds ProTable's symbol-keyed pagination into the flat page / pageSize request shape the approval RPC queries expect. The sort symbol stays on the spread copy; JSON serialization drops it.

useCategoryApi​

() => CategoryApi — CRUD API for the flow-category tree (approval/category), shaped to plug straight into a non-paginated CrudPage (see Crud).

FunctionTypeOperation
findTreeQueryFunction<FlowCategory[], QueryParams<CategorySearch>>find_tree — returns the nested tree (children)
createMutationFunction<ApiResult<unknown>, CategoryParams>create
updateMutationFunction<ApiResult<unknown>, CategoryParams>update
removeMutationFunction<ApiResult<unknown>, FlowCategory>delete — sends { id: row.id }

useFlowApi​

() => FlowApi — management API for flow definitions (approval/flow): the paginated list plus the definition lifecycle (create → deploy → publish) and its auxiliary queries. Mutations return the created/updated records so callers can chain the lifecycle (e.g. create → deploy with the returned flow id).

FunctionTypeOperation
findFlowsQueryFunction<PaginationResult<Flow>, PaginatedQueryParams<FlowSearch>>find_flows (paged via toPagedParams)
createMutationFunction<Flow, CreateFlowParams>create — returns the created Flow
updateMutationFunction<Flow, UpdateFlowParams>update — returns the updated Flow
deployMutationFunction<FlowVersion, DeployFlowParams>deploy — returns the new draft FlowVersion
publishVersionMutationFunction<unknown, PublishVersionParams>publish_version
toggleActiveMutationFunction<unknown, ToggleFlowActiveParams>toggle_active
getGraphQueryFunction<FlowGraphBundle, { flowId: string; versionId?: string }>get_graph — the latest published version by default, or the version named by versionId (the designer's edit seed)
findVersionsQueryFunction<FlowVersionSummary[], { flowId: string }>find_versions — slim summaries without definition payloads (v2.12.0 breaking change 40b6714)
findInitiatorsQueryFunction<FlowInitiator[], { flowId: string }>find_initiators
listKindOptionsQueryFunction<KindOptions, Record<string, never>>list_kind_options — the application's assignee / CC / initiator kind catalog, application-wide rather than per flow; the flow designer fetches it once for its initiator editor and its flow editor (v2.18.0)

useDelegationApi​

() => DelegationApi — CRUD API for approval delegations (approval/delegation). The list is served by the framework's standard find_page, which reads pagination from the request meta.

FunctionTypeOperation
findPageQueryFunction<PaginationResult<Delegation>, PaginatedQueryParams<DelegationSearch>>find_page
createMutationFunction<ApiResult<unknown>, DelegationParams>create
updateMutationFunction<ApiResult<unknown>, DelegationParams>update
removeMutationFunction<ApiResult<unknown>, Delegation>delete — sends { id: row.id }

useInstanceApi​

() => InstanceApi — runtime action API for approval instances and tasks (approval/instance): submission, the per-task decision, and the participant side actions. Each is a mutation triggered imperatively from the detail views.

FunctionTypeOperation
startMutationFunction<unknown, StartInstanceParams>start
processTaskMutationFunction<unknown, ProcessTaskParams>process_task — bundles approve / reject / transfer / rollback / handle
withdrawMutationFunction<unknown, WithdrawInstanceParams>withdraw
resubmitMutationFunction<unknown, ResubmitInstanceParams>resubmit
addCCMutationFunction<unknown, AddCCParams>add_cc
markCCReadMutationFunction<unknown, MarkCCReadParams>mark_cc_read
addAssigneeMutationFunction<unknown, AddAssigneeParams>add_assignee
removeAssigneeMutationFunction<unknown, RemoveAssigneeParams>remove_assignee
urgeTaskMutationFunction<unknown, UrgeTaskParams>urge_task

useMyApprovalApi​

() => MyApprovalApi — self-service API for the current user's approval work (approval/my): what I can initiate, what I submitted, what awaits me, and the per-instance detail. All operations are user-scoped server-side and carry no permission codes.

FunctionTypeOperation
findAvailableFlowsQueryFunction<PaginationResult<AvailableFlow>, PaginatedQueryParams<AvailableFlowSearch>>find_available_flows
getStartFormQueryFunction<StartForm, { flowCode: string }>get_start_form — gated exactly like starting the instance, in the tenant the caller acts in; carries the applicant and the form-visible globals the instance would record
findInitiatedQueryFunction<PaginationResult<InitiatedInstance>, PaginatedQueryParams<InitiatedInstanceSearch>>find_initiated
findPendingTasksQueryFunction<PaginationResult<PendingTask>, PaginatedQueryParams<PendingTaskSearch>>find_pending_tasks
findCompletedTasksQueryFunction<PaginationResult<CompletedTask>, PaginatedQueryParams<CompletedTaskSearch>>find_completed_tasks
findCCRecordsQueryFunction<PaginationResult<MyCCRecord>, PaginatedQueryParams<MyCCRecordSearch>>find_cc_records
getPendingCountsQueryFunction<PendingCounts, Record<string, never>>get_pending_counts
getInstanceDetailQueryFunction<MyInstanceDetail, { instanceId: string }>get_instance_detail

useAdminApprovalApi​

() => AdminApprovalApi — supervision API for approval administrators (approval/admin): cross-user instance/task queries, the audit trail, engine metrics, business-projection convergence, and the admin write actions.

FunctionTypeOperation
findInstancesQueryFunction<PaginationResult<AdminInstance>, PaginatedQueryParams<AdminInstanceSearch>>find_instances
findTasksQueryFunction<PaginationResult<AdminTask>, PaginatedQueryParams<AdminTaskSearch>>find_tasks
getInstanceDetailQueryFunction<AdminInstanceDetail, { instanceId: string }>get_instance_detail
findActionLogsQueryFunction<PaginationResult<AdminActionLog>, PaginatedQueryParams<{ instanceId: string; tenantId?: string }>>find_action_logs
getMetricsQueryFunction<ApprovalMetrics, { tenantId?: string }>get_metrics
findBusinessProjectionsQueryFunction<PaginationResult<AdminBusinessProjection>, PaginatedQueryParams<AdminBusinessProjectionSearch>>find_business_projections
terminateInstanceMutationFunction<unknown, TerminateInstanceParams>terminate_instance
reassignTaskMutationFunction<unknown, ReassignTaskParams>reassign_task
retryBusinessProjectionMutationFunction<unknown, RetryBusinessProjectionParams>retry_business_projection

Runtime components​

Presentation and detail building blocks, all reading plugins from context where relevant. Each component's props interface is exported under the <Component>Props name (InstanceDetailDrawerProps, InstanceDetailPanelProps, AdminInstanceDetailPanelProps, InstanceFormPanelProps, InstanceTimelineProps, InstanceFlowGraphViewerProps, PrincipalSelectProps, UserLabelProps, UserGroupProps) with exactly the fields tabled below.

InstanceDetailDrawer​

The self-service instance detail in a wide (880px) drawer — the standard container every runtime list page opens on row click.

PropTypeDefaultDescription
instanceIdstring | null—The instance to show; null keeps the drawer closed.
onClose() => void—Close handler.
onActionCompleted() => void—Fired after any successful action inside the detail, so the surrounding list can refetch.

InstanceDetailPanel​

The self-service instance detail body: header, the version-pinned form clamped by the viewer's field permissions, the transit timeline, and the progress flow graph — with the action bar derived entirely from the server-resolved availableActions / myTask context, so the offered set can never drift from what the engine accepts. Uses approval/my.get_instance_detail plus the useInstanceApi actions; the panel refetches its own detail after every action.

PropTypeDefaultDescription
instanceIdstring—The instance to show.
onActionCompleted() => void—Fired after any successful action so the surrounding list can refetch.

AdminInstanceDetailPanel​

The supervision detail of an instance: the same header / form / timeline / graph projections as the self-service view — but fully read-only, with no field-permission clamp (admins see every field) — plus the paginated raw audit trail (approval/admin.find_action_logs). Admin write actions (terminate, reassign) live on the admin page rows, not in this panel.

PropTypeDefaultDescription
instanceIdstring—The instance to inspect (via approval/admin.get_instance_detail).

InstanceHeader​

The shared instance header: title + status tag, then the identity fields as one descriptions block (审批单号 with copy, 所属流程, 流程编码, 申请人, 提交时间, plus 当前节点 / 完成时间 / 业务单据 / 流程标签 when present). businessRef renders through the provider's renderBusinessRef. Pass labels on operator-facing views (the admin detail) and omit it on applicant-facing ones.

PropTypeDefaultDescription
titlestring—Instance title.
statusInstanceStatus—Lifecycle status (rendered as InstanceStatusTag).
instanceNostring—Business-facing instance number (copyable).
flowNamestring—Owning flow's name.
flowCodestring—Owning flow's stable code (copyable).
applicantUserInfo—Applicant snapshot.
createdAtstring—Submission time.
finishedAtstring—Completion time (omitted while running).
currentNodeNamestring—Current node display name.
businessRefstring—Opaque business reference.
labelsRecord<string, string>—The flow's host-owned selection metadata.

InstanceFormPanel​

The instance form, rendered against the version-pinned schema with the viewer's field permissions clamped on: hidden unmounts, visible renders read-only, editable/required grant write strength. Field registries, the data-source resolver, and the evaluators come from ApprovalProvider; the applicant and the form-visible globals form its evaluation context, as $applicant and $globals — never $user, since the form is evaluated for every participant. Renders an empty state ("该流程未配置表单") for flows without a form.

PropTypeDefaultDescription
schemaFormSchema—The version-pinned host form-designer document; absent for flows without a form.
formDataFormData—The instance's form data (already stripped server-side of fields this viewer may not see).
fieldPermissionsRecord<string, FieldPermission>—The server-resolved per-field interactivity clamp, applied verbatim.
applicantUserInfo—The form's $applicant: the snapshot the instance is about to record on the start form, the instance's own everywhere else.
globalsRecord<string, unknown>—The form's $globals: the host globals the flow exposes to its form.
disabledboolean—Force the whole form read-only (viewers with nothing to execute).
devicePresentationDevice"pc"Presentation device profile.
apiRefRefObject<FormRendererApi | null>—Imperative handle: submit() runs the renderer's validation + submit pipeline, getSubmitValues() reads the writable subset without validating (the reject path).
onSubmit(values: Record<string, unknown>) => void—Fired with validated values.

InstanceTimeline​

The chronological transit record of an instance: one entry per traversed node (a rollback redo produces a second entry) plus the withdraw/terminate milestones. Participants, carbon copies, and side activities render beneath each node header.

PropTypeDefaultDescription
timelineTimelineEntry[]—The server-projected timeline. Empty renders an empty state.

InstanceFlowGraphViewer​

The read-only, progress-annotated map of an instance's flow: node positions come from the designer verbatim, progress colors the borders (blue = in motion, green = passed, red = rejected, orange = returned) and dashes the outline of everything the instance never reached, and the people involved float above each node they touched. Pan and zoom only — nothing is editable.

PropTypeDefaultDescription
flowGraphInstanceFlowGraph—The server-projected graph.
heightnumber | string420Container height; the viewer always fills its width.

PrincipalSelect​

A principal selection field: renders the host's picker from ApprovalProvider when one is wired for the rule's kind or its selection mode, else degrades to a plain id-tags input so the surrounding dialog stays functional.

PropTypeDefaultDescription
kindstring—The rule's kind; the first picker lookup key.
selectionSelectionMode—What the kind selects; the fallback picker lookup key.
valuestring[]—Selected ids.
onChange(ids: string[]) => void—Selection handler.
disabledboolean—Disable the field.
maxCountnumber—Cap the selection at this many entries (enforced on change).

UserLabel and UserGroup​

UserLabel renders a person snapshot as avatar + name (deterministic avatar hue per user id), with the department surfaced in the tooltip; it renders the id when the name is empty — the backend returns missing users with an empty name rather than omitting them. UserGroup renders a compact list, collapsing the overflow into a +N avatar whose tooltip lists the hidden names.

ComponentPropTypeDefaultDescription
UserLabeluserUserInfo—The person snapshot.
UserLabelshowAvatarbooleantrueRender the avatar in front of the name.
UserLabelavatarSizenumber22Avatar size in pixels.
UserGroupusersUserInfo[]—The snapshots to render (empty renders a dash).
UserGroupmaxCountnumber5Collapse into +N beyond this count.
UserGroupavatarSizenumber22Avatar size in pixels.

Status tags​

Each renders one vocabulary value as a colored tag:

ComponentPropsVocabulary
InstanceStatusTag{ status: InstanceStatus }Instance lifecycle
TaskStatusTag{ status: TaskStatus | string }Task lifecycle (an unknown string renders as a plain tag with the raw value)
NodeProgressTag{ status: NodeProgressStatus }Node progress in the flow graph
VersionStatusTag{ status: VersionStatus }Flow version lifecycle
ProjectionStatusTag{ status: BindingProjectionStatus }Business-projection convergence

Label and color constants​

Display labels (framework default language) and tag colors, each map total over its union so a missing entry is a type error when the backend vocabulary grows:

ExportType
INSTANCE_STATUS_LABELS / INSTANCE_STATUS_COLORSRecord<InstanceStatus, string>
TASK_STATUS_LABELS / TASK_STATUS_COLORSRecord<TaskStatus, string>
NODE_PROGRESS_LABELS / NODE_PROGRESS_COLORSRecord<NodeProgressStatus, string>
VERSION_STATUS_LABELS / VERSION_STATUS_COLORSRecord<VersionStatus, string>
BINDING_PROJECTION_STATUS_LABELS / BINDING_PROJECTION_STATUS_COLORSRecord<BindingProjectionStatus, string>
ACTIVITY_ACTION_LABELSRecord<ActivityAction, string>
PROCESS_TASK_ACTION_LABELSRecord<ProcessTaskAction, string>
INSTANCE_STATUS_OPTIONS / TASK_STATUS_OPTIONS / BINDING_PROJECTION_STATUS_OPTIONSArray<{ label: string; value: … }> — ready-made select options

Formatters​

ExportSignatureDescription
formatTimestamp(value?: string | null) => stringFormats a backend timestamp (YYYY-MM-DD HH:mm:ss) as YYYY-MM-DD HH:mm, or a dash when empty.
formatDurationSeconds(seconds: number) => stringCompact human span (3天2小时, 45分钟); sub-minute renders <1分钟, negative renders a dash.

UrgeTarget​

interface UrgeTarget { taskId: string; assigneeName: string; nodeName: string } — one pending task that can be urged (type-only export backing the urge dialog).

Types​

All wire types mirror the Go contracts. Timestamps are backend-formatted strings.

Shared base​

TypeShapeNotes
FullAudited{ id: string; createdAt?: string; createdBy?: string; updatedAt?: string; updatedBy?: string }Mirrors the Go orm.FullAuditedModel embed.
UserInfo{ id: string; name: string; departmentId?: string; departmentName?: string }A person snapshot captured at action time — the single person shape every approval projection uses. Department fields present only when the host's UserInfoResolver fills them.
FormDataValuestring | number | boolean | null | FormDataValue[] | { [key: string]: FormDataValue }Form data as submitted/stored.
FormDataRecord<string, FormDataValue>The runtime form-data map of an instance.

Enums and unions​

TypeValuesNotes
InstanceStatus"running" | "approved" | "rejected" | "withdrawn" | "returned" | "terminated"Instance lifecycle.
FINAL_INSTANCE_STATUSES["approved", "rejected", "terminated"] as constThe statuses that are final.
isFinalInstanceStatus(status: InstanceStatus) => booleanMirrors InstanceStatus.IsFinal.
TaskStatus"waiting" | "pending" | "approved" | "rejected" | "handled" | "transferred" | "rolled_back" | "canceled" | "removed" | "skipped"Task lifecycle.
NodeVisitStatus"active" | "passed" | "rejected" | "returned" | "canceled"One node traversal (visit) by an instance.
NodeProgressStatus"pending" | "active" | "passed" | "rejected" | "returned" | "canceled"Node progress in the graph projection.
ActionType"submit" | "approve" | "handle" | "reject" | "transfer" | "withdraw" | "cancel" | "rollback" | "add_assignee" | "remove_assignee" | "execute" | "resubmit" | "reassign" | "terminate" | "add_cc"Action-log vocabulary.
ActivityActionActionType | "urge"Timeline/graph activity vocabulary (urges are persisted as urge records, not action logs).
ProcessTaskAction"approve" | "reject" | "transfer" | "rollback" | "handle"Accepted by process_task.
AddAssigneeType"before" | "after" | "parallel"Position of a dynamically added assignee relative to the anchor task.
VersionStatus"draft" | "published" | "archived"Flow version status.
BindingMode"standalone" | "business"standalone stores form data in approval tables; business writes back into an existing business table.
StorageMode"json" | "table"Version-level physical storage of form data.
InitiatorKindstringKind of a flow initiator rule. Open by design (v2.18.0): the backend accepts every kind with a registered approval.InitiatorResolver, so the deployable kinds are the ones approval/flow.list_kind_options reports.
BUILTIN_INITIATOR_KINDSReadonlyArray<KindDescriptor<InitiatorKind>> — user (指定用户), role (指定角色), department (指定部门)The framework's own initiator kinds, offered before list_kind_options resolves. A deployment that registers kinds of its own reaches the designer only through the served catalog.
BindingProjectionStatus"pending" | "processing" | "applied" | "failed"Convergence of one business-record projection.
FieldPermission"visible" | "editable" | "hidden" | "required"Viewer-scoped field interactivity, matching the form renderer's vocabulary.
InstanceAction"approve" | "reject" | "handle" | "transfer" | "rollback" | "withdraw" | "resubmit" | "add_assignee" | "remove_assignee" | "add_cc" | "urge"The self-service actions my.get_instance_detail may offer, derived server-side from the state machine, the viewer's pending task, and node toggles.

Category​

TypeFieldsNotes
FlowCategoryextends FullAudited + tenantId: string, code: string, name: string, icon?: string | null, parentId?: string | null, sortOrder: number, isActive: boolean, remark?: string | null, children?: FlowCategory[]Categories form a tree via parentId; find_tree returns nested children.
CategoryParamsid?: string, tenantId: string, code: string, name: string, icon?: string | null, parentId?: string | null, sortOrder: number, isActive: boolean, remark?: string | nullCreate/update payload.
CategorySearchname?: string, isActive?: boolean, tenantId?: stringTree search, sent as the request's meta. tenantId narrows the tree to one tenant; every tenant's is read without it.

Delegation​

TypeFieldsNotes
Delegationextends FullAudited + delegatorId: string, delegateeId: string, flowCategoryId?: string | null, flowId?: string | null, startsAt: string, endsAt: string, isActive: boolean, reason?: string | nullDuring the active window, tasks assigned to the delegator are routed to the delegatee. Scope narrows via flowCategoryId / flowId; both empty means all flows.
DelegationParamssame fields plus id?: stringCreate/update payload.
DelegationSearchdelegatorId?: string, delegateeId?: string, isActive?: booleanList search.

Flow​

BusinessBindingConfig — business binding for a business-mode flow. All table/column names must be plain SQL identifiers; keyColumns must exactly match a complete, non-null primary or unique key on tableName.

FieldTypeDescription
tableNamestringBound business table.
keyColumnsstring[]The record key columns.
statusColumnstringColumn receiving the mapped instance status.
instanceIdColumnstring?Mandatory for business bindings: the engine uses it as a compare-and-set fence so a stale instance cannot overwrite the state owned by a newer approval round.
startedAtColumnstring?Optional started-at write-back column.
finishedAtColumnstring?Optional finished-at write-back column.
statusMappingPartial<Record<InstanceStatus, string>>?Translates instance statuses into host business status values; missing entries fall back to the instance-status string itself.

Flow — a flow definition record (extends FullAudited):

FieldTypeDescription
tenantIdstringOwning tenant, which manages the flow; never changes.
isSharedbooleanOffered to every tenant beside its own flows: any tenant starts it like one of its own, and a flow of that tenant with the same code takes its place there. A shared flow routes no task or CC to specific people. Fixed at creation.
categoryIdstringOwning category — a shared flow's too is one of its owner's.
codestringStable flow code (start requests address flows by code).
namestringDisplay name.
iconstring | null?Icon name.
descriptionstring | null?Description.
labelsRecord<string, string>?Host-owned selection metadata (e.g. which app a flow belongs to, mobile availability). Stored verbatim, equality-filterable; keys restricted server-side to ^[A-Za-z0-9]([A-Za-z0-9_-]*[A-Za-z0-9])?$ (≤63 chars), values to 256 characters.
bindingModeBindingModeStandalone vs business-bound.
businessBindingBusinessBindingConfig | null?Present for business-bound flows.
adminUserIdsstring[]Flow-level administrators.
isAllInitiationAllowedbooleanWhether everyone may initiate (else initiator rules apply).
instanceTitleTemplatestringTemplate used to render instance titles.
isActivebooleanWhether new instances may start.
currentVersionnumberThe currently published version number.

FlowVersion — a versioned snapshot (extends FullAudited): flowId: string, version: number, status: VersionStatus, description?: string | null, storageMode: StorageMode, flowSchema?: FlowDefinition | null, formSchema?: FormSchema | null (the host-owned form designer document, returned verbatim), formFields?: FormFieldDefinition[] | null (the flat field list derived from formSchema at deploy — the only form shape the framework itself consumes), publishedAt?: string | null, publishedBy?: string | null, businessBinding?: BusinessBindingConfig | null.

FlowVersionSummary — the version-list projection: identity and lifecycle metadata without the definition payloads (id, flowId, version, status, description?, storageMode, publishedAt?, publishedBy?, createdAt, createdBy). A single version's full definition is fetched through get_graph with an explicit versionId.

TypeFieldsNotes
FlowInitiatorid: string, flowId: string, kind: InitiatorKind, ids: string[]A stored initiator rule.
KindOptionsassignees: KindDescriptor<AssigneeKind>[], ccs: KindDescriptor<CcKind>[], initiators: KindDescriptor<InitiatorKind>[]The kinds the running application accepts, as served by approval/flow.list_kind_options. Each vocabulary is an open registry on the backend — a host adds a kind by registering a resolver — so this catalog, not a client-side union, is what the designer offers and what a deploy validates.
InitiatorParamskind: InitiatorKind, ids: string[]An initiator rule as submitted.
CreateFlowParamstenantId, code, name, categoryId (all string), isShared?: boolean, icon?, description? (string), labels?: Record<string, string>, bindingMode: BindingMode, businessBinding?: BusinessBindingConfig, adminUserIds?: string[], isAllInitiationAllowed: boolean, instanceTitleTemplate: string, initiators?: InitiatorParams[]approval/flow.create payload. isShared shares the flow with every tenant; its code must then be unique among every tenant's shared flows (40026).
UpdateFlowParamsflowId: string + the same fields as create minus tenantId/isShared/codeOmitted labels clears the stored set (full replace semantics).
DeployFlowParamsflowId: string, description?: string, storageMode?: StorageMode, flowDefinition: FlowDefinition, formSchema?: FormSchemaCreates a new draft version. formSchema is host-owned, passed through opaque and optional (flows without forms exist).
PublishVersionParamsversionId: stringpublish_version payload.
ToggleFlowActiveParamsflowId: string, isActive: booleantoggle_active payload.
FlowSearchtenantId?, categoryId?, keyword? (string), includeShared?, isActive?: boolean, labels?: Record<string, string>tenantId narrows the list to the flows one tenant owns, its shared ones included; every tenant's flows are listed without it. includeShared adds the other tenants' shared flows whose code tenantId has not taken — the flows a start by code finds there, for a picker of a tenant's usable flows. Label filters are equality predicates, AND-combined across pairs.
FlowGraphBundleflow: Flow | null, version: FlowVersion | nullget_graph result: the flow record and the resolved version (carrying flowSchema/formSchema).

Instance action params​

TypeFieldsNotes
StartInstanceParamsflowCode: string, businessRef?: string, formData?: Record<string, unknown>The instance runs in the tenant the caller acts in, from its own flow with the code or else the shared one. formData is validated server-side against the version's derived field list. businessRef is required by convention for business-bound flows unless the host's BusinessRefProvider derives one.
ProcessTaskParamstaskId: string, action: ProcessTaskAction, opinion?: string, formData?: Record<string, unknown>, attachments?: string[], transferToId?: string, targetNodeId?: stringtransferToId required for transfer; targetNodeId (a flow-node id) required for rollback.
WithdrawInstanceParamsinstanceId: string, reason?: string—
ResubmitInstanceParamsinstanceId: string, formData?: Record<string, unknown>—
AddCCParamsinstanceId: string, ccUserIds: string[]—
MarkCCReadParamsinstanceId: string—
AddAssigneeParamstaskId: string, userIds: string[], addType: AddAssigneeType—
RemoveAssigneeParamstaskId: stringTargets the peer task to remove.
UrgeTaskParamstaskId: string, message?: string—

Self-service (my) projections​

TypeFieldsNotes
AvailableFlowflowId, flowCode, flowName (string), flowIcon?, description? (string), labels?: Record<string, string>, categoryId: string, categoryName: stringA flow the current user may initiate.
StartFormflowId, flowCode, flowName (string), flowIcon?, description? (string), versionId: string, version: number, formSchema?: FormSchema, applicant: UserInfo, globals?: Record<string, unknown>The pre-submission view: identity plus the published version's host form document, returned verbatim. Loading it is gated exactly like starting. applicant is the snapshot the instance will record — the form's $applicant, resolved exactly as starting resolves it; globals are the host globals the flow exposes to its form, resolved for the caller (absent when it exposes none).
InitiatedInstanceinstanceId, instanceNo, title, flowName (string), flowIcon?: string, status: InstanceStatus, currentNodeName?: string, createdAt: string, finishedAt?: stringA submission of the current user.
PendingTasktaskId, instanceId, instanceTitle, instanceNo, flowName (string), flowIcon?: string, applicant: UserInfo, nodeName: string, createdAt: string, deadline?: string, isTimeout: booleanA task awaiting the current user.
CompletedTasktaskId, instanceId, instanceTitle, instanceNo, flowName (string), flowIcon?: string, applicant: UserInfo, nodeName: string, status: string, finishedAt?: stringA task the current user already processed.
MyCCRecordccRecordId, instanceId, instanceTitle, instanceNo, flowName (string), flowIcon?: string, applicant: UserInfo, nodeName?: string, isRead: boolean, createdAt: stringA CC notification addressed to the current user.
PendingCountspendingTaskCount: number, unreadCcCount: numberBadge counts.
MyInstanceInfoinstanceId, instanceNo, title, flowId (string), flowCode: string, flowName (string), flowIcon?: string, labels?: Record<string, string>, applicant: UserInfo, globals?: Record<string, unknown>, status: InstanceStatus, currentNodeId?, currentNodeName?, businessRef? (string), formData?: FormData, createdAt: string, finishedAt?: stringRuntime state within the detail. formData is already stripped of fields this viewer may not see; labels are read from the mutable flow at query time (display identity, not version-pinned); globals is the form-visible part of the instance's globals snapshot — the form's $globals as resolved at initiation, absent when the flow exposes none.
RollbackTargetnodeId: string, name: stringOne valid rollback destination, resolved server-side from the node's rollback config and the visit trail.
RemovableAssigneetaskId: string, assignee: UserInfo, status: stringOne peer task eligible for removal; status is the peer task's status verbatim (pending / waiting).
ViewerTasktaskId: string, nodeId: string, isOpinionRequired: boolean, addAssigneeTypes?: AddAssigneeType[], rollbackTargets?: RollbackTarget[], removableAssignees?: RemovableAssignee[]The viewer's pending task: what process_task should target plus the node-level action configuration — the client never re-derives engine semantics.
MyInstanceDetailinstance: MyInstanceInfo, formSchema?: FormSchema, timeline: TimelineEntry[], flowGraph: InstanceFlowGraph, availableActions: InstanceAction[], fieldPermissions?: Record<string, FieldPermission>, myTask?: ViewerTaskThe full self-service detail. fieldPermissions is materialized for every top-level form field — apply verbatim, no default resolution.
AvailableFlowSearchkeyword?: string, labels?: Record<string, string>—
InitiatedInstanceSearchstatus?: InstanceStatus, keyword?: string—
MyTaskSearchkeyword?: string, applicantId?: string, applicantName?: string, flowId?: stringThe filters both task queries share; every filter is optional and set filters AND together. keyword matches the instance title by substring, applicantId the applicant exactly (what a user picker yields), applicantName the applicant's name by substring.
PendingTaskSearchextends MyTaskSearch + isTimeout?: boolean, createdAtFrom?: string, createdAtTo?: stringfind_pending_tasks search. The arrival-time bounds are inclusive YYYY-MM-DD HH:mm:ss timestamps.
CompletedTaskSearchextends MyTaskSearch + status?: TaskStatus, instanceStatus?: InstanceStatus, finishedAtFrom?: string, finishedAtTo?: stringfind_completed_tasks search. status is how the caller finished the task, narrowing within the completed statuses; the finish-time bounds are inclusive YYYY-MM-DD HH:mm:ss timestamps.
MyCCRecordSearchisRead?: boolean—

Admin projections​

TypeFieldsNotes
AdminInstanceinstanceId, instanceNo, title, tenantId, flowId, flowName (string), applicant: UserInfo, status: InstanceStatus, currentNodeName?: string, createdAt: string, finishedAt?: stringAdmin list row.
AdminTasktaskId, instanceId, instanceTitle, flowName, nodeName (string), assignee: UserInfo, status: TaskStatus, createdAt: string, deadline?: string, finishedAt?: stringAdmin task row.
AdminInstanceInfoinstanceId, instanceNo, title, tenantId, flowId, flowCode: string, flowName, flowVersionId (string), labels?: Record<string, string>, applicant: UserInfo, globals?: Record<string, unknown>, status: InstanceStatus, currentNodeId?, currentNodeName?, businessRef? (string), formData?: FormData, createdAt: string, finishedAt?: stringRuntime state within the admin detail. globals is the form-visible part of the instance's globals snapshot, as on MyInstanceInfo.
AdminInstanceDetailinstance: AdminInstanceInfo, formSchema?: FormSchema, timeline: TimelineEntry[], flowGraph: InstanceFlowGraphThe raw audit trail stays on the paginated action-log query.
AdminActionLoglogId: string, action: ActionType, nodeId?, taskId? (string), operator: UserInfo, transferTo?: UserInfo, rollbackToNodeId?: string, addedAssignees?: UserInfo[], removedAssignees?: UserInfo[], ccUsers?: UserInfo[], opinion?: string, attachments?: string[], createdAt: stringOne audit entry.
ApprovalMetricstenantId: string, capturedAt: string, instanceCounts: Partial<Record<InstanceStatus, number>>, taskCounts: Partial<Record<TaskStatus, number>>, timeoutTaskCount: number, avgCompletionSeconds: number, pendingBindingFailures: number, businessProjectionCounts: Partial<Record<BindingProjectionStatus, number>>, pendingBusinessProjections: numberavgCompletionSeconds is the average end-to-end duration in seconds over completed instances; -1 means no completed instances yet.
BusinessRecordKeyRecord<string, string | number | boolean | null>Configured key columns mapped to values resolved from the instance's business ref.
AdminBusinessProjectionprojectionId, tenantId, flowId, flowVersionId, ownerInstanceId (string), appliedOwnerInstanceId?: string, businessTable: string, recordKey: BusinessRecordKey, consistency: "synchronous" | "eventual", desiredStatus: InstanceStatus, desiredStartedAt: string, desiredFinishedAt?: string, desiredRevision: number, appliedRevision: number, status: BindingProjectionStatus, attemptCount: number, nextAttemptAt?, leaseUntil?, lastError?, appliedAt? (string), updatedAt: stringOperator-facing convergence state for one bound business record.
AdminInstanceSearchtenantId?, applicantId? (string), status?: InstanceStatus, flowId?: string, keyword?: string—
AdminTaskSearchtenantId?, assigneeId?, instanceId? (string), status?: TaskStatus—
AdminBusinessProjectionSearchtenantId?: string, status?: BindingProjectionStatus—
TerminateInstanceParamsinstanceId: string, reason?: string—
ReassignTaskParamstaskId: string, newAssigneeId: string, reason?: string—
RetryBusinessProjectionParamsprojectionId: string—

Timeline and flow-graph projections​

TypeFieldsNotes
NodeParticipanttaskId: string, user: UserInfo, delegator?: UserInfo, status: string, deadline?: string, isTimeout?: boolean, opinion?: string, attachments?: string[], actionTime?: string, transferTo?: UserInfoOne assignee's involvement at an approval/handle node during a single visit; taskId is what task operations are submitted against; outcome details are fused from the action log that finished the task.
Activityaction: ActivityAction, operator: UserInfo, opinion?: string, attachments?: string[], transferTo?: UserInfo, target?: UserInfo, rollbackToNodeId?: string, rollbackToNodeName?: string, addedAssignees?: UserInfo[], removedAssignees?: UserInfo[], ccUsers?: UserInfo[], createdAt: stringA side action recorded at a node. Decisions themselves (approve / handle / reject) live on the participant that made them, not here.
CCRecipientuser: UserInfo, readAt?: stringOne CC recipient, with the read receipt when confirmed.
TimelineEntryKind"start" | "approval" | "handle" | "cc" | "end" | "withdraw" | "terminate"Node entries plus the end node and withdraw/terminate milestones.
TimelineEntrykind: TimelineEntryKind, nodeId?, name? (string), status?: NodeVisitStatus, executionType?, approvalMethod?, passRule?, passRatio? (string), passCount?: number, participants?: NodeParticipant[], ccRecipients?: CCRecipient[], activities?: Activity[], startedAt: string, finishedAt?: stringOne step of the chronological account of the path an instance actually took; entries end at the node currently in progress — unreached nodes are not predicted. The end kind marks reaching the end node on a passing finish. passRatio is a percentage in (0, 100] serialized as a decimal string; passCount is the approvals a fixed_count rule requires, present only under that rule.
FlowGraphNodeid: string, nodeId: string, kind: NodeKind, position: { x: number; y: number }, data: FlowGraphNodeDataReact Flow–ready node; kind selects the node renderer.
FlowGraphNodeDataname: string, status: NodeProgressStatus, executionType?, approvalMethod?, passRule?, passRatio? (string), passCount?: number, participants?: NodeParticipant[], ccRecipients?: CCRecipient[], activities?: Activity[], startedAt?: string, finishedAt?: stringRuntime payload: display config plus progress and the same participant/CC/activity shapes the timeline uses, aggregated across the node's visits in traversal order.
FlowGraphEdgeid: string, source: string, target: string, sourceHandle?: stringReact Flow–ready edge.
InstanceFlowGraphnodes: FlowGraphNode[], edges: FlowGraphEdge[]The read-only, progress-annotated projection of an instance's flow definition.

Re-exports from approval-flow-editor​

The picker contract hosts implement for ApprovalPlugins.pickers, re-exported so a host wires the provider from this package alone:

TypeShapeDocumented at
EditorPlugins{ pickers?, assigneeKinds?, ccKinds?, formFields?, globalSubjects?, shared? }Approval Flow Editor — Host Integration
PickerProps{ value: string[]; onChange: (ids: string[]) => void; disabled?: boolean }Approval Flow Editor — Reference
PrincipalKind"user" | "role" | "department"Approval Flow Editor — Reference
KindDescriptor{ kind: string; label: string; selection: SelectionMode }Approval Flow Editor — Reference
SelectionMode"none" | "user" | "role" | "department" | "form_field" | "custom"Approval Flow Editor — Reference

Page prop types (ApprovalTaskCenterPageProps, ApprovalMyInstancesPageProps, ApprovalInitiatePageProps, ApprovalCategoryPageProps, ApprovalFlowPageProps, ApprovalDelegationPageProps, ApprovalAdminPageProps, FlowDesignerDrawerProps, FlowVersionsDrawerProps, StartInstanceDrawerProps) are exported alongside their components — see Pages for their tables.