65 lines
2.0 KiB
Cheetah
65 lines
2.0 KiB
Cheetah
---
|
|
description: "Freezed code generation conventions for {{PROJECT_NAME}} — Pillar 4"
|
|
alwaysApply: true
|
|
---
|
|
|
|
# Freezed Standards — {{PROJECT_NAME}}
|
|
|
|
## When to use Freezed
|
|
- All domain entities and data models — use `@freezed`
|
|
- Union types / sealed classes — use `@freezed` with multiple constructors
|
|
- BLoC states and events — use `@freezed`
|
|
|
|
## Model pattern
|
|
```dart
|
|
@freezed
|
|
class Product with _$Product {
|
|
const factory Product({
|
|
required String id,
|
|
required String name,
|
|
required double price,
|
|
@Default(0) int stockCount,
|
|
String? imageUrl,
|
|
}) = _Product;
|
|
|
|
factory Product.fromJson(Map<String, dynamic> json) => _$ProductFromJson(json);
|
|
}
|
|
```
|
|
|
|
## Union type pattern
|
|
```dart
|
|
@freezed
|
|
sealed class ProductState with _$ProductState {
|
|
const factory ProductState.initial() = ProductInitial;
|
|
const factory ProductState.loading() = ProductLoading;
|
|
const factory ProductState.loaded(List<Product> products) = ProductLoaded;
|
|
const factory ProductState.error(String message) = ProductError;
|
|
}
|
|
|
|
// Usage — exhaustive switch
|
|
final widget = state.when(
|
|
initial: () => const SizedBox.shrink(),
|
|
loading: () => const ProductShimmer(),
|
|
loaded: (products) => ProductList(products: products),
|
|
error: (msg) => ErrorWidget(message: msg),
|
|
);
|
|
```
|
|
|
|
## Critical rules
|
|
- **NEVER** edit `.freezed.dart` or `.g.dart` files — they are generated
|
|
- Run `dart run build_runner build --delete-conflicting-outputs` after changes
|
|
- Run `dart run build_runner watch` during development
|
|
- Add `*.freezed.dart` and `*.g.dart` to `.gitignore` (or commit them — team must decide)
|
|
- Always define `copyWith` via Freezed — never write manual `copyWith`
|
|
|
|
## Patterns to avoid
|
|
```dart
|
|
// ❌ Manual copyWith — replaced by Freezed
|
|
Product copyWith({String? name, double? price}) => Product(
|
|
id: id, name: name ?? this.name, price: price ?? this.price,
|
|
);
|
|
|
|
// ✅ Let Freezed generate it
|
|
product.copyWith(name: 'New Name', price: 9.99)
|
|
```
|