Skip to content

lerio/antunello-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

245 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Antunello

…dei conti se ne occupa lui

A comprehensive personal finance tracker β€” income, expenses, budgets, multi-currency, bank sync, and charts.

Next.js 16 React 19 TypeScript 6 Supabase Tailwind v4


Features

πŸ’° Transaction Management

  • Add, edit, and delete transactions with optimistic updates β€” the UI reflects changes instantly and rolls back on error
  • Multi-currency support: automatic EUR conversion using ECB exchange rates (Frankfurter API), with local DB caching and retry logic
  • Money transfers between fund accounts with source/target fund selection and validation
  • Split transactions: distribute a transaction evenly across all 12 months of the year (penny rounding handled)
  • Hide from totals: flag individual transactions to exclude them from summaries
  • Title suggestions: auto-tracked by category with frequency-based ranking and one-click auto-fill

πŸ“Š Dashboards & Charts

  • Monthly view: transactions grouped by date with daily totals, sticky scrollable period selector, and comparison against previous month and same month last year
  • Yearly view: income/expense/balance aggregated by month with monthly averages
  • Dashboard: current vs previous month vs same-month-last-year comparison tables with expandable category breakdowns
  • Balance chart: interactive line chart with previous-period overlay, time range selector (1M/1Y/5Y/All), responsive sizing
  • Category charts: bar chart for category-specific spending history with transaction counts
  • Advanced filtering: multi-dimensional filter panel β€” type, category/subcategory, currency, fund source, amount range, period β€” with chip badges

πŸ” Search

  • Real-time full-text search across all transactions (300ms debounce)
  • Summary stats with income/expense/hidden breakdown

πŸ’³ Fund Accounts

  • Track balances across Checking Accounts, Savings Accounts, Investments, P2P Lending, Financial Services, and Cash
  • Expandable grouped view with collapsible sections and per-fund amounts
  • Global EUR total with currency conversion

πŸ’Έ Budgets

  • Set category-based monthly budgets
  • Color-coded progress bars: green (< 90%), amber (90–100%), red (> 100%)
  • Spending alerts when approaching or exceeding limits

🏦 Bank Integration (Enable Banking)

  • OAuth-based bank connection via PSD2 open banking
  • Automatic transaction import with deduplication
  • Pending transaction review wizard: accept or reject bank-imported transactions before they enter your ledger
  • Background cron sync (/api/cron/sync)

πŸ“± Mobile-First UX

  • Pull-to-refresh with resistance curve on transaction views
  • Privacy mode: toggle to blur all financial data on screen (persisted to localStorage)
  • Bottom navigation bar with safe-area-inset support on mobile, horizontal nav on desktop
  • Bottom-sheet modals with swipe-to-close, animated entry/exit
  • Floating action buttons with stacked layout when multiple actions are available
  • Skeleton loading states for all data views (balance, charts, forms, summaries, transaction lists)

πŸ“₯ CSV Import

  • Bulk import from Cashew-formatted CSV files
  • Batch validation with detailed error reporting
  • Rate-limited currency conversion for imported transactions

πŸ” Security

  • Row Level Security on all database tables β€” users can only access their own data
  • Cookie-based Supabase Auth sessions via @supabase/ssr
  • Security headers: X-Frame-Options, X-Content-Type-Options, Referrer-Policy
  • Cron endpoints protected by shared secret

⚑ Performance

  • Dual cache system: SWR (in-memory) + localStorage (persistent) for zero-load navigation
  • Intelligent prefetching of adjacent months/years with dedup queues
  • pushState-based navigation avoids server round-trips on month/year changes
  • Memoized components and calculations throughout
  • Paginated batch fetching for large datasets

Tech Stack

