whisper-money/app/Http/Controllers
Víctor Falcón 4408f719b4
fix(banking): update external_account_id on reconnect and store IBAN (#220)
## Problem

Enable Banking issues **new account UIDs** (`external_account_id`) with
every new session. On reconnect, `AuthorizationController::callback()`
was correctly updating `session_id` on the `banking_connections` table
but **never refreshing `external_account_id` on child accounts**.

When the background `SyncBankingConnectionJob` ran after a reconnect, it
called `GET /accounts/{old-uid}/transactions` using stale UIDs from the
expired session, causing Enable Banking to return `401 EXPIRED_SESSION`
— surfaced to users as _"Authentication failed. Your credentials may
have expired or been revoked."_

## Changes

- **`AuthorizationController`** — added `refreshAccountIds()` private
method, called in the reconnect branch after `session_id` is updated and
before the sync job is dispatched. Matches existing accounts by **IBAN
first**, falls back to **positional order** (`created_at ASC`) for
legacy accounts without a stored IBAN.
- **`AuthorizationController`** — `createAccountsFromSession()` and
`createAccountsFromPending()` now persist the `iban` field on account
creation so future reconnects can use IBAN matching.
- **`Account` model** — `iban` added to `$fillable`.
- **Migration** — adds nullable `iban` column to `accounts` table.

## Tests

4 new feature tests in `AuthorizationControllerTest`:

- `reconnect callback updates external_account_id when enable banking
issues new account uids`
- `reconnect callback matches accounts by iban before falling back to
position`
- `reconnect callback uses positional fallback for accounts without
stored iban`
- `callback stores iban when creating accounts for the first time`

## Deploy notes

Run the migration after deploying:

```
php artisan migrate --force
```
2026-03-12 10:28:23 +00:00
..
Api fix(static-analysis): clear phpstan-baseline by fixing all suppressed errors (#183) 2026-03-02 12:22:30 +00:00
OpenBanking fix(banking): update external_account_id on reconnect and store IBAN (#220) 2026-03-12 10:28:23 +00:00
Settings Add chart color scheme setting (#101) 2026-02-28 12:58:21 +01:00
Sync refactor: Simplify transaction endpoints architecture (#76) 2026-01-25 16:15:17 +01:00
AccountBalanceController.php feat: investment benefits — show gains/losses on investment accounts (#140) 2026-02-23 13:59:10 +01:00
AccountController.php fix(ux): improve status badge, hide balance update for connected accounts, localize delete confirm (#159) 2026-02-27 22:37:16 +00:00
BudgetController.php feat(Budgets): add period navigation and unify period selector UI (#171) 2026-03-01 12:25:01 +00:00
CashflowController.php Remove encryption from bank account names (#104) 2026-02-09 14:15:26 +01:00
Controller.php Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
DashboardController.php refactor: extract AccountMetricsService to deduplicate balance computation logic (#147) 2026-02-24 09:07:42 +01:00
EncryptionController.php Remove unused controllers and routes (#11) 2025-12-04 08:48:17 +01:00
OnboardingController.php feat: (Onboarding) add categorization intro screen with benefit cards (#201) 2026-03-05 11:47:12 +01:00
ReEvaluateTransactionRulesController.php feat(transactions): re-add select all matching filters to bulk actions bar (#169) 2026-03-01 10:27:43 +00:00
RobotsController.php User Onboarding Flow (#23) 2025-12-12 13:06:08 +01:00
SitemapController.php SEO landing page 2025-11-25 11:33:11 +01:00
SubscriptionController.php fix(billing): create Stripe customer before redirecting to billing portal (#206) 2026-03-05 11:58:04 +00:00
TransactionController.php fix(categorizer): fetch uncategorized transactions from backend instead of IndexedDB (#165) 2026-02-28 16:30:54 +00:00
UserLeadController.php feat(waitlist): waiting list with referral system (#199) 2026-03-04 12:36:47 +01:00