Skip to content

feat(quickbooks): add read-only procurement integration - #6099

Open
BillLeoutsakosvl346 wants to merge 32 commits into
stagingfrom
feat/quickbooks-integration
Open

feat(quickbooks): add read-only procurement integration#6099
BillLeoutsakosvl346 wants to merge 32 commits into
stagingfrom
feat/quickbooks-integration

Conversation

@BillLeoutsakosvl346

Copy link
Copy Markdown
Contributor

Summary

Adds a clean, read-only QuickBooks Online procurement integration with one OAuth connection bound to one selected QuickBooks company.

  • Adds four fixed actions: get company info, list vendors, list purchase orders, and list bills.
  • Binds realmId to the validated OAuth credential, so workflows cannot choose or override a company.
  • Pins Accounting API requests to minor version 75 and selects sandbox/production hosts only from server configuration.
  • Adds bounded response parsing, fixed-entity queries, explicit pagination, sanitized QuickBooks Fault handling, and no internal retries or automatic pagination.
  • Adds the QuickBooks block, cropped official circular icon, metadata/templates, registry entries, generated integration docs, and contract tests.

Review fixes included

  • Keeps the QuickBooks Fault extractor explicit to QuickBooks tools so unrelated provider errors retain their existing behavior.
  • Detects QuickBooks Fault envelopes even when Intuit returns HTTP 200, including during OAuth-time CompanyInfo validation.
  • Removes raw non-JSON provider bodies from tool output and logs.
  • Caps OAuth token refresh responses at 64 KiB and removes token fragments/raw token responses from logging.
  • Preserves bounded 1 MiB UserInfo and 8 MiB Accounting API reads.
  • Corrects registry ordering and generated CompanyInfo schema documentation.

Validation

  • bunx vitest run tools/index.test.ts tools/quickbooks lib/oauth/quickbooks.test.ts lib/oauth/oauth.test.ts lib/oauth/utils.test.ts app/api/auth/oauth/token/route.test.ts blocks/blocks.test.ts — 8 files, 387 tests passed.
  • bun run type-check — 23/23 monorepo tasks passed.
  • bun run lint:check — passed; only two pre-existing Biome false-positive warnings on terminal fit() method calls.
  • bun run generate-docs — passed.
  • bun run check:bare-icons — passed.
  • bun run check:icon-paths — passed.
  • bun run check:api-validation — passed.
  • git diff --check origin/staging...HEAD — passed.
  • Independent GPT-5.6-sol re-review found no remaining code issues and returned READY FOR DRAFT PR.

Manual sandbox acceptance still required

This PR remains a draft until a live Intuit sandbox confirms UserInfo realmId delivery and the full acceptance flow: CompanyInfo identity matching, all four actions, explicit page continuation, empty pages, two-company isolation, reconnect behavior, refresh-token rotation, revoked-credential guidance, and sandbox-host isolation. No credentials or unsanitized accounting data are committed.

@vercel

vercel Bot commented Jul 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Aug 6, 2026 3:40am

Request Review

@cursor

cursor Bot commented Jul 30, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Changes affect live financial data (invoices, payments, bills, journal entries) and external email delivery, with OAuth and file-transfer paths that must stay correctly scoped to the bound company.

Overview
This PR adds a full QuickBooks Online integration (not just read-only procurement): OAuth binds one Intuit company per credential via callback realmId, and the OAuth token API returns realmId for QuickBooks credentials with reconnect guidance when the stored account identity is malformed.

The QuickBooks block and tools cover master data CRUD, sales and purchasing transactions (create/update/void where supported), journal entries, deposits, financial reports, emailing transactions, PDF downloads, and file/note attachments. List reads expose explicit pagination (nextStartPosition, hasMore) without automatic paging. Document flows use bounded size limits, SSRF-guarded attachment downloads, and server routes for upload/download.

Docs and UI: new quickbooks.mdx integration page, QuickBooksIcon, icon mapping, and integrations nav entry. Config: optional QUICKBOOKS_CLIENT_ID, QUICKBOOKS_CLIENT_SECRET, and QUICKBOOKS_ENV in .env.example.