Layer Technology
Framework Next.js 16.2 (App Router, Turbopack)
UI Library React 19.2
Language TypeScript 6.0 (strict mode)
Database Supabase (PostgreSQL + RLS + real-time)
Auth Supabase Auth (@supabase/ssr, cookie-based)
Styling Tailwind CSS v4 + shadcn/ui + Radix UI primitives
Data Fetching SWR 2.4 with localStorage persistence
UI State Zustand 5.0
Charts Recharts 3.8
Date Handling date-fns 4.4, react-day-picker 10.0
Icons Lucide React 1.17
Notifications react-hot-toast 2.6
Theming next-themes 0.4 (dark/light mode)
JWT jose 6.2 (Enable Banking API auth)
Tooltips @floating-ui/react 0.27

Getting Started

Prerequisites

  • Node.js 18+ (LTS recommended)
  • A Supabase project (create one free)
  • (Optional) Enable Banking credentials for bank sync

1. Clone and install

git clone <repo-url>
cd antunello-app
npm install

2. Environment variables

Copy the example and fill in your Supabase details:

cp .env.example .env.local

Required variables in .env.local:

NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY=sb_publishable_...
SUPABASE_SERVICE_ROLE_KEY=sb_secret_...

Optional β€” Enable Banking (bank sync):

ENABLE_BANKING_APP_ID=your-app-id
ENABLE_BANKING_PRIVATE_KEY="-----BEGIN PRIVATE KEY----- ..."
ENABLE_BANKING_KID=your-key-id
CRON_SECRET=your-cron-secret
NEXT_PUBLIC_APP_URL=https://localhost:3000

3. Set up the database

Run the migration SQL files in migrations/ in numerical order via the Supabase SQL Editor. The migrations create:

  • fund_categories table and FK on transactions
  • transaction_title_patterns table for title suggestions
  • exchange_rates table for currency conversion caching
  • budgets table
  • enable_banking integration tables
  • RPC functions: get_overall_total_eur, get_balance_before_date
  • Composite indexes for query performance
  • RLS policies for data isolation

There are also rollback files for migrations 011 and 012.

4. Start the dev server

npm run dev

The app runs on https://localhost:3000 (HTTPS enabled via --experimental-https with self-signed certificates in certificates/).


Available Scripts

npm run dev                      # Start dev server with HTTPS
npm run build                    # Production build
npm start                        # Production server
npm run find-pipe-titles         # Discover transactions with || title markers
npm run find-pipe-titles:verbose # Same, with detailed output
npm run update-pipe-titles       # Dry-run: preview pipe-title updates
npm run update-pipe-titles:execute # Apply pipe-title updates to database

Project Structure

