Budget Planner
All updates

v1.9.3 · Released · March 28, 2026

Architecture Improvements & Multi-Currency Invoice Fix

Major internal refactor: error boundaries, Suspense streaming dashboard, server-side pagination for income/expense, tag-based cache revalidation, extracted UserService/AuthService/CronLogService, standardized controller patterns, useServerAction hook, and fixed invoice summary currency mixing.

Error Handling
  • Error Boundaries: Added global-error.tsx, app error.tsx, and authenticated error.tsx to catch and display errors gracefully instead of blank screens.
  • Not Found Pages: Added custom 404 pages for both public and authenticated routes with contextual navigation links.
Dashboard Streaming
  • Suspense Boundaries: Dashboard broken into 5 independently streaming sections (KPI Cards, Budget Health, Goals, Invoices, Transactions & Accounts).
  • Skeleton Loading: Each section shows a tailored skeleton while its data loads, instead of blocking the entire page.
  • Page Reduction: Dashboard page went from 600+ lines to ~56 lines of clean Suspense composition.
Income & Expense Pagination
  • Server-Side Pagination: Income and expense pages now use server-side pagination (20 per page) with sortable columns, matching the work entries pattern.
  • Month-Scoped Navigation: Browse by month/year with lightweight monthly totals grid for quick overview.
Invoice Multi-Currency Fix
  • Currency-Aware Summaries: Invoice summary cards now group totals by currency instead of mixing USD + EUR into one number.
  • Per-Currency Display: Outstanding and Total Paid cards show each currency on its own line when multiple currencies exist.
  • Dashboard Widget: Invoice dashboard widget updated to handle multi-currency outstanding amounts.
Architecture Standardization
  • Tag-Based Revalidation: All 16 controllers migrated from revalidatePath('/', 'layout') to targeted revalidateTag() with domain-specific cache tags.
  • Shared Auth Guard: Extracted getAuthenticatedUser() from 14 controllers into a single server/lib/auth-guard.ts.
  • UserService: Consolidated 15+ scattered prisma.user.* queries across pages, controllers, and services into server/modules/user/user.service.ts with 17 methods.
  • AuthService: Extracted registration, password reset, and token management from server/actions/auth.ts into server/modules/auth/auth.service.ts.
  • CronLogService: Deduplicated cron audit logging across 5 cron routes into server/modules/cron/cron.service.ts.
  • Controller Input Standardization: 6 controllers (11 actions) migrated from FormData parsing to (data: unknown) + Zod safeParse.
  • Unified Return Types: All 19 controllers standardized to ActionResponse<T> = { success: true; data?: T } | { error: string }.
  • Notification Logic: Moved notification dispatch and budget alert logic from income/expense controllers into their respective services.
  • useTransition Standardization: 9 form components migrated from manual useState pending state to React useTransition.
  • useServerAction Hook: New hook for simple mutations (delete, archive, status toggle) eliminating repeated pending/toast boilerplate.
  • Simplified Serialization: serialize() utility reduced from 2-pass to single-pass with identical output.
  • Dev Dependencies: 13 build-only packages moved from dependencies to devDependencies for smaller production images.