Skip to content

WorkflowStorage

WorkflowStorage is the storage interface used by WorkflowEngine.

dart
abstract class WorkflowStorage {
  WorkflowRepository get workflows;
  WorkflowInstanceRepository get instances;
  UserTaskInstanceRepository get userTaskInstances;
  WorkflowEventRepository get events;

  Future<T> transaction<T>(Future<T> Function() operation);
  Future<void> initialize();
  Future<void> dispose();
  Future<bool> healthCheck();
  Future<StorageStats> getStats();
}

Storage keeps typed data models. It does not resolve executors or run workflows.

Repositories

GetterRepositoryModel
workflowsWorkflowRepositoryWorkflowDefinition
instancesWorkflowInstanceRepositoryWorkflowInstance
userTaskInstancesUserTaskInstanceRepositoryUserTaskInstance
eventsWorkflowEventRepositoryWorkflowEvent

WorkflowRepository

dart
abstract class WorkflowRepository {
  Future<WorkflowDefinition> create(WorkflowDefinition workflow);
  Future<WorkflowDefinition> update(WorkflowDefinition workflow);
  Future<WorkflowDefinition?> getById(String id);
  Future<WorkflowDefinition?> getByCode(String code, {int? version});
  Future<List<WorkflowDefinition>> getAllVersions(String code);
  Future<List<WorkflowDefinition>> list({
    int limit = 100,
    int offset = 0,
    bool activeOnly = true,
  });
  Future<List<WorkflowDefinition>> search(String query, {int limit = 100});
  Future<bool> delete(String code, {int? version});
  Future<bool> activate(String code, {int? version});
  Future<bool> deactivate(String code, {int? version});
  Future<bool> codeExists(String code);
  Future<int> getNextVersion(String code);
}

WorkflowDefinition is the persisted definition shape. Use engine.loadWorkflowDefinition(definition) to convert it into an executable Workflow.

WorkflowInstanceRepository

dart
abstract class WorkflowInstanceRepository {
  Future<WorkflowInstance> create(WorkflowInstance instance);
  Future<WorkflowInstance> update(WorkflowInstance instance);
  Future<WorkflowInstance?> getById(String id);
  Future<List<WorkflowInstance>> query(WorkflowInstanceQuery query);
  Future<List<WorkflowInstance>> listByDefinition(
    String workflowId, {
    int limit = 100,
    int offset = 0,
  });
  Future<List<WorkflowInstance>> listByStatus(
    WorkflowStatus status, {
    int limit = 100,
    int offset = 0,
  });
  Future<List<WorkflowInstance>> listActive({int limit = 100, int offset = 0});
  Future<List<WorkflowInstance>> getByCorrelationId(String correlationId);
  Future<List<WorkflowInstance>> getChildInstances(String parentInstanceId);
  Future<bool> updateStatus(String id, WorkflowStatus status);
  Future<bool> mergeOutput(String id, Map<String, dynamic> output);
  Future<bool> setVariable(String id, WorkflowVariable variable);
  Future<bool> updateTokens(String id, List<WorkflowToken> tokens);
  Future<bool> delete(String id);
  Future<Map<WorkflowStatus, int>> countByStatus();
  Future<List<WorkflowInstance>> getTimedOutInstances(DateTime now);
  Future<List<WorkflowInstance>> getWaitingForSignal(String signalName);
  Future<List<WorkflowInstance>> getStaleRunningInstances({
    required Duration staleThreshold,
    int limit = 100,
  });
}

UserTaskInstanceRepository

dart
abstract class UserTaskInstanceRepository {
  Future<UserTaskInstance> create(UserTaskInstance task);
  Future<UserTaskInstance> update(UserTaskInstance task);
  Future<UserTaskInstance?> getById(String id);
  Future<void> delete(String id);
  Future<List<UserTaskInstance>> getByWorkflowInstanceId(
    String workflowInstanceId,
  );
  Future<UserTaskInstance> complete(
    String taskId,
    String userId,
    Map<String, dynamic> output,
  );
  Future<UserTaskInstance> cancel(String taskId);
  Future<int> cancelByWorkflowInstanceId(String workflowInstanceId);
  Future<List<UserTaskInstance>> getOverdue();
  Future<int> expireOverdue();
  Future<int> countPendingByWorkflowInstanceId(String workflowInstanceId);
  Future<UserTaskInstance?> findActive({
    required String workflowInstanceId,
    required String nodeId,
  });
  Future<List<UserTaskInstance>> getByStatus(TaskStatus status);
  Future<List<UserTaskInstance>> search({
    String? workflowInstanceId,
    String? assignedToUserId,
    String? assignedToRoleId,
    String? assignedToGroupId,
    TaskStatus? status,
    int limit = 100,
    int offset = 0,
  });
}

User task completion should be followed by a workflow signal when the workflow is waiting for that task's node/signal.

WorkflowEventRepository

dart
abstract class WorkflowEventRepository {
  Future<WorkflowEvent> append(WorkflowEvent event);
  Future<List<WorkflowEvent>> appendAll(List<WorkflowEvent> events);
  Future<WorkflowEvent?> getById(String id);
  Future<List<WorkflowEvent>> getByWorkflowInstanceId(
    String workflowInstanceId, {
    List<WorkflowEventType>? eventTypes,
    int? limit,
    int? offset,
  });
  Future<List<WorkflowEvent>> query(WorkflowEventQuery query);
  Future<WorkflowEvent?> getLatestByWorkflowInstanceId(String workflowInstanceId);
  Future<List<WorkflowEvent>> getByNodeId(
    String workflowInstanceId,
    String nodeId,
  );
  Future<List<WorkflowEvent>> getByUserTaskId(String userTaskId);
  Future<List<WorkflowEvent>> getByUserId(
    String userId, {
    int limit = 100,
    int offset = 0,
  });
  Future<int> countByWorkflowInstanceId(String workflowInstanceId);
  Future<Map<WorkflowEventType, int>> countByTypeForWorkflowInstance(
    String workflowInstanceId,
  );
  Future<List<WorkflowEvent>> getSummary(String workflowInstanceId);
  Future<int> deleteByWorkflowInstanceId(String workflowInstanceId);
  Future<int> pruneOlderThan(DateTime cutoff);
}

StorageStats

dart
class StorageStats {
  const StorageStats({
    required this.totalDefinitions,
    required this.totalInstances,
    required this.activeInstances,
    this.storageSizeBytes,
    this.additional = const {},
  });
}

Built-in Implementations

InMemoryStorage

dart
final storage = InMemoryStorage(
  workflowLoader: () async => [template.buildDefinition()],
);

Use it for tests, local demos, and editor simulation. It clears data on dispose.

SupabaseStorage

dart
final storage = SupabaseStorage(
  client: supabaseClient,
  config: const SupabaseStorageConfig(schema: 'elog'),
);

Default Supabase tables:

TablePurpose
elog.workflowsWorkflow definitions.
elog.workflow_instancesRuntime instances.
elog.workflow_user_tasksUser task inbox records.
elog.workflow_eventsEvent/audit log.

Engine Setup

dart
final context = RegistryTypeResolver(
  descriptors: [DefaultWorkflowDescriptor(), descriptor],
);

final engine = WorkflowEngine(
  context: context,
  storage: storage,
  executionMode: ExecutionMode.production,
);
await engine.initialize();

See Also