@appiq/flutter-workflow 1.2.0 → 1.4.0

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.
@@ -0,0 +1,357 @@
1
+ # Additional Cubit Requirements - State Management Integration
2
+
3
+ This template defines additional state management requirements, provider setup, and integration patterns for your feature.
4
+
5
+ ## State Management Architecture
6
+
7
+ ### Cubit Integration Pattern
8
+ ```dart
9
+ // Feature-specific state management structure
10
+ lib/features/{feature}/presentation/cubit/
11
+ ├── {feature}_cubit.dart // Main cubit implementation
12
+ ├── {feature}_state.dart // State definitions
13
+ └── {feature}_event.dart // Events (if using BLoC pattern)
14
+ ```
15
+
16
+ ### Global State Dependencies
17
+ - [ ] Authentication state integration
18
+ - [ ] User role state management
19
+ - [ ] Theme/settings state access
20
+ - [ ] Navigation state coordination
21
+ - [ ] Network connectivity state
22
+ - [ ] Offline/online state management
23
+
24
+ ## Provider Setup Requirements
25
+
26
+ ### Main App Provider Configuration
27
+ ```dart
28
+ // Add to main.dart MultiBlocProvider
29
+ MultiBlocProvider(
30
+ providers: [
31
+ // Existing providers...
32
+ BlocProvider<{Feature}Cubit>(
33
+ create: (context) => GetIt.instance<{Feature}Cubit>(),
34
+ ),
35
+ // Additional feature dependencies...
36
+ ],
37
+ child: MyApp(),
38
+ )
39
+ ```
40
+
41
+ ### Dependency Injection Setup
42
+ ```dart
43
+ // Add to dependency injection configuration
44
+ void configureDependencies() {
45
+ // Repository registration
46
+ getIt.registerLazySingleton<{Feature}Repository>(
47
+ () => {Feature}RepositoryImpl(
48
+ remoteDataSource: getIt(),
49
+ localDataSource: getIt(),
50
+ networkInfo: getIt(),
51
+ ),
52
+ );
53
+
54
+ // Use case registration
55
+ getIt.registerLazySingleton(() => Get{Feature}UseCase(getIt()));
56
+ getIt.registerLazySingleton(() => Create{Feature}UseCase(getIt()));
57
+ getIt.registerLazySingleton(() => Update{Feature}UseCase(getIt()));
58
+ getIt.registerLazySingleton(() => Delete{Feature}UseCase(getIt()));
59
+
60
+ // Cubit registration
61
+ getIt.registerFactory<{Feature}Cubit>(
62
+ () => {Feature}Cubit(
63
+ get{Feature}UseCase: getIt(),
64
+ create{Feature}UseCase: getIt(),
65
+ update{Feature}UseCase: getIt(),
66
+ delete{Feature}UseCase: getIt(),
67
+ ),
68
+ );
69
+ }
70
+ ```
71
+
72
+ ## State Initialization Requirements
73
+
74
+ ### Initial State Setup
75
+ ```dart
76
+ class {Feature}Cubit extends Cubit<{Feature}State> {
77
+ {Feature}Cubit({
78
+ required this.get{Feature}UseCase,
79
+ required this.create{Feature}UseCase,
80
+ required this.update{Feature}UseCase,
81
+ required this.delete{Feature}UseCase,
82
+ }) : super(const {Feature}State.initial());
83
+
84
+ // Initialize feature data on cubit creation
85
+ Future<void> initialize() async {
86
+ emit(state.copyWith(status: {Feature}Status.loading));
87
+
88
+ try {
89
+ final result = await get{Feature}UseCase.call(NoParams());
90
+ result.fold(
91
+ (failure) => emit(state.copyWith(
92
+ status: {Feature}Status.error,
93
+ errorMessage: failure.message,
94
+ )),
95
+ (data) => emit(state.copyWith(
96
+ status: {Feature}Status.loaded,
97
+ items: data,
98
+ )),
99
+ );
100
+ } catch (e) {
101
+ emit(state.copyWith(
102
+ status: {Feature}Status.error,
103
+ errorMessage: 'Unexpected error occurred',
104
+ ));
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
110
+ ### Widget Integration Pattern
111
+ ```dart
112
+ class {Feature}Page extends StatefulWidget {
113
+ @override
114
+ _State createState() => _State();
115
+ }
116
+
117
+ class _State extends State<{Feature}Page> {
118
+ late {Feature}Cubit cubit;
119
+
120
+ @override
121
+ void initState() {
122
+ super.initState();
123
+ cubit = context.read<{Feature}Cubit>();
124
+ // Initialize cubit data
125
+ cubit.initialize();
126
+ }
127
+
128
+ @override
129
+ Widget build(BuildContext context) {
130
+ return BlocConsumer<{Feature}Cubit, {Feature}State>(
131
+ listener: (context, state) {
132
+ // Handle side effects (navigation, snackbars, etc.)
133
+ if (state.status == {Feature}Status.error) {
134
+ ScaffoldMessenger.of(context).showSnackBar(
135
+ SnackBar(content: Text(state.errorMessage ?? 'Error occurred')),
136
+ );
137
+ }
138
+ },
139
+ builder: (context, state) {
140
+ return Scaffold(
141
+ body: _buildBody(state),
142
+ );
143
+ },
144
+ );
145
+ }
146
+ }
147
+ ```
148
+
149
+ ## Common Integration Issues & Solutions
150
+
151
+ ### Issue 1: Cubit Not Initialized
152
+ **Problem**: `BlocProvider.of() called with a context that does not contain a Cubit`
153
+ **Solution**:
154
+ ```dart
155
+ // Ensure proper provider hierarchy
156
+ MaterialApp(
157
+ home: MultiBlocProvider(
158
+ providers: [
159
+ BlocProvider<{Feature}Cubit>(
160
+ create: (context) => GetIt.instance<{Feature}Cubit>(),
161
+ ),
162
+ ],
163
+ child: {Feature}Page(),
164
+ ),
165
+ )
166
+ ```
167
+
168
+ ### Issue 2: Duplicate Cubit Registration
169
+ **Problem**: Multiple registrations of the same cubit type
170
+ **Solution**:
171
+ ```dart
172
+ // Use registerFactory for cubits (new instance per request)
173
+ getIt.registerFactory<{Feature}Cubit>(() => {Feature}Cubit(...));
174
+
175
+ // Or check if already registered
176
+ if (!getIt.isRegistered<{Feature}Cubit>()) {
177
+ getIt.registerFactory<{Feature}Cubit>(() => {Feature}Cubit(...));
178
+ }
179
+ ```
180
+
181
+ ### Issue 3: State Not Persisting Across Navigation
182
+ **Problem**: State resets when navigating between screens
183
+ **Solution**:
184
+ ```dart
185
+ // Use singleton registration for state that should persist
186
+ getIt.registerLazySingleton<{Feature}Cubit>(() => {Feature}Cubit(...));
187
+
188
+ // Or use global provider at app level
189
+ class MyApp extends StatelessWidget {
190
+ @override
191
+ Widget build(BuildContext context) {
192
+ return MultiBlocProvider(
193
+ providers: [
194
+ BlocProvider<{Feature}Cubit>(
195
+ create: (context) => GetIt.instance<{Feature}Cubit>(),
196
+ ),
197
+ ],
198
+ child: MaterialApp(...),
199
+ );
200
+ }
201
+ }
202
+ ```
203
+
204
+ ## Cross-Feature State Communication
205
+
206
+ ### Feature-to-Feature State Updates
207
+ ```dart
208
+ class {Feature}Cubit extends Cubit<{Feature}State> {
209
+ final AuthenticationCubit authCubit;
210
+ final UserRoleCubit userRoleCubit;
211
+ late StreamSubscription authSubscription;
212
+
213
+ {Feature}Cubit({
214
+ required this.authCubit,
215
+ required this.userRoleCubit,
216
+ // ... other dependencies
217
+ }) : super(const {Feature}State.initial()) {
218
+ // Listen to authentication changes
219
+ authSubscription = authCubit.stream.listen((authState) {
220
+ if (authState is! AuthenticatedState) {
221
+ // Clear feature data on logout
222
+ emit(const {Feature}State.initial());
223
+ }
224
+ });
225
+ }
226
+
227
+ @override
228
+ Future<void> close() {
229
+ authSubscription.cancel();
230
+ return super.close();
231
+ }
232
+ }
233
+ ```
234
+
235
+ ### Global State Access Pattern
236
+ ```dart
237
+ // Access other cubits from within a cubit
238
+ void updateBasedOnUserRole() {
239
+ final userRole = userRoleCubit.state.role;
240
+
241
+ switch (userRole) {
242
+ case UserRole.admin:
243
+ loadAdminData();
244
+ break;
245
+ case UserRole.manager:
246
+ loadManagerData();
247
+ break;
248
+ case UserRole.user:
249
+ loadUserData();
250
+ break;
251
+ }
252
+ }
253
+ ```
254
+
255
+ ## Performance Optimization
256
+
257
+ ### Selective State Updates
258
+ ```dart
259
+ // Use copyWith efficiently to avoid unnecessary rebuilds
260
+ emit(state.copyWith(
261
+ status: {Feature}Status.loading,
262
+ // Only update changed fields
263
+ ));
264
+
265
+ // Use state comparison to prevent duplicate emissions
266
+ void updateItems(List<{Entity}> newItems) {
267
+ if (!listEquals(state.items, newItems)) {
268
+ emit(state.copyWith(items: newItems));
269
+ }
270
+ }
271
+ ```
272
+
273
+ ### Memory Management
274
+ ```dart
275
+ class {Feature}Cubit extends Cubit<{Feature}State> {
276
+ final List<StreamSubscription> _subscriptions = [];
277
+
278
+ void addSubscription(StreamSubscription subscription) {
279
+ _subscriptions.add(subscription);
280
+ }
281
+
282
+ @override
283
+ Future<void> close() {
284
+ // Cancel all subscriptions
285
+ for (final subscription in _subscriptions) {
286
+ subscription.cancel();
287
+ }
288
+ _subscriptions.clear();
289
+ return super.close();
290
+ }
291
+ }
292
+ ```
293
+
294
+ ## Testing Integration
295
+
296
+ ### Cubit Testing Setup
297
+ ```dart
298
+ // Test setup with proper mocking
299
+ class MockAuthCubit extends MockCubit<AuthState> implements AuthCubit {}
300
+ class MockUserRoleCubit extends MockCubit<UserRoleState> implements UserRoleCubit {}
301
+
302
+ void main() {
303
+ late {Feature}Cubit cubit;
304
+ late MockAuthCubit mockAuthCubit;
305
+ late MockUserRoleCubit mockUserRoleCubit;
306
+
307
+ setUp(() {
308
+ mockAuthCubit = MockAuthCubit();
309
+ mockUserRoleCubit = MockUserRoleCubit();
310
+
311
+ cubit = {Feature}Cubit(
312
+ authCubit: mockAuthCubit,
313
+ userRoleCubit: mockUserRoleCubit,
314
+ // ... other dependencies
315
+ );
316
+ });
317
+
318
+ tearDown(() {
319
+ cubit.close();
320
+ });
321
+ }
322
+ ```
323
+
324
+ ## Integration Checklist
325
+
326
+ ### Provider Setup
327
+ - [ ] Cubit registered in dependency injection
328
+ - [ ] Provider added to MultiBlocProvider
329
+ - [ ] Dependencies properly injected
330
+ - [ ] Initialization logic implemented
331
+
332
+ ### State Management
333
+ - [ ] Initial state properly defined
334
+ - [ ] State transitions implemented
335
+ - [ ] Error handling added
336
+ - [ ] Loading states managed
337
+
338
+ ### Cross-Feature Integration
339
+ - [ ] Authentication state integration
340
+ - [ ] User role state access
341
+ - [ ] Global state dependencies resolved
342
+ - [ ] Navigation state coordination
343
+
344
+ ### Performance & Memory
345
+ - [ ] Efficient state updates implemented
346
+ - [ ] Memory leaks prevented (subscriptions canceled)
347
+ - [ ] Unnecessary rebuilds minimized
348
+ - [ ] State persistence strategy defined
349
+
350
+ ### Testing
351
+ - [ ] Unit tests for cubit logic
352
+ - [ ] Integration tests with providers
353
+ - [ ] Mock implementations for dependencies
354
+ - [ ] Error scenario testing
355
+
356
+ ## Notes
357
+ Add any feature-specific state management requirements, custom integration patterns, or special initialization needs.