OUT-4003: bank deposit settings — dedicated toggle + bank account dropdown#267
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR adds a bank deposit settings feature: a dedicated toggle (
Confidence Score: 5/5Safe to merge — the feature is self-contained, the DB writes are transactional, and both client-side and server-side guards prevent saving an incomplete bank-deposit configuration. The schema validation, transactional persistence, loading/error state handling, and canSave guard all work together correctly. No logic gaps or data-loss paths were found across the full stack. No files require special attention. The two deferred items noted in the PR description (double DB round-trip in getSettings, label disambiguation) are non-blocking and clearly documented. Important Files Changed
Sequence DiagramsequenceDiagram
participant UI as InvoiceDetail (UI)
participant Hook as useInvoiceDetailSettings
participant SettingAPI as GET /api/quickbooks/setting
participant BankAPI as GET /api/quickbooks/setting/bank-account
participant QBO as QuickBooks Online
participant DB as Database
UI->>Hook: mount
Hook->>SettingAPI: "fetch settings (type=invoice)"
SettingAPI->>DB: getOneByPortalId (QBSetting)
SettingAPI->>DB: getPortalConnection (QBPortalConnection)
DB-->>SettingAPI: "{setting, bankAccountRef}"
SettingAPI-->>Hook: "{setting, bankAccountRef}"
Hook->>Hook: hydrate settingState (bankAccountRef ?? '')
Hook->>BankAPI: fetch bank accounts (if connected)
BankAPI->>QBO: "SELECT ... FROM Account WHERE AccountType='Bank' AND Active=true maxresults 100"
QBO-->>BankAPI: accounts[]
BankAPI-->>Hook: "{accounts}"
Hook->>UI: bankAccountOptions, canSave
UI->>Hook: changeSettings('bankDepositFeeFlag', true)
Hook->>Hook: "canSave = false (no account yet)"
UI->>Hook: changeSettings('bankAccountRef', 'id-123')
Hook->>Hook: "canSave = true"
UI->>Hook: submitInvoiceSettings()
Hook->>SettingAPI: "POST /api/quickbooks/setting?type=invoice"
Note over SettingAPI,DB: DB Transaction
SettingAPI->>DB: updateQBSettings (QBSetting)
SettingAPI->>DB: updateQBPortalConnection (bankAccountRef)
DB-->>SettingAPI: result
SettingAPI-->>Hook: "{setting}"
Hook->>Hook: mutate (refetch settings)
Reviews (2): Last reviewed commit: "fix(OUT-4003): address PR #267 review" | Re-trigger Greptile |
…chema SettingRequestSchema gains bankDepositFeeFlag and bankAccountRef; for invoice type the flag is required and a non-empty bankAccountRef is required when the flag is enabled. InvoiceSettingType carries both fields. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New endpoint backed by BankAccountService (route → controller → service). Lists active QBO Bank-type accounts to populate the deposit-account dropdown; selects the full account column set so the response parses against real QBO output, capped at maxresults 100. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
getSettings returns bankAccountRef and bankDepositFeeFlag for invoice type; updateSettings persists bankAccountRef transactionally with the settings write (empty coerced to null), with setTransaction/unsetTransaction paired for both services. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extract the shared AccountSelect dropdown; add an independent bankDepositFeeFlag toggle and a "Deposit bank account" dropdown in InvoiceDetail (fed by the bank-account endpoint), with an inline hint / error and a canSave gate that disables the Update button until an account is chosen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
34c1b7c to
768447d
Compare
- AccountSelect distinguishes the loading state (options undefined →
"Loading accounts…") from the genuinely-empty state ("No matching
accounts"), and InvoiceDetail only shows the "select an account" hint
once options have loaded — so enabling the toggle mid-fetch no longer
shows a misleading empty message.
- changeSettings is now generic over the field key
(<K extends keyof InvoiceSettingType>(flag: K, value: InvoiceSettingType[K])),
so the value type is tied to the field and e.g. a string can't be passed
for a boolean flag.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@greptileai review whole thing again |
Add the missing effect dependencies flagged by react-hooks/exhaustive-deps, hoist emptyMappedItem to a module singleton, and memoize the formatted QuickBooks item list so useMapItem's effect keeps a stable reference. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
100 could miss active bank accounts; 1000 is QBO's max single-page size and returns them all in one query. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collapse the let + if into a ternary that reads bankAccountRef directly off the portal connection for INVOICE settings, and drop the now-unused NotNull import. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
65aef9a to
69c059b
Compare
f6f3cfe
into
feature/payout-reconciliation
- AccountSelect distinguishes the loading state (options undefined →
"Loading accounts…") from the genuinely-empty state ("No matching
accounts"), and InvoiceDetail only shows the "select an account" hint
once options have loaded — so enabling the toggle mid-fetch no longer
shows a misleading empty message.
- changeSettings is now generic over the field key
(<K extends keyof InvoiceSettingType>(flag: K, value: InvoiceSettingType[K])),
so the value type is tied to the field and e.g. a string can't be passed
for a boolean flag.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stacked on #266 (OUT-3604). Base:
OUT-3604-new-re.What
Adds the settings-dashboard UI + API so a user can enable batched Stripe→QBO bank deposits and choose the deposit bank account. Without this,
bankAccountRefis never set and the payout handler aborts with "bank account not configured."Commits
SettingRequestSchema+InvoiceSettingTypegainbankDepositFeeFlag+bankAccountRef; invoice type requires the flag, and requires a non-emptybankAccountRefwhen the flag is on (surfaces as 422).GET /api/quickbooks/setting/bank-account(route → controller →BankAccountService) lists active QBO Bank accounts; selects the full account column set so it parses against real QBO,maxresults 100.setting.controllerGET returnsbankAccountRef; POST persists it transactionally with the invoice flags (empty → null;setTransaction/unsetTransactionpaired for both services).AccountSelect; independentbankDepositFeeFlagtoggle + "Deposit bank account" dropdown inInvoiceDetail; inline hint/error;canSavedisables the Invoice Update button until an account is chosen.Verification
tsc0 errors, lint clean,next buildOK, full suite 92 files / 342 tests pass.maxresultscap, empty→null coercion).https://www.loom.com/share/243d1bee5d7b446a8c29e3619c4cc692
Notes
settingintegration tests) and their test-infra are managed separately and are not in these commits — CI on this branch won't exercise the new tests until that lands.getSettingsdouble DB round-trip.🤖 Generated with Claude Code