interaqt 0.3.1 → 0.4.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 (32) hide show
  1. package/agent/.claude/agents/code-generation-handler.md +3 -3
  2. package/agent/.claude/agents/computation-generation-handler.md +15 -4
  3. package/agent/.claude/agents/implement-design-handler.md +2 -72
  4. package/agent/.claude/agents/requirements-analysis-handler.md +156 -9
  5. package/agent/agentspace/knowledge/generator/api-reference.md +538 -101
  6. package/agent/agentspace/knowledge/generator/computation-analysis.md +22 -20
  7. package/agent/agentspace/knowledge/generator/computation-implementation.md +62 -38
  8. package/agent/agentspace/knowledge/generator/data-analysis.md +124 -22
  9. package/dist/index.js +2977 -2976
  10. package/dist/index.js.map +1 -1
  11. package/dist/runtime/ComputationSourceMap.d.ts +11 -21
  12. package/dist/runtime/ComputationSourceMap.d.ts.map +1 -1
  13. package/dist/runtime/Controller.d.ts +2 -2
  14. package/dist/runtime/MonoSystem.d.ts.map +1 -1
  15. package/dist/runtime/Scheduler.d.ts +6 -6
  16. package/dist/runtime/Scheduler.d.ts.map +1 -1
  17. package/dist/runtime/System.d.ts +5 -0
  18. package/dist/runtime/System.d.ts.map +1 -1
  19. package/dist/runtime/computations/Computation.d.ts +4 -9
  20. package/dist/runtime/computations/Computation.d.ts.map +1 -1
  21. package/dist/runtime/computations/StateMachine.d.ts +4 -7
  22. package/dist/runtime/computations/StateMachine.d.ts.map +1 -1
  23. package/dist/runtime/computations/Transform.d.ts +7 -1
  24. package/dist/runtime/computations/Transform.d.ts.map +1 -1
  25. package/dist/runtime/computations/TransitionFinder.d.ts +2 -2
  26. package/dist/runtime/computations/TransitionFinder.d.ts.map +1 -1
  27. package/dist/shared/StateTransfer.d.ts +15 -5
  28. package/dist/shared/StateTransfer.d.ts.map +1 -1
  29. package/dist/shared/Transform.d.ts +17 -3
  30. package/dist/shared/Transform.d.ts.map +1 -1
  31. package/package.json +1 -1
  32. package/agent/.claude/agents/requirements-analysis-handler-bak.md +0 -530
@@ -134,7 +134,7 @@ For each element:
134
134
  2. For properties, check controlType first:
135
135
  - If `creation-only` or `derived-with-parent` → use `_owner`
136
136
  - If `independent` → apply standard dependency analysis rules
137
- 3. Apply the appropriate rules based on creation type and deletion capability
137
+ 3. Apply the appropriate rules based on creation type
138
138
  4. For entities/relations that can be hard-deleted, use Transform + HardDeletionProperty with StateMachine
139
139
 
140
140
  ### Step 3: Generate Output Document
@@ -149,7 +149,7 @@ Create `docs/computation-analysis.json` with this structure:
149
149
  "entityAnalysis": {
150
150
  "purpose": "<from data-design.json>",
151
151
  "lifecycle": "<directly copy from lifecycle field in data-design.json>",
152
- "computationDecision": "<Transform/StateMachine/_parent:[ParentName]/None based on rules>",
152
+ "computationDecision": "<Transform/_parent:[ParentName]/None based on rules>",
153
153
  "reasoning": "<automated based on lifecycle and deletion capability>",
154
154
  "calculationMethod": "<from computationMethod>"
155
155
  },
@@ -175,7 +175,7 @@ Create `docs/computation-analysis.json` with this structure:
175
175
  "relationAnalysis": {
176
176
  "purpose": "<from data-design.json>",
177
177
  "lifecycle": "<directly copy from lifecycle field in data-design.json>",
178
- "computationDecision": "<Transform/_parent:[ParentName]/StateMachine based on rules>",
178
+ "computationDecision": "<Transform/_parent:[ParentName] based on rules>",
179
179
  "reasoning": "<automated based on lifecycle>",
180
180
  "calculationMethod": "<from computationMethod>"
181
181
  }
