Back to All Projects
Problem Statement
Personal spending usually ends up scattered across notes, bank apps, and memory, and money lent to other people is tracked informally. Without one consistent record, it is hard to see where money goes, whether monthly goals are being met, or who still owes what.
Proposed Solution
Finlytics brings transaction entry, category analysis, monthly goals, account balances, and debtor tracking into a single private app. A React frontend talks to Supabase for data, authentication, and Row-Level Security, while scheduled Edge Functions send daily reminders and monthly and annual reports by email.
Key Features
- Income and expense tracking with categories, notes, and date-based history.
- Dashboard analytics with a spending trend chart, category breakdown, and a goal progress ring.
- Monthly spending goals with progress monitoring.
- Account Book for balances, balance history, and money owed by others, with balance changes applied atomically through a database function.
- Automated daily reminders and monthly and annual reports delivered by email through scheduled Edge Functions.
- Single-user access with public sign-up disabled, protected routes, and Row-Level Security.
System Architecture Flow
Frontend (React + Vite, public landing page and protected /app routes) -> AuthContext and DataContext -> Supabase (PostgreSQL, Auth, Row-Level Security, migrations) -> Edge Functions (send-reminder, send-report) triggered by scheduled jobs -> Email delivery
Engineering Challenges
- Securing a single-user app required more than a login screen, so public sign-up is disabled and access is enforced at both the route level and the database level with Row-Level Security.
- Balance edits could leave data inconsistent, so they run through a single database function that updates the account, the balance history, and any matching transaction together.
- Layouts broke on small screens, which took repeated fixes for stacking controls, text truncation, and minimum widths to stop overflow.
Lessons Learned
- Securing a private app needs both client-side route guards and database-level enforcement.
- Financial data stays consistent only when related updates run as one transaction.
- Scheduled jobs need deduplication and clear guardrails so reminders and reports do not repeat.
Results
Built for my own daily finance tracking, with six database migrations and two scheduled Edge Functions for reminders and reports.