interaqt 0.3.0 → 0.3.1

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 (35) hide show
  1. package/agent/.claude/agents/code-generation-handler.md +2 -0
  2. package/agent/.claude/agents/computation-generation-handler.md +1 -0
  3. package/agent/.claude/agents/implement-design-handler.md +4 -13
  4. package/agent/.claude/agents/requirements-analysis-handler.md +46 -14
  5. package/agent/agentspace/knowledge/generator/api-reference.md +3378 -0
  6. package/agent/agentspace/knowledge/generator/basic-interaction-generation.md +377 -0
  7. package/agent/agentspace/knowledge/generator/computation-analysis.md +307 -0
  8. package/agent/agentspace/knowledge/generator/computation-implementation.md +959 -0
  9. package/agent/agentspace/knowledge/generator/data-analysis.md +463 -0
  10. package/agent/agentspace/knowledge/generator/entity-relation-generation.md +395 -0
  11. package/agent/agentspace/knowledge/generator/permission-implementation.md +460 -0
  12. package/agent/agentspace/knowledge/generator/permission-test-implementation.md +870 -0
  13. package/agent/agentspace/knowledge/generator/test-implementation.md +674 -0
  14. package/agent/agentspace/knowledge/usage/00-mindset-shift.md +322 -0
  15. package/agent/agentspace/knowledge/usage/01-core-concepts.md +131 -0
  16. package/agent/agentspace/knowledge/usage/02-define-entities-properties.md +407 -0
  17. package/agent/agentspace/knowledge/usage/03-entity-relations.md +599 -0
  18. package/agent/agentspace/knowledge/usage/04-reactive-computations.md +2186 -0
  19. package/agent/agentspace/knowledge/usage/05-interactions.md +1411 -0
  20. package/agent/agentspace/knowledge/usage/06-attributive-permissions.md +10 -0
  21. package/agent/agentspace/knowledge/usage/07-payload-parameters.md +593 -0
  22. package/agent/agentspace/knowledge/usage/08-activities.md +863 -0
  23. package/agent/agentspace/knowledge/usage/09-filtered-entities.md +784 -0
  24. package/agent/agentspace/knowledge/usage/10-async-computations.md +734 -0
  25. package/agent/agentspace/knowledge/usage/11-global-dictionaries.md +942 -0
  26. package/agent/agentspace/knowledge/usage/12-data-querying.md +1033 -0
  27. package/agent/agentspace/knowledge/usage/13-testing.md +1201 -0
  28. package/agent/agentspace/knowledge/usage/14-api-reference.md +1606 -0
  29. package/agent/agentspace/knowledge/usage/15-entity-crud-patterns.md +1122 -0
  30. package/agent/agentspace/knowledge/usage/16-frontend-page-design-guide.md +485 -0
  31. package/agent/agentspace/knowledge/usage/17-performance-optimization.md +283 -0
  32. package/agent/agentspace/knowledge/usage/18-api-exports-reference.md +176 -0
  33. package/agent/agentspace/knowledge/usage/19-common-anti-patterns.md +563 -0
  34. package/agent/agentspace/knowledge/usage/README.md +148 -0
  35. package/package.json +1 -1
