@the-bearded-bear/claude-craft 8.8.1 → 8.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/Dev/i18n/de/Angular/commands/check-compliance.md +218 -168
  2. package/Dev/i18n/de/Common/agents/refactoring-specialist.md +146 -69
  3. package/Dev/i18n/de/Common/commands/add-technology.md +166 -68
  4. package/Dev/i18n/de/Common/commands/setup-ci.md +216 -33
  5. package/Dev/i18n/de/Laravel/commands/check-compliance.md +223 -115
  6. package/Dev/i18n/de/Python/checklists/new-feature.md +319 -44
  7. package/Dev/i18n/de/React/rules/02-architecture.md +483 -322
  8. package/Dev/i18n/de/React/rules/03-coding-standards.md +584 -368
  9. package/Dev/i18n/de/Symfony/commands/check-compliance.md +186 -114
  10. package/Dev/i18n/de/Symfony/rules/07-testing-symfony.md +679 -10
  11. package/Dev/i18n/de/UIUX/commands/a11y-component.md +284 -26
  12. package/Dev/i18n/de/UIUX/commands/design-tokens.md +199 -35
  13. package/Dev/i18n/de/UIUX/commands/user-flow.md +179 -16
  14. package/Dev/i18n/de/VueJS/commands/check-compliance.md +227 -102
  15. package/Dev/i18n/es/Angular/commands/check-compliance.md +217 -167
  16. package/Dev/i18n/es/Common/commands/add-technology.md +158 -60
  17. package/Dev/i18n/es/Laravel/commands/check-compliance.md +223 -115
  18. package/Dev/i18n/es/React/commands/check-testing.md +263 -169
  19. package/Dev/i18n/es/ReactNative/commands/check-testing.md +256 -198
  20. package/Dev/i18n/es/Symfony/commands/check-compliance.md +189 -117
  21. package/Dev/i18n/es/Symfony/commands/check-testing.md +301 -102
  22. package/Dev/i18n/es/Symfony/commands/migration-plan.md +267 -34
  23. package/Dev/i18n/es/UIUX/commands/a11y-component.md +274 -16
  24. package/Dev/i18n/es/UIUX/commands/design-tokens.md +186 -22
  25. package/Dev/i18n/es/UIUX/commands/user-flow.md +173 -10
  26. package/Dev/i18n/es/VueJS/commands/check-compliance.md +227 -102
  27. package/Dev/i18n/fr/Angular/commands/check-compliance.md +217 -167
  28. package/Dev/i18n/fr/Common/commands/ralph-run.md +138 -60
  29. package/Dev/i18n/fr/Laravel/commands/check-compliance.md +223 -115
  30. package/Dev/i18n/fr/React/commands/check-architecture.md +370 -53
  31. package/Dev/i18n/fr/React/commands/check-code-quality.md +454 -64
  32. package/Dev/i18n/fr/React/commands/check-testing.md +476 -102
  33. package/Dev/i18n/fr/Symfony/commands/check-compliance.md +188 -116
  34. package/Dev/i18n/fr/VueJS/commands/check-compliance.md +227 -102
  35. package/Dev/i18n/pt/Angular/commands/check-compliance.md +225 -175
  36. package/Dev/i18n/pt/Common/agents/ralph-conductor.md +211 -30
  37. package/Dev/i18n/pt/Common/commands/add-technology.md +149 -51
  38. package/Dev/i18n/pt/Common/commands/ralph-run.md +239 -35
  39. package/Dev/i18n/pt/Flutter/commands/analyze-performance.md +331 -46
  40. package/Dev/i18n/pt/Flutter/commands/check-compliance.md +234 -29
  41. package/Dev/i18n/pt/Flutter/commands/generate-feature.md +526 -51
  42. package/Dev/i18n/pt/Flutter/commands/generate-widget.md +515 -27
  43. package/Dev/i18n/pt/Flutter/commands/golden-update.md +322 -46
  44. package/Dev/i18n/pt/Flutter/commands/localization-check.md +278 -37
  45. package/Dev/i18n/pt/Laravel/commands/check-compliance.md +212 -104
  46. package/Dev/i18n/pt/React/commands/accessibility-check.md +151 -42
  47. package/Dev/i18n/pt/React/commands/bundle-analyze.md +300 -25
  48. package/Dev/i18n/pt/React/commands/check-architecture.md +369 -34
  49. package/Dev/i18n/pt/React/commands/check-code-quality.md +440 -34
  50. package/Dev/i18n/pt/React/commands/check-compliance.md +232 -62
  51. package/Dev/i18n/pt/React/commands/check-security.md +370 -31
  52. package/Dev/i18n/pt/React/commands/check-testing.md +473 -43
  53. package/Dev/i18n/pt/React/commands/generate-component.md +454 -19
  54. package/Dev/i18n/pt/React/commands/generate-hook.md +425 -24
  55. package/Dev/i18n/pt/React/commands/storybook-story.md +520 -35
  56. package/Dev/i18n/pt/ReactNative/commands/app-size.md +358 -387
  57. package/Dev/i18n/pt/ReactNative/commands/check-code-quality.md +246 -75
  58. package/Dev/i18n/pt/ReactNative/commands/check-compliance.md +191 -85
  59. package/Dev/i18n/pt/ReactNative/commands/check-security.md +363 -115
  60. package/Dev/i18n/pt/ReactNative/commands/check-testing.md +269 -79
  61. package/Dev/i18n/pt/ReactNative/commands/generate-screen.md +491 -324
  62. package/Dev/i18n/pt/ReactNative/commands/native-module.md +539 -82
  63. package/Dev/i18n/pt/ReactNative/commands/store-prepare.md +429 -185
  64. package/Dev/i18n/pt/ReactNative/rules/02-architecture.md +1084 -31
  65. package/Dev/i18n/pt/Symfony/commands/check-compliance.md +195 -123
  66. package/Dev/i18n/pt/UIUX/commands/a11y-audit.md +208 -24
  67. package/Dev/i18n/pt/UIUX/commands/a11y-component.md +281 -23
  68. package/Dev/i18n/pt/UIUX/commands/design-tokens.md +197 -33
  69. package/Dev/i18n/pt/UIUX/commands/user-flow.md +183 -20
  70. package/Dev/i18n/pt/VueJS/commands/check-compliance.md +228 -103
  71. package/Dev/i18n/pt/Workflow/commands/analyze.md +147 -146
  72. package/Dev/i18n/pt/Workflow/commands/design.md +205 -204
  73. package/Dev/i18n/pt/Workflow/commands/implement.md +184 -184
  74. package/Project/i18n/de/Sprint/commands/dev.md +339 -86
  75. package/Project/i18n/es/Sprint/commands/dev.md +342 -91
  76. package/Project/i18n/pt/Sprint/commands/dev.md +343 -92
  77. package/bundles/cursor/.cursorrules +1 -1
  78. package/bundles/windsurf/.windsurfrules +1 -1
  79. package/package.json +1 -1
