Commit Graph

32 Commits

Author SHA1 Message Date
null 005b0b7b64 refactor(server): migrate 10 services to TypeScript (.cts)
Continues the incremental server TS migration (after utils/*.mts and
paymentValidation.cts): converts 10 services to .cts (CommonJS TypeScript,
run natively via Node type-stripping — no build step), type-checked by
tsconfig.server.json.

Migrated: totpService, amountSuggestionService, encryptionService,
paymentAccountingService, statusService, aprService, driftService,
analyticsService, spendingService, billMerchantRuleService.

- types/db.d.ts: shared minimal better-sqlite3 Db/Statement types (the lib
  ships none), reused across the migrated modules.
- Every require of a migrated service updated to the explicit .cts extension
  (extensionless require does not resolve .cts) across routes / services /
  db migrations / server.js / workers / tests — require-only changes.
- package.json: check:server find pattern now includes *.cts (it silently
  skipped .cts before, so paymentValidation.cts had no node --check gate).

Behavior-preserving (types only). Verified: typecheck:server 0,
check:server 0, full server suite 226/226, real boot → /api/health 200.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-06 10:35:29 -05:00
null 01030fe7d0 feat(settings): configurable "Due soon" window (plan Tier 4)
- 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]>
2026-07-05 16:00:32 -05:00
null 3f9a6cf23e feat(server-ts): utils/dates → TypeScript (.mts); utils/ dir now TS (Phase 2)
dates.mts (ESM, typed) joins money.mts — the two most-required server
leaves are now TypeScript. Added .cts to the server tsconfig for the
CJS-module migration path. typecheck:server clean; suite 225 + probe 17/17.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-05 13:48:44 -05:00
null 200c6373f5 feat(server-ts): migrate the money boundary to TypeScript on Node's native runtime (Phase 2)
Establishes the server-TypeScript foundation and migrates utils/money →
utils/money.mts with branded Cents/Dollars (mirroring the client), so the
cents↔dollars boundary — the origin of the reconciliation bug class — is a
compile error for any typed server caller.

Approach (no build step): Node 25 runs .ts natively (type-stripping).
Migrated modules use the explicit-ESM .mts extension (the project is
"type":"commonjs", which disables .ts ESM auto-detection) and are required
from the CJS callers via Node's require(esm) — verified working. Infra:
tsconfig.server.json (allowJs + checkJs:false → incremental like the
client), npm run typecheck:server, check:server extended to .mts, wired
into ci. 28 require sites repointed to money.mts.

typecheck:server clean; full server suite 225 + e2e probe 17/17 green.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-05 13:44:04 -05:00
null 995f635d35 refactor(tracker): consolidate isPaidStatus + rowOutstanding + toast gap (T5)
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 <[email protected]>
2026-07-03 18:36:30 -05:00
null 9f4b53d37a perf(tracker): batch getTracker per-bill queries (kill N+1) (P1)
getTracker ran a payments query per bill plus computeAmountSuggestion per bill
(up to 12 queries each: 6 months x 2) inside bills.map — ~70-450 queries for a
35-bill account per load. Now one query fetches all cycle payments (grouped in
JS per bill range) and two compute all amount suggestions
(computeAmountSuggestionsBatch). Behavior-preserving.

Test: tests/amountSuggestionService.test.js pins batch == per-bill output.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-03 18:25:55 -05:00
null 73631ab812 fix(tracker): route error handling + autopay write atomicity (T2)
routes/tracker.js had no try/catch and returned a plain {error} shape; the
three GET handlers now wrap in try/catch + standardizeError (including the
invalid-month path). applyAutopaySuggestions ran INSERT + applyBalanceDelta
as two un-transactional steps on a GET — wrapped both in one db.transaction.

Tests: autopay creates one payment + drops balance (idempotent), route
returns standardized error.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-03 18:21:28 -05:00
null 4a38cc8614 fix(tracker): gate bank card unpaid/remaining by occurrence + add trackerService tests (T1)
buildBankTracking summed expected_amount for all active unpaid bills with no
resolveDueDate gate, so annual/off-month bills inflated unpaid_this_month and
the bank remaining (same class as QA-B5-02, live on the bank path). getTracker
now derives the unpaid total from the already-gated rows (netting partials) and
passes it in. summary.remaining/total_remaining now use the bank card's own
remaining in bank mode (agreeing with safe-to-spend), and a stray balance/100
is now fromCents.

New tests/trackerService.test.js: gating fix, summary totals, bank-mode
remaining agreement, cents<->dollars, getOverdueCount gating.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-03 18:10:28 -05:00
null dc49eb9633 feat(cashflow): safe-to-spend projection with timeline, vitest setup, package upgrades 2026-06-12 01:32:28 -05:00
null d6639f1385 feat(money): cents migration stage 2 — schema flip to integer cents (batch 0.38.4) 2026-06-11 20:12:31 -05:00
null bf66ab1ee6 feat(money): migrate services to cent-exact money.js helpers (batch 0.38.3) 2026-06-10 20:14:13 -05:00
null 947fa3bdf8 feat(auth): add per-username rate limiter, migrate dates to local-time utils (batch 0.38.1) 2026-06-10 19:42:51 -05:00
null ca514e5f26 fix(tracker): BillModal save/close race and pending badge logic
- Use controlled Dialog state (setDialogOpen) instead of immediate onClose()
  to let Radix cleanup properly before unmount
- Amber 'Pending' badge now only shows for bank-linked bills — unlinked
  bills skip the pending-cleared check and show 'Paid' directly
- TrackerPage onSave no longer nullifies edit state before BillModal can
  animate closed

(batch 0.37.4)
2026-06-08 16:33:48 -05:00
null fab4945d50 fix(tracker): bank pending counts, overdue center cleanup, and payment source labels
- 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)
2026-06-08 16:05:31 -05:00
null e1082145ab feat: tracker payment flow and mobile row improvements 2026-06-07 14:49:39 -05:00
null 6811eb8be5 feat: payment accounting service, SQL schema + migration, backend route refactor, test updates 2026-06-07 01:05:48 -05:00
null 4dd01c13c4 feat: live transaction search in merchant rules, link-import preference toggle, tracker row tweaks 2026-06-06 23:04:53 -05:00
null 840620efe2 feat: v0.93 — stable provider keys, per-payment interest tracking with once-per-month gating 2026-06-06 16:34:20 -05:00
null 3745ef79b7 docs: update HISTORY.md with bank tracking, merchant rules, and UI changes 2026-06-04 02:48:32 -05:00
null ccdd16a626 fix: summary route and trackerService refinements 2026-06-04 01:27:00 -05:00
null 5783f80e38 fix: include b.name in overdue query for tooltip display 2026-06-04 01:16:48 -05:00
null 46bcf83d22 fix: NavPill and Sidebar UI refinements, trackerService adjustments 2026-06-04 01:00:29 -05:00
null a88d5c4647 fix: move cashflow calculations before the cashflow block reference 2026-06-03 23:08:20 -05:00
null c26880da89 fix: bank tracking Pending badge cleanup, CalendarPage money map polish
- TrackerPage Pending badge: consistent styling and tooltip text
- CalendarPage money map: handle edge cases when bank tracking is active but no pending payments
- trackerService: deduplicate pending payment query, handle zero-pending state
2026-06-03 21:30:02 -05:00
null 690a86611a feat: SimpleFIN bank budget tracking with live balance, pending payments, bank tracking mode
- 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
2026-06-03 21:09:26 -05:00
null 31bafb0e55 0.34.3 2026-05-31 15:06:10 -05:00
null 5449427b86 Add persistent bill reordering 2026-05-30 16:13:37 -05:00
null 3978507572 feat(tracker): overdue command center with snooze/skip/pay + sidebar badge
- migration v0.70 adds snoozed_until TEXT to monthly_bill_state
- trackerService: snoozed_until in monthly state fetch + getOverdueCount()
- GET /api/tracker/overdue-count endpoint
- PUT /bills/:id/monthly-state validates snoozed_until
- OverdueCommandCenter component: collapsible, per-bill actions, hides snoozed
- useOverdueCount hook (2-min stale, 5-min poll, tab-only)
- Sidebar/nav uses overdue count badge on Tracker menu item
- Bump v0.33.8.7 → v0.34.0
2026-05-30 13:19:09 -05:00
null d3f2a921bf no exploitable SQL injection vulnerabilities 2026-05-28 03:43:50 -05:00
null e8218a3dd8 bill tracker futurue 2026-05-28 02:09:49 -05:00
null 9d933f70cc v0.28.01 2026-05-16 20:26:09 -05:00
null b124e48ebc v0.28.0 2026-05-16 15:38:28 -05:00