@@ -0,0 +1,10 @@
1
+ # Permission Control (Deprecated)
2
+
3
+ The `userAttributives` and `dataAttributives` permission control features have been removed from the interaqt framework.
4
+
5
+ For controlling access to interactions and data, please use:
6
+ - `conditions` parameter in Interaction.create() for execution conditions
7
+ - Application-level authentication and authorization (e.g., JWT, OAuth)
8
+ - Custom business logic in your interactions
9
+
10
+ The framework now focuses on reactive business logic rather than built-in permission control.
@@ -0,0 +1,593 @@
1
+ # How to Use Payload for Interaction Parameters
2
+
3
+ Payload is the core mechanism for defining and validating interaction parameters in interaqt. It allows you to declare what data an interaction accepts, enforce validation rules, and ensure type safety through the framework's reactive system.
4
+
5
+ ## Understanding Payload and PayloadItem
6
+
7
+ ### What is Payload
8
+
9
+ Payload defines the structure and validation rules for data that users pass to interactions. It consists of one or more PayloadItems, each representing a specific parameter.
10
+
11
+ ```javascript
12
+ const CreatePost = Interaction.create({
13
+ name: 'CreatePost',
14
+ action: Action.create({ name: 'create' }),
15
+ payload: Payload.create({
16
+ items: [
17
+ PayloadItem.create({ name: 'title', required: true }),
18
+ PayloadItem.create({ name: 'content', required: true }),
19
+ PayloadItem.create({ name: 'tags', isCollection: true })
20
+ ]
21
+ })
22
+ });
23
+ ```
24
+
25
+ ### PayloadItem Structure
26
+
27
+ ```javascript
28
+ PayloadItem.create({
29
+ name: 'itemName', // Parameter name (required)
30
+ base: Entity, // Reference to Entity/Relation (optional)
31
+ isRef: true, // Whether it's a reference with id (default: false)
32
+ required: true, // Whether this parameter is required (default: false)
33
+ isCollection: true, // Whether it's an array (default: false)
34
+ attributives: Attributive, // Validation rules (optional)
35
+ itemRef: Entity // Reference to other concepts (optional)
36
+ })
37
+ ```
38
+
39
+ ## Basic Payload Usage
40
+
41
+ ### Simple Parameters Without Entity Reference
42
+
43
+ When PayloadItem doesn't have a `base` property, the framework treats it as simple data without concept validation:
44
+
45
+ ```javascript
46
+ const SendMessage = Interaction.create({
47
+ name: 'SendMessage',
48
+ action: Action.create({ name: 'send' }),
49
+ payload: Payload.create({
50
+ items: [
51
+ // Simple string parameter
52
+ PayloadItem.create({
53
+ name: 'message',
54
+ required: true
55
+ }),
56
+ // Simple number parameter
57
+ PayloadItem.create({
58
+ name: 'priority',
59
+ required: false
60
+ }),
61
+ // Array of strings
62
+ PayloadItem.create({
63
+ name: 'recipients',
64
+ isCollection: true,
65
+ required: true
66
+ })
67
+ ]
68
+ })
69
+ });
70
+
71
+ // Usage:
72
+ await controller.callInteraction('SendMessage', {
73
+ user: currentUser,
74
+ payload: {
75
+ message: 'Hello World',
76
+ priority: 1,
77
+ recipients: ['user1@example.com', 'user2@example.com']
78
+ }
79
+ });
80
+ ```
81
+
82
+ **Important**: When `base` is not specified, the framework only checks:
83
+ - Whether required parameters are present
84
+ - Whether collection parameters are arrays
85
+ - No concept validation or attributive checks are performed
86
+
87
+ ### Parameters with Entity Reference
88
+
89
+ When PayloadItem has a `base` property pointing to an Entity, the framework provides additional validation:
90
+
91
+ ```javascript
92
+ const User = Entity.create({
93
+ name: 'User',
94
+ properties: [
95
+ Property.create({ name: 'name', type: 'string' }),
96
+ Property.create({ name: 'email', type: 'string' }),
97
+ Property.create({ name: 'status', type: 'string' })
98
+ ]
99
+ });
100
+
101
+ const Post = Entity.create({
102
+ name: 'Post',
103
+ properties: [
104
+ Property.create({ name: 'title', type: 'string' }),
105
+ Property.create({ name: 'content', type: 'string' }),
106
+ Property.create({ name: 'status', type: 'string' })
107
+ ]
108
+ });
109
+
110
+ const UpdatePost = Interaction.create({
111
+ name: 'UpdatePost',
112
+ action: Action.create({ name: 'update' }),
113
+ payload: Payload.create({
114
+ items: [
115
+ // Reference to existing post
116
+ PayloadItem.create({
117
+ name: 'post',
118
+ base: Post,
119
+ isRef: true, // Must have an id
120
+ required: true
121
+ }),
122
+ // New data (not a reference)
123
+ PayloadItem.create({
124
+ name: 'updates',
125
+ base: Post,
126
+ isRef: false, // New data without id
127
+ required: true
128
+ })
129
+ ]
130
+ })
131
+ });
132
+ ```
133
+
134
+ ## Using isRef for Entity References
135
+
136
+ ### isRef: true - Reference to Existing Entity
137
+
138
+ When `isRef` is true, the payload item must contain an `id` pointing to an existing entity:
139
+
140
+ ```javascript
141
+ const DeleteComment = Interaction.create({
142
+ name: 'DeleteComment',
143
+ action: Action.create({ name: 'delete' }),
144
+ payload: Payload.create({
145
+ items: [
146
+ PayloadItem.create({
147
+ name: 'comment',
148
+ base: Comment,
149
+ isRef: true, // Must reference existing comment
150
+ required: true
151
+ })
152
+ ]
153
+ })
154
+ });
155
+
156
+ // Usage:
157
+ await controller.callInteraction('DeleteComment', {
158
+ user: currentUser,
159
+ payload: {
160
+ comment: { id: 'comment-123' } // Only id is required
161
+ }
162
+ });
163
+ ```
164
+
165
+ ### isRef: false - Creating New Entity Data
166
+
167
+ When `isRef` is false and `base` is specified, the payload contains new entity data:
168
+
169
+ ```javascript
170
+ const CreateProduct = Interaction.create({
171
+ name: 'CreateProduct',
172
+ action: Action.create({ name: 'create' }),
173
+ payload: Payload.create({
174
+ items: [
175
+ PayloadItem.create({
176
+ name: 'product',
177
+ base: Product,
178
+ isRef: false, // New product data
179
+ required: true
180
+ })
181
+ ]
182
+ })
183
+ });
184
+
185
+ // Usage:
186
+ await controller.callInteraction('CreateProduct', {
187
+ user: currentUser,
188
+ payload: {
189
+ product: {
190
+ name: 'New Product',
191
+ price: 99.99,
192
+ category: 'Electronics'
193
+ // No id - this is new data
194
+ }
195
+ }
196
+ });
197
+ ```
198
+
199
+ ## Collection Parameters
200
+
201
+ Use `isCollection: true` for array parameters:
202
+
203
+ ```javascript
204
+ const TagPosts = Interaction.create({
205
+ name: 'TagPosts',
206
+ action: Action.create({ name: 'tag' }),
207
+ payload: Payload.create({
208
+ items: [
209
+ // Array of post references
210
+ PayloadItem.create({
211
+ name: 'posts',
212
+ base: Post,
213
+ isRef: true,
214
+ isCollection: true,
215
+ required: true
216
+ }),
217
+ // Array of tag references
218
+ PayloadItem.create({
219
+ name: 'tags',
220
+ base: Tag,
221
+ isRef: true,
222
+ isCollection: true,
223
+ required: true
224
+ })
225
+ ]
226
+ })
227
+ });
228
+
229
+ // Usage:
230
+ await controller.callInteraction('TagPosts', {
231
+ user: currentUser,
232
+ payload: {
233
+ posts: [
234
+ { id: 'post-1' },
235
+ { id: 'post-2' }
236
+ ],
237
+ tags: [
238
+ { id: 'tag-javascript' },
239
+ { id: 'tag-react' }
240
+ ]
241
+ }
242
+ });
243
+ ```
244
+
245
+ ## Payload Validation with Attributives
246
+
247
+ ### Basic Attributive Validation
248
+
249
+ When PayloadItem has both `base` and `attributives`, the framework validates the payload data:
250
+
251
+ ```javascript
252
+ // Define validation attributive
253
+ const PublishedPost = Attributive.create({
254
+ name: 'PublishedPost',
255
+ content: function(post, eventArgs) {
256
+ return post.status === 'published';
257
+ }
258
+ });
259
+
260
+ const SharePost = Interaction.create({
261
+ name: 'SharePost',
262
+ action: Action.create({ name: 'share' }),
263
+ payload: Payload.create({
264
+ items: [
265
+ PayloadItem.create({
266
+ name: 'post',
267
+ base: Post,
268
+ isRef: true,
269
+ required: true,
270
+ attributives: PublishedPost // Only published posts can be shared
271
+ })
272
+ ]
273
+ })
274
+ });
275
+
276
+ // This will succeed:
277
+ await controller.callInteraction('SharePost', {
278
+ user: currentUser,
279
+ payload: {
280
+ post: { id: 'published-post-id' }
281
+ }
282
+ });
283
+
284
+ // This will fail validation:
285
+ await controller.callInteraction('SharePost', {
286
+ user: currentUser,
287
+ payload: {
288
+ post: { id: 'draft-post-id' } // Assuming this post has status: 'draft'
289
+ }
290
+ });
291
+ ```
292
+
293
+ ### Complex Validation with BoolExp
294
+
295
+ You can combine multiple attributives using BoolExp:
296
+
297
+ ```javascript
298
+ const ActiveTag = Attributive.create({
299
+ name: 'ActiveTag',
300
+ content: function(tag, eventArgs) {
301
+ return tag.isActive === true;
302
+ }
303
+ });
304
+
305
+ const PopularTag = Attributive.create({
306
+ name: 'PopularTag',
307
+ content: function(tag, eventArgs) {
308
+ return tag.usageCount > 100;
309
+ }
310
+ });
311
+
312
+ const AddTags = Interaction.create({
313
+ name: 'AddTags',
314
+ action: Action.create({ name: 'addTags' }),
315
+ payload: Payload.create({
316
+ items: [
317
+ PayloadItem.create({
318
+ name: 'tags',
319
+ base: Tag,
320
+ isRef: true,
321
+ isCollection: true,
322
+ // Tags must be both active AND popular
323
+ attributives: Attributives.create({
324
+ content: BoolExp.atom(ActiveTag).and(BoolExp.atom(PopularTag))
325
+ })
326
+ })
327
+ ]
328
+ })
329
+ });
330
+ ```
331
+
332
+ ### Validation for Collections
333
+
334
+ When `isCollection` is true, attributives are checked for **every item** in the array:
335
+
336
+ ```javascript
337
+ const VerifiedUser = Attributive.create({
338
+ name: 'VerifiedUser',
339
+ content: function(user, eventArgs) {
340
+ return user.isVerified === true;
341
+ }
342
+ });
343
+
344
+ const InviteUsers = Interaction.create({
345
+ name: 'InviteUsers',
346
+ action: Action.create({ name: 'invite' }),
347
+ payload: Payload.create({
348
+ items: [
349
+ PayloadItem.create({
350
+ name: 'users',
351
+ base: User,
352
+ isRef: true,
353
+ isCollection: true,
354
+ attributives: VerifiedUser // ALL users must be verified
355
+ })
356
+ ]
357
+ })
358
+ });
359
+
360
+ // This will fail if ANY user in the array is not verified
361
+ await controller.callInteraction('InviteUsers', {
362
+ user: currentUser,
363
+ payload: {
364
+ users: [
365
+ { id: 'verified-user-1' },
366
+ { id: 'unverified-user' }, // This will cause validation to fail
367
+ { id: 'verified-user-2' }
368
+ ]
369
+ }
370
+ });
371
+ ```
372
+
373
+ ## Important Framework Behaviors
374
+
375
+ ### When base is NOT specified
376
+
377
+ ```javascript
378
+ PayloadItem.create({
379
+ name: 'customData',
380
+ required: true
381
+ // No base property
382
+ })
383
+ ```
384
+
385
+ Framework behavior:
386
+ - ✅ Checks if required parameter is present
387
+ - ✅ Checks if collection parameter is an array (when isCollection: true)
388
+ - ❌ Does NOT perform concept validation
389
+ - ❌ Does NOT check attributives
390
+ - ❌ Does NOT validate data structure
391
+ - **You must handle validation in your own logic**
392
+
393
+ ### When base IS specified
394
+
395
+ ```javascript
396
+ PayloadItem.create({
397
+ name: 'post',
398
+ base: Post, // Entity reference
399
+ isRef: true,
400
+ attributives: PublishedPost
401
+ })
402
+ ```
403
+
404
+ Framework behavior:
405
+ - ✅ Checks if required parameter is present
406
+ - ✅ Validates the data matches the concept (Entity/Relation)
407
+ - ✅ If isRef: true, verifies id exists and fetches full record
408
+ - ✅ If attributives exist, validates the data against them
409
+ - ✅ For collections, validates every item
410
+
411
+ ### Payload Storage Behavior
412
+
413
+ When `isRef: false` and `base` is specified, the framework automatically stores the payload data:
414
+
415
+ ```javascript
416
+ const CreateArticle = Interaction.create({
417
+ name: 'CreateArticle',
418
+ payload: Payload.create({
419
+ items: [
420
+ PayloadItem.create({
421
+ name: 'article',
422
+ base: Article,
423
+ isRef: false // New data will be stored
424
+ })
425
+ ]
426
+ })
427
+ });
428
+
429
+ // The article data will be automatically saved to storage
430
+ // and the saved record (with id) will be available in the interaction event
431
+ ```
432
+
433
+ ## Best Practices
434
+
435
+ ### 1. Use Appropriate Validation Level
436
+
437
+ ```javascript
438
+ // ✅ Good: Use base for entity-related data
439
+ PayloadItem.create({
440
+ name: 'targetUser',
441
+ base: User,
442
+ isRef: true,
443
+ attributives: ActiveUser
444
+ })
445
+
446
+ // ✅ Good: Simple parameters without base
447
+ PayloadItem.create({
448
+ name: 'searchQuery',
449
+ required: true
450
+ // No base needed for simple strings
451
+ })
452
+
453
+ // ❌ Bad: Over-engineering simple parameters
454
+ PayloadItem.create({
455
+ name: 'pageNumber',
456
+ base: SomeNumberEntity, // Unnecessary
457
+ isRef: false
458
+ })
459
+ ```
460
+
461
+ ### 2. Clear Naming and Documentation
462
+
463
+ ```javascript
464
+ const UpdateUserProfile = Interaction.create({
465
+ name: 'UpdateUserProfile',
466
+ payload: Payload.create({
467
+ items: [
468
+ PayloadItem.create({
469
+ name: 'user', // Clear: which user
470
+ base: User,
471
+ isRef: true,
472
+ required: true
473
+ }),
474
+ PayloadItem.create({
475
+ name: 'profileData', // Clear: what data
476
+ base: UserProfile,
477
+ isRef: false,
478
+ required: true
479
+ }),
480
+ PayloadItem.create({
481
+ name: 'notifyFollowers', // Clear: simple flag
482
+ required: false
483
+ // Boolean flag, no base needed
484
+ })
485
+ ]
486
+ })
487
+ });
488
+ ```
489
+
490
+ ### 3. Consistent Validation Patterns
491
+
492
+ ```javascript
493
+ // Define reusable attributives
494
+ const CanBeEdited = Attributive.create({
495
+ name: 'CanBeEdited',
496
+ content: function(item, eventArgs) {
497
+ return item.status !== 'locked' &&
498
+ item.createdBy === eventArgs.user.id;
499
+ }
500
+ });
501
+
502
+ // Use consistently across interactions
503
+ const EditPost = Interaction.create({
504
+ payload: Payload.create({
505
+ items: [
506
+ PayloadItem.create({
507
+ name: 'post',
508
+ base: Post,
509
+ isRef: true,
510
+ attributives: CanBeEdited
511
+ })
512
+ ]
513
+ })
514
+ });
515
+
516
+ const EditComment = Interaction.create({
517
+ payload: Payload.create({
518
+ items: [
519
+ PayloadItem.create({
520
+ name: 'comment',
521
+ base: Comment,
522
+ isRef: true,
523
+ attributives: CanBeEdited
524
+ })
525
+ ]
526
+ })
527
+ });
528
+ ```
529
+
530
+ ### 4. Handle Validation Errors Gracefully
531
+
532
+ ```javascript
533
+ // In your application code
534
+ try {
535
+ const result = await controller.callInteraction('SharePost', {
536
+ user: currentUser,
537
+ payload: { post: { id: postId } }
538
+ });
539
+ } catch (error) {
540
+ if (error instanceof AttributeError) {
541
+ if (error.type === 'post not match attributive') {
542
+ // Handle validation failure
543
+ console.error('Cannot share: Post is not published');
544
+ }
545
+ }
546
+ }
547
+ ```
548
+
549
+ ## Known Issues and Workarounds
550
+
551
+ ### Entity Resolution with Circular Dependencies
552
+
553
+ In some cases, using entity references in PayloadItem can cause resolution issues, particularly when entities have circular dependencies:
554
+
555
+ ```javascript
556
+ // May cause "entity undefined not found" error
557
+ PayloadItem.create({
558
+ name: 'version',
559
+ base: Version, // Entity with circular dependencies
560
+ isRef: false
561
+ })
562
+
563
+ // Workaround: Use generic object type
564
+ // do not set base property to avoids resolution issues
565
+ PayloadItem.create({
566
+ name: 'version',
567
+ isRef: false
568
+ })
569
+ ```
570
+
571
+ This issue typically occurs when:
572
+ - Entities reference each other in complex ways
573
+ - The entity being referenced has forward references
574
+ - The interaction is defined before all entities are fully initialized
575
+
576
+ NOT setting base property maintains the same functionality but avoids the resolution problem, though you lose framework-level validation.
577
+
578
+ ## Summary
579
+
580
+ The Payload system in interaqt provides a powerful way to:
581
+ - Define structured interaction parameters
582
+ - Enforce validation rules through attributives
583
+ - Ensure type safety with entity references
584
+ - Handle both simple data and complex entity relationships
585
+
586
+ Key points to remember:
587
+ - **With base**: Framework handles validation and attributive checks
588
+ - **Without base**: You handle validation in your own logic
589
+ - **isRef**: Distinguishes between references and new data
590
+ - **attributives**: Only work when base is specified
591
+ - **isCollection**: Validates every item in arrays
592
+
593
+ By properly using Payload and PayloadItem, you can build robust, type-safe interactions that validate data at the framework level, reducing the need for manual validation code and improving system reliability.