antunello-app/
β”œβ”€β”€ app/                          # Next.js App Router
β”‚   β”œβ”€β”€ (auth)/sign-in/           # Login page
β”‚   β”œβ”€β”€ api/                      # API routes
β”‚   β”‚   β”œβ”€β”€ cron/sync/            # Enable Banking background sync
β”‚   β”‚   β”œβ”€β”€ enable-banking/       # Bank OAuth + disconnect + mapping
β”‚   β”‚   β”œβ”€β”€ overall-totals/       # Global balance RPC
β”‚   β”‚   └── pending-transactions/ # Accept/reject bank transactions
β”‚   β”œβ”€β”€ protected/                # Authenticated pages
β”‚   β”‚   β”œβ”€β”€ add/                  # Add transaction
β”‚   β”‚   β”œβ”€β”€ admin/                # CSV import, fund management
β”‚   β”‚   β”œβ”€β”€ budgets/              # Budget list, add, edit
β”‚   β”‚   β”œβ”€β”€ category/[category]/  # Category + subcategory views
β”‚   β”‚   β”œβ”€β”€ edit/[id]/            # Edit transaction
β”‚   β”‚   β”œβ”€β”€ filter/               # Advanced filtering
β”‚   β”‚   β”œβ”€β”€ search/               # Full-text search
β”‚   β”‚   β”œβ”€β”€ settings/             # User settings
β”‚   β”‚   β”œβ”€β”€ transactions/         # Monthly view
β”‚   β”‚   └── year/                 # Yearly view
β”‚   β”œβ”€β”€ actions.ts                # Server actions (auth)
β”‚   β”œβ”€β”€ globals.css               # Tailwind v4 theme + shadcn CSS vars
β”‚   └── layout.tsx                # Root layout
β”œβ”€β”€ components/
β”‚   β”œβ”€β”€ features/                 # Business logic components (17 files)
β”‚   β”œβ”€β”€ layout/                   # Navigation, header, hero, theme, privacy
β”‚   └── ui/                       # Base components + skeletons (30+ files)
β”œβ”€β”€ hooks/                        # Custom React hooks (31 total)
β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ supabase/                 # Client, server, middleware, admin, DB utils
β”‚   β”œβ”€β”€ enable-banking/           # API client + sync service
β”‚   β”œβ”€β”€ currency-conversion.ts    # Frankfurter API + exchange rate caching
β”‚   β”œβ”€β”€ csv-import.ts             # Cashew CSV parser + validator
β”‚   β”œβ”€β”€ split-transactions.ts     # Split-amount calculation logic
β”‚   └── ...                       # Date, formatting, validation, styling utils
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ swr-config.ts             # Global SWR + localStorage provider
β”‚   β”œβ”€β”€ cache-persistence.ts      # localStorage cache serialization
β”‚   └── utils.ts                  # cn() + encodedRedirect()
β”œβ”€β”€ types/
β”‚   └── database.ts               # All TypeScript types + category definitions
β”œβ”€β”€ constants/
β”‚   └── app-constants.ts          # Currency options and symbols
β”œβ”€β”€ migrations/                   # 17 numbered SQL migration files
β”œβ”€β”€ scripts/                      # Pipe-title utilities + migration runner
β”œβ”€β”€ certificates/                 # HTTPS dev certs (gitignored)
└── public/                       # Static assets

Data Models

Transaction

The core entity. Fields: amount, currency, type (expense/income), main_category, sub_category, title, date, eur_amount, exchange_rate, hide_from_totals, fund_category_id, is_money_transfer, target_fund_category_id, split_across_year.

FundCategory

Bank accounts and fund balances: name, description, currency, amount, top_level_category (Checking, Savings, Investments, P2P Lending, Financial Services, Cash), order_index, is_active.

Budget

Category-based monthly budgets: category, amount.

ExchangeRate

Cached ECB rates: date, base_currency, target_currency, rate, source, is_missing.

PendingTransaction

Bank-imported transactions awaiting review: account_id, amount, currency, description, booking_date, status (pending/accepted/rejected).

Categories (20 total)

Income: Primary Income, Government Benefits, Other Income, Money Transfer Expenses: Dining, Groceries, Housing, Transportation, Shopping, Health, Entertainment, Travel, Education, Fitness, Personal Care, Services, Insurance, Taxes and Fines, Gifts and Donations, Bank Movements


Key Architecture Decisions

  • Query-param navigation: Month/year changes use ?year=2024&month=12 with pushState instead of route-based URLs. This eliminates server round-trips on period navigation.
  • Dual cache: SWR handles in-memory caching and revalidation while localStorage provides instant data on reload. Both are kept in sync on every mutation.
  • Optimistic updates: Mutations update all affected caches (month, year, balance, fund categories, overall totals) immediately, with full rollback on error.
  • CET timezone awareness: Year boundaries use CET (Jan 1 00:00 CET = Dec 31 23:00 UTC) to match the user's timezone.
  • No real-time on iOS Safari: PostgreSQL LISTEN/NOTIFY subscriptions are disabled on iOS Safari to avoid performance issues β€” background polling (useBackgroundSync) serves as fallback.
  • Custom component implementations: Dropdown menus, modals, and selects use custom implementations rather than headless UI libraries to minimize bundle size and maximize control.
  • Tailwind v4 CSS-native config: All theme values are defined via @theme in globals.css β€” there is no tailwind.config.ts file.

License

Private project.

About

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors