Budget Breeze: AI-Powered Personal Finance Companion
A production-grade Flutter application published on Google Play that transforms raw financial data into actionable intelligence. Built on MVVM architecture with GetX, the app features real-time Firestore synchronisation, Google & email authentication, Vertex AI–driven personalised financial analysis reports via Cloud Functions, idempotent recurring-expense automation through Cloud Scheduler CRON jobs, interactive visualisations with fl_chart & Syncfusion, multi-language support (TR/EN), and a full Firebase observability stack covering Crashlytics, Performance Monitoring, Analytics, and App Check.
Gallery
Problem Statement
Most people ask themselves the same questions at the end of every month — "How much is left?", "Where did it all go?" — yet never arrive at a satisfying answer. Manual tracking is tedious, spreadsheets provide no analytical layer, and existing apps either drown users in complexity or reduce finance management to a basic ledger. The goal was to design a personal finance companion that makes expense tracking genuinely frictionless, surfaces meaningful behavioural patterns through interactive visualisations, and — critically — leverages generative AI to produce real, contextualised financial advisory reports so users can act on data rather than intuition.
Role: Lead Developer & Architect
Personal finance management is a problem space everyone recognises but few products solve with genuine depth. Spreadsheets demand discipline and offer no intelligence; banking apps lack cross-account perspective; most third-party trackers surface charts without surfacing insight. Budget Breeze was architected to close this gap — a single application that not only records and categorises every transaction but reasons over that data to generate personalised, AI-driven financial guidance.
As the sole developer, I owned every layer of the product lifecycle: UI architecture informed by Figma prototypes (with UI/UX collaboration from Nurgül Karayiğit), Firestore data modelling, Cloud Functions orchestration, Vertex AI prompt engineering, and end-to-end Google Play release management. The project served as a rigorous engineering exercise spanning mobile architecture, serverless backend design, generative AI integration, and full production operations.
Core Technical Features
A. Transaction Tracking & Data Layer
Structured financial records with real-time sync
Users log income and expenses with custom categories, date metadata, and descriptive labels. The data model follows an inheritance-based hierarchy — BaseTransactionModel extended by Expense and Income — with bidirectional Firestore serialisation via fromJson/toJson. Real-time Firestore listeners propagate mutations across sessions instantly, while offline persistence ensures full functionality without network connectivity, leveraging Firestore's built-in local cache and conflict resolution.
Idempotent recurring-expense automation via Cloud Scheduler
Expenses flagged as recurring are automatically replicated into subsequent billing periods by a dedicated Cloud Function — processRecurringExpenses — triggered daily at 03:00 (Europe/Istanbul) via Google Cloud Scheduler. The function iterates each user's Firestore subcollection, issues compound queries filtered by originalRecurringId and month-boundary Timestamps to detect existing copies, and writes new entries under deterministic document IDs (templateId_YYYY_MM). This design guarantees absolute idempotency: concurrent invocations and Scheduler retry storms produce zero duplicate records.
B. Vertex AI Integration — Generative Financial Advisory
AI-generated financial analysis reports
The application's flagship capability: users can request AI-generated financial analysis reports scoped to weekly, monthly, or yearly intervals. An onCall Cloud Function — analyzeFinancials — aggregates the user's totalIncome, per-category expense breakdown, and selected date range, then constructs a structured prompt delivered to Vertex AI's Gemini 3.0 Flash model. The model returns a structured response comprising an executive summary, key spending pattern observations, concrete and prioritised savings recommendations, and a financial health score benchmarked against the 50/30/20 budgeting framework. Completed reports are persisted to Firestore under users/{userId}/analysis_reports, and a local FCM push notification is dispatched upon generation.
Multi-language prompt engineering & inference configuration
Financial prompts are dynamically localised to the user's active locale — Turkish or English — by propagating a language parameter through the Cloud Function's callable payload. This ensures the model's tone, financial terminology, and number formatting conventions align with the reader's linguistic context. Inference is configured with temperature 0.3 and topP 0.8, deliberately biasing the model toward factual consistency and reproducibility over creative variance — a deliberate trade-off appropriate for advisory content where precision outweighs novelty.
C. Interactive Analytics & Visualisation
Reactive chart rendering with GetX
fl_chart and Syncfusion Flutter Charts power a suite of interactive visualisations: pie charts for categorical expense distribution, bar graphs for period-over-period comparison, and trend lines for longitudinal analysis. The ViewModel layer — ArchiveCashController — computes derived datasets such as pieChartData and filtered result sets reactively using GetX observables. Every state mutation triggers scoped UI rebuilds through Obx wrappers, preventing unnecessary widget tree re-renders. Users can compose multi-dimensional filters across category, date range, and transaction type to interrogate their financial behaviour with precision.
D. Production Infrastructure & Security
Full-stack Firebase observability
Firebase Crashlytics captures every unhandled exception with complete stack traces and device metadata for rapid triage. Performance Monitoring instruments cold start latency, screen rendering durations, and HTTP round-trip times, establishing performance baselines against which regressions are detected. Firebase Analytics records granular engagement events — screen views, report generation requests, IAP conversion funnels — enabling data-driven iteration. Firebase App Check enforces attestation on every Cloud Function invocation and Firestore access, rejecting requests from unverified clients and mitigating replay and API-abuse attacks.
Monetisation architecture
The app implements a freemium model: Google AdMob delivers ad-supported free-tier usage, while an In-App Purchase subscription unlocks unlimited AI report generation. Premium entitlement is validated server-side within Cloud Functions to prevent client-side bypass. The app is distributed via Google Play with automated release pipelines and integrates Flutter's in_app_update API to surface seamless forced and flexible upgrade prompts — ensuring critical patches reach users without friction.
Outcome: Measurable benefit
Budget Breeze evolved from a conceptual side project into a fully shipped, revenue-capable production application. It demonstrates that a single engineer can deliver a polished, AI-augmented mobile product end-to-end — from data architecture through App Store deployment — when disciplined MVVM layering is paired with the right serverless primitives and a clear product vision.
- Live on Google Play: real user base, active crash reporting pipeline, and closed production feedback loops.
- Vertex AI integration: automated, contextualised financial advisory that transcends static chart-based reporting.
- Idempotent CRON automation: deterministic document ID strategy guarantees zero duplicate records across Scheduler retries and concurrent function invocations.
- Full observability stack: Crashlytics, Performance Monitoring, Analytics, and App Check form a closed-loop production feedback system.
- Complete multi-language support: seamless TR/EN switching across all UI surfaces, including AI-generated report content and prompts.
Data Architecture
users/{userId} # User profile, auth provider metadata, device tokens
/expenses/{expenseId} # Expense records (amount, category, date, isRecurring, originalRecurringId)
/incomes/{incomeId} # Income records (amount, category, date)
/analysis_reports/{reportId} # Vertex AI financial analysis reports (report body, date range, analysis type, timestamp)
/categories/{categoryId} # User-defined income and expense categoriesAll financial data is scoped within per-user subcollections, providing natural data isolation and straightforward Firestore security rules without collection group queries. Expenses, incomes, and AI reports occupy separate subcollections, enabling each to be independently queried, indexed, and paginated. For recurring expenses, the originalRecurringId field establishes a flat reference between template and derived copies — preserving the relationship without requiring nested document references or denormalisation.
Composite indexes are defined to support the application's primary filter and sort patterns: (isRecurring + date) and (category + date) on expenses; (analysisType + timestamp) on analysis_reports. The CRON function's idempotency check — querying by originalRecurringId within month-boundary Timestamps — relies on a composite index to execute as a targeted document lookup rather than a full subcollection scan, ensuring the daily job remains performant as user data scales.
Security
Firebase Authentication supports both email/password and Google Sign-In flows. All Firestore security rules enforce user data isolation through strict request.auth.uid == userId checks — no cross-user data access is possible at the rules layer. AI analysis reports are write-protected at the rules level (allow write: if false) and can only be created or updated by Cloud Functions operating under the Admin SDK, preserving report integrity and preventing client-side manipulation.
The AI analysis function (analyzeFinancials) is exposed as an onCall Cloud Function, meaning all invocations are authenticated and attributable to a verified Firebase user. Firebase App Check adds a second attestation layer, rejecting requests originating outside the genuine application binary. Premium tier entitlement is validated server-side within the function, preventing free-tier users from circumventing report generation limits regardless of client-side state.
Security Rules Snippet
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
match /expenses/{expenseId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
match /incomes/{incomeId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
match /analysis_reports/{reportId} {
allow read: if request.auth != null && request.auth.uid == userId;
allow write: if false; // Write access restricted to Cloud Functions via Admin SDK
}
}Engineering Decisions
Architecture Diagram
Cookies & analytics
We use anonymous page views and usage statistics to improve the site. Data is used only for measurement; no personal data is collected.
