Skip to content

Commit 4ecec8c

Browse files
Bill LeoutsakosBill Leoutsakos
authored andcommitted
fix(netsuite): harden integration contracts
1 parent b191f44 commit 4ecec8c

35 files changed

Lines changed: 502 additions & 374 deletions

apps/docs/content/docs/en/integrations/gong.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ Retrieve detailed call data including trackers, topics, highlights, and AI spotl
247247
|`section` | string | Outline section name |
248248
|`startTime` | number | Section start in seconds from call start |
249249
|`duration` | number | Section duration in seconds |
250+
|`items` | array | Bullet items within the section |
250251
|`keyPoints` | array | AI-generated key points of the call |
251252
|`text` | string | Key point text |
252253
|`callOutcome` | object | AI-determined call outcome \(Call Spotlight\) |
@@ -273,6 +274,9 @@ Retrieve detailed call data including trackers, topics, highlights, and AI spotl
273274
|`occurrences` | array | Details per occurrence |
274275
|`highlights` | array | AI-generated highlights including next steps, action items, and key moments |
275276
|`title` | string | Title of the highlight |
277+
|`items` | array | Individual highlight items |
278+
|`text` | string | Text of the highlight item |
279+
|`startTimes` | array | Start times in seconds from call start |
276280
|`interaction` | object | Interaction statistics |
277281
|`interactionStats` | array | Interaction stat measurements \(Longest Monologue, Interactivity, Patience, etc.\) |
278282
|`name` | string | Stat name |

apps/docs/content/docs/en/integrations/google_forms.mdx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,16 @@ Apply multiple updates to a form (add items, update info, change settings, etc.)
146146
|`quizSettings` | object | Quiz settings |
147147
|`isQuiz` | boolean | Whether the form is a quiz |
148148
|`emailCollectionType` | string | Email collection type |
149+
|`items` | array | The form items \(questions, sections, etc.\) |
150+
|`itemId` | string | Item ID |
151+
|`title` | string | Item title |
152+
|`description` | string | Item description |
153+
|`questionItem` | json | Question item configuration |
154+
|`questionGroupItem` | json | Question group configuration |
155+
|`pageBreakItem` | json | Page break configuration |
156+
|`textItem` | json | Text item configuration |
157+
|`imageItem` | json | Image item configuration |
158+
|`videoItem` | json | Video item configuration |
149159
|`revisionId` | string | The revision ID of the form |
150160
|`responderUri` | string | The URI to share with responders |
151161
|`linkedSheetId` | string | The ID of the linked Google Sheet |

apps/docs/content/docs/en/integrations/netsuite.mdx

Lines changed: 23 additions & 46 deletions
Large diffs are not rendered by default.

apps/docs/content/docs/en/integrations/onepassword.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ List all vaults accessible by the Connect token or Service Account
5959
|`description` | string | Vault description |
6060
|`attributeVersion` | number | Vault attribute version |
6161
|`contentVersion` | number | Vault content version |
62+
|`items` | number | Number of items in the vault |
6263
|`type` | string | Vault type \(USER_CREATED, PERSONAL, or EVERYONE\) |
6364
|`createdAt` | string | Creation timestamp |
6465
|`updatedAt` | string | Last update timestamp |

apps/docs/content/docs/en/integrations/sap_concur.mdx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,7 @@ List allocations on an expense (GET /expensereports/v4/users/\{userId\}/context/
14791479
| --------- | ---- | ----------- |
14801480
| `status` | number | HTTP status code returned by Concur |
14811481
| `data` | json | Allocations list payload |
1482+
|`items` | array | Array of allocation objects \(allocationId, accountCode, percentage, allocationAmount, approvedAmount, claimedAmount, customData, expenseId, isSystemAllocation, isPercentEdited, overLimitAccountCode\) |
14821483

14831484
### SAP Concur List Attendee Associations
14841485

@@ -1547,6 +1548,12 @@ List budget categories (GET /budget/v4/budgetCategory).
15471548
| --------- | ---- | ----------- |
15481549
| `status` | number | HTTP status code returned by Concur |
15491550
| `data` | json | Budget categories collection payload |
1551+
|`items` | array | Array of budget category objects |
1552+
|`id` | string | Category ID |
1553+
|`name` | string | Admin-facing category name |
1554+
|`description` | string | Friendly name |
1555+
|`statusType` | string | Status: OPEN or REMOVED |
1556+
|`expenseTypes` | array | Expense types in this category \(id, featureTypeCode, expenseTypeCode, name\) |
15501557

15511558
### SAP Concur List Budgets
15521559

@@ -1573,6 +1580,7 @@ List budget item headers (GET /budget/v4/budgetItemHeader).
15731580
| --------- | ---- | ----------- |
15741581
| `status` | number | HTTP status code returned by Concur |
15751582
| `data` | json | Budget headers collection payload |
1583+
|`items` | array | Array of budget item header summaries \(id, name, description, budgetItemStatusType, budgetType, currencyCode, fiscalYear, budgetAmounts, owner, ...\) |
15761584
|`offset` | number | Page offset |
15771585
|`limit` | number | Page size |
15781586
|`totalCount` | number | Total result count |

apps/docs/content/docs/en/integrations/sharepoint.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ Get metadata (and optionally columns/items) for a SharePoint list
267267
|`lastModifiedDateTime` | string | When the list was last modified |
268268
|`list` | object | List properties \(e.g., template\) |
269269
|`columns` | array | List column definitions |
270+
|`items` | array | List items \(with fields when expanded\) |
271+
|`id` | string | Item ID |
272+
|`fields` | object | Field values for the item |
270273
| `lists` | array | All lists in the site when no listId/title provided |
271274
| `items` | array | List items with expanded fields when reading list items |
272275
|`id` | string | Item ID |

apps/sim/blocks/blocks/netsuite.test.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,45 @@ describe('Oracle NetSuite block', () => {
3131
}
3232
})
3333