@@ -223,11 +223,12 @@ Examples:
223
223
  ├─ lifecycle.creation.type: "interaction-created" + canBeDeleted: true (soft)? → Transform + status StateMachine
224
224
  ├─ lifecycle.creation.type: "interaction-created" + canBeDeleted: false? → Transform with InteractionEventEntity
225
225
  └─ lifecycle.creation.type: "derived"? → Transform from source entity
226
+ └─ lifecycle.creation.type: "mutation-derived"? → Transform from record mutation event
226
227
 
227
228
  2. Relation Lifecycle?
228
229
  ├─ lifecycle.creation.type: "created-with-entity"? → _parent:[parent]
229
230
  ├─ Can be deleted? → Transform/parent + HardDeletionProperty with StateMachine
230
- ├─ Needs audit trail? → Original computation + status StateMachine (soft delete)
231
+ ├─ Needs audit trail? → Transform + status StateMachine (soft delete)
231
232
  └─ Never deleted? → Transform (if interaction-created) or _parent:[parent]
232
233
 
233
234
  3. Property Value?
@@ -244,22 +245,6 @@ Examples:
244
245
  └─ Check computationMethod → Map to Count/Summation/Custom
245
246
  ```
246
247
 
247
- ## Implementation Checklist
248
-
249
- - [ ] Parse `data-design.json` completely
250
- - [ ] Apply mapping rules for every entity (check deletion capability)
251
- - [ ] Check `controlType` for every property first
252
- - [ ] Apply mapping rules for properties based on `controlType`
253
- - [ ] Apply mapping rules for every relation
254
- - [ ] Apply mapping rules for every dictionary
255
- - [ ] Format all dependencies correctly
256
- - [ ] Separate `dependencies` and `interactionDependencies`
257
- - [ ] Add `InteractionEventEntity` when needed
258
- - [ ] Verify properties with `controlType: "creation-only"` or `"derived-with-parent"` use `_owner`
259
- - [ ] Verify Transform + HardDeletionProperty is used for deletable entities (hard-delete)
260
- - [ ] Verify Transform + HardDeletionProperty is used for deletable relations (hard-delete)
261
- - [ ] Generate complete `computation-analysis.json`
262
-
263
248
  ## Common Patterns
264
249
 
265
250
  ### Timestamps
@@ -305,3 +290,20 @@ Before finalizing, verify:
305
290
  8. All dependencies are properly formatted with specific properties
306
291
  9. `InteractionEventEntity` is included when interactions are dependencies
307
292
  10. The parent name in `_parent:[ParentName]` matches `lifecycle.creation.parent`
293
+
294
+
295
+ ## Implementation Checklist
296
+
297
+ - [ ] Parse `data-design.json` completely
298
+ - [ ] Apply mapping rules for every entity (check deletion capability)
299
+ - [ ] Check `controlType` for every property first
300
+ - [ ] Apply mapping rules for properties based on `controlType`
301
+ - [ ] Apply mapping rules for every relation
302
+ - [ ] Apply mapping rules for every dictionary
303
+ - [ ] Format all dependencies correctly
304
+ - [ ] Separate `dependencies` and `interactionDependencies`
305
+ - [ ] Add `InteractionEventEntity` when needed
306
+ - [ ] Verify properties with `controlType: "creation-only"` or `"derived-with-parent"` use `_owner`
307
+ - [ ] Verify Transform + HardDeletionProperty is used for deletable entities (hard-delete)
308
+ - [ ] Verify Transform + HardDeletionProperty is used for deletable relations (hard-delete)
309
+ - [ ] Generate complete `computation-analysis.json`
@@ -94,8 +94,14 @@ When using `InteractionEventEntity` as the Transform input source, understand th
94
94
  name: 'Style'
95
95
  });
96
96
  Style.computation = Transform.create({
97
- record: InteractionEventEntity,
98
- callback: function(event) {
97
+ eventDeps: {
98
+ StyleInteraction: {
99
+ recordName: InteractionEventEntity.name,
100
+ type: 'create'
101
+ }
102
+ },
103
+ callback: function(mutationEvent) {
104
+ const event = mutationEvent.record;
99
105
  if (event.interactionName === 'UpdateStyle') {
100
106
  // This will CREATE a new Style, not update existing!
101
107
  return { id: event.payload.id, ... } // WRONG!
@@ -115,7 +121,7 @@ When using `InteractionEventEntity` as the Transform input source, understand th
115
121
  trigger: UpdateStyleInteraction,
116
122
  current: updatedState,
117
123
  next: updatedState,
118
- computeTarget: (event) => ({ id: event.payload.id })
124
+ computeTarget: (mutationEvent) => ({ id: mutationEvent.record.payload.id })
119
125
  })
120
126
  ]
121
127
  });
@@ -133,7 +139,7 @@ When using `InteractionEventEntity` as the Transform input source, understand th
133
139
  trigger: DeleteStyleInteraction,
134
140
  current: activeState,
135
141
  next: deletedState,
136
- computeTarget: (event) => ({ id: event.payload.id })
142
+ computeTarget: (mutationEvent) => ({ id: mutationEvent.record.payload.id })
137
143
  })
138
144
  ]
139
145
  });
@@ -179,8 +185,14 @@ export const Style = Entity.create({
179
185
  });
180
186
  // Transform in Entity's computation property
181
187
  Style.computation = Transform.create({
182
- record: InteractionEventEntity,
183
- callback: function(event) {
188
+ eventDeps: {
189
+ StyleInteraction: {
190
+ recordName: InteractionEventEntity.name,
191
+ type: 'create'
192
+ }
193
+ },
194
+ callback: function(mutationEvent) {
195
+ const event = mutationEvent.record;
184
196
  if (event.interactionName === 'CreateStyle') {
185
197
  return {
186
198
  label: event.payload.label,
@@ -238,8 +250,14 @@ export const OrderItemRelation = Relation.create({
238
250
 
239
251
 
240
252
  Order.computation = Transform.create({
241
- record: InteractionEventEntity,
242
- callback: function(event) {
253
+ eventDeps: {
254
+ OrderInteraction: {
255
+ recordName: InteractionEventEntity.name,
256
+ type: 'create'
257
+ }
258
+ },
259
+ callback: function(mutationEvent) {
260
+ const event = mutationEvent.record;
243
261
  if (event.interactionName === 'CreateOrder') {
244
262
  return {
245
263
  orderNumber: event.payload.orderNumber,
@@ -374,13 +392,13 @@ statusProperty.computation = StateMachine.create({
374
392
  current: draftState,
375
393
  next: activeState,
376
394
  trigger: PublishStyle,
377
- computeTarget: (event) => ({ id: event.payload.id })
395
+ computeTarget: (mutationEvent) => ({ id: mutationEvent.record.payload.id })
378
396
  }),
379
397
  StateTransfer.create({
380
398
  current: activeState,
381
399
  next: offlineState,
382
400
  trigger: DeleteStyle,
383
- computeTarget: (event) => ({ id: event.payload.id })
401
+ computeTarget: (mutationEvent) => ({ id: mutationEvent.record.payload.id })
384
402
  })
385
403
  ]
386
404
  });
@@ -404,7 +422,7 @@ const UpdateStyle = Interaction.create({
404
422
  // Define state node with computeValue
405
423
  const updatedState = StateNode.create({
406
424
  name: 'updated',
407
- computeValue: () => Math.floor(Date.now()/1000) // Returns timestamp in seconds when state is entered
425
+ computeValue: (lastValue, mutationEvent) => Math.floor(Date.now()/1000) // Returns timestamp in seconds when state is entered
408
426
  });
409
427
 
410
428
  const updatedAtProperty = Property.create({
@@ -420,7 +438,7 @@ updatedAtProperty.computation = StateMachine.create({
420
438
  current: updatedState,
421
439
  next: updatedState, // Self-loop to same state
422
440
  trigger: UpdateStyle,
423
- computeTarget: (event) => ({ id: event.payload.id })
441
+ computeTarget: (mutationEvent) => ({ id: mutationEvent.record.payload.id })
424
442
  })
425
443
  ]
426
444
  });
@@ -428,7 +446,7 @@ updatedAtProperty.computation = StateMachine.create({
428
446
 
429
447
  #### StateMachine with Event Context in computeValue
430
448
 
431
- The `computeValue` function can access the interaction event as a second parameter, allowing you to use interaction context (user, payload) in value computation:
449
+ The `computeValue` function can access the mutation event as a second parameter, allowing you to use interaction context (user, payload) from `mutationEvent.record` in value computation:
432
450
 
433
451
  ```typescript
