# IngTrak Personal finance app for **Enable Banking** (ING and other supported banks): transactions, labels, charts, budgets, look-ahead projections, and **PocketBase** cloud sync. - **Package:** `com.ingtrak.app` - **Platform:** Android (Flutter) - **Flutter:** 3.47+ · **Dart:** 3.13+ ## Features - **Bank connect** — Enable Banking via backend API + in-app WebView; optional deep link `ingtrak://connected` - **Home** — Balance, customizable layout: built-in sections (Transactions / Categorized / Recent) and filter widgets (stats or budget, half/full width, bar/pie/ring) - **Transactions** — Search, filters, month heatmap, labels, notes, merchant / “apply to similar” rules - **Overview** — Income/expense and label charts; save **favourite** chart filters - **Look ahead** — Projected balance from recurring templates - **Sync** — Bidirectional PocketBase sync (transactions, labels, annotations, favourites, home widgets, app prefs) - **Theme** — Light / dark / system (local) - **CSV** — Import ING CSV exports (Settings) ## Prerequisites - [Flutter SDK](https://docs.flutter.dev/get-started/install) **3.47** or newer (Dart **3.13**) - Android Studio / SDK (Java **17**), emulator or device - Reachable **bank API** (`API_BASE_URL`) and **PocketBase** (`POCKETBASE_URL`) - PocketBase auth collection **`usersapp`** (create this before running migrations) ```bash flutter doctor flutter doctor --android-licenses # if prompted ``` ## Quick start ```bash cd ingtrakapp cp .env.example .env # edit URLs if needed flutter pub get flutter devices flutter run # or: flutter run -d android ``` First Android build downloads Gradle and may take a few minutes. ### Useful commands ```bash flutter analyze flutter test flutter run --release flutter build apk ``` ### Override config without editing `.env` ```bash flutter run \ --dart-define=API_BASE_URL=https://your-api.example \ --dart-define=POCKETBASE_URL=https://your-pb.example \ --dart-define=POCKETBASE_USERS_COLLECTION=usersapp ``` `--dart-define` values win over `.env`. ## Configuration Copy [`.env.example`](.env.example) to `.env` (both are listed as Flutter assets). No secrets belong in these files. | Variable | Purpose | Example | |----------|---------|---------| | `API_BASE_URL` | FastAPI bank / Enable Banking proxy | `https://ingtrak.satoshinakamoto.win` | | `POCKETBASE_URL` | PocketBase instance | `https://pb.satoshinakamoto.win` | | `POCKETBASE_USERS_COLLECTION` | Auth collection name | `usersapp` | Loaded in `lib/utils/app_config.dart` at startup (`flutter_dotenv`). Fallbacks: hosted API URL, PocketBase `http://127.0.0.1:8090`. ### Bank redirect URIs 1. **HTTP callback (Enable Banking Control Panel / backend `REDIRECT_URI`):** `{API_BASE_URL}/api/connect/callback` 2. **Optional app deep link** (after HTML bounce; not registered with Enable Banking): `ingtrak://connected?code=…` Declared in `AndroidManifest.xml` and handled via `app_links`. ## PocketBase setup Migrations live in [`pocketbase/pb_migrations/`](pocketbase/pb_migrations/). They assume collection **`usersapp`** already exists. ### Collections | Migration | Collection | |-----------|------------| | `1740000000` | `labels`, `tx_meta`, `merchant_rules`, `exact_templates` | | `1740000001` | `transactions` | | `1740000002` | `recurring_templates` | | `1740000003` | `overview_favourites` | | `1740000004`–`0006` | `home_filter_widgets` (+ half width, budget fields) | | `1740000007` | `app_prefs` (Home section toggles + Look ahead years) | | `1740000008` | `home_filter_widgets.label_match` (AND/OR) | Built-in labels stay in the app; only **custom** labels sync. Rows are scoped per user (`user = @request.auth.id`). ### Apply migrations (typical Linux host) ```bash sudo cp pocketbase/pb_migrations/*.js /opt/pocketbase/pb_migrations/ sudo chown pocketbase:pocketbase /opt/pocketbase/pb_migrations/*.js sudo -u pocketbase /opt/pocketbase/pocketbase migrate up sudo systemctl restart pocketbase ``` Adjust paths if your PocketBase install differs. After migrate, sign in on the app and run **Sync** (Account) so local data uploads. ### What syncs - Bank transactions, labels, tx annotations, merchant/exact templates - Recurring templates, overview favourites, home filter widgets - App prefs: Home built-in section visibility, Look ahead max years Theme mode stays **device-local**. ## Project layout ``` ingtrakapp/ ├── android/ # Android embedding (com.ingtrak.app) ├── assets/branding/ # App icon source + generated launcher assets ├── lib/ │ ├── main.dart # Providers, dotenv, deep links │ ├── models/ # Bank, meta, favourites, home widgets, prefs │ ├── providers/ # Auth, bank, sync, tx_meta, preferences, theme │ ├── screens/ # Splash, auth, Home / Overview / Look ahead, … │ ├── services/ # Bank API, PocketBase sync, CSV, storage │ ├── utils/ # Config, theme, constants, connect helpers │ └── widgets/ # Home widgets, filters, charts, sync UI ├── pocketbase/pb_migrations/ # Schema migrations ├── test/ ├── .env.example └── pubspec.yaml ``` ## Launcher icon Source: `assets/branding/app_icon.png`. Regenerate Android mipmaps: ```bash dart run flutter_launcher_icons ``` (Configured in `pubspec.yaml`; iOS not enabled — no `ios/` folder yet.) ## First-run checklist 1. `.env` points at your API + PocketBase 2. PocketBase migrations applied; `usersapp` exists; create an account (or use Admin → Users) 3. Backend Enable Banking `REDIRECT_URI` matches `{API_BASE_URL}/api/connect/callback` 4. `flutter run` → sign in → **Settings** → connect bank (or import CSV) → **Account** → Sync ## License / privacy Private project. Bank credentials and tokens are handled by your backend and Enable Banking — keep API and PocketBase access controlled.