M1: marking a bill paid/unpaid flips the row instantly via local optimistic
state (cleared when fresh data arrives, rolled back on error) on both desktop
and mobile rows, instead of waiting for the server round-trip.
M2: bank sync (Tracker) and the bill-modal Sync use sonner toast.promise —
one toast transitioning loading -> done -> error, replacing the manual
spinner-flag + separate success/error toasts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Each bucket header gains a 'Pay all due (N)' action: one bulkPay for every
unpaid gated bill in the bucket, behind a confirm (count + total) and a single
Undo toast that deletes the created payments.
- Quick-pay and mark-paid now show a specific toast ('Rent - $1,200 paid');
quick-pay gained an Undo action to match un-pay.
- Per-bill snooze already existed in the Overdue Command Center.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Added a single isPaidStatus(status) (+ PAID_STATUSES) to statusService and a
matching client helper in trackerUtils, routing the unambiguous settled-status
checks through it (trackerService, StatusBadge, CalendarPage, rowIsPaid). The
intentionally paid-only counts stay distinct. Replaced two inline
Math.max(r.balance||0,0) with rowOutstanding, and gave the Tracker settings
load a quiet toast instead of a silent swallow. Behavior-preserving.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add bank_pending_count to tracker rows showing pending bank transaction
matches for bills with merchant rules
- Remove snoozed-only state from OverdueCommandCenter (always show when
overdue rows exist)
- Display 'Synced' label for transaction-matched payments in BillModal
- Prioritize 'Pending' badge over StatusBadge when bank has pending matches
- Exclude bank-synced and transaction-matched payments from pending_cleared
(batch 0.37.3)
- Opt-in Bank Budget Tracking mode replaces manual starting amounts with live bank balance
- Calendar money map shows Balance / Pending / Unpaid Bills / After Bills in bank mode
- Pending badge (amber) on tracker rows within configurable pending window (0-7 days)
- New GET /api/data-sources/accounts/all endpoint for account picker
- Tracker starting-amounts card shows account name and live balance hint
Detects when a bill's recent payments have diverged from its configured
expected amount for 2+ consecutive months and surfaces it in a new
collapsible amber panel on the Tracker page.
- Migration v0.71: adds `drift_snoozed_until` to bills and
`notify_amount_change` to users
- New `driftService.getDriftReport()`: computes per-bill payment median
over last 3 months, flags drift above a user-configurable threshold
(default 5%, minimum $1 delta)
- New `GET /api/bills/drift-report` and `POST /api/bills/:id/snooze-drift`
routes (registered before `/:id` to avoid routing conflict)
- `runDriftNotifications()` added to daily worker — sends amber digest
email per user listing all changed bills with old → new amounts
- `notify_amount_change` wired through profile and notifications routes
- `DriftInsightPanel`: collapsible amber panel with per-bill
strikethrough old → new amount, ±% badge, TrendingUp/TrendingDown
icons, "Update to $X.XX" (with undo toast) and "Dismiss" (30 days)
actions; teal palette for price decreases
- `drift_threshold_pct` setting added to SettingsPage Billing Behavior
- "Notify on price changes" toggle added to ProfilePage notifications
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>