Skip to main content

Integrating with Apps

A workflow component describes interaction. @zuilib/apps supplies the governed execution around it: named actions, permissions, confirmation, idempotency, retries, transitions and telemetry.

Declare the action

const app = defineApp({
version: 1,
id: 'commercial-operations',
name: 'Commercial operations',
pages: [{id: 'approvals', path: '/', title: 'Approvals', view}],
actions: [{
id: 'approve-adjustment',
name: 'Approve adjustment',
kind: 'approval',
policies: ['finance-approver'],
confirmation: {mode: 'type', phrase: 'APPROVE'},
retry: {attempts: 2, strategy: 'exponential'},
onSuccess: [
{type: 'refresh-resource', target: 'approvals'},
{type: 'notify', message: 'Adjustment approved'},
],
onError: [{type: 'notify', message: 'Approval failed'}],
audit: true,
}],
policies: [{
id: 'finance-approver',
effect: 'allow',
level: 'approve',
scope: 'action',
target: 'approve-adjustment',
subjects: {groups: ['finance']},
}],
})

Reference it from the view

{
"type": "approval-list",
"props": {
"items": {"$bind": {"source": "resource", "ref": "approvals"}},
"onApprove": {"$action": "approve-adjustment"},
"onReject": {"$action": "reject-adjustment"}
}
}

The document contains names and intent, never API clients or credentials.

Execute in the host

const adapters: AppRuntimeAdapters = {
resources: ({resource, params, signal}) =>
dataPlatform.run(resource.id, {params, signal}),
actions: ({action, inputs, subject, signal}) =>
actionGateway.execute(action.id, {inputs, subject, signal}),
policies: (policy, context) => authorization.evaluate(policy, context),
telemetry: productTelemetry,
confirm: (action) => openConfirmation(action.confirmation),
}

<AppRuntimeProvider app={app} adapters={adapters} subject={currentUser}>
<PublishedApp registry={registry} />
</AppRuntimeProvider>

The runtime prevents denied actions from reaching the executor, applies the declared confirmation, tracks the run and emits telemetry. The backend remains the final authorization boundary.

Validate before publishing

validateAppForPublish(app, registry, {environment}) verifies workflow node types, action references, protected mutations, policy targets and environment gates. This keeps authored and AI-generated operational pages from shipping with disconnected controls.