WealthFlow
A React Native finance app for transactions, budgets and savings, with Supabase and PostgreSQL access policies.
Built as a working showcase that can serve as a foundation for a customized business implementation.
Inspect the evidence
Review the implementation, data model and tests in the repository.
What I built
- Relational data architecture for transactions, categories, budgets, and savings goals backed by Supabase PostgreSQL
- Database-level Row Level Security (RLS) enforcing strict user-scoped isolation across all 6 financial tables
- Persistent authentication lifecycle with AsyncStorage token hydration and decoupled initialization states
- Monthly category budgets with 3-tier threshold warning calculations (healthy, warning at 80%, over budget at 100%)
- Target-driven savings goals with relational contribution tracking and mathematical milestone verification
- Centralized multi-currency formatting engine across 7 global currencies handling currency-specific decimal rules
- Structured JSON personal financial data export via Expo FileSystem and native OS share sheet integration
- Automated verification harness containing 114 Jest tests across 11 test suites covering arithmetic, formatting, and auth
- Native Android compilation architecture with reproducible codegen and Babel runtime patches via patch-package
Client-Side Security Limits, Session Drift & Calculation Errors
Mobile finance tools often rely purely on client-side filtering (where user_id = ...) as their primary boundary, leaving user databases vulnerable to API inspection and tampering. Furthermore, naive session hydration frequently causes mobile navigation flickers or drops authenticated state on app restart, while floating-point arithmetic and inconsistent currency decimals introduce subtle rounding drifts across transactions, budgets, and savings goals.
Database-Level RLS, Hydrated Sessions & Verified Arithmetic
WealthFlow establishes PostgreSQL Row Level Security (RLS) policies using auth.uid() across all 6 database tables, ensuring the database engine rejects unauthorized reads and writes regardless of client behavior. The mobile authentication lifecycle decouples initial AsyncStorage session restoration from interactive action states to preserve React Navigation stability, while a deterministic calculation engine standardizes multi-currency decimals and budget thresholds across 114 automated Jest tests.
03 / PRODUCT EXPERIENCE
Core Capabilities & Workflow
Transaction Ledger & Category Resolution
Chronological logging of income and expense transactions with canonical category resolution, merchant details, relative date grouping, and real-time search.
Computes total net cash balance deterministically as total income minus total expenses, preventing drift across ledger reviews.
Chronological transaction ledger with merchant categorization, flow type segmentation, and real-time search
Monthly Budgets & Consumption Thresholds
Category-specific monthly expenditure caps evaluated against real-time spending with three discrete status thresholds: healthy, warning (>= 80%), and over budget (>= 100%).
Alerts users before budget ceilings are breached through visual progress indicators and rule-based financial insight notifications.
Category-specific budget allocation with real-time consumption progress and threshold warnings
Savings Targets & Relational Contributions
Target-driven savings goals tracking current balance against target amounts, with itemized contribution records enforced by database foreign-key checks.
Maintains mathematical consistency between individual deposits and goal balances, protected by database RLS rules verifying goal ownership.
Financial Analytics & Trend Telemetry
Deterministic monthly cash flow trends, savings rate calculations, and categorical expense breakdown visualization powered by React Native SVG.
Generates objective financial observations (e.g. savings rate evaluation, top expense drivers) calculated directly from recorded transactions.
Financial analytics dashboard featuring net savings calculation, savings rate benchmark, and SVG category distribution
Multi-Currency Formatting & Native Data Export
Centralized formatting engine across 7 global currencies handling currency-specific decimal rules (e.g. 0 decimals for JPY, 2 for USD/EUR), paired with structured JSON export via Expo FileSystem and Sharing.
Allows complete personal data portability by writing a validated JSON backup to the mobile device cache and invoking the native OS share sheet.
Personal finance preferences with 7 global currencies, theme selection, and complete JSON data export
04 / TECHNICAL ARCHITECTURE
Engineering Foundation & Architecture
Mobile Authentication Lifecycle & Navigation Decoupling
On mobile clients, naive authentication listeners frequently produce race conditions when session hydration from AsyncStorage overlaps with user-triggered login or logout actions, causing React Navigation root containers to remount and lose state. WealthFlow solves this by maintaining a dedicated initialization flag (isInitializing) that guards navigation mounting until getSession() resolves. Furthermore, onAuthStateChange listeners deduplicate INITIAL_SESSION and redundant sign-in events during hydration, while refs track intentional logout to distinguish user sign-out from token expiration without triggering erroneous redirect loops.
Database-Level User Isolation via PostgreSQL Row Level Security
Because mobile applications run in untrusted user environments, filtering queries client-side with .eq('user_id', user.id) provides zero defense against malicious request tampering or API inspection. WealthFlow establishes security strictly at the database layer using PostgreSQL Row Level Security (RLS) on all 6 tables: profiles, categories, transactions, budgets, savings_goals, and savings_contributions. Every query is scoped by auth.uid() = user_id, while contribution insertions enforce relational foreign-key validation ensuring the referenced savings goal also belongs to the authenticated user.
Native Android Codegen & Module Interop Patches
During native compilation on React Native 0.76.9 and Expo SDK 52, Android builds failed due to upstream toolchain incompatibilities: @react-native/codegen failed when parsing TypeScript Readonly and ReadonlyArray type annotations on component props, while @babel/runtime triggered CommonJS/ESM interop bundling errors with interopRequireDefault. Rather than maintaining unstable library forks, reproducible patches were generated using patch-package (@react-native+codegen+0.76.9.patch and @babel+runtime+7.29.7.patch) and executed automatically via the npm postinstall lifecycle, ensuring reliable native build compilation.
Verified Financial Calculation Engine (114 Jest Tests across 11 Suites)
Personal finance software requires deterministic numerical integrity to prevent calculation drift across transactions, monthly budgets, and multi-currency formatting. WealthFlow centralizes core calculations in pure utility modules verified by 114 automated Jest tests across 11 test suites. The test harness deterministically validates cash balance calculation (income minus expenses), month-to-date category allocations, budget status transitions (healthy, warning at 80%, over-budget at 100%), savings milestone percentages, currency-specific decimal formatting (e.g. 0 decimals for JPY, 2 for USD), and native file export serialization.
05 / VERIFIED IMPLEMENTATION
Engineering Evidence & Mobile Architecture
Database-level Row Level Security, atomic financial mutations, and native toolchain hardening verified directly in the codebase.
PostgreSQL Row Level Security (RLS) Isolation
Data isolation is enforced at the PostgreSQL engine level, not trusted to mobile client code. WealthFlow enables Row Level Security (RLS) across all 6 relational tables. Even if client-side logic were intercepted or tampered with, the database engine strictly rejects any query attempting to access records outside the authenticated user's auth.uid() scope.
6 Relational Tables & Ownership Constraints
Cross-user contribution injection guard
The RLS policy verifies user identity and asserts that the target savings goal belongs to the same user, preventing foreign goal injections.
Atomic database-side contribution RPC
The PL/pgSQL function coordinates contribution logging and goal balance mutation within a single atomic database transaction.
Async Hydration & Session State Machine
Resilient mobile state handling: The isInitializing state holds a native splash screen (RootSplash) until AsyncStorage hydration completes, preventing login screen flickers. Synchronized ref guards (intentionalSignOutRef) cleanly separate manual user sign-outs from involuntary session token expiration.
Reproducible Patches for React Native 0.76
Flow / TypeScript Type Parser Patch
Extends native codegen parsers to recognize TypeScript Readonly and ReadonlyArray aliases alongside Flow-specific $ReadOnly, preventing Android Gradle build failures during codegen.
Metro Bundler ESM / CommonJS Interop
Rewrites helper exports in interopRequireDefault to CommonJS compatible module.exports, resolving runtime freezes in Metro bundler evaluations on native Android APK runs.
7 global currencies with explicit 0-decimal precision for JPY.
Standardized across USD ($), EUR (€), GBP (£), MAD (DH), JPY (¥), CAD (CA$), and AUD (A$). Japanese Yen enforces 0 decimal places (e.g. ¥1,500), while all other 6 currencies preserve 2 decimal places.
Deterministic status thresholds computed at 80% and 100% utilization.
The getBudgetStatus engine classifies spending: Healthy (< 80%), Warning (80% to 99.9%), and Over Budget (≥ 100%). Sanitized JSON data export via Expo FileSystem & Sharing strictly omits auth tokens and session keys.
114 Passing Tests Across 11 Dedicated Suites
The automated test harness rigorously asserts financial balance calculations, JPY 0-decimal formatting, local date parsing, sanitized JSON exports, chart accessibility labels, category invariants, asynchronous authentication lifecycle transitions, and PostgREST database error translation into safe user notifications.
05 / ENGINEERING DECISIONS
Technical decisions & trade-offs
PostgreSQL Row Level Security as Primary Security Boundary
Enforce user isolation directly inside the PostgreSQL database engine using Supabase RLS policies tied to auth.uid(), rather than trusting mobile client query parameters.
Mobile clients operate outside a trusted server perimeter and can be decompiled or intercepted. Implementing RLS at the database engine guarantees that malicious API requests can never read or mutate another user's financial records.
Decoupled Session Hydration from Navigation State
Maintain an isolated isInitializing boolean during AsyncStorage session restoration and deduplicate early subscription events before exposing user authentication state to React Navigation.
Coupling initial token loading with ongoing sign-in loading states caused root navigation containers to remount and flicker on app boot. Isolating initialization guarantees a seamless transition from splash screen to authenticated tab navigator.
Reproducible Dependency Patching via patch-package
Commit versioned patch files in the patches/ directory and execute patch-package automatically during npm postinstall to resolve React Native 0.76 codegen and Babel runtime issues.
Forking upstream packages creates ongoing maintenance burdens and complicates updates. Using patch-package keeps package.json pointing to official registry releases while maintaining a deterministic, reproducible native Android build pipeline.
Pure Utility Architecture for Financial Calculations
Structure all financial arithmetic, category aggregation, and currency formatting as pure, deterministic functions in dedicated utility modules completely independent of React component lifecycles.
Decoupling financial logic from UI rendering enables fast, deterministic automated testing via Jest without mocking mobile UI primitives, ensuring numerical invariants remain provable and regression-free.
06 / REFLECTIONS & LEARNINGS
What This Project Demonstrated
Mobile Security Must Reside at the Database Layer
Building WealthFlow confirmed that mobile client code can never serve as a security boundary. Enforcing PostgreSQL Row Level Security (RLS) ensures user data isolation is guaranteed by the database engine regardless of client tampering or network interception.
Navigating Native Toolchain Integration and Upstream Incompatibilities
Modern React Native development extends beyond component authoring: native Android compilation frequently exposes subtle codegen and module interop discrepancies. Diagnosing type parser errors and applying disciplined, reproducible patches via patch-package is essential for reliable native releases.
Deterministic Verification Protects Critical Financial Logic
Isolating business arithmetic into pure functions backed by 114 automated Jest tests proved indispensable for maintaining calculation consistency across multi-currency formatting, budget consumption thresholds, and savings goal milestones.
Dedicated WealthFlow landing page deployed on Vercel, with product overview, feature showcase, technical details, and Android preview download.
Read the implementation and browse its history.
Inspect the layouts in the screenshots and demo.
Explore the architecture and decisions in this case study.
Explore the WealthFlow Product Site
Dedicated WealthFlow landing page deployed on Vercel, with product overview, feature showcase, technical details, and Android preview download.
🔒 Read-only environment · Synthetic data
MOBILE DEVELOPMENT & CLOUD PERSISTENCE
Interested in cross-platform mobile apps or data persistence?
I'm keen to connect on React Native mobile development, Supabase backend integration, financial data modeling, or developer opportunities.
Looking for full-stack web application development or custom internal software? Explore the BusinessOS flagship platform →