chore: update README and CLI usage for cursor_gen, version bump to 1.0.1
- Changed CLI usage instructions from `dart run cursor_gen` to `cursor_gen` for global activation. - Updated project-brief.yaml example and README to reflect new command usage. - Added app_context section in project-brief.yaml for theme variants and RBAC roles. - Fixed bundled template resolution for local and global installs to prevent 'Template not found' errors. - Version bump to 1.0.1 with corresponding updates in CHANGELOG and pubspec.yaml.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
---
|
||||
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)
|
||||
```
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
---
|
||||
description: "Injectable dependency injection conventions for {{PROJECT_NAME}} — Pillar 4"
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Injectable (get_it) Standards — {{PROJECT_NAME}}
|
||||
|
||||
## Setup
|
||||
```dart
|
||||
// lib/core/di/injection.dart
|
||||
@InjectableInit()
|
||||
void configureDependencies() => getIt.init();
|
||||
```
|
||||
|
||||
## Annotations
|
||||
```dart
|
||||
@singleton // One instance for app lifetime
|
||||
@lazySingleton // Created on first access (preferred for most services)
|
||||
@injectable // New instance each time (use sparingly)
|
||||
@factoryMethod // Custom factory logic
|
||||
```
|
||||
|
||||
## Example
|
||||
```dart
|
||||
@lazySingleton
|
||||
class ProductRepository {
|
||||
final DioClient _client;
|
||||
const ProductRepository(this._client); // Constructor injection
|
||||
}
|
||||
|
||||
@injectable
|
||||
class GetProductsUseCase {
|
||||
final ProductRepository _repo;
|
||||
const GetProductsUseCase(this._repo);
|
||||
}
|
||||
```
|
||||
|
||||
## Rules
|
||||
- Run `dart run build_runner build` after adding/modifying `@injectable` annotations
|
||||
- **NEVER** use `getIt<T>()` in widget `build()` methods — inject via constructor or provider
|
||||
- Use `@module` for third-party registrations (Dio, SharedPreferences, etc.)
|
||||
- Register environment-specific implementations with `@Environment('dev')` / `@Environment('prod')`
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
description: "json_serializable conventions for {{PROJECT_NAME}} — Pillar 4"
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# json_serializable Standards — {{PROJECT_NAME}}
|
||||
|
||||
## Model annotation
|
||||
```dart
|
||||
@JsonSerializable(explicitToJson: true) // explicitToJson for nested objects
|
||||
class ProductDto {
|
||||
final String id;
|
||||
final String name;
|
||||
@JsonKey(name: 'unit_price') // snake_case API → camelCase Dart
|
||||
final double unitPrice;
|
||||
@JsonKey(defaultValue: false)
|
||||
final bool isActive;
|
||||
final DateTime createdAt; // auto-converted from ISO 8601 string
|
||||
|
||||
const ProductDto({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.unitPrice,
|
||||
required this.isActive,
|
||||
required this.createdAt,
|
||||
});
|
||||
|
||||
factory ProductDto.fromJson(Map<String, dynamic> json) => _$ProductDtoFromJson(json);
|
||||
Map<String, dynamic> toJson() => _$ProductDtoToJson(this);
|
||||
}
|
||||
```
|
||||
|
||||
## Critical rules
|
||||
- **NEVER** edit `*.g.dart` files
|
||||
- Use `@JsonKey(defaultValue: ...)` for nullable API fields — API contracts change
|
||||
- Use `explicitToJson: true` whenever the model has nested objects
|
||||
- Null safety: API fields not guaranteed to be non-null should be `String?` not `String`
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
description: "Retrofit (Dio) API client conventions for {{PROJECT_NAME}} — Pillar 4"
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Retrofit Standards — {{PROJECT_NAME}}
|
||||
|
||||
## API client definition
|
||||
```dart
|
||||
@RestApi()
|
||||
abstract class ProductApiClient {
|
||||
factory ProductApiClient(Dio dio, {String? baseUrl}) = _ProductApiClient;
|
||||
|
||||
@GET('/products')
|
||||
Future<List<ProductDto>> getProducts(@Query('category') String? category);
|
||||
|
||||
@GET('/products/{id}')
|
||||
Future<ProductDto> getProduct(@Path('id') String id);
|
||||
|
||||
@POST('/products')
|
||||
Future<ProductDto> createProduct(@Body() CreateProductDto dto);
|
||||
}
|
||||
```
|
||||
|
||||
## Rules
|
||||
- **NEVER** edit `*.g.dart` files
|
||||
- Run `dart run build_runner build` after modifying API client
|
||||
- All DTOs used in Retrofit must have `fromJson`/`toJson` (via `json_serializable` or Freezed)
|
||||
- Handle `DioException` in the repository layer — never let it reach the presentation layer
|
||||
- Use `@Headers({'Content-Type': 'application/json'})` at class level, not per-method
|
||||
Reference in New Issue
Block a user