@@ -1,69 +1,544 @@
1
1
  ---
2
- description: Gerar Nova Funcionalidade Flutter
2
+ description: Geração de Feature Flutter Completa
3
+ argument-hint: [arguments]
3
4
  ---
4
5
 
5
- # Gerar Nova Funcionalidade Flutter
6
+ # Geração de Feature Flutter Completa
6
7
 
7
- Gere toda a estrutura necessária para uma nova funcionalidade seguindo Clean Architecture.
8
+ Você é um desenvolvedor Flutter sênior. Você deve gerar uma feature completa seguindo a Clean Architecture com BLoC/Riverpod, incluindo todos os arquivos necessários e os testes.
8
9
 
9
- ## Entrada Necessária
10
+ ## Argumentos
11
+ $ARGUMENTS
10
12
 
11
- - Nome da funcionalidade (ex: "user_profile")
12
- - Camadas necessárias: [data, domain, presentation]
13
- - Tipo de gerenciamento de estado: [bloc, riverpod, provider]
13
+ Argumentos:
14
+ - Nome da feature (ex: `authentication`, `product_catalog`)
15
+ - (Opcional) Gerenciamento de estado (bloc, riverpod, cubit)
14
16
 
15
- ## Modo Plano
17
+ Exemplo: `/flutter:generate-feature authentication riverpod`
16
18
 
17
- > **O modo plano é obrigatório.** Antes de executar, Claude ativa o modo plano para analisar o código impactado, propor um plano de implementação e aguardar sua validação antes de realizar qualquer alteração.
19
+ ## Plan Mode
18
20
 
