Commit Graph

19 Commits

Author SHA1 Message Date
Víctor Falcón 726bce61ef
fix: Add gap between filter/create button on mobile settings pages (#115)
## Summary

- Added `gap-4` to the flex containers holding the filter input and
create button on the accounts, categories, labels, and connections
settings pages
- Without the gap, these elements had no spacing on mobile viewports and
appeared cramped
- The automation rules page already had `gap-4` — this makes all
settings pages consistent

## Screenshots (mobile 375px)

### Accounts

![Accounts](https://raw.githubusercontent.com/whisper-money/whisper-money/fix/settings-mobile-button-gap/screenshots/settings-accounts-mobile.png)

### Categories

![Categories](https://raw.githubusercontent.com/whisper-money/whisper-money/fix/settings-mobile-button-gap/screenshots/settings-categories-mobile.png)

### Labels

![Labels](https://raw.githubusercontent.com/whisper-money/whisper-money/fix/settings-mobile-button-gap/screenshots/settings-labels-mobile.png)

### Connections

![Connections](https://raw.githubusercontent.com/whisper-money/whisper-money/fix/settings-mobile-button-gap/screenshots/settings-connections-mobile.png)

## Test plan
- [x] Verify gap appears between filter input and create button on
mobile for accounts, categories, labels, and connections settings pages
- [x] Verify desktop layout is unaffected
2026-02-12 20:50:05 +01:00
Víctor Falcón db7b6e4da7
feat: Integrate EnableBanking as open banking provider (#106)
## Summary

- Adds **EnableBanking** as the first open banking provider, allowing
users to connect real bank accounts and automatically sync transactions
and balances
- Uses a **`BankingProviderInterface`** contract so future providers
(Plaid, GoCardless, etc.) can be added by implementing the same
interface
- Feature-flagged behind the **`open-banking`** Pennant flag (default:
off)
- Connected accounts are **unencrypted** and transactions have `source =
'enablebanking'`

### What's included

**Backend:**
- `BankingProviderInterface` contract + `EnableBankingProvider`
implementation (JWT RS256 auth)
- `BankingConnection` model with full lifecycle (pending →
awaiting_mapping → active → expired/revoked/error)
- `TransactionSyncService` — pagination, deduplication by
`external_transaction_id`, amount/date mapping
- `BalanceSyncService` — preferred balance type selection (CLBD → ITAV
fallback)
- Authorization flow: start auth → bank redirect → callback → session
creation → account mapping → sync
- `SyncBankingConnectionJob` (unique per connection, 3 retries) +
scheduled every 6 hours
- `banking:sync` artisan command
- 5 migrations: `banking_connections` table, account fields, transaction
`external_transaction_id`, `pending_accounts_data`, `linked_at`

**Frontend:**
- Manual vs Connected account choice in the create account dialog
- Multi-step bank connection dialog (country → bank selection →
confirmation → redirect)
- Account mapping page — map discovered bank accounts to existing
accounts, create new ones, or skip
- Settings/Connections page with status badges, sync/disconnect actions
- "Connected" badge on linked accounts in settings

**Tests:**
- 49 tests covering feature flags, controllers, account mapping,
transaction sync, balance sync, deduplication, and pagination

### Feature Flags

This PR introduces **two Pennant feature flags**:

1. **`open-banking`** — Gates the entire open banking feature
(institutions endpoint, authorization flow, connections page). When
disabled, all open banking routes return 404.

2. **`account-mapping`** — Controls whether users see an intermediate
account mapping step after connecting a bank. When **enabled**, users
are redirected to a mapping page where they can choose to create new
accounts, link to existing ones, or skip each discovered bank account.
When **disabled**, all discovered accounts are automatically created
(original behavior). Linked accounts only sync transactions from their
last transaction date and only update the current balance from the
provider (no historical balance calculation or daily balance tracking).

Enable per-user:
```bash
php artisan feature:enable open-banking user@example.com
php artisan feature:enable account-mapping user@example.com
```

Enable for all users:
```bash
php artisan feature:enable open-banking all
php artisan feature:enable account-mapping all
```

## Test plan

- [x] Enable feature flag: `php artisan feature:enable open-banking`
- [x] Verify "Connected" option appears in create account dialog
- [x] Start authorization flow and verify redirect to bank
- [x] With `account-mapping` **disabled**: verify callback creates
accounts directly and dispatches sync
- [x] With `account-mapping` **enabled**: verify callback redirects to
mapping page
- [x] Test mapping page: create new, link to existing, and skip actions
- [x] Verify linked accounts sync only from last transaction date and
only update current balance
- [x] Verify connections page shows "Setup Required" badge for
awaiting_mapping status
- [x] Run `php artisan banking:sync` and verify transactions sync
- [x] Verify connections page shows status, sync, and disconnect actions
- [x] Run full test suite: `php artisan test --compact`
2026-02-12 09:09:28 +01:00
Víctor Falcón 2dc8cb554c
Remove encryption from bank account names (#104)
## Summary

- Store account names in plaintext instead of encrypting them
client-side. Encryption remains only for transaction descriptions and
notes.
- Existing encrypted account names are silently migrated when the user
unlocks their encryption key, via a new `useDecryptAccountNames` hook
that calls API endpoints to update each account.
- New `AccountName` component handles rendering both encrypted (legacy)
and plaintext accounts across the app.

## Test plan

- [x] Create a new account — name should be stored in plaintext
(`encrypted = false`, `name_iv = null`)
- [x] Unlock encryption key with existing encrypted accounts — they
should auto-migrate silently
- [x] After migration, verify accounts show `encrypted = false` in DB
and names are readable plaintext
- [x] Edit a migrated account — should work without encryption
- [x] Verify all account name displays work across dashboard, account
details, transactions, settings
2026-02-09 14:15:26 +01:00
Víctor Falcón 70b603e901
feat: Spanish localization (#74)
## Pending
- [x] Translate landing page
- [x] Dashboard
- [x] Accounts list page
- [x] Account page
- [x] Cashflow
- [x] Budgets
- [x] Transactions
- [x] Settings

## Screenshots
<img width="1210" height="969" alt="image"
src="https://github.com/user-attachments/assets/c7935e5c-488d-4941-8f19-8834e5668257"
/>
<img width="1211" height="972" alt="image"
src="https://github.com/user-attachments/assets/e94e1daf-233a-4a49-aa65-5678c772d178"
/>
2026-02-08 11:58:08 +01:00
Víctor Falcón 439ec86722
chore: Simplify IndexedDB sync by moving to Inertia shared props (#63)
This PR simplifies the IndexedDB synchronization mechanism by removing
individual sync controllers and services, and instead using Inertia.js
shared props to provide data globally across the application.

## Benefits

1. **Simplified Architecture**: Removed complex sync logic for
static/semi-static data (accounts, categories, banks, labels, automation
rules)
2. **Better Performance**: Data is now shared via Inertia props,
eliminating unnecessary API calls and IndexedDB operations
3. **Reduced Complexity**: Significantly reduced codebase size (~2000
lines removed)
4. **Better UX**: Data is immediately available on page load without
waiting for sync operations
5. **Maintainability**: Fewer moving parts means easier to maintain and
debug

## Migration Notes

- Transaction syncing still uses IndexedDB for offline support
- All other data (accounts, categories, banks, labels, automation rules)
is now fetched via Inertia shared props
- Components automatically receive updated data on navigation without
manual sync operations
2026-01-19 19:15:26 +01:00
Víctor Falcón 0d76913e5d
test: Fix and improve Browser test suite (#62) 2026-01-19 10:04:25 +01:00
Víctor Falcón 7f2771381c Add bank relation to account model and update related components 2025-12-04 16:24:12 +01:00
Víctor Falcón d179c952c7
Accounts: Allow users to create custom banks with his own logo, and name (#12)
**When a bank is not found**
<img width="1220" height="619" alt="image"
src="https://github.com/user-attachments/assets/f46cdedf-8c12-4d9b-a531-8ab17abba9c2"
/>

**You can create a new one**
<img width="1218" height="695" alt="image"
src="https://github.com/user-attachments/assets/115e6b44-d423-4edf-a9aa-e45da81f9598"
/>
2025-12-04 15:24:04 +01:00
Víctor Falcón 2fefb64710 Fix CI: Update bun.lock and fix linting errors 2025-12-01 15:16:06 +01:00
Víctor Falcón 3cc225deb0 Y3:0 2025-11-26 12:01:49 +01:00
Víctor Falcón 32c3b32804 Context menu to tables 2025-11-15 13:57:10 +01:00
Víctor Falcón 573b2fdb0a feat(lucide-react): Add custom icons to Toaster component 2025-11-14 14:40:54 +01:00
Víctor Falcón ab63edde2b feat(settings): Update account management UI and add sync functionality 2025-11-14 10:53:55 +01:00
Víctor Falcón 71b8d69020 Migrate IndexDB integration to use Dexie 2025-11-11 08:25:50 +00:00
Víctor Falcón b3016f24a4 Udpate tables when a resource is updated, created, or deleted 2025-11-10 13:33:40 +00:00
Víctor Falcón 509065e28d Transactions page 2025-11-08 23:38:35 +00:00
Víctor Falcón 9d95f884a0 Offline First: sync bank, accounts, and categories 2025-11-08 11:29:21 +00:00
Víctor Falcón b9679b9328 Settings: add account view 2025-11-07 21:38:23 +00:00
Víctor Falcón 59bc62f976 Banks accounts 2025-11-07 19:19:29 +00:00