whisper-money/app/Enums
Víctor Falcón 021cb66643
feat(transactions): serve import dedup and account ledger from the backend (#631)
## Summary

Migrates the last two flows off the deprecated client-side
IndexedDB/Dexie "offline-first" model so they read from the backend
instead of the local database. The Dexie cache was already being
dismantled and is no longer the source of truth for the transaction
list; these two consumers were the last ones still tied to it, and the
local read could silently return incomplete data.

**Duplicate detection on import** and **the account detail transaction
list** now both come from the server.

### What changed

- **Import duplicate detection** → new `POST
/api/transactions/check-duplicates`. Matches on day + amount (integer
cents) + normalized description server-side, replacing
`sync()`-then-read-Dexie, which silently missed duplicates that fell
outside the local cache window.
- **Account detail transaction list** → served as an Inertia prop from
`AccountController@show` (eager-loading `category` + `labels`) instead
of fetching every transaction from `/api/sync/transactions` and
filtering client-side (which could show an incomplete list for accounts
with long history).
- **Import preview "existing transactions" panel** → reads from `GET
/api/transactions?account_id=…&per_page=10` (the index gains an
`account_id` filter + clamped `per_page`) instead of Dexie.
- `TransactionList` now renders only from the provided prop; the
`/api/sync` fetch path, the Dexie-backed search, and the `refreshKey`
refetch are removed (search is in-memory; create triggers a scoped
`router.reload({ only: ['transactions'] })`).

### Commits

1. `feat` — the backend migration (endpoints, controller prop, frontend
rewiring, tests).
2. `refactor` — centralize the "has transaction ledger" rule in
`AccountType::hasTransactionLedger()` (a single named concept the
frontend mirrors, documented as distinct from `isNonTransactional()`),
and add an `id` tiebreak for deterministic pagination.
3. `fix` — drop rows reassigned to another account from the account list
(they lingered now that the list no longer refetches).
4. `fix` — match Unicode whitespace (e.g. non-breaking spaces) in
server-side duplicate detection, matching the old JS behavior; hardens
endpoint tests.

## Review notes

Two review agents (architecture/quality and bugs/correctness) reviewed
the change. Applied: the `AccountType` single-source-of-truth, stable
pagination sort, the account-reassignment stale-row fix, the
Unicode-whitespace parity fix, and extra edge-case tests (validation,
date-range boundary, cross-user scoping).

**Deferred (follow-up):** `AccountController@show` still loads the
account's full transaction history into the Inertia payload. It's
acceptable now (single account, strictly better than the old
load-all-accounts approach) and marked with a `ponytail:` comment, but
accounts with very long history should move to a deferred +
cursor-paginated prop (the new `?account_id=` endpoint can back it).
Also, the deprecated Dexie/sync-manager stack (`sync()`, `getAll`,
`getByAccountId`, `/api/sync/transactions`) now has fewer callers and
can be retired in a dedicated cleanup.

## Test plan

- `tests/Feature/Api/TransactionDuplicateCheckTest.php` — matching,
normalization (incl. NBSP), date-range boundary, account scoping, IDOR,
validation.
- `tests/Feature/Api/TransactionIndexTest.php` — `account_id` filter +
newest-first order, `per_page` cap and lower clamp, cross-user scoping.
- `tests/Feature/AccountControllerTest.php` — the account-show
`transactions` prop (own vs other accounts, non-transactional accounts).
- Existing `DecryptTransactionsTest` (the other `/api/transactions`
consumer) unaffected.
- Frontend vitest suites for the touched areas pass.

Draft while the deferred payload/cleanup items are discussed.
2026-07-03 16:49:59 +02:00
..
AccountType.php feat(transactions): serve import dedup and account ledger from the backend (#631) 2026-07-03 16:49:59 +02:00
AnalysisMode.php feat(analysis): project-aware transaction analysis (#513) 2026-06-09 15:32:07 +02:00
BankingConnectionStatus.php feat: Integrate EnableBanking as open banking provider (#106) 2026-02-12 09:09:28 +01:00
BankingProvider.php feat(banking): add Interactive Brokers sync via Flex Web Service (#581) 2026-06-23 11:39:24 +02:00
BankingSyncLogStatus.php fix(banking): retry failed sync connections and log every sync attempt (#251) 2026-03-31 11:34:35 +01:00
BudgetPeriodType.php Add yearly budget period (#384) 2026-05-12 13:35:25 +02:00
CategoryCashflowDirection.php feat(cashflow): track transfer categories in trends (#236) 2026-03-18 14:02:47 +00:00
CategoryColor.php Add category type field support (#2) 2025-12-01 20:19:47 +01:00
CategoryDeletionStrategy.php feat: parent/child category tree (#474) 2026-06-03 19:30:12 +02:00
CategorySource.php feat(ai): auto-categorize transactions with AI (behind flag) (#535) 2026-06-15 16:35:20 +02:00
CategoryType.php feat(cashflow): add savings and period views (#424) 2026-05-25 16:41:00 +02:00
ChartColorScheme.php Add chart color scheme setting (#101) 2026-02-28 12:58:21 +01:00
DripEmailType.php feat(email): follow up after post-onboarding AI consent (#596) 2026-06-26 17:56:06 +00:00
IntegrationRequestStatus.php feat(integration-requests): add done status and fix review command crash on orphaned author (#601) 2026-06-27 14:42:09 +00:00
LabelColor.php feat: add transaction labels feature (#24) 2025-12-13 13:02:19 +01:00
LeadCohort.php feat(leads): cohort-based launch invitations with per-user Stripe coupons (#333) 2026-04-30 15:10:28 +01:00
Locale.php refactor: centralize duplicated provider & locale keys into enums (#543) 2026-06-16 13:43:14 +00:00
PlanFeature.php feat(ai): suggest automation rules during onboarding (#523) 2026-06-13 22:51:15 +02:00
PropertyType.php feat(accounts): add real estate asset tracking (#241) 2026-03-24 10:21:32 +00:00
RolloverType.php Add Budgeting Feature to Track and Manage Spending (#36) 2026-01-21 15:25:50 +01:00
RuleOrigin.php feat(ai): learn from category corrections so the AI stops repeating the same mistake (#608) 2026-06-29 19:12:15 +02:00
RuleSuggestionStatus.php feat(ai): suggest automation rules during onboarding (#523) 2026-06-13 22:51:15 +02:00
SuggestionRunStatus.php feat(ai): suggest automation rules during onboarding (#523) 2026-06-13 22:51:15 +02:00
TransactionSource.php feat: add Wise open banking integration with balance sync (#525) 2026-06-16 13:23:25 +00:00