19
- ## Estrutura a Gerar
21
+ > **O modo de planejamento é obrigatório.** Antes de executar, o Claude ativa o modo de planejamento para analisar o código impactado, propor um plano de implementação e aguardar sua validação antes de realizar qualquer alteração.
20
22
 
23
+ ## MISSÃO
24
+
25
+ ### Etapa 1: Estrutura da Feature
26
+
27
+ ```
28
+ lib/
29
+ └── features/
30
+ └── {feature}/
31
+ ├── data/
32
+ │ ├── datasources/
33
+ │ │ ├── {feature}_local_datasource.dart
34
+ │ │ └── {feature}_remote_datasource.dart
35
+ │ ├── models/
36
+ │ │ └── {feature}_model.dart
37
+ │ └── repositories/
38
+ │ └── {feature}_repository_impl.dart
39
+ ├── domain/
40
+ │ ├── entities/
41
+ │ │ └── {feature}_entity.dart
42
+ │ ├── repositories/
43
+ │ │ └── {feature}_repository.dart
44
+ │ └── usecases/
45
+ │ ├── get_{feature}.dart
46
+ │ └── create_{feature}.dart
47
+ └── presentation/
48
+ ├── bloc/ (ou providers/)
49
+ │ ├── {feature}_bloc.dart
50
+ │ ├── {feature}_event.dart
51
+ │ └── {feature}_state.dart
52
+ ├── pages/
53
+ │ ├── {feature}_page.dart
54
+ │ └── {feature}_detail_page.dart
55
+ └── widgets/
56
+ ├── {feature}_list_item.dart
57
+ └── {feature}_form.dart
58
+
59
+ test/
60
+ └── features/
61
+ └── {feature}/
62
+ ├── data/
63
+ │ └── repositories/
64
+ │ └── {feature}_repository_impl_test.dart
65
+ ├── domain/
66
+ │ └── usecases/
67
+ │ └── get_{feature}_test.dart
68
+ └── presentation/
69
+ ├── bloc/
70
+ │ └── {feature}_bloc_test.dart
71
+ └── pages/
72
+ └── {feature}_page_test.dart
73
+ ```
74
+
75
+ ### Etapa 2: Camada de Domínio
76
+
77
+ #### Entidade
78
+ ```dart
79
+ // lib/features/{feature}/domain/entities/{feature}_entity.dart
80
+ import 'package:equatable/equatable.dart';
81
+
82
+ class {Feature}Entity extends Equatable {
83
+ final String id;
84
+ final String name;
85
+ final String? description;
86
+ final DateTime createdAt;
87
+ final DateTime? updatedAt;
88
+
89
+ const {Feature}Entity({
90
+ required this.id,
91
+ required this.name,
92
+ this.description,
93
+ required this.createdAt,
94
+ this.updatedAt,
95
+ });
96
+
97
+ @override
98
+ List<Object?> get props => [id, name, description, createdAt, updatedAt];
99
+
100
+ {Feature}Entity copyWith({
101
+ String? id,
102
+ String? name,
103
+ String? description,
104
+ DateTime? createdAt,
105
+ DateTime? updatedAt,
106
+ }) {
107
+ return {Feature}Entity(
108
+ id: id ?? this.id,
109
+ name: name ?? this.name,
110
+ description: description ?? this.description,
111
+ createdAt: createdAt ?? this.createdAt,
112
+ updatedAt: updatedAt ?? this.updatedAt,
113
+ );
114
+ }
115
+ }
116
+ ```
117
+
118
+ #### Interface do Repositório
119
+ ```dart
120
+ // lib/features/{feature}/domain/repositories/{feature}_repository.dart
121
+ import 'package:dartz/dartz.dart';
122
+ import '../entities/{feature}_entity.dart';
123
+ import '../../../../core/error/failures.dart';
124
+
125
+ abstract class {Feature}Repository {
126
+ Future<Either<Failure, List<{Feature}Entity>>> getAll();
127
+ Future<Either<Failure, {Feature}Entity>> getById(String id);
128
+ Future<Either<Failure, {Feature}Entity>> create({Feature}Entity entity);
129
+ Future<Either<Failure, {Feature}Entity>> update({Feature}Entity entity);
130
+ Future<Either<Failure, void>> delete(String id);
131
+ }
132
+ ```
133
+
134
+ #### Casos de Uso
135
+ ```dart
136
+ // lib/features/{feature}/domain/usecases/get_{feature}_list.dart
137
+ import 'package:dartz/dartz.dart';
138
+ import '../../../../core/error/failures.dart';
139
+ import '../../../../core/usecases/usecase.dart';
140
+ import '../entities/{feature}_entity.dart';
141
+ import '../repositories/{feature}_repository.dart';
142
+
143
+ class Get{Feature}List implements UseCase<List<{Feature}Entity>, NoParams> {
144
+ final {Feature}Repository repository;
145
+
146
+ Get{Feature}List(this.repository);
147
+
148
+ @override
149
+ Future<Either<Failure, List<{Feature}Entity>>> call(NoParams params) {
150
+ return repository.getAll();
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### Etapa 3: Camada de Dados
156
+
157
+ #### Modelo
158
+ ```dart
159
+ // lib/features/{feature}/data/models/{feature}_model.dart
160
+ import '../../domain/entities/{feature}_entity.dart';
161
+
162
+ class {Feature}Model extends {Feature}Entity {
163
+ const {Feature}Model({
164
+ required super.id,
165
+ required super.name,
166
+ super.description,
167
+ required super.createdAt,
168
+ super.updatedAt,
169
+ });
170
+
171
+ factory {Feature}Model.fromJson(Map<String, dynamic> json) {
172
+ return {Feature}Model(
173
+ id: json['id'] as String,
174
+ name: json['name'] as String,
175
+ description: json['description'] as String?,
176
+ createdAt: DateTime.parse(json['created_at'] as String),
177
+ updatedAt: json['updated_at'] != null
178
+ ? DateTime.parse(json['updated_at'] as String)
179
+ : null,
180
+ );
181
+ }
182
+
183
+ Map<String, dynamic> toJson() {
184
+ return {
185
+ 'id': id,
186
+ 'name': name,
187
+ 'description': description,
188
+ 'created_at': createdAt.toIso8601String(),
189
+ 'updated_at': updatedAt?.toIso8601String(),
190
+ };
191
+ }
192
+
193
+ factory {Feature}Model.fromEntity({Feature}Entity entity) {
194
+ return {Feature}Model(
195
+ id: entity.id,
196
+ name: entity.name,
197
+ description: entity.description,
198
+ createdAt: entity.createdAt,
199
+ updatedAt: entity.updatedAt,
200
+ );
201
+ }
202
+ }
203
+ ```
204
+
205
+ #### Implementação do Repositório
206
+ ```dart
207
+ // lib/features/{feature}/data/repositories/{feature}_repository_impl.dart
208
+ import 'package:dartz/dartz.dart';
209
+ import '../../../../core/error/exceptions.dart';
210
+ import '../../../../core/error/failures.dart';
211
+ import '../../../../core/network/network_info.dart';
212
+ import '../../domain/entities/{feature}_entity.dart';
213
+ import '../../domain/repositories/{feature}_repository.dart';
214
+ import '../datasources/{feature}_local_datasource.dart';
215
+ import '../datasources/{feature}_remote_datasource.dart';
216
+ import '../models/{feature}_model.dart';
217
+
218
+ class {Feature}RepositoryImpl implements {Feature}Repository {
219
+ final {Feature}RemoteDataSource remoteDataSource;
220
+ final {Feature}LocalDataSource localDataSource;
221
+ final NetworkInfo networkInfo;
222
+
223
+ {Feature}RepositoryImpl({
224
+ required this.remoteDataSource,
225
+ required this.localDataSource,
226
+ required this.networkInfo,
227
+ });
228
+
229
+ @override
230
+ Future<Either<Failure, List<{Feature}Entity>>> getAll() async {
231
+ if (await networkInfo.isConnected) {
232
+ try {
233
+ final remoteData = await remoteDataSource.getAll();
234
+ await localDataSource.cacheAll(remoteData);
235
+ return Right(remoteData);
236
+ } on ServerException {
237
+ return Left(ServerFailure());
238
+ }
239
+ } else {
240
+ try {
241
+ final localData = await localDataSource.getAll();
242
+ return Right(localData);
243
+ } on CacheException {
244
+ return Left(CacheFailure());
245
+ }
246
+ }
247
+ }
248
+
249
+ // Outros métodos...
250
+ }
251
+ ```
252
+
253
+ ### Etapa 4: Camada de Apresentação (BLoC)
254
+
255
+ #### BLoC
256
+ ```dart
257
+ // lib/features/{feature}/presentation/bloc/{feature}_bloc.dart
258
+ import 'package:flutter_bloc/flutter_bloc.dart';
259
+ import 'package:equatable/equatable.dart';
260
+ import '../../domain/entities/{feature}_entity.dart';
261
+ import '../../domain/usecases/get_{feature}_list.dart';
262
+ import '../../../../core/usecases/usecase.dart';
263
+
264
+ part '{feature}_event.dart';
265
+ part '{feature}_state.dart';
266
+
267
+ class {Feature}Bloc extends Bloc<{Feature}Event, {Feature}State> {
268
+ final Get{Feature}List get{Feature}List;
269
+
270
+ {Feature}Bloc({required this.get{Feature}List}) : super(const {Feature}Initial()) {
271
+ on<Load{Feature}List>(_onLoad{Feature}List);
272
+ on<Refresh{Feature}List>(_onRefresh{Feature}List);
273
+ }
274
+
275
+ Future<void> _onLoad{Feature}List(
276
+ Load{Feature}List event,
277
+ Emitter<{Feature}State> emit,
278
+ ) async {
279
+ emit(const {Feature}Loading());
280
+
281
+ final result = await get{Feature}List(NoParams());
282
+
283
+ result.fold(
284
+ (failure) => emit({Feature}Error(message: failure.message)),
285
+ (data) => emit({Feature}Loaded(items: data)),
286
+ );
287
+ }
288
+
289
+ Future<void> _onRefresh{Feature}List(
290
+ Refresh{Feature}List event,
291
+ Emitter<{Feature}State> emit,
292
+ ) async {
293
+ final result = await get{Feature}List(NoParams());
294
+
295
+ result.fold(
296
+ (failure) => emit({Feature}Error(message: failure.message)),
297
+ (data) => emit({Feature}Loaded(items: data)),
298
+ );
299
+ }
300
+ }
301
+ ```
302
+
303
+ #### Eventos
304
+ ```dart
305
+ // lib/features/{feature}/presentation/bloc/{feature}_event.dart
306
+ part of '{feature}_bloc.dart';
307
+
308
+ abstract class {Feature}Event extends Equatable {
309
+ const {Feature}Event();
310
+
311
+ @override
312
+ List<Object> get props => [];
313
+ }
314
+
315
+ class Load{Feature}List extends {Feature}Event {
316
+ const Load{Feature}List();
317
+ }
318
+
319
+ class Refresh{Feature}List extends {Feature}Event {
320
+ const Refresh{Feature}List();
321
+ }
322
+ ```
323
+
324
+ #### Estados
325
+ ```dart
326
+ // lib/features/{feature}/presentation/bloc/{feature}_state.dart
327
+ part of '{feature}_bloc.dart';
328
+
329
+ abstract class {Feature}State extends Equatable {
330
+ const {Feature}State();
331
+
332
+ @override
333
+ List<Object?> get props => [];
334
+ }
335
+
336
+ class {Feature}Initial extends {Feature}State {
337
+ const {Feature}Initial();
338
+ }
339
+
340
+ class {Feature}Loading extends {Feature}State {
341
+ const {Feature}Loading();
342
+ }
343
+
344
+ class {Feature}Loaded extends {Feature}State {
345
+ final List<{Feature}Entity> items;
346
+
347
+ const {Feature}Loaded({required this.items});
348
+
349
+ @override
350
+ List<Object?> get props => [items];
351
+ }
352
+
353
+ class {Feature}Error extends {Feature}State {
354
+ final String message;
355
+
356
+ const {Feature}Error({required this.message});
357
+
358
+ @override
359
+ List<Object?> get props => [message];
360
+ }
21
361
  ```
22
- lib/features/{feature_name}/
23
- data/
24
- datasources/
25
- {feature}_local_datasource.dart
26
- {feature}_remote_datasource.dart
27
- models/
28
- {feature}_model.dart
29
- repositories/
30
- {feature}_repository_impl.dart
31
- domain/
32
- entities/
33
- {feature}.dart
34
- repositories/
35
- {feature}_repository.dart
36
- usecases/
37
- get_{feature}.dart
38
- presentation/
39
- bloc/
40
- {feature}_bloc.dart
41
- {feature}_event.dart
42
- {feature}_state.dart
43
- pages/
44
- {feature}_page.dart
45
- widgets/
46
- {feature}_widget.dart
362
+
363
+ ### Etapa 5: Página
364
+
365
+ ```dart
366
+ // lib/features/{feature}/presentation/pages/{feature}_page.dart
367
+ import 'package:flutter/material.dart';
368
+ import 'package:flutter_bloc/flutter_bloc.dart';
369
+ import '../bloc/{feature}_bloc.dart';
370
+ import '../widgets/{feature}_list_item.dart';
371
+
372
+ class {Feature}Page extends StatelessWidget {
373
+ const {Feature}Page({super.key});
374
+
375
+ static const routeName = '/{feature}';
376
+
377
+ @override
378
+ Widget build(BuildContext context) {
379
+ return Scaffold(
380
+ appBar: AppBar(
381
+ title: const Text('{Feature}'),
382
+ actions: [
383
+ IconButton(
384
+ icon: const Icon(Icons.refresh),
385
+ onPressed: () {
386
+ context.read<{Feature}Bloc>().add(const Refresh{Feature}List());
387
+ },
388
+ ),
389
+ ],
390
+ ),
391
+ body: BlocBuilder<{Feature}Bloc, {Feature}State>(
392
+ builder: (context, state) {
393
+ return switch (state) {
394
+ {Feature}Initial() => const Center(
395
+ child: Text('Pressione refresh'),
396
+ ),
397
+ {Feature}Loading() => const Center(
398
+ child: CircularProgressIndicator(),
399
+ ),
400
+ {Feature}Loaded(:final items) => items.isEmpty
401
+ ? const Center(child: Text('Nenhum item'))
402
+ : RefreshIndicator(
403
+ onRefresh: () async {
404
+ context
405
+ .read<{Feature}Bloc>()
406
+ .add(const Refresh{Feature}List());
407
+ },
408
+ child: ListView.builder(
409
+ itemCount: items.length,
410
+ itemBuilder: (context, index) {
411
+ return {Feature}ListItem(item: items[index]);
412
+ },
413
+ ),
414
+ ),
415
+ {Feature}Error(:final message) => Center(
416
+ child: Column(
417
+ mainAxisAlignment: MainAxisAlignment.center,
418
+ children: [
419
+ Text('Erro: $message'),
420
+ const SizedBox(height: 16),
421
+ ElevatedButton(
422
+ onPressed: () {
423
+ context
424
+ .read<{Feature}Bloc>()
425
+ .add(const Load{Feature}List());
426
+ },
427
+ child: const Text('Tentar novamente'),
428
+ ),
429
+ ],
430
+ ),
431
+ ),
432
+ };
433
+ },
434
+ ),
435
+ floatingActionButton: FloatingActionButton(
436
+ onPressed: () {
437
+ // Navegação para criação
438
+ },
439
+ child: const Icon(Icons.add),
440
+ ),
441
+ );
442
+ }
443
+ }
47
444
  ```
48
445
 
49
- ## Testes a Gerar
446
+ ### Etapa 6: Testes
447
+
448
+ ```dart
449
+ // test/features/{feature}/presentation/bloc/{feature}_bloc_test.dart
450
+ import 'package:bloc_test/bloc_test.dart';
451
+ import 'package:dartz/dartz.dart';
452
+ import 'package:flutter_test/flutter_test.dart';
453
+ import 'package:mocktail/mocktail.dart';
454
+
455
+ class MockGet{Feature}List extends Mock implements Get{Feature}List {}
456
+
457
+ void main() {
458
+ late {Feature}Bloc bloc;
459
+ late MockGet{Feature}List mockGet{Feature}List;
460
+
461
+ setUp(() {
462
+ mockGet{Feature}List = MockGet{Feature}List();
463
+ bloc = {Feature}Bloc(get{Feature}List: mockGet{Feature}List);
464
+ });
50
465
 
466
+ tearDown(() {
467
+ bloc.close();
468
+ });
469
+
470
+ test('initial state should be {Feature}Initial', () {
471
+ expect(bloc.state, const {Feature}Initial());
472
+ });
473
+
474
+ blocTest<{Feature}Bloc, {Feature}State>(
475
+ 'emits [Loading, Loaded] when Load{Feature}List is added successfully',
476
+ build: () {
477
+ when(() => mockGet{Feature}List(any()))
478
+ .thenAnswer((_) async => const Right([]));
479
+ return bloc;
480
+ },
481
+ act: (bloc) => bloc.add(const Load{Feature}List()),
482
+ expect: () => [
483
+ const {Feature}Loading(),
484
+ const {Feature}Loaded(items: []),
485
+ ],
486
+ );
487
+
488
+ blocTest<{Feature}Bloc, {Feature}State>(
489
+ 'emits [Loading, Error] when Load{Feature}List fails',
490
+ build: () {
491
+ when(() => mockGet{Feature}List(any()))
492
+ .thenAnswer((_) async => Left(ServerFailure()));
493
+ return bloc;
494
+ },
495
+ act: (bloc) => bloc.add(const Load{Feature}List()),
496
+ expect: () => [
497
+ const {Feature}Loading(),
498
+ isA<{Feature}Error>(),
499
+ ],
500
+ );
501
+ }
51
502
  ```
52
- test/features/{feature_name}/
53
- data/
54
- models/{feature}_model_test.dart
55
- repositories/{feature}_repository_impl_test.dart
56
- domain/
57
- usecases/get_{feature}_test.dart
58
- presentation/
59
- bloc/{feature}_bloc_test.dart
60
- widgets/{feature}_widget_test.dart
503
+
504
+ ### Etapa 7: Resumo
505
+
61
506
  ```