Reviewed by Cursor Bugbot for commit ed74a2f. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a read-only QuickBooks Online procurement integration.

  • Registers four tools for company information, vendors, purchase orders, and bills.
  • Binds QuickBooks company identity to OAuth credentials and propagates the validated realm into tool execution.
  • Adds bounded response parsing, sanitized fault handling, explicit pagination, environment-selected API hosts, and token-refresh hardening.
  • Adds the block configuration, registries, icons, generated documentation, templates, and contract tests.

Confidence Score: 5/5

The PR appears safe to merge based on the reviewed code, with no actionable defects identified.

The company identifier remains credential-bound through OAuth validation and tool execution, requests are constrained to fixed read-only entities and configured hosts, and response, pagination, refresh, and error-handling paths include explicit bounds and validation.

Important Files Changed

Filename Overview
apps/sim/lib/oauth/quickbooks.ts Defines and validates the company-bound QuickBooks account identity and OAuth connection profile.
apps/sim/lib/auth/auth.ts Registers the QuickBooks generic OAuth flow and validates the selected company during connection.
apps/sim/app/api/auth/oauth/token/route.ts Extracts the bound QuickBooks realm from authorized credentials and returns it to tool execution.
apps/sim/lib/quickbooks/client.ts Centralizes environment-specific hosts, URL construction, response limits, headers, and CompanyInfo validation.
apps/sim/tools/quickbooks/utils.ts Implements fixed-entity queries, bounded JSON parsing, fault detection, pagination validation, and response transformation.
apps/sim/tools/index.ts Propagates provider context, supports per-tool response limits, and sanitizes QuickBooks errors before output or logging.
apps/sim/blocks/blocks/quickbooks.ts Adds the QuickBooks block, four fixed operations, validated pagination mapping, templates, and skills.
apps/sim/lib/oauth/oauth.ts Registers QuickBooks OAuth metadata and hardens shared refresh-response parsing and logging.

Sequence Diagram

sequenceDiagram
  participant User
  participant OAuth as QuickBooks OAuth
  participant Auth as Sim Auth
  participant Token as OAuth Token Route
  participant Tool as QuickBooks Tool
  participant QBO as QuickBooks Accounting API
  User->>OAuth: Authorize selected company
  OAuth-->>Auth: Authorization code
  Auth->>OAuth: Exchange code and fetch UserInfo
  Auth->>QBO: Validate CompanyInfo for realmId
  Auth-->>User: Store company-bound credential
  Tool->>Token: Request refreshed credential context
  Token-->>Tool: accessToken and bound realmId
  Tool->>QBO: Fixed read-only request for bound company
  QBO-->>Tool: CompanyInfo or paginated entities
  Tool-->>User: Sanitized bounded response
Loading

Reviews (1): Last reviewed commit: "feat(quickbooks): add read-only procurem..." | Re-trigger Greptile

Comment thread apps/sim/app/api/auth/oauth/token/route.ts
Comment thread apps/sim/tools/quickbooks/fault.ts
Comment thread apps/sim/tools/index.ts
@BillLeoutsakosvl346

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 33d9afb. Configure here.

Comment thread apps/sim/lib/oauth/oauth.ts Outdated
Comment thread apps/sim/tools/quickbooks/get_company_info.ts
@BillLeoutsakosvl346

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 29bfcc5. Configure here.

Comment thread apps/sim/lib/oauth/oauth.ts Outdated
@BillLeoutsakosvl346

Copy link
Copy Markdown
Contributor Author

@cursor review

Comment thread apps/sim/lib/auth/auth.ts Outdated
@BillLeoutsakosvl346

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 19e00eb. Configure here.

@BillLeoutsakosvl346

Copy link
Copy Markdown
Contributor Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 00fc671. Configure here.

* feat(quickbooks): add master data and CRUD tools

* feat(quickbooks): expose compact master data operations

* docs(quickbooks): document master data actions

* fix(quickbooks): harden master data outputs

* fix(redaction): preserve workflow state tokens

* fix(quickbooks): address integration review findings

* fix(quickbooks): align item updates and generated docs

* fix(quickbooks): sanitize customer tax identifiers

* fix(quickbooks): preserve read-write compatibility

* fix(quickbooks): use action-first operation labels

* test(quickbooks): align operation label expectations

* fix(quickbooks): align catalog operation labels

