.agents/skills/usecase-pattern/SKILL.md
Use when creating or refactoring domain use cases in app modules and you need consistent constructor injection, guard clauses, immutable updates, and orchestration without state management.
npx skillsauth add auravibes-apps/auravibes usecase-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 cases are plain domain classes that orchestrate business flow.
Core rule: providers/widgets manage state, use cases coordinate logic, repositories perform data access.
Use this pattern when:
Do not use this for simple UI-only state changes.
class ActionUseCase {
const ActionUseCase({
required FeatureRepository repository,
required SecondaryDependency secondary,
}) : _repository = repository,
_secondary = secondary;
final FeatureRepository _repository;
final SecondaryDependency _secondary;
Future<ActionOutput> call({required ActionInput input}) async {
if (input.items.isEmpty) {
throw const ManagedDomainException('Input items are required');
}
final prepared = _prepare(input);
final entity = await _repository.execute(prepared);
return ActionOutput.fromEntity(entity);
}
}
Use local DTOs only when needed by the flow (for example batch update structures or metadata updates). Otherwise return the domain value directly.
Rules:
call(...)Keep use cases focused on orchestration, not storage details.
When a use case updates nested metadata/collections:
toolCallId)This keeps behavior deterministic and testable.
Use cases should not wrap errors into generic result objects.
Rules:
call(...) method is the single entry pointref.read(...) inside the use case instead of constructor injection.Use case usage pattern in app modules:
Reference implementation:
apps/auravibes_app/lib/providers/tool_execution_controller.dartapps/auravibes_app/lib/providers/tool_calling_manager_provider.dartInside a controller method:
call(...) methods.This keeps wiring explicit, testable, and easy to refactor.
runTask(...): create permission/check/update use cases -> filter allowed work -> execute batch -> continue next step only when pending work is resolved.grantToolCall(...): build grant + execution use cases -> grant permission -> execute -> continue flow.skipToolCall(...) / stop flows: update metadata through dedicated update use case, then continue orchestration as needed.Do:
call(...)Don't:
Prompt examples:
During implementation, follow this order:
tools
Convert tasks from tasks.md into GitHub issues. Use after task breakdown to track work items in GitHub project management.
tools
Break down implementation plans into actionable task lists. Use after planning to create a structured task breakdown. Generates tasks.md with ordered, dependency-aware tasks.
development
Create or update feature specifications from natural language descriptions. Use when starting new features or refining requirements. Generates spec.md with user stories, functional requirements, and acceptance criteria following spec-driven development methodology.
testing
Generate technical implementation plans from feature specifications. Use after creating a spec to define architecture, tech stack, and implementation phases. Creates plan.md with detailed technical design.