Repository navigation
feat(quickbooks): add core webhook triggers - #6245
BillLeoutsakosvl346 wants to merge 32 commits into
Conversation
…tegration # Conflicts: # apps/sim/tools/generated/tool-ids.ts # apps/sim/tools/generated/tool-metadata.ts # apps/sim/tools/generated/tool-outputs.ts
…tegration # Conflicts: # apps/sim/tools/index.ts
…tegration # Conflicts: # apps/sim/tools/generated/tool-outputs.ts
* 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>
…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.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryMedium Risk Overview Ingress: New fixed callback Deploy & lifecycle: Trigger deploy resolves the connected OAuth company to a routing key (realm ID); credential removal deactivates bound QuickBooks webhook rows alongside Slack. Copilot / VFS: Multi-select dropdown subblocks are validated and serialized so trigger Docs and integration metadata list trigger configuration outputs; Reviewed by Cursor Bugbot for commit 6e6494d. Bugbot is set up for automated code reviews on this repo. Configure here. |
Greptile SummaryThe PR adds authenticated QuickBooks webhook ingestion and routes company-scoped events through durable workflow dispatch.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains; the previously reported batch-termination issue is resolved because target and lookup failures are isolated until all later events have been processed.
|
| Filename | Overview |
|---|---|
| apps/sim/app/api/webhooks/quickbooks/route.ts | Adds bounded, signature-authenticated app-level webhook ingress that acknowledges deliveries only after durable enqueue. |
| apps/sim/background/quickbooks-webhook-ingress.ts | Routes every accepted event by QuickBooks company, isolates target failures, and retries after processing the complete batch. |
| apps/sim/lib/webhooks/providers/quickbooks.ts | Adds QuickBooks signature verification, event matching, normalization, and event-ID extraction for idempotency. |
| apps/sim/lib/webhooks/deploy.ts | Integrates QuickBooks with the app-level trigger deployment lifecycle. |
| apps/sim/triggers/quickbooks/index.ts | Exports the new QuickBooks event trigger catalog for registry consumption. |
| apps/sim/blocks/blocks/quickbooks.ts | Enables trigger mode and exposes the registered QuickBooks trigger options on the existing block. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
QB[QuickBooks] --> Route[Signed webhook route]
Route --> Validate[Verify signature and validate bounded envelope]
Validate --> Ingress[Durable ingress job]
Ingress --> Lookup[Find deployed targets by company realm]
Lookup --> Dispatch[Dispatch each event to matching workflows]
Dispatch --> Idempotency[Webhook execution idempotency]
Idempotency --> Execute[Execute workflow]
Reviews (4): Last reviewed commit: "refactor(quickbooks): align webhook trig..." | Re-trigger Greptile
* feat(quickbooks): complete webhook trigger matrix * fix(quickbooks): document webhook event selectors * fix(quickbooks): clarify webhook setup --------- Co-authored-by: Bill Leoutsakos <billleoutsakos@Mac.localdomain>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit afb7009. Configure here.
QuickBooks trigger file classificationThe implementation has been kept mostly within Sim’s normal trigger patterns. I’ve classified the files as:
StandardThese are the normal files expected when adding triggers to an existing integration. Trigger definitions
These contain the conventional trigger definitions, the fixed Intuit entity/action matrix, trigger matching, input formatting, and shared QuickBooks trigger options. Block and registries
These expose the 29 grouped trigger choices through the existing QuickBooks block, register them, and update the generated integration catalogue and documentation. Standard trigger tests
This provides table-driven behavioral coverage for all 29 choices and 101 supported entity/action combinations, including matching, formatting, event-type isolation, and Intuit Semi-standardThese files are needed because QuickBooks uses one app-level webhook endpoint rather than giving every workflow its own webhook URL. Comparable patterns exist in integrations such as TikTok and Slack: they authenticate a shared provider callback, route an event to deployed workflows using provider-owned identity information, and then use Sim’s shared webhook dispatcher. App-level webhook callback
The route receives Intuit’s app-level callback, reads a bounded raw body, verifies the This belongs in the trigger PR because Intuit cannot deliver events to the QuickBooks triggers without a public authenticated callback. Test:
Webhook provider handling
The provider handles QuickBooks-specific signature authentication, entity/action matching, output formatting, and event-ID idempotency while still using Sim’s standard dispatcher. TikTok and Slack have comparable provider handlers because their webhook authentication and payload formats are provider-specific. This belongs here because these are the minimum adapters required to translate Intuit events into Sim’s standard trigger execution model. Test:
Deployment-time company routing
When a QuickBooks trigger is deployed, Sim stores the connected company’s Deleting the credential also deactivates its deployed triggers. TikTok similarly stores an account identity in These changes belong in this PR because correct company isolation and credential cleanup are essential parts of deploying the trigger safely. Tests:
Provider configuration
These register the server-only Intuit webhook verifier token used to authenticate callback signatures. This is comparable to the signing secrets or verifier configuration required by other authenticated webhook providers and is directly required for the QuickBooks endpoint to reject forged deliveries. Mothership multi-select support
QuickBooks trigger actions use Sim’s existing These are small provider-neutral corrections to support an existing block feature—not QuickBooks-specific branches or new abstractions. They belong in this PR because without them most of the trigger matrix was impossible to configure through Mothership. Tests:
UniqueThere is one unique runtime component: the durable QuickBooks batch-ingress job.
Test:
Intuit may send a single webhook request containing multiple events for multiple QuickBooks companies, while requiring the endpoint to acknowledge the delivery within roughly three seconds and recommending asynchronous processing. The ingress job lets the callback perform only: |
80b3121 to
2405a19
Compare
0f23331 to
6249489
Compare
|
| 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
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secret safely. Learn here the best practices.
- Revoke and rotate this secret.
- 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
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 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.
Preserve the current credential-scoped QuickBooks implementation already incorporated in staging: app-key ingress, encrypted verifier tokens, app-and-company routing, bounded durable processing, deployed target metadata, and the complete trigger matrix. Resolve inherited foundation conflicts against their current owners and retain deliberate moves and deletions. Remove superseded global ingress, per-entity trigger duplicates, HTTP tool adapters, and legacy VFS files rather than reviving older architecture. Canonical outputs retain the staging versions because their source inputs are unchanged. Validation was limited to source and Git inspection as requested.

Summary
Validation
Live Intuit delivery remains dependent on configuring the public callback and QUICKBOOKS_WEBHOOK_VERIFIER_TOKEN; signed raw-body fixtures cover ingress locally.