* fix(redaction): cover namespaced secret fields

* fix(quickbooks): expose master data pagination metadata

* fix(quickbooks): omit null optional values

* fix(quickbooks): validate master data inputs

* chore(tools): sync master data metadata

* fix(redaction): anchor workflow token allowlist

* feat(quickbooks): add sales and accounts receivable (#6130)

* feat(quickbooks): add bounded sales transaction reads

* feat(quickbooks): add sales and receivables mutations

* feat(quickbooks): expose sales operations in the block

* fix(quickbooks): address independent sales review

* fix(quickbooks): address final integration review

* fix(quickbooks): clarify master data output metadata

* fix(quickbooks): mark sales pagination outputs optional

* fix(quickbooks): validate calculated sales amounts

* fix(quickbooks): generate sales arrays correctly

* fix(quickbooks): align sales metadata conditions

* chore(tools): sync sales metadata

* feat(quickbooks): add purchasing and payables (#6159)

* feat(quickbooks): add safe purchasing and payables tools

* feat(quickbooks): expose purchasing and payables operations

* docs(quickbooks): document purchasing and payables tools

* fix(quickbooks): require current purchase payment type

* fix(quickbooks): allow rounded purchasing line totals

* fix(quickbooks): generate purchasing arrays correctly

* fix(quickbooks): validate bill payment accounts

* fix(quickbooks): validate bill allocations before account lookup

* chore(tools): sync purchasing metadata

* fix(quickbooks): sanitize bill payment faults

* feat(quickbooks): add general accounting operations (#6185)

* feat(quickbooks): add accounting transaction tools

* feat(quickbooks): expose accounting operations

* docs(quickbooks): generate accounting catalog

* fix(quickbooks): preserve accounting amount precision

* fix(quickbooks): balance journal entries in exact cents

* fix(quickbooks): include account in deposit updates

* chore(quickbooks): sync accounting catalog

* feat(quickbooks): add observable PO-to-bill linking (#6194)

* feat(quickbooks): link bills to purchase order lines

* docs(quickbooks): document observable bill linking

* fix(quickbooks): document purchase order link identifiers

* fix(quickbooks): keep shared line example valid

* chore(quickbooks): sync bill linking catalog

* feat(quickbooks): add accountant-focused financial reports (#6197)

* feat(quickbooks): add verified financial report contracts

* feat(quickbooks): expose reports in block and catalog

* test(quickbooks): cover null report filters

* fix(quickbooks): expose report header time

* chore(quickbooks): sync reports catalog

* feat(quickbooks): add documents and attachments (#6200)

* feat(quickbooks): add document and attachment tools

* feat(quickbooks): add bounded document file routes

* feat(quickbooks): expose document workflows

* fix(quickbooks): enforce attachment upload bounds

* fix(quickbooks): tighten document handling

* fix(quickbooks): align file response limits

* test(quickbooks): cover missing PDF content type

* test(quickbooks): cover attachment MIME fallback

* fix(quickbooks): redact attachment access URLs

* fix(quickbooks): store downloaded documents safely

* fix(quickbooks): stop cancelled attachment downloads

* fix(quickbooks): correct document schemas and upload bytes

* chore(quickbooks): sync document catalog

* feat(quickbooks): add accountant filters (#6208)

* feat(quickbooks): add safe n8n parity tools

* feat(quickbooks): expose accountant parity options

* fix(quickbooks): address parity review findings

* fix(quickbooks): require recipient for payment email

* chore(quickbooks): sync parity catalog

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Mac.localdomain>
Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Mac.localdomain>
Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Mac.localdomain>
Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>
Co-authored-by: Bill Leoutsakos <billleoutsakos@Mac.localdomain>

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Mac.localdomain>
Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>
Co-authored-by: Bill Leoutsakos <billleoutsakos@Mac.localdomain>

---------

Co-authored-by: Bill Leoutsakos <billleoutsakos@Bills-MacBook-Pro.local>
Co-authored-by: Bill Leoutsakos <billleoutsakos@Mac.localdomain>
@gitguardian

gitguardian Bot commented Aug 4, 2026

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
35640005 Triggered Generic Password 0c3de74 apps/desktop/src/main/browser-import/import-service.test.ts View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@BillLeoutsakosvl346

Copy link
Copy Markdown
Contributor Author

QuickBooks PR file inventory

I reviewed the effective PR diff against the latest staging base. This excludes unrelated files brought into the branch by the recent staging merge. This is to make the reviewer's life a bit easier.

Files are grouped into:

  • Standard: Conventional files expected in nearly every substantial Sim integration.
  • Semi-standard: Established patterns used by integrations requiring OAuth, file handling, internal routes, or specialized errors.
  • Unique: Shared-platform changes specifically required by QuickBooks behavior.

For semi-standard and unique files, I have explained why the change is necessary and why it belongs in this PR.

Diff size

Excluding tests:

  • 93 non-test files
  • +18,605 / −72 lines

Tests:

  • 19 test files
  • +6,174 / −32 lines

Complete PR:

  • 112 files
  • +24,779 / −104 lines

The non-test total includes the generated 2,915-line QuickBooks documentation and generated catalogues, so it is not all handwritten source.


Standard

These are the conventional files expected when adding a substantial Sim integration.

Block and integration catalogue

  • apps/sim/blocks/blocks/quickbooks.tscreated
  • apps/sim/blocks/registry-maps.tsmodified
  • apps/sim/lib/integrations/integrations.jsonmodified
  • apps/sim/lib/integrations/icon-mapping.tsmodified
  • apps/sim/components/icons.tsxmodified

Tool registration and generated catalogues

  • apps/sim/tools/quickbooks/index.tscreated
  • apps/sim/tools/registry.tsmodified
  • apps/sim/tools/generated/tool-ids.tsmodified
  • apps/sim/tools/generated/tool-metadata.tsmodified
  • apps/sim/tools/generated/tool-outputs.tsmodified

QuickBooks tool infrastructure

  • apps/sim/tools/quickbooks/client.tscreated
  • apps/sim/tools/quickbooks/fault.tscreated
  • apps/sim/tools/quickbooks/types.tscreated
  • apps/sim/tools/quickbooks/utils.tscreated
  • apps/sim/tools/quickbooks/accounting_utils.tscreated
  • apps/sim/tools/quickbooks/sales_utils.tscreated
  • apps/sim/tools/quickbooks/purchasing_utils.tscreated
  • apps/sim/tools/quickbooks/documents_utils.tscreated
Read, report, and document tools
  • apps/sim/tools/quickbooks/get_company_info.tscreated
  • apps/sim/tools/quickbooks/read_master_data.tscreated
  • apps/sim/tools/quickbooks/read_sales_transactions.tscreated
  • apps/sim/tools/quickbooks/read_purchasing_transactions.tscreated
  • apps/sim/tools/quickbooks/read_accounting_transactions.tscreated
  • apps/sim/tools/quickbooks/run_financial_report.tscreated
  • apps/sim/tools/quickbooks/email_transaction.tscreated
  • apps/sim/tools/quickbooks/read_attachments.tscreated
  • apps/sim/tools/quickbooks/add_attachment.tscreated
  • apps/sim/tools/quickbooks/download_attachment.tscreated
  • apps/sim/tools/quickbooks/download_transaction_pdf.tscreated
Create tools
  • apps/sim/tools/quickbooks/create_bill.tscreated
  • apps/sim/tools/quickbooks/create_bill_payment.tscreated
  • apps/sim/tools/quickbooks/create_credit_memo.tscreated
  • apps/sim/tools/quickbooks/create_customer.tscreated
  • apps/sim/tools/quickbooks/create_customer_payment.tscreated
  • apps/sim/tools/quickbooks/create_deposit.tscreated
  • apps/sim/tools/quickbooks/create_employee.tscreated
  • apps/sim/tools/quickbooks/create_estimate.tscreated
  • apps/sim/tools/quickbooks/create_invoice.tscreated
  • apps/sim/tools/quickbooks/create_item.tscreated
  • apps/sim/tools/quickbooks/create_journal_entry.tscreated
  • apps/sim/tools/quickbooks/create_purchase.tscreated
  • apps/sim/tools/quickbooks/create_purchase_order.tscreated
  • apps/sim/tools/quickbooks/create_refund_receipt.tscreated
  • apps/sim/tools/quickbooks/create_sales_receipt.tscreated
  • apps/sim/tools/quickbooks/create_vendor.tscreated
  • apps/sim/tools/quickbooks/create_vendor_credit.tscreated
Update and void tools
  • apps/sim/tools/quickbooks/update_bill.tscreated
  • apps/sim/tools/quickbooks/update_bill_payment.tscreated
  • apps/sim/tools/quickbooks/update_credit_memo.tscreated
  • apps/sim/tools/quickbooks/update_customer.tscreated
  • apps/sim/tools/quickbooks/update_customer_payment.tscreated
  • apps/sim/tools/quickbooks/update_deposit.tscreated
  • apps/sim/tools/quickbooks/update_employee.tscreated
  • apps/sim/tools/quickbooks/update_estimate.tscreated
  • apps/sim/tools/quickbooks/update_invoice.tscreated
  • apps/sim/tools/quickbooks/update_item.tscreated
  • apps/sim/tools/quickbooks/update_journal_entry.tscreated
  • apps/sim/tools/quickbooks/update_purchase.tscreated
  • apps/sim/tools/quickbooks/update_purchase_order.tscreated
  • apps/sim/tools/quickbooks/update_refund_receipt.tscreated
  • apps/sim/tools/quickbooks/update_sales_receipt.tscreated
  • apps/sim/tools/quickbooks/update_vendor.tscreated
  • apps/sim/tools/quickbooks/update_vendor_credit.tscreated
  • apps/sim/tools/quickbooks/void_customer_payment.tscreated
  • apps/sim/tools/quickbooks/void_invoice.tscreated

Generated integration documentation

  • apps/docs/content/docs/en/integrations/quickbooks.mdxcreated
  • apps/docs/content/docs/en/integrations/meta.jsonmodified
  • apps/docs/components/icons.tsxmodified
  • apps/docs/components/ui/icon-mapping.tsmodified

Semi-standard

These files follow established Sim patterns, but they are needed only by integrations with features such as OAuth, binary files, internal routes, or specialized provider errors.

OAuth configuration and registration

  • apps/sim/.env.examplemodified
  • apps/sim/lib/core/config/env.tsmodified
  • apps/sim/lib/auth/connectors/providers.tsmodified
  • apps/sim/lib/oauth/oauth.tsmodified
  • apps/sim/lib/oauth/quickbooks.tscreated
  • apps/sim/lib/oauth/types.tsmodified
  • apps/sim/lib/oauth/utils.tsmodified

Why these are needed

QuickBooks uses OAuth in the same general way as Slack, Microsoft, Atlassian, Google, and other OAuth-backed integrations. These files register:

  • Intuit client credentials
  • OAuth endpoints
  • Accounting scopes
  • Provider metadata
  • Refresh-token support
  • Sandbox/production environment selection

Why they belong in this PR

The QuickBooks tools cannot operate without a registered OAuth provider and verified access to the selected QuickBooks company. These are direct integration dependencies rather than unrelated platform features.

Binary-document routes and contracts

  • apps/sim/app/api/tools/quickbooks/add-attachment/route.tscreated
  • apps/sim/app/api/tools/quickbooks/download-attachment/route.tscreated
  • apps/sim/app/api/tools/quickbooks/download-transaction-pdf/route.tscreated
  • apps/sim/lib/api/contracts/tools/quickbooks.tscreated
  • apps/sim/lib/core/security/input-validation.server.tsmodified
  • apps/sim/tools/types.tsmodified
  • scripts/check-api-validation-contracts.tsmodified

Why these are needed

Integrations that upload or download files need more than a normal JSON tool request. These routes provide:

  • Authenticated server-side file handling
  • Workspace-file access checks
  • Canonical request validation
  • File-size limits
  • MIME and filename validation
  • SSRF-protected attachment downloads
  • Bounded binary responses

Why they belong in this PR

Attachments and transaction PDFs are user-facing QuickBooks operations included in this integration. Moving these routes elsewhere would leave those operations incomplete or force unsafe binary handling into ordinary tool requests.

Error and documentation infrastructure

  • apps/sim/tools/error-extractors.tsmodified
  • scripts/generate-docs.tsmodified

Why these are needed

The error extractor follows Sim’s existing provider-specific error pattern and turns QuickBooks Fault.Error[] responses into useful, sanitized messages.

The documentation generator was updated to:

  • Exclude hidden realmId values from generated documentation
  • Preserve existing BlockInfoCard formatting
  • Preserve trailing-newline conventions
  • Avoid unrelated integration-document churn

Why they belong in this PR

QuickBooks errors otherwise lose important validation, authentication, tracking-ID, and rate-limit information. The documentation changes are needed to generate the QuickBooks document safely without exposing hidden connection fields or rewriting unrelated documentation.


Unique

These are shared-platform changes specifically required by unusual QuickBooks behavior.

Company identity binding

  • apps/sim/app/api/auth/[...all]/route.tsmodified
  • apps/sim/app/api/auth/oauth/token/route.tsmodified
  • apps/sim/lib/api/contracts/oauth-connections.tsmodified
  • apps/sim/lib/api/contracts/selectors/oauth.tsmodified

Why these are needed

Intuit supplies the selected QuickBooks company as realmId in the OAuth callback. This is separate from the access token and user identity, but every QuickBooks Accounting API request requires it.

Sim captures that value during OAuth, validates the selected company, binds it to the credential, and supplies it automatically during tool execution.

Why they belong in this PR

Without this behavior:

  • Users would need to enter realmId manually
  • A credential would not be safely bound to one QuickBooks company
  • Requests could be sent with an incorrect or missing company identity

Automatic company binding is therefore part of the core QuickBooks authentication contract, not optional platform cleanup.

QuickBooks refresh concurrency

  • apps/sim/app/api/auth/oauth/utils.tsmodified

Why this is needed

Intuit rotates refresh tokens. A normal short follower wait could expire while Intuit’s token request was still running, potentially allowing two refresh leaders to race and invalidate one another’s credentials.

QuickBooks therefore receives a 30-second refresh-lock TTL and follower wait, while other providers retain their established defaults.

Why it belongs in this PR

This is a small provider-specific branch inside the existing refresh orchestration. Shipping QuickBooks without it would create unreliable long-lived credentials, especially when workflows execute concurrently.

Operational token redaction

  • apps/sim/lib/core/security/redaction.tsmodified

Why this is needed

QuickBooks calls its optimistic-concurrency version a SyncToken. Sim’s previous broad token redaction treated any field containing “token” as secret, which made QuickBooks IDs and synchronization tokens unusable in subsequent Update and Void operations.

The change keeps unknown tokens redacted while preserving narrow categories of operational values such as:

  • Synchronization tokens
  • Pagination and continuation tokens
  • Cursor tokens
  • Idempotency tokens

OAuth access and refresh tokens remain redacted.

Why it belongs in this PR

QuickBooks updates require the current SyncToken. If this value is redacted from workflow output, the mutation operations are effectively unusable.

This is the most broadly applicable shared change in the PR, but QuickBooks directly depends on it and the behavior is covered by regression tests.

Advanced-mode credential serialization

  • apps/sim/serializer/index.tsmodified

Why this is needed

Opening “additional fields” caused a singleton OAuth credential to be treated like the advanced half of a nonexistent basic/advanced input pair. As a result, the selected QuickBooks credential disappeared during serialization.

The correction makes singleton canonical groups preserve their sole value while leaving real basic/advanced pairs unchanged.

Why it belongs in this PR

Most QuickBooks operations contain advanced accounting fields. Without this correction, opening those fields could make an otherwise valid QuickBooks block fail before execution.

The correction is only one focused serializer change and has dedicated regression coverage.

Tool execution plumbing

  • apps/sim/tools/index.tsmodified

Why this is needed

This file contains the centralized execution behavior required to:

  • Inject the credential-bound QuickBooks realmId
  • Enforce QuickBooks’ explicit 8 MiB response cap
  • Sanitize QuickBooks faults before logging or returning them
  • Preserve useful Intuit headers such as tracking IDs and retry guidance

Why it belongs in this PR

Implementing this separately in every QuickBooks tool would duplicate security-sensitive logic across 47 operations.

The centralized implementation ensures consistent company isolation, response limits, error handling, and sanitization throughout the entire integration.


Test files

The following tests were added or changed to cover the integration and the shared behavior it relies upon.

Modified tests

  • apps/sim/app/api/auth/[...all]/route.test.tsmodified
  • apps/sim/app/api/auth/oauth/token/route.test.tsmodified
  • apps/sim/app/api/auth/oauth/utils.test.tsmodified
  • apps/sim/lib/core/security/redaction.test.tsmodified
  • apps/sim/lib/core/security/secure-fetch-response-cap.server.test.tsmodified
  • apps/sim/lib/oauth/oauth.test.tsmodified
  • apps/sim/lib/oauth/utils.test.tsmodified
  • apps/sim/serializer/field-analysis.test.tsmodified
  • apps/sim/tools/index.test.tsmodified

Created tests

  • apps/sim/app/api/tools/quickbooks/documents.test.tscreated
  • apps/sim/lib/oauth/quickbooks.test.tscreated
  • apps/sim/tools/quickbooks/accounting.test.tscreated
  • apps/sim/tools/quickbooks/documents.test.tscreated
  • apps/sim/tools/quickbooks/employees.test.tscreated
  • apps/sim/tools/quickbooks/error-extractor.test.tscreated
  • apps/sim/tools/quickbooks/purchasing.test.tscreated
  • apps/sim/tools/quickbooks/quickbooks.test.tscreated
  • apps/sim/tools/quickbooks/reports.test.tscreated
  • apps/sim/tools/quickbooks/sales.test.tscreated

…rink shared-logic surface

Validation of the integration against Intuit's published attribute tables
(static.developer.intuit.com/JSONObjects/*, the payload behind the docs SPA)
surfaced defects that write wrong data to customers' books, plus shared-module
changes broader than this integration needs.

Data integrity:
- update_customer_payment now reads the payment and merges allocations. QuickBooks
  applies payment lines ALL-or-NONE, so sending a subset silently unapplied every
  omitted invoice. Destructive replacement stays reachable via a user-only
  unapplyOmittedInvoices flag. Also validates the merged total, not just the
  caller's allocations.
- create_item required ExpenseAccountRef (required for Service and NonInventory)
  as optional while mandating IncomeAccountRef (not required for NonInventory).
- create_employee required DisplayName, which QuickBooks derives and treats as
  read-only under Payroll, while leaving the real at-least-one GivenName/FamilyName
  rule unchecked. Both tools threw a raw TypeError on their schema-minimal call.
- create_purchase sent PaymentRefNum, absent from the Purchase entity; QuickBooks
  discards unknown fields silently, so check numbers vanished. Now DocNumber.
- A Fault nested in QueryResponse was reported as an empty result set. Detected in
  parseQuickBooksJson so every response path is covered.
- assertQuickBooksSparseUpdate never checked sparse despite its name.
- Bill header-level LinkedTxn omitted the required TxnLineId and duplicated the
  line-level links; DescriptionOnly lines omitted DescriptionLineDetail.
- Line amounts were positive-only, making discounts, returns and credits
  unrepresentable, and bare Number() silently coerced true and [5] onto the wire.
- Phantom report parameters removed; aging method and period split so each report
  only offers the control it accepts.

Safety and boundaries:
- confirmVoid and confirmPosting moved to user-only, so an agent can no longer
  supply its own approval for voids and journal postings.
- Split the runtime-free helpers out of tools/quickbooks/utils.ts. The block was
  the only one in the repo dragging error-extractors, client.ts,
  microsoft_excel/utils and stream-limits into the client bundle.
- Attachment routes: 20 MB cap per Intuit's limit, outbound timeouts, extension
  preserved through filename truncation, Unicode filenames, wider MIME acceptance.
- The two download routes merged into one; extracted storeToolOutputFile.

Shared logic reduced to what this integration needs:
- redaction.ts back to a bypass-set entry for SyncToken; every origin/staging
  assertion retained.
- refreshOAuthToken read the body before the ok check, so a token response over
  64 KiB became a spurious failure for every provider. Provider error text is
  restored to logs, redacted and truncated, and kept out of the caller message.
- maxResponseBytes clamped to the global ceiling.
- generate-docs is deterministic again; its output no longer depends on what is
  already on disk.

The generic redaction engine, the serializer singleton-canonical fix and the
visibility-based docs filter are deferred to their own PRs.

Sparse-update semantics for ten write tools remain unverified against a live
sandbox; apps/sim/scripts/quickbooks-sparse-probe.ts settles it.
Bill Leoutsakos added 3 commits August 5, 2026 16:51
…tegration

# Conflicts:
#	apps/sim/.env.example
#	apps/sim/tools/generated/tool-metadata.ts
#	apps/sim/tools/generated/tool-outputs.ts
@BillLeoutsakosvl346

Copy link
Copy Markdown
Contributor Author

QuickBooks codebase-standardization update

I simplified the QuickBooks implementation to follow Sim’s existing integration patterns and removed the shared infrastructure that had been introduced specifically for QuickBooks.

What was removed

  • Custom QuickBooks authorization-code exchange
  • QuickBooks-specific refresh-lock timings
  • Per-tool response-size configuration
  • Response-header propagation for QuickBooks errors
  • Custom error-extractor fallback behavior
  • Shared QuickBooks file-storage helper
  • Serializer singleton-group exception
  • QuickBooks-driven shared secure-fetch changes
  • Provider-specific realmId injection logic

The cleanup removed substantially more code than it added:

  • 125 lines added
  • 712 lines removed

No QuickBooks operations, block fields, OAuth scopes, endpoints, accounting behavior, or output contracts changed.

Standard files

These now follow the normal structure used by other Sim integrations:

  • apps/sim/blocks/blocks/quickbooks.ts
  • Everything under apps/sim/tools/quickbooks/
  • Tool and block registries
  • Integration and icon registries
  • Generated tool metadata
  • Generated QuickBooks documentation

The tools remain provider-local, generally with one file per operation and small shared QuickBooks utilities for sales, purchasing, accounting, reports, faults, and documents.

Semi-standard files

These use established Sim patterns needed by integrations with OAuth metadata, binary files, or structured provider errors.

OAuth and company binding

  • apps/sim/lib/auth/connectors/providers.ts
  • apps/sim/lib/oauth/quickbooks.ts
  • apps/sim/lib/oauth/oauth.ts
  • apps/sim/lib/oauth/types.ts
  • apps/sim/lib/oauth/utils.ts
  • apps/sim/app/api/auth/[...all]/route.ts
  • apps/sim/app/api/auth/oauth/token/route.ts
  • OAuth API contracts and environment registration

QuickBooks now uses Better Auth’s standard Basic-auth token exchange and Sim’s normal refresh-lock behavior. The remaining provider-specific callback code is required because Intuit returns the selected company’s realmId separately from the OAuth token response.

The credential-derived realmId is propagated through the same generic OAuth metadata path used for values such as Salesforce instanceUrl, Atlassian cloudId, and Zoho apiDomain.

Binary documents and attachments

  • apps/sim/app/api/tools/quickbooks/add-attachment/route.ts
  • apps/sim/app/api/tools/quickbooks/download-document/route.ts
  • apps/sim/lib/api/contracts/tools/quickbooks.ts

These routes follow the established file-backed integration pattern. They are needed for workspace-file authorization, binary size limits, secure downloads, and conversion to Sim UserFile outputs.

Structured faults and operational tokens

  • apps/sim/tools/error-extractors.ts
  • apps/sim/lib/core/security/redaction.ts

QuickBooks faults use Sim’s existing extractor registry. SyncToken uses the existing exact redaction-allowlist pattern because it is a required record version for updates, not an authentication token.

Unique infrastructure

None.

QuickBooks no longer introduces a custom shared framework or QuickBooks-only platform architecture. Its remaining nonstandard requirements are implemented through patterns already used by comparable integrations.

Validation

  • 1,382 test files passed
  • 18,668 tests passed
  • TypeScript type-check passed
  • Formatting and lint checks passed
  • API validation passed
  • Client and registry boundary checks passed
  • Tool metadata and integration catalog checks passed
  • git diff --check passed
  • BugBot passed with no unresolved findings

Cleanup commit: 1512602f51

Bill Leoutsakos added 2 commits August 5, 2026 20:30
…tegration

# Conflicts:
#	apps/sim/tools/generated/tool-metadata.ts
#	apps/sim/tools/generated/tool-outputs.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants