Skip to content

OUT-3617-new: AB feature-testing gate for the bank deposit flow - #278

Merged
SandipBajracharya merged 4 commits into
feature/payout-reconciliationfrom
OUT-3617-new
Aug 3, 2026
Merged

OUT-3617-new: AB feature-testing gate for the bank deposit flow#278
SandipBajracharya merged 4 commits into
feature/payout-reconciliationfrom
OUT-3617-new

Conversation

@SandipBajracharya

Copy link
Copy Markdown
Collaborator

Problem

The bank-deposit flow is going out to a limited set of portals (Permit Pushers) first, not all at once.

Shipped

An env-driven allowlist gate. AB_FEATURE_TESTING_PORTALS (comma-separated portalIds) controls availability; empty/unset = available to all portals (full-rollout default). Backed by isPortalInBankDepositABTest(portalId).

Gated at exactly the points that decide behavior:

  • FreezeInvoiceService.readBankDepositFeeFlag(): excluded portals freeze invoices non-batched regardless of the stored flag.
  • Reconcile — top of PayoutService.reconcile(): excluded portals short-circuit to { depositId: null }, covering both the payout webhook and the resync cron. Logged (not silent) so a rare mid-flight exclusion is visible.
  • Settings — write path strips the flag + bank account for non-AB portals; GET returns bankDepositEnabled.
  • UI — checkbox + bank-account dropdown hidden when off; bank-account fetch skipped.

No schema changes, no migrations.

Code sites

  • src/config/index.ts, src/utils/abTesting.ts
  • src/app/api/quickbooks/invoice/invoice.service.ts, payout/payout.service.ts, setting/setting.controller.ts
  • src/hook/useSettings.ts, components/dashboard/settings/SettingAccordion.tsx, .../invoice/InvoiceDetail.tsx

Tests

Unit: gate util, freeze gate, reconcile gate, settings write path + bankDepositEnabled. Integration: real webhook → invoice.service → DB proves an excluded portal freezes non-batched. Full suite green (282 unit / 117 integration), tsc + lint + prettier clean.

Rollout

Set AB_FEATURE_TESTING_PORTALS in Vercel (all environments) as part of enabling the feature.

🤖 Generated with Claude Code

SandipBajracharya and others added 4 commits August 3, 2026 14:33
Parse AB_FEATURE_TESTING_PORTALS into an allowlist (empty/unset = all
portals) and expose isPortalInBankDepositABTest for the rollout gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Freeze gate in readBankDepositFeeFlag (non-allowlisted portals freeze
non-batched) and a reconcile gate covering both the payout webhook and
resync cron. The settings write path strips the flag + bank account for
non-AB portals, and GET returns bankDepositEnabled for the UI. The
reconcile short-circuit is logged so a rare mid-flight exclusion is
visible rather than silent.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Read bankDepositEnabled from the settings GET, thread it through the
accordion into InvoiceDetail to hide the checkbox + bank-account
dropdown, and skip the bank-account fetch entirely for gated-off portals.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Unit tests for the gate util, the freeze and reconcile gates, and the
settings write path + bankDepositEnabled signal. Integration test drives
the real webhook -> invoice.service -> DB path to confirm an excluded
portal freezes non-batched. The gate is env-parsed at config load, so the
integration harness mocks it via a globalThis-pinned allowlist (default
= all portals) driven per-test by test/helpers/abTestGate.ts.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Aug 3, 2026

Copy link
Copy Markdown

OUT-3617

@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
quickbooks-sync Ready Ready Preview Aug 3, 2026 8:58am

Request Review

@greptile-apps

greptile-apps Bot commented Aug 3, 2026

Copy link
Copy Markdown

Greptile Summary

Adds an environment-driven portal allowlist for incrementally rolling out the bank-deposit flow, with an empty allowlist retaining full availability.

  • Applies the gate when freezing invoice deposit intent and reconciling payouts.
  • Prevents excluded portals from writing bank-deposit settings and exposes the gate state to the settings UI.
  • Hides bank-deposit controls and skips bank-account loading for excluded portals.
  • Adds unit and integration coverage for gate parsing and affected service paths.

Confidence Score: 5/5

The PR appears safe to merge under the documented fixed-before-rollout allowlist operation.

No blocking failure remains; the previously reported mid-flight exclusion scenario was explicitly identified as outside the supported rollout model because individual portals will not be removed after enablement.

Important Files Changed

Filename Overview
src/utils/abTesting.ts Implements the shared portal-membership gate with the documented full-rollout default for an empty allowlist.
src/config/index.ts Parses and normalizes the comma-separated portal allowlist at module initialization.
src/app/api/quickbooks/invoice/invoice.service.ts Ensures excluded portals freeze new invoices without batched-deposit intent.
src/app/api/quickbooks/payout/payout.service.ts Short-circuits deposit reconciliation for excluded portals under the documented fixed allowlist rollout model.
src/app/api/quickbooks/setting/setting.controller.ts Gates bank-deposit setting writes and returns feature availability to invoice-settings clients.
src/hook/useSettings.ts Consumes server-provided availability and avoids fetching bank accounts while the feature is disabled.
src/components/dashboard/settings/sections/invoice/InvoiceDetail.tsx Conditionally renders the bank-deposit controls according to the server-provided gate state.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Portal request or sync event] --> B{Allowlist empty?}
    B -->|Yes| C[Bank deposit feature enabled]
    B -->|No| D{Portal ID allowlisted?}
    D -->|Yes| C
    D -->|No| E[Bank deposit feature disabled]
    C --> F[Allow settings and freeze batched intent]
    C --> G[Reconcile payout into deposit]
    E --> H[Hide and strip bank-deposit settings]
    E --> I[Freeze invoices as non-batched]
    E --> J[Skip payout reconciliation]
Loading

Reviews (2): Last reviewed commit: "test(OUT-3617): cover the bank-deposit A..." | Re-trigger Greptile

Comment thread src/app/api/quickbooks/payout/payout.service.ts
@SandipBajracharya

Copy link
Copy Markdown
Collaborator Author

@greptileai review the PR again

@SandipBajracharya SandipBajracharya changed the title feat(OUT-3617): AB feature-testing gate for the bank deposit flow OUT-3617-new: AB feature-testing gate for the bank deposit flow Aug 3, 2026
Comment thread src/utils/abTesting.ts

@priosshrsth priosshrsth left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

lgtm

@SandipBajracharya
SandipBajracharya merged commit e3c4e4f into feature/payout-reconciliation Aug 3, 2026
6 checks passed
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