interaqt 0.8.2 → 0.8.4
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/agent/.claude/agents/code-generation-handler.md +31 -17
- package/agent/.claude/agents/error-check-handler.md +17 -0
- package/agent/.claude/agents/frontend-generation-handler.md +34 -1
- package/agent/.claude/agents/implement-integration-handler.md +21 -0
- package/agent/.claude/agents/requirements-analysis-handler.md +16 -0
- package/dist/index.js +470 -520
- package/dist/index.js.map +1 -1
- package/dist/runtime/activity/InteractionCall.d.ts.map +1 -1
- package/dist/shared/BoolExp.d.ts +2 -5
- package/dist/shared/BoolExp.d.ts.map +1 -1
- package/package.json +2 -1
- package/agent/agentspace/prompt/integration_sub_agent_refactor.md +0 -19
- package/agent/agentspace/prompt/requirement_analysis_refactor.md +0 -34
|
@@ -162,27 +162,41 @@ git commit -m "feat: Task 3.1.2 - Complete entity and relation implementation"
|
|
|
162
162
|
- [ ] Ensure all payloads match the documented fields
|
|
163
163
|
- [ ] **🔴 CRITICAL: For query interactions (action: GetAction):**
|
|
164
164
|
- **MUST declare `data` field** - specify the Entity or Relation to query
|
|
165
|
-
- **SHOULD declare `
|
|
166
|
-
-
|
|
165
|
+
- **SHOULD declare `dataPolicy` field** if there are predefined filters/fields or access restrictions
|
|
166
|
+
- **⚠️ IMPORTANT: Data Access Scope vs Business Rules**
|
|
167
|
+
- If `dataConstraints` express **data access scope restrictions** (e.g., "can only view own entities", "can only view specific fields"), use `dataPolicy` NOT `condition`
|
|
168
|
+
- `dataPolicy` controls what data can be accessed AFTER the operation is permitted
|
|
169
|
+
- `condition` controls WHETHER the operation can execute (permissions/business rules)
|
|
170
|
+
- Example of data policy: Restricting visible fields, filtering by ownership
|
|
171
|
+
- Example with dynamic data policy (user-based filtering):
|
|
172
|
+
```typescript
|
|
173
|
+
const ViewMyOrders = Interaction.create({
|
|
174
|
+
name: 'ViewMyOrders',
|
|
175
|
+
action: GetAction,
|
|
176
|
+
data: Order,
|
|
177
|
+
dataPolicy: DataPolicy.create({
|
|
178
|
+
match: function(this: Controller, event: any) {
|
|
179
|
+
// Only show user's own orders
|
|
180
|
+
return MatchExp.atom({key: 'owner.id', value:['=', event.user.id]})
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
```
|
|
185
|
+
- Example with combined data policy (filtering + field restrictions + pagination):
|
|
167
186
|
```typescript
|
|
168
187
|
const ViewMyFollowers = Interaction.create({
|
|
169
|
-
name: '
|
|
188
|
+
name: 'ViewMyFollowers',
|
|
170
189
|
action: GetAction,
|
|
171
190
|
data: User, // REQUIRED: specify what to query
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
value: function(this:Controller, event:any) {
|
|
182
|
-
return MatchExp.atom({key: 'follow.id', value:['=', event.user.id]})
|
|
183
|
-
}
|
|
184
|
-
})
|
|
185
|
-
]
|
|
191
|
+
dataPolicy: DataPolicy.create({
|
|
192
|
+
// Dynamic filter: only users who follow the current user
|
|
193
|
+
match: function(this: Controller, event: any) {
|
|
194
|
+
return MatchExp.atom({key: 'following.id', value:['=', event.user.id]})
|
|
195
|
+
},
|
|
196
|
+
// Field restrictions: only expose specific fields
|
|
197
|
+
attributeQuery: ['id', 'name', 'email'],
|
|
198
|
+
// Default pagination
|
|
199
|
+
modifier: { limit: 20, orderBy: { name: 'asc' } }
|
|
186
200
|
})
|
|
187
201
|
})
|
|
188
202
|
```
|
|
@@ -1015,6 +1015,23 @@ const GetUserDonations = Interaction.create({
|
|
|
1015
1015
|
]
|
|
1016
1016
|
})
|
|
1017
1017
|
})
|
|
1018
|
+
|
|
1019
|
+
// Query interaction with dataPolicy for access control
|
|
1020
|
+
const GetMyDonations = Interaction.create({
|
|
1021
|
+
name: 'GetMyDonations',
|
|
1022
|
+
action: GetAction,
|
|
1023
|
+
data: Donation, // ✅ Entity reference
|
|
1024
|
+
dataPolicy: DataPolicy.create({
|
|
1025
|
+
// ✅ Dynamic filter: users can only see their own donations
|
|
1026
|
+
match: function(this: Controller, event: any) {
|
|
1027
|
+
return MatchExp.atom({key: 'donor.id', value: ['=', event.user.id]})
|
|
1028
|
+
},
|
|
1029
|
+
// ✅ Field restrictions: limit exposed fields
|
|
1030
|
+
attributeQuery: ['id', 'amount', 'createdAt', 'status'],
|
|
1031
|
+
// ✅ Default pagination
|
|
1032
|
+
modifier: { limit: 20, orderBy: { createdAt: 'desc' } }
|
|
1033
|
+
})
|
|
1034
|
+
})
|
|
1018
1035
|
```
|
|
1019
1036
|
|
|
1020
1037
|
### Pattern 5: Test Error Checking
|
|
@@ -231,7 +231,40 @@ npm run generate-frontend-api
|
|
|
231
231
|
}
|
|
232
232
|
```
|
|
233
233
|
|
|
234
|
-
2. **
|
|
234
|
+
2. **Query Interactions Always Return Arrays:**
|
|
235
|
+
- Backend query-type interactions always return arrays in `response.data`
|
|
236
|
+
- To query a specific entity/relation, use the `match` field in the query options (2nd parameter)
|
|
237
|
+
- Do NOT put match criteria in the payload (1st parameter)
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
// ✅ Correct: Use match in query options
|
|
241
|
+
const response = await apiClient.ViewVideoGenerationStatus(
|
|
242
|
+
{ videoGenerationRequestId: videoId }, // payload
|
|
243
|
+
{
|
|
244
|
+
attributeQuery: ['id', 'status', 'videoUrl'],
|
|
245
|
+
match: {
|
|
246
|
+
key: 'id',
|
|
247
|
+
value: ['=', videoId] // Match condition here
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
);
|
|
251
|
+
const item = response.data[0]; // Extract first item from array
|
|
252
|
+
|
|
253
|
+
// ❌ Wrong: Don't rely on payload for filtering
|
|
254
|
+
const response = await apiClient.ViewVideoGenerationStatus(
|
|
255
|
+
{ videoGenerationRequestId: videoId } // This won't filter results
|
|
256
|
+
);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
3. **Handling Asynchronous External System Tasks:**
|
|
260
|
+
- For asynchronous tasks that call external systems, backend typically does NOT implement polling unless explicitly specified in requirements
|
|
261
|
+
- Backend usually provides a separate API endpoint to trigger status updates
|
|
262
|
+
- Frontend can call this API to trigger backend status updates
|
|
263
|
+
- Frontend implementation options:
|
|
264
|
+
- **Manual trigger**: Add a button in the component for users to manually trigger the status update API
|
|
265
|
+
- **Automatic polling**: Implement polling in the component (on mount) until the task reaches a completion state
|
|
266
|
+
|
|
267
|
+
4. **Reference Existing Components for Patterns:**
|
|
235
268
|
- Look at `frontend/src/components/*.tsx` files
|
|
236
269
|
- Follow the same patterns for API client usage
|
|
237
270
|
- Check how error handling is implemented
|
|
@@ -45,6 +45,27 @@ This applies to BOTH async APIs (with task IDs) and sync APIs (immediate results
|
|
|
45
45
|
- All integration documentation files MUST be prefixed with current module name from `.currentmodule`
|
|
46
46
|
- Format: `docs/{module}.{integration-name}.integration-design.md`
|
|
47
47
|
|
|
48
|
+
**🔴 CRITICAL PRINCIPLE: Status Polling Strategy**
|
|
49
|
+
|
|
50
|
+
**Default Approach: Frontend Polling with Manual Query API**
|
|
51
|
+
|
|
52
|
+
Backend polling consumes significant server resources. Follow this priority order:
|
|
53
|
+
|
|
54
|
+
1. **Default (ALWAYS implement)**: Provide manual query API for frontend
|
|
55
|
+
- Create API endpoint to query external status
|
|
56
|
+
- Frontend can poll this API at its own pace
|
|
57
|
+
- Even if polling is needed, frontend handles it unless explicitly stated otherwise
|
|
58
|
+
|
|
59
|
+
2. **Backend Polling (ONLY if explicitly required)**: Implement server-side polling
|
|
60
|
+
- ONLY implement if user explicitly requests "backend polling" in requirements
|
|
61
|
+
- Use with caution due to resource consumption
|
|
62
|
+
- Example: volcjmeng integration (only because explicitly required)
|
|
63
|
+
|
|
64
|
+
3. **Webhook (ONLY if both conditions met)**: Implement webhook endpoint
|
|
65
|
+
- ONLY if external service supports webhook registration
|
|
66
|
+
- AND user can register webhook themselves
|
|
67
|
+
- Requires exposing public endpoint for external callbacks
|
|
68
|
+
|
|
48
69
|
# Core Concepts
|
|
49
70
|
|
|
50
71
|
## Interaqt Framework
|
|
@@ -1280,6 +1280,22 @@ git commit -m "feat: Task 1.4 - Complete data concept extraction"
|
|
|
1280
1280
|
- Interaction IDs must be semantic names (e.g., "BorrowBook", "ViewAvailableBooks") not codes (e.g., "I001")
|
|
1281
1281
|
- ❌ If a requirement has role="System", it was incorrectly created - SKIP it, do NOT create interaction
|
|
1282
1282
|
|
|
1283
|
+
**⚠️ IMPORTANT: Distinguishing Data Access Constraints**
|
|
1284
|
+
|
|
1285
|
+
For read-type interaction requirements with access restrictions, distinguish between:
|
|
1286
|
+
|
|
1287
|
+
1. **Business Rules** - Constraints on whether the read operation can execute
|
|
1288
|
+
- Example: "Only administrators can view XXX entity"
|
|
1289
|
+
- Controls who can perform the action
|
|
1290
|
+
- Should be specified in the `conditions` field
|
|
1291
|
+
|
|
1292
|
+
2. **Data Policy** - Constraints on the scope of data returned
|
|
1293
|
+
- Example: "Can only view own XXX entities" or "Can only view YYY fields of XXX entity"
|
|
1294
|
+
- Controls what data is accessible after the operation is permitted
|
|
1295
|
+
- Should be specified in the `dataConstraints` field
|
|
1296
|
+
|
|
1297
|
+
These must be separated as they are implemented differently in subsequent phases.
|
|
1298
|
+
|
|
1283
1299
|
**⚠️ IMPORTANT: External Integration Interactions**
|
|
1284
1300
|
|
|
1285
1301
|
If Task 1.4 includes API Call entities, design error handling interactions:
|