feat(netsuite): add Oracle NetSuite integration (#6476)

* revise netsuite integration

* fix(netsuite): align selector route with snowflake

* test(netsuite): remove selector route coverage

* test(netsuite): align coverage with snowflake

* fix(netsuite): complete integration validation

* refactor(netsuite): align integration with codebase patterns

* test(netsuite): correct async job citation

* fix(netsuite): address final audit findings

* fix(netsuite): surface upsert/transform Location, relax task link check

Oracle documents the Location response header for create and update, and
both tools already require it. Upsert and transform also produce a record
but Oracle documents no response headers for either, so they dropped the
header entirely and the new record's ID was unreachable.

Add a `resource-optional` location mode that captures Location when
NetSuite sends it and never fails when it is absent, and wire it to
upsert and transform along with their tool and block outputs.

Async task discovery rejected the whole response if any task link carried
a rel other than `self`, collapsing the picker into a 502. Oracle
documents a `self` link per task but never guarantees it is the only one,
so skip other relationships and fail only when no self link exists.

Also use the shared `truncate` helper in the error sanitizer per the
repo convention instead of an inline slice.

* fix(netsuite): validate SuiteQL pages against their documented shape

The shared collection-page validator required links, items, count,
hasMore, offset, and totalResults on every 200, and a missing field turns
a successful call into a reported failure.

Oracle documents all six for record collections and SuiteAnalytics
dataset pages, but its SuiteQL reference lists only links, count, offset,
totalResults, and items. A documented SuiteQL response that omits hasMore
would therefore have been rejected.

Split out a suiteql-page validator that requires the five documented
SuiteQL fields and type-checks hasMore only when the account returns it.
Record collections and dataset pages keep requiring all six.

* chore(netsuite): regenerate tool metadata after rebase on staging

The rebase conflicted only in the generated tool-id, tool-metadata, and
tool-output artifacts, which NetSuite and the newly landed LogRocket
integration both extend. Regenerated from the merged registries: the
result is staging's catalog plus the 27 NetSuite tools, with LogRocket's
entries intact and no other tool changed.

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>
Co-authored-by: Bill Leoutsakos <billleoutsakos@Mac.localdomain>
Co-authored-by: Waleed Latif <walif6@gmail.com>
This commit is contained in:
Bill Leoutsakos
2026-08-13 15:47:03 -07:00
committed by GitHub
co-authored by Bill Leoutsakos Bill Leoutsakos Waleed Latif
parent 046302aa2a
commit 1424809614
78 changed files with 9596 additions and 36 deletions
+2 -2
View File
@@ -9,8 +9,8 @@ const QUERY_HOOKS_DIR = path.join(ROOT, 'apps/sim/hooks/queries')
const SELECTOR_HOOKS_DIR = path.join(ROOT, 'apps/sim/hooks/selectors')
const BASELINE = {
totalRoutes: 1105,
zodRoutes: 1105,
totalRoutes: 1106,
zodRoutes: 1106,
nonZodRoutes: 0,
} as const
+1
View File
@@ -65,6 +65,7 @@ const HANDWRITTEN_INTEGRATION_DOCS = new Set([
'hubspot-setup',
'linear-service-account',
'monday-service-account',
'netsuite-service-account',
'notion-service-account',
'pipedrive-service-account',
'salesforce-service-account',