Skip to content

OUT-3617: AB testing gate for bank deposit feature#229

Draft
SandipBajracharya wants to merge 10 commits intoOUT-3609from
OUT-3617
Draft

OUT-3617: AB testing gate for bank deposit feature#229
SandipBajracharya wants to merge 10 commits intoOUT-3609from
OUT-3617

Conversation

@SandipBajracharya
Copy link
Copy Markdown
Collaborator

Summary

  • Add AB_FEATURE_TESTING_PORTALS env var for incremental rollout of bank deposit feature
  • Portals in the list get the bank deposit UI and webhook flow; others use the legacy expense flow
  • Empty/unset env var = feature available to all (production rollout state)

Changes

  • src/config/index.ts — parse AB_FEATURE_TESTING_PORTALS comma-separated list
  • src/utils/abTesting.tsisPortalInBankDepositABTest(portalId) utility
  • src/app/api/quickbooks/invoice/invoice.service.ts — AB check on useBankDepositFlow
  • src/app/api/quickbooks/webhook/webhook.service.ts — AB check on useBankDepositFlow
  • src/app/api/quickbooks/setting/setting.controller.ts — return bankDepositEnabled in GET
  • src/hook/useSettings.ts — conditional bank account fetch based on bankDepositEnabled
  • src/components/ — hide deposit checkbox + dropdown when portal not in AB test
  • Remove EventType.DEPOSITED — use SUCCEEDED for both flows (flag decides behavior)
  • Fix cascade bug: only reset bankDepositFeeFlag when feature is visible

Test plan

  • Set AB_FEATURE_TESTING_PORTALS=<portal-id> in .env
  • Portal in list: deposit checkbox, dropdown, and bank deposit flow work
  • Portal not in list: checkbox hidden, legacy expense flow used
  • Toggle absorbed fees on/off for non-AB portal — buttons disappear correctly
  • Remove env var entirely — feature available to all portals

🤖 Generated with Claude Code

@linear-code
Copy link
Copy Markdown

linear-code Bot commented Apr 20, 2026

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 20, 2026

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

Project Deployment Actions Updated (UTC)
quickbooks-sync Building Building Apr 21, 2026 5:47am
quickbooks-sync (dev) Ready Ready Preview, Comment Apr 21, 2026 5:47am

Request Review

aschwartz91 and others added 4 commits April 20, 2026 16:34
When payments are received, optionally create QBO Bank Deposits that
match the net amount deposited to the customer's bank (after Stripe
fees), enabling automatic bank transaction matching. Payments are
routed through Undeposited Funds, then a Bank Deposit moves the net
amount to the bank account with the fee recorded as a negative line.

This is behind a new opt-in bankDepositFeeFlag setting that requires
absorbedFeeFlag to also be enabled.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…elector

- Add GET endpoint for QBO bank accounts (/setting/bank-account)
- Consolidate bankAccountRef write into settings POST endpoint (single API call)
- Fix missing undepositedFundsAccountRef/bankAccountRef in token refresh and action
- Fix deposit payload: add required TxnLineId to LinkedTxn
- Fix Undeposited Funds lookup: query by AccountSubType instead of getOrCreate
- Replace inline type with PaymentSucceededResponseType in handleBankDepositFlow
- Add Sentry breadcrumbs and structured logging to bank deposit flow
- Move deposit log after API call, use CustomLogger
- Make PrivateNote optional in deposit schema
- Add bankAccountRef to SettingRequestSchema and InvoiceSettingType
- Add design doc for IntuitAPI token refresh (future ticket)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Wrap qb_settings + qb_portal_connections writes in db.transaction to
  prevent partial state (bankDepositFeeFlag=true with bankAccountRef=null)
- Add null guard on paidSyncLog.amount before division in handleBankDepositFlow
- Add invoiceNumber to failed DEPOSITED sync log for future resync support

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@SandipBajracharya SandipBajracharya changed the title feat(OUT-3617): AB testing gate for bank deposit feature OUT-3617: AB testing gate for bank deposit feature Apr 20, 2026
Copy link
Copy Markdown
Collaborator

@arpandhakal arpandhakal left a comment

Choose a reason for hiding this comment

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

The migrations is being rewritten and not updated. I see the old migration file deleted and new one is introduced. Are these already pushed into preview, production databases? If so, I think that will cause a problem. Flagging this early.

@SandipBajracharya
Copy link
Copy Markdown
Collaborator Author

The migrations is being rewritten and not updated. I see the old migration file deleted and new one is introduced. Are these already pushed into preview, production databases? If so, I think that will cause a problem. Flagging this early.

No we have not pushed those migration to production yet. However, we have ran this in supabase dev. It makes sense to update the migration file in first PR i.e on OUT-3064. Will update this and let you know

SandipBajracharya and others added 4 commits April 21, 2026 11:14
Undeposited Funds is a QBO system account that always exists and cannot
be deleted. Caching its ID in qb_portal_connections was unnecessary.

- Add getUndepositedFundsAccountId() on IntuitAPI (live lookup by subtype)
- Call it directly in invoice.service.ts instead of checkAndUpdateAccountStatus
- Remove undepositedFundsAccountRef from schema, type, and all plumbing
- Remove UndepositedFunds from AccountTypeObj, updateAccountMapping, restoreAccountRef
- Reuse single IntuitAPI instance in webhookInvoicePaid
- Update migration: drop undeposited_funds_account_ref column addition

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…s UI

- Add bank account dropdown in InvoiceDetail below bankDepositFeeFlag checkbox
- Fetch QBO bank accounts via SWR (GET /api/quickbooks/setting/bank-account)
- Include bankAccountRef in settingState for single-request save
- Add click-outside-to-close, loading state, and amber warning when unselected
- Pass bankAccounts, isBankAccountsLoading, selectBankAccount props via SettingAccordion

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…t bank account

Block the Confirm/Update button when bankDepositFeeFlag is on but no
bank account is selected. Without a bank account, the webhook deposit
flow throws on every payment.succeeded event.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SandipBajracharya and others added 2 commits April 21, 2026 11:30
- Add AB_FEATURE_TESTING_PORTALS env var to config (empty = all portals)
- Create isPortalInBankDepositABTest utility for portal eligibility check
- Gate bank deposit flow in invoice.service and webhook.service
- Gate settings UI: return bankDepositEnabled from GET, hide checkbox/dropdown
- Remove EventType.DEPOSITED — use SUCCEEDED for both legacy and deposit flows
- Fix cascade bug: only reset bankDepositFeeFlag when feature is visible
- Increase payment.succeeded sleep to 25s

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Strip bankDepositFeeFlag/bankAccountRef from payload for non-AB portals
  (prevents garbage state if portal is later added to AB list)
- Reject bankDepositFeeFlag:true without bankAccountRef on the backend
- Fix res.Deposit.Id optional chaining inconsistency in payment.service.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Don't merge enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants