@appiq/flutter-workflow 1.1.0 → 1.3.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.
- package/CHANGELOG.md +106 -0
- package/agents/claude/cubit-agent.md +63 -0
- package/agents/claude/data-agent.md +93 -0
- package/agents/claude/domain-agent.md +76 -0
- package/agents/claude/initial-flow-agent.md +55 -0
- package/agents/claude/orchestrator.md +41 -0
- package/agents/claude/po-agent.md +42 -0
- package/agents/claude/security-agent.md +91 -0
- package/agents/claude/test-agent.md +114 -0
- package/agents/claude/ui-agent.md +56 -0
- package/agents/data-agent.md +20 -13
- package/agents/initial-flow-agent.md +342 -0
- package/bin/cli.js +61 -3
- package/package.json +2 -2
- package/templates/additional_cubit_req.md +357 -0
- package/templates/additional_data_req.md +480 -0
- package/templates/additional_domain_req.md +431 -0
- package/templates/additional_ui_req.md +205 -0
@@ -0,0 +1,480 @@
|
|
1
|
+
# Additional Data Requirements - Supabase MCP Integration
|
2
|
+
|
3
|
+
This template defines advanced data layer requirements with Supabase MCP integration for automated backend communication and management.
|
4
|
+
|
5
|
+
## Supabase MCP Integration
|
6
|
+
|
7
|
+
### Automatic Backend Setup
|
8
|
+
The Data Agent now includes Supabase MCP integration for seamless backend operations:
|
9
|
+
- **Database Schema Creation** - Automatic table and relationship setup
|
10
|
+
- **API Generation** - Auto-generated REST and GraphQL endpoints
|
11
|
+
- **Authentication Integration** - Built-in user management and session handling
|
12
|
+
- **Real-time Subscriptions** - Live data updates and change notifications
|
13
|
+
- **File Storage Integration** - Automatic file upload and management
|
14
|
+
- **Edge Functions** - Serverless function deployment and management
|
15
|
+
|
16
|
+
### MCP Configuration
|
17
|
+
```yaml
|
18
|
+
# Supabase MCP automatically configured for:
|
19
|
+
database:
|
20
|
+
- table_creation: true
|
21
|
+
- relationship_setup: true
|
22
|
+
- index_optimization: true
|
23
|
+
- rls_policies: true
|
24
|
+
|
25
|
+
api:
|
26
|
+
- rest_endpoints: auto_generated
|
27
|
+
- graphql_schema: auto_generated
|
28
|
+
- openapi_spec: auto_generated
|
29
|
+
|
30
|
+
auth:
|
31
|
+
- user_management: enabled
|
32
|
+
- session_handling: automatic
|
33
|
+
- oauth_providers: configurable
|
34
|
+
- jwt_validation: built_in
|
35
|
+
|
36
|
+
realtime:
|
37
|
+
- change_subscriptions: enabled
|
38
|
+
- broadcast_channels: enabled
|
39
|
+
- presence_tracking: enabled
|
40
|
+
|
41
|
+
storage:
|
42
|
+
- bucket_management: automatic
|
43
|
+
- file_uploads: integrated
|
44
|
+
- cdn_optimization: enabled
|
45
|
+
```
|
46
|
+
|
47
|
+
## Advanced Data Layer Patterns
|
48
|
+
|
49
|
+
### Real-time Data Synchronization
|
50
|
+
```dart
|
51
|
+
class {Entity}RealtimeRepository extends {Entity}Repository {
|
52
|
+
final SupabaseClient supabase;
|
53
|
+
final RealtimeChannel? _subscription;
|
54
|
+
|
55
|
+
{Entity}RealtimeRepository({required this.supabase});
|
56
|
+
|
57
|
+
// Automatic real-time subscription setup via MCP
|
58
|
+
Stream<List<{Entity}>> watchEntities() {
|
59
|
+
return supabase
|
60
|
+
.from('{entity_table}')
|
61
|
+
.stream(primaryKey: ['id'])
|
62
|
+
.map((data) => data.map((json) => {Entity}.fromJson(json)).toList());
|
63
|
+
}
|
64
|
+
|
65
|
+
// Real-time updates with optimistic UI
|
66
|
+
Future<Either<Failure, {Entity}>> updateWithRealtime({Entity} entity) async {
|
67
|
+
try {
|
68
|
+
// MCP handles optimistic updates and conflict resolution
|
69
|
+
final response = await supabase
|
70
|
+
.from('{entity_table}')
|
71
|
+
.update(entity.toJson())
|
72
|
+
.eq('id', entity.id)
|
73
|
+
.select();
|
74
|
+
|
75
|
+
if (response.isEmpty) {
|
76
|
+
return Left(DataFailure('Update failed'));
|
77
|
+
}
|
78
|
+
|
79
|
+
return Right({Entity}.fromJson(response.first));
|
80
|
+
} catch (e) {
|
81
|
+
return Left(DataFailure(e.toString()));
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
```
|
86
|
+
|
87
|
+
### Automated Database Migrations
|
88
|
+
```dart
|
89
|
+
// MCP automatically handles database schema changes
|
90
|
+
class DatabaseMigrationManager {
|
91
|
+
final SupabaseClient supabase;
|
92
|
+
|
93
|
+
// MCP integration for automatic migrations
|
94
|
+
Future<void> runMigrations() async {
|
95
|
+
// Supabase MCP automatically:
|
96
|
+
// 1. Detects schema changes in entities
|
97
|
+
// 2. Generates migration scripts
|
98
|
+
// 3. Applies migrations safely
|
99
|
+
// 4. Updates API endpoints
|
100
|
+
// 5. Refreshes client SDKs
|
101
|
+
|
102
|
+
await supabase.rpc('apply_automatic_migrations');
|
103
|
+
}
|
104
|
+
}
|
105
|
+
```
|
106
|
+
|
107
|
+
### Advanced Query Optimization
|
108
|
+
```dart
|
109
|
+
class OptimizedQueryRepository {
|
110
|
+
final SupabaseClient supabase;
|
111
|
+
|
112
|
+
// MCP-optimized complex queries
|
113
|
+
Future<Either<Failure, List<{Entity}>>> getEntitiesWithRelations({
|
114
|
+
required QueryParams params,
|
115
|
+
}) async {
|
116
|
+
try {
|
117
|
+
// MCP automatically optimizes:
|
118
|
+
// - Join operations
|
119
|
+
// - Index usage
|
120
|
+
// - Query planning
|
121
|
+
// - Result caching
|
122
|
+
|
123
|
+
final query = supabase
|
124
|
+
.from('{entity_table}')
|
125
|
+
.select('''
|
126
|
+
*,
|
127
|
+
related_table!inner(*),
|
128
|
+
nested_relation(*)
|
129
|
+
''');
|
130
|
+
|
131
|
+
// Apply filters with MCP optimization
|
132
|
+
if (params.filters.isNotEmpty) {
|
133
|
+
for (final filter in params.filters) {
|
134
|
+
query.filter(filter.column, filter.operator, filter.value);
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
// MCP handles pagination and sorting
|
139
|
+
final response = await query
|
140
|
+
.range(params.offset, params.offset + params.limit)
|
141
|
+
.order(params.sortBy, ascending: params.ascending);
|
142
|
+
|
143
|
+
return Right(
|
144
|
+
response.map((json) => {Entity}.fromJson(json)).toList(),
|
145
|
+
);
|
146
|
+
} catch (e) {
|
147
|
+
return Left(DataFailure('Query failed: ${e.toString()}'));
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
```
|
152
|
+
|
153
|
+
## File Storage Integration
|
154
|
+
|
155
|
+
### Automatic File Management
|
156
|
+
```dart
|
157
|
+
class {Entity}StorageRepository {
|
158
|
+
final SupabaseClient supabase;
|
159
|
+
|
160
|
+
// MCP-managed file operations
|
161
|
+
Future<Either<Failure, String>> uploadFile({
|
162
|
+
required File file,
|
163
|
+
required String bucket,
|
164
|
+
String? path,
|
165
|
+
}) async {
|
166
|
+
try {
|
167
|
+
// MCP automatically handles:
|
168
|
+
// - File validation and processing
|
169
|
+
// - Thumbnail generation
|
170
|
+
// - Compression optimization
|
171
|
+
// - CDN distribution
|
172
|
+
// - Security scanning
|
173
|
+
|
174
|
+
final fileName = path ?? '${DateTime.now().millisecondsSinceEpoch}_${file.path.split('/').last}';
|
175
|
+
|
176
|
+
await supabase.storage
|
177
|
+
.from(bucket)
|
178
|
+
.upload(fileName, file);
|
179
|
+
|
180
|
+
// Get public URL with CDN optimization
|
181
|
+
final publicUrl = supabase.storage
|
182
|
+
.from(bucket)
|
183
|
+
.getPublicUrl(fileName);
|
184
|
+
|
185
|
+
return Right(publicUrl);
|
186
|
+
} catch (e) {
|
187
|
+
return Left(StorageFailure(e.toString()));
|
188
|
+
}
|
189
|
+
}
|
190
|
+
|
191
|
+
// Automatic file cleanup and lifecycle management
|
192
|
+
Future<Either<Failure, void>> cleanupOrphanedFiles() async {
|
193
|
+
try {
|
194
|
+
// MCP automatically identifies and removes unused files
|
195
|
+
await supabase.rpc('cleanup_orphaned_files');
|
196
|
+
return const Right(null);
|
197
|
+
} catch (e) {
|
198
|
+
return Left(StorageFailure(e.toString()));
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
```
|
203
|
+
|
204
|
+
## Authentication & Security Integration
|
205
|
+
|
206
|
+
### Automatic User Management
|
207
|
+
```dart
|
208
|
+
class AuthRepository {
|
209
|
+
final SupabaseClient supabase;
|
210
|
+
|
211
|
+
// MCP-integrated authentication
|
212
|
+
Future<Either<Failure, User>> signUpWithEmail({
|
213
|
+
required String email,
|
214
|
+
required String password,
|
215
|
+
Map<String, dynamic>? metadata,
|
216
|
+
}) async {
|
217
|
+
try {
|
218
|
+
// MCP automatically handles:
|
219
|
+
// - Email validation and verification
|
220
|
+
// - Password strength enforcement
|
221
|
+
// - Rate limiting and security
|
222
|
+
// - User profile creation
|
223
|
+
// - Welcome email sequences
|
224
|
+
|
225
|
+
final response = await supabase.auth.signUp(
|
226
|
+
email: email,
|
227
|
+
password: password,
|
228
|
+
data: metadata,
|
229
|
+
);
|
230
|
+
|
231
|
+
if (response.user == null) {
|
232
|
+
return Left(AuthFailure('Sign up failed'));
|
233
|
+
}
|
234
|
+
|
235
|
+
return Right(User.fromSupabaseUser(response.user!));
|
236
|
+
} catch (e) {
|
237
|
+
return Left(AuthFailure(e.toString()));
|
238
|
+
}
|
239
|
+
}
|
240
|
+
|
241
|
+
// Automatic session management
|
242
|
+
Stream<AuthState> watchAuthState() {
|
243
|
+
return supabase.auth.onAuthStateChange.map((event) {
|
244
|
+
return AuthState.fromSupabaseAuthState(event);
|
245
|
+
});
|
246
|
+
}
|
247
|
+
}
|
248
|
+
```
|
249
|
+
|
250
|
+
### Row Level Security (RLS) Integration
|
251
|
+
```dart
|
252
|
+
// MCP automatically configures RLS policies
|
253
|
+
class SecureDataRepository {
|
254
|
+
final SupabaseClient supabase;
|
255
|
+
|
256
|
+
// Queries automatically respect RLS policies
|
257
|
+
Future<Either<Failure, List<{Entity}>>> getUserEntities() async {
|
258
|
+
try {
|
259
|
+
// MCP automatically:
|
260
|
+
// - Applies user-specific RLS policies
|
261
|
+
// - Validates permissions
|
262
|
+
// - Logs access attempts
|
263
|
+
// - Handles multi-tenant data isolation
|
264
|
+
|
265
|
+
final response = await supabase
|
266
|
+
.from('{entity_table}')
|
267
|
+
.select()
|
268
|
+
.eq('user_id', supabase.auth.currentUser?.id);
|
269
|
+
|
270
|
+
return Right(
|
271
|
+
response.map((json) => {Entity}.fromJson(json)).toList(),
|
272
|
+
);
|
273
|
+
} catch (e) {
|
274
|
+
return Left(SecurityFailure(e.toString()));
|
275
|
+
}
|
276
|
+
}
|
277
|
+
}
|
278
|
+
```
|
279
|
+
|
280
|
+
## Edge Functions Integration
|
281
|
+
|
282
|
+
### Automatic Function Deployment
|
283
|
+
```dart
|
284
|
+
class EdgeFunctionRepository {
|
285
|
+
final SupabaseClient supabase;
|
286
|
+
|
287
|
+
// MCP-deployed edge functions
|
288
|
+
Future<Either<Failure, T>> callEdgeFunction<T>({
|
289
|
+
required String functionName,
|
290
|
+
required Map<String, dynamic> payload,
|
291
|
+
required T Function(Map<String, dynamic>) fromJson,
|
292
|
+
}) async {
|
293
|
+
try {
|
294
|
+
// MCP automatically:
|
295
|
+
// - Deploys functions based on use case definitions
|
296
|
+
// - Handles authentication and authorization
|
297
|
+
// - Manages function versioning
|
298
|
+
// - Provides monitoring and logging
|
299
|
+
|
300
|
+
final response = await supabase.functions.invoke(
|
301
|
+
functionName,
|
302
|
+
body: payload,
|
303
|
+
);
|
304
|
+
|
305
|
+
if (response.data == null) {
|
306
|
+
return Left(FunctionFailure('Function call failed'));
|
307
|
+
}
|
308
|
+
|
309
|
+
return Right(fromJson(response.data));
|
310
|
+
} catch (e) {
|
311
|
+
return Left(FunctionFailure(e.toString()));
|
312
|
+
}
|
313
|
+
}
|
314
|
+
}
|
315
|
+
```
|
316
|
+
|
317
|
+
## Offline-First with Sync
|
318
|
+
|
319
|
+
### Automatic Data Synchronization
|
320
|
+
```dart
|
321
|
+
class OfflineFirstRepository extends {Entity}Repository {
|
322
|
+
final SupabaseClient supabase;
|
323
|
+
final LocalDatabase localDb;
|
324
|
+
|
325
|
+
// MCP-managed offline/online sync
|
326
|
+
Future<Either<Failure, List<{Entity}>>> getEntitiesOfflineFirst() async {
|
327
|
+
try {
|
328
|
+
// 1. Return local data immediately
|
329
|
+
final localData = await localDb.getEntities();
|
330
|
+
|
331
|
+
// 2. MCP automatically syncs in background
|
332
|
+
_syncWithSupabase();
|
333
|
+
|
334
|
+
return Right(localData);
|
335
|
+
} catch (e) {
|
336
|
+
return Left(DataFailure(e.toString()));
|
337
|
+
}
|
338
|
+
}
|
339
|
+
|
340
|
+
Future<void> _syncWithSupabase() async {
|
341
|
+
// MCP handles:
|
342
|
+
// - Conflict resolution
|
343
|
+
// - Delta synchronization
|
344
|
+
// - Connection state management
|
345
|
+
// - Retry logic with exponential backoff
|
346
|
+
|
347
|
+
await supabase.rpc('sync_offline_data', params: {
|
348
|
+
'last_sync': await localDb.getLastSyncTime(),
|
349
|
+
'local_changes': await localDb.getPendingChanges(),
|
350
|
+
});
|
351
|
+
}
|
352
|
+
}
|
353
|
+
```
|
354
|
+
|
355
|
+
## Performance Optimization
|
356
|
+
|
357
|
+
### Automatic Caching & CDN
|
358
|
+
```dart
|
359
|
+
class CachedDataRepository {
|
360
|
+
final SupabaseClient supabase;
|
361
|
+
final CacheManager cache;
|
362
|
+
|
363
|
+
Future<Either<Failure, List<{Entity}>>> getCachedEntities() async {
|
364
|
+
try {
|
365
|
+
// MCP automatically:
|
366
|
+
// - Implements intelligent caching strategies
|
367
|
+
// - Manages cache invalidation
|
368
|
+
// - Distributes via CDN
|
369
|
+
// - Compresses responses
|
370
|
+
// - Handles cache warming
|
371
|
+
|
372
|
+
final cacheKey = 'entities_${DateTime.now().day}';
|
373
|
+
|
374
|
+
// Check cache first
|
375
|
+
final cached = await cache.get(cacheKey);
|
376
|
+
if (cached != null) {
|
377
|
+
return Right(cached);
|
378
|
+
}
|
379
|
+
|
380
|
+
// Fetch from Supabase with MCP optimizations
|
381
|
+
final response = await supabase
|
382
|
+
.from('{entity_table}')
|
383
|
+
.select()
|
384
|
+
.withCount();
|
385
|
+
|
386
|
+
final entities = response.map((json) => {Entity}.fromJson(json)).toList();
|
387
|
+
|
388
|
+
// Cache with MCP-determined TTL
|
389
|
+
await cache.set(cacheKey, entities);
|
390
|
+
|
391
|
+
return Right(entities);
|
392
|
+
} catch (e) {
|
393
|
+
return Left(DataFailure(e.toString()));
|
394
|
+
}
|
395
|
+
}
|
396
|
+
}
|
397
|
+
```
|
398
|
+
|
399
|
+
## Analytics & Monitoring
|
400
|
+
|
401
|
+
### Automatic Performance Tracking
|
402
|
+
```dart
|
403
|
+
class AnalyticsRepository {
|
404
|
+
final SupabaseClient supabase;
|
405
|
+
|
406
|
+
// MCP automatically tracks:
|
407
|
+
// - Query performance
|
408
|
+
// - Error rates
|
409
|
+
// - User behavior
|
410
|
+
// - System usage
|
411
|
+
// - Cost optimization opportunities
|
412
|
+
|
413
|
+
Future<void> trackUserAction({
|
414
|
+
required String action,
|
415
|
+
Map<String, dynamic>? metadata,
|
416
|
+
}) async {
|
417
|
+
// Automatic analytics via MCP
|
418
|
+
await supabase.rpc('track_analytics_event', params: {
|
419
|
+
'event_name': action,
|
420
|
+
'user_id': supabase.auth.currentUser?.id,
|
421
|
+
'metadata': metadata,
|
422
|
+
'timestamp': DateTime.now().toIso8601String(),
|
423
|
+
});
|
424
|
+
}
|
425
|
+
}
|
426
|
+
```
|
427
|
+
|
428
|
+
## Implementation Checklist
|
429
|
+
|
430
|
+
### Supabase MCP Setup
|
431
|
+
- [ ] Supabase project configured with MCP integration
|
432
|
+
- [ ] Database schema automatically generated from entities
|
433
|
+
- [ ] API endpoints auto-generated with proper typing
|
434
|
+
- [ ] Authentication and session management configured
|
435
|
+
- [ ] Real-time subscriptions enabled
|
436
|
+
- [ ] File storage buckets and policies setup
|
437
|
+
- [ ] Edge functions deployed for business logic
|
438
|
+
|
439
|
+
### Data Layer Implementation
|
440
|
+
- [ ] Repository implementations with Supabase MCP integration
|
441
|
+
- [ ] Real-time data synchronization patterns
|
442
|
+
- [ ] Offline-first architecture with automatic sync
|
443
|
+
- [ ] File upload and management integration
|
444
|
+
- [ ] Authentication state management
|
445
|
+
- [ ] Row-level security and permission handling
|
446
|
+
|
447
|
+
### Performance & Monitoring
|
448
|
+
- [ ] Automatic caching and CDN configuration
|
449
|
+
- [ ] Query optimization and performance monitoring
|
450
|
+
- [ ] Error tracking and logging setup
|
451
|
+
- [ ] Analytics and user behavior tracking
|
452
|
+
- [ ] Cost optimization and usage monitoring
|
453
|
+
- [ ] Automated backup and disaster recovery
|
454
|
+
|
455
|
+
### Security & Compliance
|
456
|
+
- [ ] Row-level security policies configured
|
457
|
+
- [ ] User permission and role management
|
458
|
+
- [ ] Data encryption and security scanning
|
459
|
+
- [ ] GDPR and compliance feature setup
|
460
|
+
- [ ] Audit logging and security monitoring
|
461
|
+
- [ ] Automated security updates and patches
|
462
|
+
|
463
|
+
## MCP Benefits
|
464
|
+
|
465
|
+
### Developer Experience
|
466
|
+
- **Zero Backend Configuration** - MCP handles all Supabase setup automatically
|
467
|
+
- **Type-Safe APIs** - Auto-generated client SDKs with full type safety
|
468
|
+
- **Real-time by Default** - Live data updates without manual subscription management
|
469
|
+
- **Automatic Scaling** - Backend scales automatically based on usage
|
470
|
+
- **Built-in Security** - RLS and authentication handled automatically
|
471
|
+
|
472
|
+
### Production Ready
|
473
|
+
- **High Availability** - Built-in redundancy and failover
|
474
|
+
- **Global CDN** - Automatic content distribution and caching
|
475
|
+
- **Monitoring & Alerts** - Comprehensive monitoring and alerting
|
476
|
+
- **Automated Backups** - Point-in-time recovery and data protection
|
477
|
+
- **Compliance Ready** - GDPR, SOC2, and other compliance features
|
478
|
+
|
479
|
+
## Notes
|
480
|
+
The Supabase MCP integration eliminates manual backend configuration and provides a fully automated, production-ready data layer that scales automatically and handles all the complex backend operations seamlessly.
|