434
452
  // Track who made changes and what was changed
@@ -448,21 +466,21 @@ const UpdateArticle = Interaction.create({
448
466
  // State node that captures user and payload information
449
467
  const modifiedState = StateNode.create({
450
468
  name: 'modified',
451
- // computeValue receives (lastValue, event) parameters
452
- computeValue: (lastValue, event) => {
469
+ // computeValue receives (lastValue, mutationEvent) parameters
470
+ computeValue: (lastValue, mutationEvent) => {
453
471
  // Access user who triggered the update
454
- const modifier = event?.user?.name || event?.user?.id || 'anonymous';
472
+ const modifier = mutationEvent?.record?.user?.name || mutationEvent?.record?.user?.id || 'anonymous';
455
473
 
456
474
  // Access payload to see what was changed
457
475
  const changes = [];
458
- if (event?.payload?.title) changes.push('title');
459
- if (event?.payload?.content) changes.push('content');
476
+ if (mutationEvent?.record?.payload?.title) changes.push('title');
477
+ if (mutationEvent?.record?.payload?.content) changes.push('content');
460
478
 
461
479
  return {
462
480
  modifiedAt: Math.floor(Date.now()/1000),
463
481
  modifiedBy: modifier,
464
482
  changedFields: changes,
465
- updateReason: event?.payload?.updateReason || 'No reason provided',
483
+ updateReason: mutationEvent?.record?.payload?.updateReason || 'No reason provided',
466
484
  // Preserve previous modification history
467
485
  previousModifications: lastValue?.previousModifications || []
468
486
  };
@@ -483,7 +501,7 @@ modificationInfoProperty.computation = StateMachine.create({
483
501
  current: modifiedState,
484
502
  next: modifiedState,
485
503
  trigger: UpdateArticle,
486
- computeTarget: (event) => ({ id: event.payload.id })
504
+ computeTarget: (mutationEvent) => ({ id: mutationEvent.record.payload.id })
487
505
  })
488
506
  ]
489
507
  });
@@ -502,25 +520,25 @@ const ApproveRequest = Interaction.create({
502
520
 
503
521
  const approvedState = StateNode.create({
504
522
  name: 'approved',
505
- computeValue: (lastValue, event) => {
523
+ computeValue: (lastValue, mutationEvent) => {
506
524
  // Capture complete approval context from event
507
525
  return {
508
526
  status: 'approved',
509
527
  approvedAt: Math.floor(Date.now()/1000),
510
528
  approvedBy: {
511
- id: event?.user?.id,
512
- name: event?.user?.name,
513
- role: event?.user?.role
529
+ id: mutationEvent?.record?.user?.id,
530
+ name: mutationEvent?.record?.user?.name,
531
+ role: mutationEvent?.record?.user?.role
514
532
  },
515
- approvalComments: event?.payload?.comments,
533
+ approvalComments: mutationEvent?.record?.payload?.comments,
516
534
  // Keep approval history
517
535
  approvalHistory: [
518
536
  ...(lastValue?.approvalHistory || []),
519
537
  {
520
538
  action: 'approved',
521
539
  timestamp: Math.floor(Date.now()/1000),
522
- user: event?.user?.name || 'unknown',
523
- comments: event?.payload?.comments
540
+ user: mutationEvent?.record?.user?.name || 'unknown',
541
+ comments: mutationEvent?.record?.payload?.comments
524
542
  }
525
543
  ]
526
544
  };
@@ -528,11 +546,11 @@ const approvedState = StateNode.create({
528
546
  });
529
547
  ```
530
548
 
531
- **Key Points about Event Parameter:**
532
- - The `event` parameter is optional and may be `undefined` during initial state setup
533
- - Contains the full interaction context: `user`, `payload`, `interactionName`, etc.
549
+ **Key Points about MutationEvent Parameter:**
550
+ - The `mutationEvent` parameter is optional and may be `undefined` during initial state setup
551
+ - Access the interaction context through `mutationEvent.record`: `user`, `payload`, `interactionName`, etc.
534
552
  - Useful for audit trails, tracking who made changes, and capturing interaction-specific data
535
- - Always use optional chaining (`?.`) when accessing event properties as it may be undefined
553
+ - Always use optional chaining (`?.`) when accessing mutationEvent properties as it may be undefined
536
554
 
537
555
 
538
556
  ### 3. Custom - Complete User Control (USE WITH CAUTION!)
@@ -747,8 +765,14 @@ export const Style = Entity.create({
747
765
  ]
748
766
  });
749
767
  Style.computation = Transform.create({
750
- record: InteractionEventEntity,
751
- callback: (event) => {
768
+ eventDeps: {
769
+ StyleInteraction: {
770
+ recordName: InteractionEventEntity.name,
771
+ type: 'create'
772
+ }
773
+ },
774
+ callback: (mutationEvent) => {
775
+ const event = mutationEvent.record;
752
776
  if (event.interactionName === 'CreateStyle') {
753
777
  return {
754
778
  label: event.payload.label,
@@ -780,7 +804,7 @@ export const UpdateStyle = Interaction.create({
780
804
  // Property with update tracking
781
805
  const updatedState = StateNode.create({
782
806
  name: 'updated',
783
- computeValue: () => Math.floor(Date.now()/1000)
807
+ computeValue: (lastValue, mutationEvent) => Math.floor(Date.now()/1000)
784
808
  });
785
809
 
786
810
  const updatedAtProperty = Property.create({
@@ -795,7 +819,7 @@ updatedAtProperty.computation = StateMachine.create({
795
819
  current: updatedState,
796
820
  next: updatedState,
797
821
  trigger: UpdateStyle,
798
- computeTarget: (event) => ({ id: event.payload.id })
822
+ computeTarget: (mutationEvent) => ({ id: mutationEvent.record.payload.id })
799
823
  })
800
824
  ]
801
825
  });
@@ -831,7 +855,7 @@ statusProperty.computation = StateMachine.create({
831
855
  current: activeState,
832
856
  next: offlineState,
833
857
  trigger: DeleteStyle,
834
- computeTarget: (event) => ({ id: event.payload.id })
858
+ computeTarget: (mutationEvent) => ({ id: mutationEvent.record.payload.id })
835
859
  })
836
860
  ]
837
861
  });
@@ -888,7 +912,7 @@ Property.create({
888
912
  // ✅ CORRECT: Updated at - updates on changes (in seconds)
889
913
  const updatedState = StateNode.create({
890
914
  name: 'updated',
891
- computeValue: () => Math.floor(Date.now()/1000) // Always convert to seconds!
915
+ computeValue: (lastValue, mutationEvent) => Math.floor(Date.now()/1000) // Always convert to seconds!
892
916
  });
893
917
 
894
918
  const updatedAtProperty = Property.create({
@@ -903,7 +927,7 @@ updatedAtProperty.computation = StateMachine.create({
903
927
  current: updatedState,
904
928
  next: updatedState,
905
929
  trigger: UpdateInteraction,
906
- computeTarget: (event) => ({ id: event.payload.id })
930
+ computeTarget: (mutationEvent) => ({ id: mutationEvent.record.payload.id })
907
931
  })
908
932
  ]
909
933
  });
@@ -63,8 +63,12 @@ For **EACH entity** in data-concepts.json:
63
63
  Analyze `requirements/interactions-design.json` to identify how entities are created:
64
64
 
65
65
  **Step A: Find Creation Interactions**
66
- 1. Search all interactions where the entity appears in `data.creates`
67
- 2. List these as `creationInteractions` (use interaction **names**, not IDs)
66
+ 1. Search all interactions where the entity appears in `interactions.specification.data.creates`
67
+ 2. For each creation interaction, capture:
68
+ - Interaction name (not ID)
69
+ - Description from the creates entry
70
+ - Dependencies from the creates entry
71
+ 3. Store as `creationInteractions` with detailed information for each interaction
68
72
 
69
73
  **Step B: Determine Creation Type**
70
74
  Analyze the creation pattern:
@@ -81,24 +85,50 @@ Analyze the creation pattern:
81
85
  - **derived**: Entity is filtered/computed from other entities
82
86
  - No interactions directly create it
83
87
  - Views in data-concepts.json are typically derived
88
+
89
+ - **mutation-derived**: Entity is created from record mutation events
90
+ - Not directly in any interaction's `data.creates`
91
+ - Created by reactive computations (e.g., Transform) responding to other entities' creation/update/deletion
92
+ - Check for descriptions mentioning "when X is created/updated/deleted, create Y"
93
+ - Often used for audit logs, history tracking, or event-driven workflows
84
94
 
85
95
  **Example Analysis**:
86
96
  ```json
87
97
  // In interaction "CreateDormitory":
88
98
  "data": {
89
- "creates": ["Dormitory", "Bed"]
90
- },
91
- "dataConstraints": [
92
- "Automatically create individual bed entities for each bed"
93
- ]
94
- // Result: Dormitory is interaction-created, Bed is created-with-parent (parent: Dormitory)
99
+ "creates": [
100
+ {
101
+ "target": "Dormitory",
102
+ "description": "Create new dormitory with basic info",
103
+ "dependencies": ["DormitoryValidation"]
104
+ },
105
+ {
106
+ "target": "Bed",
107
+ "description": "Automatically create individual bed entities for each bed",
108
+ "dependencies": ["Dormitory"]
109
+ }
110
+ ]
111
+ }
112
+ // Result:
113
+ // Dormitory is interaction-created with creation details
114
+ // Bed is created-with-parent (parent: Dormitory) with creation details
115
+
116
+ // For mutation-derived entity (not in any interaction's creates):
117
+ // In data-concepts.json: "UserActivityLog: Records all user actions"
118
+ // In interactions: No interaction directly creates UserActivityLog
119
+ // In descriptions: "Activity logs are automatically created when users perform actions"
120
+ // Result: UserActivityLog is mutation-derived
95
121
  ```
96
122
 
97
123
  #### 2.2 Determine Deletion Pattern
98
124
 
99
125
  Search interactions for deletion operations:
100
- 1. Find interactions where entity appears in `data.deletes` (record interaction **names**, not IDs)
101
- 2. Determine deletion type:
126
+ 1. Find interactions where entity appears in `data.deletes`
127
+ 2. For each deletion interaction, capture:
128
+ - Interaction name (not ID)
129
+ - Description from the deletes entry
130
+ - Dependencies from the deletes entry
131
+ 3. Determine deletion type:
102
132
  - **hard-delete**: Entity removed from storage
103
133
  - **soft-delete**: Entity marked as deleted (status change)
104
134
  - **auto-delete**: Deleted when parent/dependency is deleted
@@ -157,23 +187,46 @@ Similar to entities, analyze how relations are created:
157
187
 
158
188
  **Find Creation Interactions**:
159
189
  1. Search for relation name in `data.creates`
160
- 2. Analyze creation context
161
- 3. Record interaction **names**, not IDs
190
+ 2. For each creation interaction, capture:
191
+ - Interaction name (not ID)
192
+ - Description from the creates entry
193
+ - Dependencies from the creates entry
194
+ 3. Analyze creation context
162
195
 
163
196
  **Determine Creation Type**:
164
197
  - **interaction-created**: Relation created independently
165
198
  - **created-with-entity**: Created when source/target entity is created
166
199
  - **derived**: Computed from data conditions
200
+ - **mutation-derived**: Created from record mutation events
201
+ - Not directly in any interaction's `data.creates`
202
+ - Created by reactive computations responding to entity/relation changes
203
+ - Common for maintaining referential integrity or creating audit trails
167
204
 
168
205
  **Example**:
169
206
  ```json
170
207
  // UserBedAssignment appears in:
171
- // "AssignUserToBed": "data": { "creates": ["UserBedAssignment"] }
172
- // Result: interaction-created
208
+ // "AssignUserToBed": "data": {
209
+ // "creates": [{
210
+ // "target": "UserBedAssignment",
211
+ // "description": "Create assignment between user and bed",
212
+ // "dependencies": ["User", "Bed", "AvailabilityCheck"]
213
+ // }]
214
+ // }
215
+ // Result: interaction-created with detailed creation info
173
216
 
174
217
  // If it appeared with entity creation:
175
- // "CreatePost": "data": { "creates": ["Post", "PostAuthorRelation"] }
176
- // Result: PostAuthorRelation is created-with-entity (Post)
218
+ // "CreatePost": "data": {
219
+ // "creates": [
220
+ // {"target": "Post", "description": "Create new post", "dependencies": ["User"]},
221
+ // {"target": "PostAuthorRelation", "description": "Link post to author", "dependencies": ["Post", "User"]}
222
+ // ]
223
+ // }
224
+ // Result: PostAuthorRelation is created-with-entity (Post) with creation details
225
+
226
+ // For mutation-derived relation:
227
+ // UserFollowRelation not in any interaction's creates
228
+ // Description: "Automatically created when user likes multiple posts by same author"
229
+ // Result: UserFollowRelation is mutation-derived
177
230
  ```
178
231
 
179
232
  ### Step 5: Transform Dictionaries to Analysis Format
@@ -310,14 +363,26 @@ Transform the analyzed data into the standard output format:
310
363
  "computationMethod": "[Creation pattern description]",
311
364
  "lifecycle": {
312
365
  "creation": {
313
- "type": "[interaction-created | derived | created-with-parent]",
366
+ "type": "[interaction-created | derived | created-with-parent | mutation-derived]",
314
367
  "parent": "[Parent entity name if created-with-parent]",
315
- "creationInteractions": "[List from Step 2.1]"
368
+ "creationInteractions": [
369
+ {
370
+ "name": "[Interaction name]",
371
+ "description": "[Description from creates entry]",
372
+ "dependencies": "[Dependencies from creates entry]"
373
+ }
374
+ ]
316
375
  },
317
376
  "deletion": {
318
377
  "canBeDeleted": "[true/false based on Step 2.2]",
319
378
  "deletionType": "[soft-delete | hard-delete | auto-delete]",
320
- "deletionInteractions": "[List from Step 2.2]"
379
+ "deletionInteractions": [
380
+ {
381
+ "name": "[Interaction name]",
382
+ "description": "[Description from deletes entry]",
383
+ "dependencies": "[Dependencies from deletes entry]"
384
+ }
385
+ ]
321
386
  }
322
387
  },
323
388
  "properties": {
@@ -345,14 +410,26 @@ Transform the analyzed data into the standard output format:
345
410
  "computationMethod": "[From Step 4.2]",
346
411
  "lifecycle": {
347
412
  "creation": {
348
- "type": "[From Step 4.2]",
413
+ "type": "[interaction-created | created-with-entity | derived | mutation-derived]",
349
414
  "parent": "[If created-with-entity]",
350
- "creationInteractions": "[From Step 4.2]"
415
+ "creationInteractions": [
416
+ {
417
+ "name": "[Interaction name]",
418
+ "description": "[Description from creates entry]",
419
+ "dependencies": "[Dependencies from creates entry]"
420
+ }
421
+ ]
351
422
  },
352
423
  "deletion": {
353
424
  "canBeDeleted": "[Based on analysis]",
354
425
  "deletionType": "[Type identified]",
355
- "deletionInteractions": "[List of interactions]"
426
+ "deletionInteractions": [
427
+ {
428
+ "name": "[Interaction name]",
429
+ "description": "[Description from deletes entry]",
430
+ "dependencies": "[Dependencies from deletes entry]"
431
+ }
432
+ ]
356
433
  }
357
434
  },
358
435
  "properties": {
@@ -449,6 +526,31 @@ Entities filtered from base entities:
449
526
  }
450
527
  ```
451
528
 
529
+ ### 5. Multiple Creation Interactions
530
+ Entity created by different interactions with different logic:
531
+ ```json
532
+ "Style": {
533
+ "lifecycle": {
534
+ "creation": {
535
+ "type": "interaction-created",
536
+ "parent": null,
537
+ "creationInteractions": [
538
+ {
539
+ "name": "CreateStyle",
540
+ "description": "Create new Style entity with provided data, automatically setting status to 'draft', generating slug if not provided, and setting timestamps",
541
+ "dependencies": ["SlugUniquenessCheck"]
542
+ },
543
+ {
544
+ "name": "RestoreToVersion",
545
+ "description": "Recreate Style entities from version snapshot data",
546
+ "dependencies": ["StyleVersion.snapshotData"]
547
+ }
548
+ ]
549
+ }
550
+ }
551
+ }
552
+ ```
553
+
452
554
  ## Validation Checklist
453
555
 
454
556
  - [ ] All entities from data-concepts.json are analyzed