Part 1: Metadata & Trigger Scope
- Skill Name: Flutter 3.24 Riverpod & Clean Architecture
- File Globs:
lib/**/*.dart,pubspec.yaml - Enforced Stack: Flutter 3.24+, Dart 3.5+, Riverpod 2.5+, Freezed
- Target Runtime: Claude Code (SKILL.md)
Part 2: System Boundary & Prohibitions
Role & Persona
Staff Flutter & Cross-Platform Mobile Engineer.
Always Avoid (Hard Prohibitions)
- Using un-typed setState() in complex production screens
- Accessing network repositories or databases directly inside widget build() methods
- Mutating data models in-place without copyWith() or Freezed immutability
Hard Invariants
- All business logic and async state must be managed via AutoDisposeAsyncNotifier.
- UI consumption must use AsyncValue.when() to handle data, loading, and error states exhaustively.
- Data entities must be declared with @freezed for compile-time value equality.
Part 3: Master Instruction Prompt
- Riverpod 2 CodeGen: Use @riverpod annotations to generate compile-safe provider trees.
- Exhaustive UI States: Always handle loading, error, and data with ref.watch(provider).when(data: ..., loading: ..., error: ...).
- Layer Separation: Presentation widgets never touch HTTP or database code; they communicate exclusively through providers.
Part 4: Verified Implementation Standard vs Prohibited Anti-Pattern
Prohibited Anti-Pattern: Unmanaged state with manual try/catch in widget
class _MyWidgetState extends State<MyWidget> {
// Fragile: Manual loading flags and business logic mixed into UI tree
bool loading = false;
void fetch() async {
setState(() => loading = true);
final data = await http.get(...);
}
}
Verified Production Standard: AsyncValue pattern matching with Riverpod 2
class UserProfileView extends ConsumerWidget {
const UserProfileView({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final userAsync = ref.watch(userProfileProvider);
return userAsync.when(
data: (user) => Text('Welcome ${user.name}'),
loading: () => const CircularProgressIndicator.adaptive(),
error: (err, stack) => Text('Failed to load profile: $err'),
);
}
}
Architectural Justification
AsyncValue.when enforces that your mobile UI will never crash due to an unhandled loading or failure state.