Inspiration

Most finance apps either oversimplify (just expense tracking) or overwhelm with complexity. I wanted to build something that grows with the user -- start simple with transactions and budgets, then unlock
investments, debt planning, and AI insights as they engage more. And I wanted it fully offline, with no cloud account required for sensitive financial data.

## What it does

FinWise is a 32-feature personal finance app covering:

  • Core: Transactions, accounts, categories, budgets, savings goals, bill reminders
  • Advanced: Net worth tracking, investment portfolio, debt payoff planning (avalanche/snowball), subscription tracking, cash flow analysis
  • Smart: AI-powered anomaly detection, automated category rules, recurring transaction detection, financial wellness scoring (0-100)
  • Engagement: Achievement badges, onboarding checklist, confetti celebrations
  • Security: PIN lock, biometric auth, privacy mode
  • Data: CSV/PDF export, multi-profile support, shared budgets, freemium monetization

## How I built it

I followed spec-driven development in 5 phases:

  1. Foundation -- Set up Clean Architecture (UI -> BLoC -> UseCase -> Repository -> DataSource), Drift database, GoRouter navigation, Material 3 theming
  2. Core Finance -- Transactions, accounts, categories, budgets, savings goals, dashboard
  3. Gamification -- Achievements, wellness score, onboarding checklist, notifications
  4. Advanced Features -- Investments, net worth, debt payoff, AI insights, analytics, reports
  5. Monetization & Polish -- Feature gates, paywall, security, privacy mode

Claude Code acted as a building assistant throughout. The key was .claude/rules/ files -- 8 rule files covering architecture, state management, routing, theming, error handling, testing, code style, and
workflow. These turned the AI into a team member that followed project conventions consistently.

## Challenges I ran into

  • Coordinating 25 BLoCs at the app root without creating BLoC-to-BLoC dependencies. Solved by using BlocListener in the UI layer to bridge state changes between features.
  • Database schema growth from 3 tables to 21. Drift's migration system handled it, but planning the schema upfront in the tech spec would have saved iteration.
  • Feature gate retrofitting -- adding freemium gates in Phase 5 was easier than expected because Clean Architecture already isolated each feature, but the FeatureGateWrapper caused overflow issues in
    Settings ListTiles that required a dedicated fix.

## What I learned

  • Specs save more time than they cost. Writing scope docs and PRDs before coding eliminated entire categories of rework. The AI produced consistent code when it had a clear spec.
  • Layer discipline compounds. Clean Architecture felt like overhead with 3 features. With 32 features, it meant adding investments or AI insights without touching existing transaction code.
  • AI works best with constraints. The .claude/rules/ files were the single most impactful decision. Rules like "no mutable instance variables in BLoC" and "no error strings in state" prevented entire
    classes of bugs automatically.

Built With

  • bloc
  • claude
  • dart
  • drift
  • fl-chart
  • flutter
  • fpdart
  • freezed
  • getit
  • gorouter
  • injectable
  • material-3
  • sqlite
Share this project:

Updates

Submission history