Skip to content

Vyuh Workflows

Durable Process Orchestration

Write long-running business processes as typed Dart. Every side effect, human decision, signal, and timer is a durable await that WorkflowRuntime can replay after a crash, restart, or competing worker.

Why Durable Workflows?

Deterministic Replay

Workflows are Dart functions. After a restart, the runtime replays recorded history and stops at the next unresolved durable await.

Assigned Work

User tasks wait in storage, not in a process. Assignment, claim, expiry, and completion are first-class runtime actions.

Transactional History

Runs, events, and commands commit together. PostgreSQL leases, fencing, and SKIP LOCKED keep competing workers honest.

One Vocabulary, Two Surfaces

Author in typed Dart or constrained JSON. Both compile to a WorkflowDefinition and execute in WorkflowRuntime.

Getting Started

Core Concepts

Durable Vocabulary

AwaitPurpose
Service taskIdempotent automated work
User taskAssigned durable work
SignalExternal event wait
TimerDurable sleep
Child workflowCall, spawn, and join

Patterns & Examples

Quick Example

dart
import 'package:vyuh_workflow_engine/vyuh_workflow_runtime.dart';

final reserve = Workflow.activity<Order, Reservation>(
  name: 'orders.reserve',
  input: orderCodec,
  output: reservationCodec,
);

final approve = Workflow.userTask<Reservation, Approval>(
  name: 'orders.approve',
  input: reservationCodec,
  response: approvalCodec,
);

final orderApproval = Workflow.define<Order, Result>(
  code: 'orders.approval',
  version: 1,
  fingerprint: buildFingerprint,
  input: orderCodec,
  output: resultCodec,
  execute: (flow, order) async {
    final reservation = await flow.serviceTask(
      reserve,
      order,
      id: 'reserve',
      retry: RetryPolicy.simple,
    );
    final decision = await flow.userTask(
      approve,
      reservation,
      id: 'approve',
      title: 'Approve order',
      assignment: Assignment(roleIds: ['order-approver']),
    );
    return decision.approved ? Result.approved() : Result.rejected();
  },
);

final runtime = WorkflowRuntime(
  storage: InMemoryWorkflowStorage(),
  modules: [
    WorkflowModule(
      name: 'orders',
      workflows: [orderApproval],
      activities: [
        ActivityBinding.from(reserve, ReservationHandler()),
      ],
      userTasks: [approve],
    ),
  ],
);

final run = await runtime.start(orderApproval.ref, order);

New application code imports vyuh_workflow_runtime.dart. The graph LegacyWorkflowEngine remains only as a compatibility surface for in-flight product runs.

For CDX approvals, use ApprovalWorkflowDefinition from cdx_workflow_templates and complete work through the workflow service. See Approval Workflows and CDX Integration.