507
+ ══════════════════════════════════════════════════════════════
508
+ ✅ FEATURE GERADA - {feature}
509
+ ══════════════════════════════════════════════════════════════
62
510
 
63
- ## Ações
511
+ 📁 Arquivos criados:
64
512
 
65
- 1. Criar estrutura de pastas
66
- 2. Gerar arquivos com templates
67
- 3. Configurar injeção de dependências
68
- 4. Adicionar ao roteamento se necessário
69
- 5. Criar testes básicos
513
+ Camada de Domínio (4 arquivos):
514
+ - lib/features/{feature}/domain/entities/{feature}_entity.dart
515
+ - lib/features/{feature}/domain/repositories/{feature}_repository.dart
516
+ - lib/features/{feature}/domain/usecases/get_{feature}_list.dart
517
+ - lib/features/{feature}/domain/usecases/create_{feature}.dart
518
+
519
+ Camada de Dados (4 arquivos):
520
+ - lib/features/{feature}/data/models/{feature}_model.dart
521
+ - lib/features/{feature}/data/repositories/{feature}_repository_impl.dart
522
+ - lib/features/{feature}/data/datasources/{feature}_remote_datasource.dart
523
+ - lib/features/{feature}/data/datasources/{feature}_local_datasource.dart
524
+
525
+ Camada de Apresentação (6 arquivos):
526
+ - lib/features/{feature}/presentation/bloc/{feature}_bloc.dart
527
+ - lib/features/{feature}/presentation/bloc/{feature}_event.dart
528
+ - lib/features/{feature}/presentation/bloc/{feature}_state.dart
529
+ - lib/features/{feature}/presentation/pages/{feature}_page.dart
530
+ - lib/features/{feature}/presentation/widgets/{feature}_list_item.dart
531
+ - lib/features/{feature}/presentation/widgets/{feature}_form.dart
532
+
533
+ Testes (4 arquivos):
534
+ - test/features/{feature}/domain/usecases/get_{feature}_list_test.dart
535
+ - test/features/{feature}/data/repositories/{feature}_repository_impl_test.dart
536
+ - test/features/{feature}/presentation/bloc/{feature}_bloc_test.dart
537
+ - test/features/{feature}/presentation/pages/{feature}_page_test.dart
538
+
539
+ 🔧 Próximas etapas:
540
+ 1. Configurar a injeção de dependências (get_it/riverpod)
541
+ 2. Adicionar as rotas
542
+ 3. Implementar os datasources
543
+ 4. Executar os testes: flutter test
544
+ ```