Skip to content

Conversation

@makeitraina
Copy link
Member

Summary

  • Fixed a critical race condition bug where invoices were being synced to the wrong QuickBooks company when multiple webhook requests processed concurrently
  • Root cause: Static properties in InvoiceService and IntuitAPI were shared across all concurrent requests, allowing one request to overwrite another's QuickBooks credentials mid-processing

Changes

  • Convert InvoiceService.intuitApiService from static to instance property
  • Convert InvoiceService.oneOffItem from static to instance property
  • Convert InvoiceService.incomeAccountRef from static to instance property
  • Convert IntuitAPI.headers from static to instance property

Evidence

Vercel logs showed realm ID changing mid-request:

  • 16:09:16.830 - getAnAccount used realm 123145893478919 (workspace A - correct)
  • 16:09:18.041 - Concurrent webhook from workspace B started
  • 16:09:18.923 - getACustomer used realm 1372015430 (workspace B - wrong!)

A concurrent webhook overwrote the static IntuitAPI instance, causing workspace A's invoice to be created in workspace B's QuickBooks company.

Test plan

  • Deploy to staging and verify concurrent webhook processing maintains correct realm isolation
  • Test with multiple simultaneous invoice.created webhooks from different workspaces
  • Verify invoices are created in the correct QuickBooks company for each workspace

🤖 Generated with Claude Code

Static properties in InvoiceService and IntuitAPI were shared across
concurrent webhook requests, causing invoices to be synced to the wrong
QuickBooks company when multiple webhooks processed simultaneously.

Changes:
- Convert InvoiceService.intuitApiService from static to instance property
- Convert InvoiceService.oneOffItem from static to instance property
- Convert InvoiceService.incomeAccountRef from static to instance property
- Convert IntuitAPI.headers from static to instance property

This ensures each request maintains its own IntuitAPI instance with the
correct realm ID and credentials throughout the entire request lifecycle.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@vercel
Copy link

vercel bot commented Jan 6, 2026

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

Project Deployment Review Updated (UTC)
quickbooks-sync Error Error Jan 6, 2026 0:37am

private static intuitApiService: IntuitAPI
private static oneOffItem: OneOffItemType
private static incomeAccountRef: string
private intuitApiService!: IntuitAPI
Copy link
Member Author

Choose a reason for hiding this comment

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

i dont like this !, i need this to pass ci to merge.

@makeitraina makeitraina merged commit 95480b3 into master Jan 6, 2026
2 of 3 checks passed
@makeitraina makeitraina deleted the fix/race-condition-cross-workspace-sync branch January 6, 2026 00:44
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