A Personal Finance Management (PFM) application targeting Singapore. Flow helps users track, analyze, and understand their spending patterns through secure bank connectivity, AI-powered transaction categorization, and real-time financial insights.
Flow follows a distributed microservices architecture:
┌─────────────────────────────────────────────────────────────┐
│ Flutter Mobile App │
│ (Redux State Management, gRPC Client) │
└────────────────────────┬────────────────────────────────────┘
│ gRPC + gRPC-Web
▼
┌─────────────────────────────────────────────────────────────┐
│ Spring Boot Backend (Kotlin) │
│ (gRPC Services, Event Processing, Integrations) │
└──────────┬─────────────────────────────────────┬────────────┘
│ │
▼ ▼
┌────────────────────────┐ ┌───────────────────────────┐
│ Bank Scraper │ │ Third-party Services │
│ (Node.js gRPC) │ │ - Finverse (Open Banking)│
│ - DBS, OCBC, UOB │ │ - AWS Bedrock (AI) │
│ - Browser Automation │ │ - AWS SES (Email) │
└────────────────────────┘ └───────────────────────────┘
| Component | Description |
|---|---|
| Backend | Kotlin/Spring Boot API server with gRPC services, Kafka event processing, and third-party integrations |
| Mobile App | Flutter app with Redux state management, offline-first storage, and gRPC client |
| Bank Scraper | Node.js gRPC service for browser-based bank data extraction using Playwright |
| gRPC Contract | Shared Protocol Buffer definitions for type-safe API communication |
- Bank Linking: Mobile app initiates bank connection → Backend orchestrates scraper → Scraper automates browser login with 2FA → Normalized data stored in PostgreSQL
- Transaction Analysis: New transactions trigger Kafka events → AWS Bedrock AI categorizes and analyzes → Results stored and surfaced in mobile app
- Real-time Updates: Backend pushes updates via gRPC streaming → Mobile Redux store updates → UI reflects changes immediately
flow/
├── be/ # Spring Boot backend (Kotlin)
│ ├── src/main/kotlin/sg/flow/
│ │ ├── grpc/ # gRPC service implementations
│ │ ├── services/ # Business logic
│ │ ├── entities/ # Database entities
│ │ └── repositories/ # Data access layer
│ ├── src/main/resources/
│ │ └── sql/ # Database schema and migrations
│ └── compose.yaml # Local dev services (Postgres, Redis, Kafka)
│
├── flow_mobile/ # Flutter mobile app (Dart)
│ └── lib/
│ ├── domain/
│ │ ├── entity/ # Data models with Hive adapters
│ │ ├── redux/ # Actions, reducers, thunks, states
│ │ └── manager/ # Business logic interfaces
│ ├── presentation/ # UI screens and widgets
│ └── service/ # API and storage services
│
├── scraper/ # Bank scraper service (Node.js/TypeScript)
│ ├── src/
│ │ ├── server/ # gRPC server and handlers
│ │ ├── core/ # Session management, state machine
│ │ ├── adapters/ # Bank-specific scrapers (DBS, OCBC)
│ │ └── browser/ # Playwright browser pool
│ └── configs/ # Bank configuration YAMLs
│
├── grpc_contract/ # Shared Protocol Buffer definitions
│ ├── auth/v1/
│ ├── account/v1/
│ ├── transaction_history/v1/
│ └── common/v1/
│
└── infra/ # Infrastructure as Code
├── terraform/ # AWS resources (Bedrock, SES)
└── emails/ # Email templates
| Layer | Technologies |
|---|---|
| Backend | Kotlin 2.2, Spring Boot 3.5, Spring WebFlux, R2DBC, gRPC |
| Mobile | Flutter 3.24+, Dart 3.9+, Redux, Hive, gRPC |
| Scraper | Node.js 22, TypeScript, gRPC, Playwright |
| Database | PostgreSQL 15, Redis 7 |
| Messaging | Apache Kafka |
| Cloud | AWS (Bedrock, SES, Lambda), HashiCorp Vault |
| DevOps | Docker, Terraform, GitHub Actions |
- Java 21+
- Node.js 22+
- Flutter 3.24+
- Docker and Docker Compose
Each component has detailed documentation for setup and development:
| Component | Documentation | Description |
|---|---|---|
| Backend | be/README.md | Spring Boot API server, gRPC services, Kafka event processing |
| Mobile App | flow_mobile/README.md | Flutter app with Android emulator setup instructions |
| Bank Scraper | scraper/README.md | Node.js gRPC service for bank data extraction |
The recommended startup sequence is:
1. Start the Backend (from be/):
./gradlew bootRunThis single command will:
- Automatically start all Docker Compose services (PostgreSQL, Redis, Kafka, Vault)
- Start the Bank Scraper service (via Docker Compose with source file mounting)
- Launch the Spring Boot backend on port 8081
Note: You do not need to manually run
docker compose upor start the scraper separately. Spring Boot's Docker Compose integration handles all infrastructure automatically.
2. Run the Mobile App (from flow_mobile/):
flutter pub get
flutter runFor detailed Android emulator setup instructions, see flow_mobile/README.md.
If you need to run components independently (e.g., for scraper development):
# Backend only (with infrastructure)
cd be && ./gradlew bootRun
# Scraper standalone (requires Redis)
cd scraper && npm install && npm run dev
# Mobile app (requires backend running)
cd flow_mobile && flutter pub get && flutter runAfter modifying .proto files in grpc_contract/:
# Generate Dart code
cd grpc_contract && ./generate_dart_proto.sh
# Generate Kotlin code
cd be && ./gradlew generateProto| Bank | Integration Method | Status |
|---|---|---|
| DBS Singapore | Browser Automation | Active |
| OCBC Singapore | Browser Automation | Active |
| UOB Singapore | Finverse API | Planned |
- Secure Bank Connectivity: Browser-based scraping with 2FA support, no credential storage
- AI Transaction Analysis: AWS Bedrock-powered categorization and merchant identification
- Recurring Spending Detection: Automatic subscription and recurring payment identification
- Spending Insights: Age-group benchmarks, spending trends, and daily asset tracking
- Offline-First Mobile: Hive local storage for offline data access
- Event-Driven Architecture: Kafka-based async processing for scalability