34+
it('covers every operation on canvas and preserves required action targets', () => {
35+
const byOperation = NetSuiteBlock.canvasPresentation?.sentences?.byOperation
36+
if (!byOperation) throw new Error('NetSuite block must define operation canvas sentences')
37+
expect(Object.keys(byOperation)).toEqual([...NETSUITE_TOOL_IDS])
38+
39+
const coreFields = (operation: keyof typeof byOperation) => {
40+
const sentence = byOperation[operation]
41+
if (!Array.isArray(sentence)) return []
42+
return sentence.flatMap((part) =>
43+
typeof part === 'object' && part.core && part.field ? [part.field] : []
44+
)
45+
}
46+
47+
expect(coreFields('netsuite_get_subresource')).toEqual([
48+
'subresourcePath',
49+
'recordType',
50+
'recordId',
51+
])
52+
expect(coreFields('netsuite_get_select_options')).toEqual(['fields', 'recordType'])
53+
expect(coreFields('netsuite_attach_record')).toEqual([
54+
'relatedType',
55+
'relatedId',
56+
'recordType',
57+
'recordId',
58+
])
59+
expect(coreFields('netsuite_detach_record')).toEqual([
60+
'relatedType',
61+
'relatedId',
62+
'recordType',
63+
'recordId',
64+
])
65+
expect(coreFields('netsuite_execute_action')).toEqual(['action', 'recordType', 'recordId'])
66+
expect(coreFields('netsuite_transform_record')).toEqual([
67+
'recordType',
68+
'recordId',
69+
'targetRecordType',
70+
])
71+
})
72+
3473
it('requires the four inline credential fields and masks the private key', () => {
3574
for (const field of ['accountId', 'clientId', 'certificateId', 'privateKey']) {
3675
expect(getSubBlock(field).required, field).toBe(true)
@@ -221,6 +260,27 @@ describe('Oracle NetSuite block', () => {
221260
]
222261
expect(Object.keys(NetSuiteBlock.inputs)).toEqual(expectedInputs)
223262
expect(Object.keys(NetSuiteBlock.outputs)).toEqual(['status', 'data', 'location', 'jobId'])
263+
expect(NetSuiteBlock.outputs.location.condition).toEqual({
264+
field: 'operation',
265+
value: [
266+
'netsuite_create_record',
267+
'netsuite_batch_get_records',
268+
'netsuite_batch_create_records',
269+
'netsuite_batch_update_records',
270+
'netsuite_batch_upsert_records',
271+
'netsuite_batch_delete_records',
272+
],
273+
})
274+
expect(NetSuiteBlock.outputs.jobId.condition).toEqual({
275+
field: 'operation',
276+
value: [
277+
'netsuite_batch_get_records',
278+
'netsuite_batch_create_records',
279+
'netsuite_batch_update_records',
280+
'netsuite_batch_upsert_records',
281+
'netsuite_batch_delete_records',
282+
],
283+
})
224284
for (const input of expectedInputs) {
225285
if (input !== 'operation' && input !== 'taskId')
226286
expect(getSubBlock(input), input).toBeDefined()

apps/sim/blocks/blocks/netsuite.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ const BATCH_OPERATIONS = [
111111
'netsuite_batch_delete_records',
112112
]
113113

114+
const LOCATION_OPERATIONS = ['netsuite_create_record', ...BATCH_OPERATIONS]
115+
114116
const BATCH_WRITE_OPERATIONS = [
115117
'netsuite_batch_create_records',
116118
'netsuite_batch_update_records',
@@ -193,8 +195,8 @@ export const NetSuiteBlock: BlockConfig<NetSuiteResponse> = {
193195
],
194196
netsuite_get_subresource: [
195197
{ text: 'Read subresource', field: 'subresourcePath', core: true },
196-
{ text: 'from', field: 'recordType' },
197-
{ text: 'record', field: 'recordId' },
198+
{ text: 'from', field: 'recordType', core: true },
199+
{ text: 'record', field: 'recordId', core: true },
198200
],
199201
netsuite_get_record_form: [
200202
{ text: 'Get the form for', field: 'recordType', core: true },
@@ -206,7 +208,7 @@ export const NetSuiteBlock: BlockConfig<NetSuiteResponse> = {
206208
],
207209
netsuite_get_select_options: [
208210
{ text: 'Get select options for', field: 'fields', core: true },
209-
{ text: 'on', field: 'recordType' },
211+
{ text: 'on', field: 'recordType', core: true },
210212
{ text: 'record', field: 'recordId' },
211213
{ text: ', matching', field: 'q' },
212214
{ text: ', using', field: 'body' },
@@ -216,27 +218,27 @@ export const NetSuiteBlock: BlockConfig<NetSuiteResponse> = {
216218
netsuite_attach_record: [
217219
{ text: 'Attach', field: 'relatedType', core: true },
218220
{ text: 'ID', field: 'relatedId', core: true },
219-
{ text: 'to', field: 'recordType' },
220-
{ text: 'record', field: 'recordId' },
221+
{ text: 'to', field: 'recordType', core: true },
222+
{ text: 'record', field: 'recordId', core: true },
221223
{ text: ', with role ID', field: 'roleId' },
222224
{ text: ', or role external ID', field: 'roleExternalId' },
223225
],
224226
netsuite_detach_record: [
225227
{ text: 'Detach', field: 'relatedType', core: true },
226228
{ text: 'ID', field: 'relatedId', core: true },
227-
{ text: 'from', field: 'recordType' },
228-
{ text: 'record', field: 'recordId' },
229+
{ text: 'from', field: 'recordType', core: true },
230+
{ text: 'record', field: 'recordId', core: true },
229231
],
230232
netsuite_execute_action: [
231233
{ text: 'Run action', field: 'action', core: true },
232-
{ text: 'on', field: 'recordType' },
233-
{ text: 'record', field: 'recordId' },
234+
{ text: 'on', field: 'recordType', core: true },
235+
{ text: 'record', field: 'recordId', core: true },
234236
{ text: ', with', field: 'body' },
235237
],
236238
netsuite_transform_record: [
237239
{ text: 'Transform', field: 'recordType', core: true },
238240
{ text: 'record', field: 'recordId', core: true },
239-
{ text: 'into', field: 'targetRecordType' },
241+
{ text: 'into', field: 'targetRecordType', core: true },
240242
{ text: ', with', field: 'body' },
241243
],
242244
netsuite_batch_get_records: [
@@ -296,8 +298,8 @@ export const NetSuiteBlock: BlockConfig<NetSuiteResponse> = {
296298
{ text: 'Get result from async job', field: 'jobId', core: true },
297299
{ text: 'for task', field: 'resultTaskId', core: true },
298300
],
299-
netsuite_get_server_time: ['Get NetSuite server time'],
300-
netsuite_get_governance_limits: ['Get NetSuite governance limits'],
301+
netsuite_get_server_time: ['Get server time'],
302+
netsuite_get_governance_limits: ['Get governance limits'],
301303
},
302304
},
303305
},
@@ -828,8 +830,16 @@ Return ONLY the comma-separated sublist IDs - no explanations, no extra text.`,
828830
description:
829831
'NetSuite payload: account-specific record fields, collection items and paging fields, metadata, or async task data',
830832
},
831-
location: { type: 'string', description: 'Created resource or async job location' },
832-
jobId: { type: 'string', description: 'Async job ID parsed from the Location header' },
833+
location: {
834+
type: 'string',
835+
description: 'Created resource or async job location',
836+
condition: { field: 'operation', value: LOCATION_OPERATIONS },
837+
},
838+
jobId: {
839+
type: 'string',
840+
description: 'Async job ID parsed from the Location header',
841+
condition: { field: 'operation', value: BATCH_OPERATIONS },
842+
},
833843
},
834844
}
835845

apps/sim/tools/generated/tool-outputs.ts

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

apps/sim/tools/netsuite/attach_record.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,5 @@ export const netsuiteAttachRecordTool: ToolConfig<NetSuiteAttachParams, NetSuite
114114
description: 'NetSuite response body; record fields are account-specific and dynamic',
115115
nullable: true,
116116
},
117-
location: {
118-
type: 'string',
119-
description: 'Created resource or asynchronous job location returned by NetSuite',
120-
optional: true,
121-
},
122-
jobId: {
123-
type: 'string',
124-
description: 'Asynchronous job ID parsed from the Location header',
125-
optional: true,
126-
},
127117
},
128118
}

0 commit comments

Comments
 (0)