This commit is contained in:
null 2026-06-06 19:47:05 -05:00
parent fc3709337c
commit 17478ebd9c
1 changed files with 7 additions and 0 deletions

View File

@ -3,6 +3,13 @@
### ✨ Added ### ✨ Added
- **Improved unmatch flow — choice dialog + bulk deselect** — Clicking Unmatch on a linked transaction in the Bill modal now opens a two-option choice dialog instead of immediately removing the match. Option 1 ("Unmatch this payment only") confirms via a single AlertDialog and removes only that transaction. Option 2 ("Review all similar matches") fetches all linked transactions for the bill whose payee normalizes to the same prefix and opens a checklist dialog where each similar match is pre-checked. Users can deselect individual transactions to keep them matched, use All/None quick-selects, and optionally check a "Remove merchant rule" checkbox (shown only when a merchant rule matching the payee pattern exists on the bill). The confirm button shows the count of selected transactions and is disabled when nothing is selected. New backend endpoint `POST /api/transactions/unmatch-bulk` handles mixed `provider_sync` (restores balance + soft-deletes payment) and `transaction_match` (standard unmatch service) entries in a single database transaction.
- **Subscription catalog: bank descriptors + pricing (2026 researched dataset)**`subscription_catalog` now carries researched bank statement descriptor strings and common nicknames/slang from a 200-service dataset. Migration v0.95 adds four columns (`subcategory`, `starting_monthly_usd`, `starting_annual_usd`, `price_notes`) and a new `subscription_catalog_descriptors` table (1,501 rows: 1,069 bank descriptors + 432 slang terms). `loadCatalog` joins descriptors into each catalog entry at load time. `lookupCatalog` now checks bank statement descriptors first (score 2000+) before falling back to name/domain fuzzy-match (1000/500); this resolves cases where bank payee strings like "NETFLIX *SUBSCRIPTION" or "AMZN PRIME VIDEO" bore no obvious similarity to the service name. `catalogMatchPayload` now includes `starting_monthly_usd`.
- **Improved unmatch flow — choice dialog + bulk deselect** — Clicking Unmatch on a linked transaction in the Bill modal now opens a two-option choice dialog. Option 1 ("Unmatch this payment only") shows a confirmation AlertDialog and removes just that transaction. Option 2 ("Review all similar matches") fetches all linked transactions for the bill whose payee normalizes to the same prefix and opens a checklist dialog: each similar match is pre-checked, users can deselect ones to keep, All/None quick-selects are available, and an optional "Remove merchant rule" checkbox appears when a matching merchant rule exists. Confirm shows the count of selected transactions. New backend endpoint `POST /api/transactions/unmatch-bulk` handles mixed `provider_sync` (restores balance + soft-deletes payment) and `transaction_match` entries in a single database transaction.
- **Auto-match review panel** — Merchant-rule auto-matches (payment_source = provider_sync) are now surfaced in a collapsible "Auto-matched — review" panel in the Data → Bank Sync section. Each entry shows the payee, date, amount, and the bill it was matched to. An Undo button reverses the match: the payment is soft-deleted, the bill balance is restored (including any interest), and the transaction reverts to unmatched. The panel appears only when there are reviewable items in the last 7 days, disappears when the list is empty, and automatically refreshes after each Sync Now or Backfill. New endpoints: `GET /api/payments/recent-auto` (fetch the review list), `POST /api/payments/:id/undo-auto` (reverse one match). - **Auto-match review panel** — Merchant-rule auto-matches (payment_source = provider_sync) are now surfaced in a collapsible "Auto-matched — review" panel in the Data → Bank Sync section. Each entry shows the payee, date, amount, and the bill it was matched to. An Undo button reverses the match: the payment is soft-deleted, the bill balance is restored (including any interest), and the transaction reverts to unmatched. The panel appears only when there are reviewable items in the last 7 days, disappears when the list is empty, and automatically refreshes after each Sync Now or Backfill. New endpoints: `GET /api/payments/recent-auto` (fetch the review list), `POST /api/payments/:id/undo-auto` (reverse one match).
- **Auto-learn merchant rules from manual matches** — When a user explicitly confirms a transaction→bill match (via the confirm-match button or the transaction match endpoint with `learnMerchant: true`), a normalized merchant rule is automatically created so future synced transactions from the same payee auto-match without manual intervention. The derived rule is gated by `learnableMerchantFromTransaction()` which rejects payee text that is too short (<4 chars) or composed entirely of generic financial tokens (ach, atm, transfer, fee, etc.), preventing a rule like "ACH Payment" from becoming a catch-all. Background auto-matching (via `applyMerchantRules`) never creates rules only explicit user actions do. Generic API endpoint tokens are also now collapsed in `normalizeMerchant` (apostrophes stripped so "Sam's Club" "sams club"). - **Auto-learn merchant rules from manual matches** — When a user explicitly confirms a transaction→bill match (via the confirm-match button or the transaction match endpoint with `learnMerchant: true`), a normalized merchant rule is automatically created so future synced transactions from the same payee auto-match without manual intervention. The derived rule is gated by `learnableMerchantFromTransaction()` which rejects payee text that is too short (<4 chars) or composed entirely of generic financial tokens (ach, atm, transfer, fee, etc.), preventing a rule like "ACH Payment" from becoming a catch-all. Background auto-matching (via `applyMerchantRules`) never creates rules only explicit user actions do. Generic API endpoint tokens are also now collapsed in `normalizeMerchant` (apostrophes stripped so "Sam's Club" "sams club").