The Overdue Command Center and Price-Change (drift) panels reset to
expanded on every load — their collapse arrows used local useState. Now
the collapsed state is remembered per-user via two new settings
(tracker_overdue_collapsed / tracker_drift_collapsed), mirroring the
search panel's useSearchPanelPreference pattern. Each panel header also
gains an inline "Hide" control (EyeOff, like the search panel) that writes
the existing tracker_show_* setting and fires an Undo toast; hidden
sections come back from Settings → Tracker Layout.
- services/userSettings.js: allowlist + defaults for the two collapse keys
- TrackerPage: read collapse state, hide handlers with Undo, wire props
- OverdueCommandCenter/DriftInsightPanel: controlled collapse + header hide
Verified: typecheck 0, lint 0 errors, build, and a live settings round-trip
(collapse persists, hide writes, Undo restores, allowlist rejects junk keys).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- New per-user 'default_landing_page' setting (tracker default / calendar /
summary / spending), registered in the whitelist + defaults.
- Implemented as a post-login redirect (keeps /=Tracker so the Home link and
direct nav are unaffected). Precedence: admin → deep-link they were bounced
from (state.from) → default landing → /. Resolved by fetching settings in the
login success path, with a safe / fallback so a fetch failure never blocks login.
- Settings: Select in the Regional section.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- statusService: resolveDueSoonDays (clamp 0–31, default 3) replaces the
hardcoded 3-day threshold in calculateStatus; threaded via options.dueSoonDays
through rowOptions in trackerService (×2) and routes/calendar.
- New per-user 'due_soon_days' setting registered in the whitelist + defaults.
- Settings: numeric "Due soon window" row next to Grace period, with min/max +
clamp guard. Tooltips added to Grace period, Due-soon, and Price-change
sensitivity explaining each.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- New per-user 'week_start' setting (0=Sun default / 1=Mon), registered in
USER_SETTING_KEYS + USER_SETTING_DEFAULTS.
- CalendarPage reads it and offsets the month grid: leading-blank count
(getDay()-weekStart+7)%7 and a rotated weekday header. Purely presentational.
- Settings: Sun/Mon Select in the new "Regional" section. Also aligns the
grace_period_days client default (3→5) with the server seed.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- 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 <[email protected]>