.cursor/skills/workflow-controller-pattern/SKILL.md
Implements base workflow controller patterns for multi-step processes. Use when creating complex workflows that require orchestration of multiple steps with error handling and rollback.
npx skillsauth add avra-cadavra/avrai workflow-controller-patternInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use base workflow controller for multi-step processes:
import 'dart:developer' as developer;
abstract class WorkflowController<TInput, TOutput> {
final AppLogger _logger;
WorkflowController({AppLogger? logger})
: _logger = logger ?? const AppLogger(
defaultTag: 'WorkflowController',
minimumLevel: LogLevel.debug,
);
Future<Result<TOutput>> execute(TInput input) async {
_logger.info('Starting workflow execution');
try {
return await executeWorkflow(input);
} catch (e, st) {
_logger.error('Workflow execution failed', error: e, stackTrace: st);
return Result.failure('Workflow execution failed: ${e.toString()}');
}
}
@protected
Future<Result<TOutput>> executeWorkflow(TInput input);
@protected
Future<void> onWorkflowStart(TInput input) async {}
@protected
Future<void> onWorkflowComplete(TOutput output) async {}
@protected
Future<void> onWorkflowError(Object error, StackTrace stackTrace) async {}
}
class MyWorkflowController extends WorkflowController<InputType, OutputType> {
final Step1Service _step1Service;
final Step2Service _step2Service;
final Step3Service _step3Service;
MyWorkflowController({
required Step1Service step1Service,
required Step2Service step2Service,
required Step3Service step3Service,
super.logger,
}) : _step1Service = step1Service,
_step2Service = step2Service,
_step3Service = step3Service;
@override
Future<Result<OutputType>> executeWorkflow(InputType input) async {
await onWorkflowStart(input);
// Step 1
final step1Result = await _step1Service.execute(input);
if (step1Result.isFailure) {
await onWorkflowError(step1Result.error, StackTrace.current);
return step1Result.toFailure();
}
// Step 2
final step2Result = await _step2Service.execute(step1Result.value);
if (step2Result.isFailure) {
await _step1Service.rollback(step1Result.value);
await onWorkflowError(step2Result.error, StackTrace.current);
return step2Result.toFailure();
}
// Step 3
final step3Result = await _step3Service.execute(step2Result.value);
if (step3Result.isFailure) {
await _step2Service.rollback(step2Result.value);
await _step1Service.rollback(step1Result.value);
await onWorkflowError(step3Result.error, StackTrace.current);
return step3Result.toFailure();
}
await onWorkflowComplete(step3Result.value);
return Result.success(step3Result.value);
}
}
For workflows that need rollback:
abstract class ReversibleWorkflowController<TInput, TOutput>
extends WorkflowController<TInput, TOutput> {
final List<RollbackAction> _rollbackActions = [];
@protected
void registerRollback(Future<void> Function() rollbackAction) {
_rollbackActions.add(RollbackAction(rollbackAction));
}
@protected
Future<void> executeRollback() async {
for (final action in _rollbackActions.reversed) {
try {
await action.execute();
} catch (e, st) {
developer.log(
'Rollback action failed',
error: e,
stackTrace: st,
name: 'WorkflowController',
);
}
}
_rollbackActions.clear();
}
@override
Future<Result<TOutput>> executeWorkflow(TInput input) async {
try {
return await super.executeWorkflow(input);
} catch (e, st) {
await executeRollback();
rethrow;
}
}
}
class RollbackAction {
final Future<void> Function() execute;
RollbackAction(this.execute);
}
Each step should handle its own errors:
Future<Result<StepData>> _executeStep(StepInput input) async {
try {
final result = await _service.performOperation(input);
return Result.success(result);
} on ValidationException catch (e) {
return Result.failure('Validation failed: ${e.message}');
} on NetworkException catch (e) {
return Result.failure('Network error: ${e.message}');
} catch (e, st) {
developer.log('Step execution failed', error: e, stackTrace: st);
return Result.failure('Step execution failed');
}
}
See base workflow controller in:
lib/core/controllers/base/workflow_controller.dartdevelopment
--- name: world-model-development description: Guides world model development patterns: state/action encoders, ONNX inference, feature extraction pipeline, latency budgets. Use when implementing world model components, state encoders, action encoders, feature extractors, or ONNX models. Core skill for Phases 3-6. --- # World Model Development Patterns ## Core Principle All world model components follow LeCun's autonomous machine intelligence framework. State observations flow through a percep
testing
--- name: widget-test-patterns description: Guides widget test patterns: BLoC testing, user interactions, state changes, material app setup. Use when writing widget tests, testing UI components, or validating widget behavior. --- # Widget Test Patterns ## Core Pattern Widget tests verify UI behavior: user interactions, state changes, and visual display. ## Basic Widget Test Setup ```dart testWidgets('widget displays correctly', (WidgetTester tester) async { // Arrange: Create widget awa
testing
--- name: test-template-generation description: Generates test templates: unit, widget, integration, service tests following project patterns. Use when creating new tests or ensuring tests follow project standards. --- # Test Template Generation ## Available Templates Test templates are located in `test/templates/`: - `unit_test_template.dart` - `widget_test_template.dart` - `integration_test_template.dart` - `service_test_template.dart` ## Unit Test Template ```dart /// SPOTS Component Uni
development
--- name: test-quality-enforcement description: Enforces test quality standards: behavior-focused tests, no property-only tests, round-trip JSON, comprehensive test blocks. Use when writing tests, reviewing test code, or ensuring test quality. --- # Test Quality Enforcement ## Core Principle **Test what the code DOES, not what it IS.** ## ✅ DO Test - **Behavior** - What happens when you call a method? - **Business Logic** - Calculations, validation, transformations - **Error Handling** - Ho