Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# moneyinsight codebase context

Flutter personal finance app. Riverpod state management. Drift (SQLite) is the
primary database — Firestore is auth + sync only.

**Data flow:** screen (`ConsumerWidget`) → `ref.watch(provider)` → provider function
→ DAO method → Drift table

**Before editing the data layer:** read `lib/core/database/tables.dart` for schemas.

**Key files:**
- `lib/core/database/tables.dart` — all table definitions
- `lib/core/database/daos/` — 6 DAOs (accounts, budget, budget_snapshots, categories, recurring_queue, transactions)
- `lib/features/shell/main_shell.dart` — app navigation
- `lib/features/budget/budget_calculator.dart` — TBB and allocation logic (pure, no DB)
- `lib/features/sync/sync_service.dart` — Firestore sync bridge (local → cloud only)

**Month scoping:** use `selectedMonthProvider` for budget views; pass explicit `DateTime` ranges to DAO methods for other queries.
**Never write to Drift directly from screens** — always go through a provider → DAO.
**Generated files (`*.g.dart`):** never edit manually — run `dart run build_runner build`.
**Account balance:** `balanceCents` is opening balance; running balance = `balanceCents + sum(transactionAmounts)` via `accountRunningBalancesProvider`.

Full architecture docs: `.github/docs/README.md`
Symbol index (providers, DAOs, tables, screens): `.github/docs/symbol_index.md`
76 changes: 76 additions & 0 deletions .github/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# moneyinsight — Architecture Documentation

Generated by the Deep Reverse Engineering Agent.
Run timestamp: 2026-03-20T17:53:43.645376+00:00

## Tech stack
- **Flutter + Dart** — cross-platform mobile UI framework
- **State management:** Riverpod (code-generated providers via `@riverpod` annotation)
- **Local database:** Drift (SQLite) — all primary data stored on-device
- **Auth:** Firebase Auth + Google Sign-In + Biometric (`local_auth`)
- **Cloud sync:** Firestore (sync layer only — not primary storage; local is source of truth)
- **Charts:** `fl_chart`

## Architecture pattern
The app follows a layered architecture:

```
Screen (ConsumerWidget)
└─ watches Riverpod Provider
└─ reads/writes via DAO (Drift DatabaseAccessor)
└─ Drift Table (SQLite on device)
↕ (one-directional, on demand)
Firestore Cloud
```

Business logic lives in calculator classes (pure functions) and service classes.
Providers expose reactive `Stream<>` data from DAO watch methods, keeping the UI
automatically up-to-date when the database changes.

## Feature index
- [Account Management](features/accounts.md) — Allows users to create and manage their financial accounts (checking, savings, c...
- [Analytics & Budget History](features/analytics.md) — Provides charts and historical views of spending by category and income vs expen...
- [Authentication & Biometric Lock](features/auth.md) — Handles user identity via Firebase Auth (email/Google sign-in) and provides a lo...
- [Budget Management](features/budget.md) — Allows users to allocate available funds across spending categories for a given ...
- [Financial Goals](features/goals.md) — Lets users set savings goals on categories (target amount + target date). A calc...
- [Onboarding](features/onboarding.md) — First-run flow that walks new users through setting up their first account and i...
- [Settings](features/settings.md) — App settings screen. Allows users to configure preferences such as currency disp...
- [Navigation Shell](features/shell.md) — The main navigation scaffold housing the bottom navigation bar. Routes between A...
- [Cloud Sync](features/sync.md) — Bridges local Drift/SQLite data to Firestore for cloud backup. On sync trigger, ...
- [Transaction Management](features/transactions.md) — Core feature for recording and reviewing financial transactions. Users can add i...

## Data model summary
See [data_model.md](data_model.md) for the full schema.

Tables:
- `accounts` — user financial accounts (checking, savings, credit, cash)
- `category_groups` — logical groupings of spending categories
- `categories` — individual budget categories; may carry a savings goal
- `monthly_budgets` — per-category monthly allocation (envelope budgeting)
- `transactions` — all income, expense, and transfer transactions
- `net_worth_snapshots` — periodic net worth snapshots for trending
- `budget_snapshots` — end-of-month budget performance snapshots
- `pending_recurring_queue` — upcoming recurring transactions awaiting user review

## User flows
- [User Adds an Account](flows/user-adds-account.md)
- [User Records a Transaction](flows/user-records-transaction.md)
- [User Budgets a Month](flows/user-budgets-month.md)
- [User Imports Transactions from CSV](flows/user-imports-csv.md)
- [User Syncs Data to Firestore](flows/user-syncs-data.md)
- [User Sets a Financial Goal](flows/user-sets-goal.md)

## Key design decisions observed
- **Envelope budgeting (YNAB-style):** `monthly_budgets` stores per-category allocations.
The To Be Budgeted (TBB) value is calculated in `budget_calculator.dart` as:
`TBB = sum(account balances) − sum(category allocations for month)`.
- **Month boundaries:** `month_boundary_service.dart` runs on app startup to detect
month roll-overs, trigger budget snapshots, and optionally roll over unspent category
balances where `categories.rollover = true`.
- **Drift as source of truth:** All reads go to local SQLite via Drift. Firestore is
written to on demand (sync button) and is never read back — no conflict resolution needed.
- **Biometric lock:** Applied at the `MaterialApp` home widget level via
`BiometricLockScreen`, which wraps the entire app and re-locks on background.
- **Recurring transactions:** Template transactions with `recurring = true` generate
`pending_recurring_queue` entries; the `RecurringDueBanner` prompts users to review
and post them each month.
Loading
Loading