whisper-money/app/Jobs
Víctor Falcón 220b1e11f1
refactor(banking): scalable per-provider sync via a syncer factory (#545)
## Why

Syncing was a growing `if/elseif` chain in
`SyncBankingConnectionJob::handle()` plus one private method per
provider. Every new provider meant editing the job, and the file mixed
provider-specific logic with cross-cutting orchestration. This does not
scale to dozens/hundreds of providers.

## What

Introduces a **factory + strategy** pattern:

- **`App\Contracts\BankingConnectionSyncer`** — interface: `sync()`,
`expires()`, `notifiesOnAuthFailure()`.
- **`AbstractBankingConnectionSyncer`** — defaults for the common case
(API-key provider: never expires, notifies on auth failure). A new
provider usually only implements `sync()`.
- **`BankingConnectionSyncerFactory`** — maps `connection.provider` to
its syncer (resolved from the container, so dependencies are injected).
- **Six syncers** — `IndexaCapitalSyncer`, `BinanceSyncer`,
`WiseSyncer`, `BitpandaSyncer`, `CoinbaseSyncer`, `EnableBankingSyncer`.
Each fully owns its provider behavior, including EnableBanking's daily
email and first-sync cutoff.

`SyncBankingConnectionJob` drops from ~520 to ~190 lines and now only
orchestrates: deleted-user/expiry/rate-limit checks, error handling,
retries, logging, and status updates. It asks the syncer `expires()` /
`notifiesOnAuthFailure()` instead of hardcoding provider lists.

### Adding a provider now

1. Create `XSyncer extends AbstractBankingConnectionSyncer` implementing
`sync()`.
2. Add one line to the factory map.

No changes to the job.

## Tests

- Existing job tests (`SyncBankingConnectionJobTest`,
`SyncRetryAndLoggingTest`) migrated through a shared `runSync()` helper
in `tests/Pest.php`; all original assertions preserved.
- New `BankingConnectionSyncerFactoryTest`: provider→syncer resolution,
unknown-provider exception, and the capability flags.
- Full suite green: **1604 passed**, 0 failures. PHPStan clean, Pint
applied.

## Docs

Adds `docs/adding-a-banking-provider.md` — a step-by-step developer
guide (usable by a human or an AI agent) covering the sync provider and
the broader end-to-end integration touchpoints.
2026-06-16 16:25:29 +02:00
..
Drip Support soft-deleted users with reusable emails (#316) 2026-04-22 11:41:41 +01:00
ApplySingleAutomationRuleJob.php fix: batch automation rule application (#435) 2026-05-26 10:45:37 +02:00
AssignHistoricalTransactionsToBudget.php feat: Load transactions history on budget created (#72) 2026-01-22 11:10:15 +01:00
CategorizeOnboardingTransactionsJob.php feat(ai): defer per-transaction categorization until onboarding completes (#536) 2026-06-15 17:33:26 +02:00
GenerateHistoricalLoanBalancesJob.php feat(loans): backfill historical balances on loan creation (#322) 2026-04-24 13:09:34 +01:00
GenerateHistoricalRealEstateBalancesJob.php feat(real-estate): auto-calculate revaluation % and generate historical balances (#253) 2026-04-15 12:18:33 +00:00
GenerateRuleSuggestionsJob.php feat(ai): suggest automation rules during onboarding (#523) 2026-06-13 22:51:15 +02:00
ReEvaluateTransactionRulesJob.php feat(transactions): re-add select all matching filters to bulk actions bar (#169) 2026-03-01 10:27:43 +00:00
SendDailyBankTransactionsSyncedEmailJob.php feat(settings): let users disable bank transactions email (#472) 2026-06-02 12:24:39 +02:00
SendUpdateEmailJob.php Support soft-deleted users with reusable emails (#316) 2026-04-22 11:41:41 +01:00
SyncAllBankingConnectionsJob.php refactor: centralize duplicated provider & locale keys into enums (#543) 2026-06-16 13:43:14 +00:00
SyncBankingConnectionJob.php refactor(banking): scalable per-provider sync via a syncer factory (#545) 2026-06-16 16:25:29 +02:00
SyncBinanceHistoricalBalancesJob.php feat: Add Binance integration (#131) 2026-02-18 15:23:46 +01:00