A production-ready Grex project with Clean Architecture, enterprise-grade configuration management, and comprehensive developer tooling.
- β Clean Architecture - Separation of concerns with Domain, Data, and Presentation layers
- β State Management - BLoC for feature logic, Riverpod for infrastructure and routing, GetIt for repositories β see docs/architecture/state-management.md
- β Code Generation - Freezed for immutable classes and JSON serialization
- β
Linting - Very Good Analysis (
flutter analyzeis clean) - β Testing - 160 test files including property-based tests (100+ iterations each)
- β Multi-Environment Support - Development, Staging, Production
- β
Flexible Configuration -
.envfiles for local dev,--dart-definefor CI/CD - β Feature Flags - Local and remote (Firebase Remote Config) feature flags
- β Environment-Aware Defaults - Smart defaults based on environment
- β Type-Safe Configuration - Typed getters with fallback chain
- β Multi-Language Support - English, Vietnamese, Spanish, Arabic
- β RTL Support - Right-to-left language support for Arabic
- β Locale Persistence - Save and restore user language preference
- β
Standardized Localization - Context extension for easy access (
context.l10n)
- β Secure Storage - Flutter Secure Storage for sensitive data
- β Shared Preferences - Simple key-value storage for non-sensitive data
- β Storage Migration - Version-based storage migration system
- β Error Handling - Comprehensive error handling with custom exceptions
- β Email/Password Authentication - Complete auth system with email verification
- β Social Login - Google OAuth and Apple Sign In integration (98% complete)
- β Account Linking - Link social providers to existing accounts
- β Profile Setup - Guided profile completion for new social users
- β Deep Link Handling - OAuth callback processing with performance optimization
- β Session Management - Persistent sessions across app restarts
- β Security Compliance - HTTPS-only, minimal scopes, secure token storage
- β Group Management - Create and manage expense groups with role-based permissions
- β Expense Tracking - Record expenses with 4 split methods (equal, percentage, exact, shares)
- β Payment Recording - Track payments between group members
- β Balance Calculation - Real-time balance calculations with settlement plan generation
- β Data Export - Export group data in CSV/PDF formats
- β Search & Filter - Advanced search and filtering across expenses
All data access goes through the Supabase client directly. The Dio layer below
is built but not referenced by any repository (apiClientProvider has no
callers). Keep it only if you plan to call non-Supabase APIs; see
F7 in the code audit.
- π§ HTTP Client - Dio with interceptors support
- π§ Configurable Timeouts - Environment-based timeout configuration
- π§ Request/Response Logging - Debug-friendly HTTP logging
- π§ Error Interceptors - Automatic error handling and conversion
- π§ Auth Interceptors - Automatic token injection and refresh
- β Material Design - Material 3 theme support
- β Dark Mode - Built-in dark theme support
- β Accessibility - Semantic labels and accessibility support
- β Responsive Design - Adaptive layouts for different screen sizes
- β Type-Safe Routing - GoRouter with type-safe route definitions
- β Deep Linking - Support for deep links and URL navigation
- β Auth-Based Routing - Protected routes with authentication redirects
- β Navigation Logging - Automatic route tracking and logging
- β Comprehensive Logging - Multi-level logging with file and console output
- β Log Rotation - Automatic log file rotation
- β Structured Logging - JSON formatting for production
- β Performance Monitoring - Firebase Performance integration
- β Screen Tracking - Automatic screen load time tracking
- β Multi-Platform - Android, iOS, Web, Linux, macOS, Windows support
- β CI/CD Ready - GitHub Actions workflows included (disabled by default, uncomment triggers to enable)
- β Version Management - Automated version bumping scripts
- β Fastlane Integration - iOS and Android deployment automation
- β Comprehensive Docs - Architecture, guides, API documentation
- β Migration Guides - From MVC, GetX, Bloc, and other architectures
- β Best Practices - Code examples and patterns
- β API Documentation - Complete API reference
- β Example Features - Complete features demonstrating Clean Architecture (Auth, Groups, Expenses, Balances, etc.)
- β 160 Test Files - 1308 passing, 572 skipped, 0 failing (2026-08-04)
- β Unit Tests - Domain and data layer testing
- β Widget Tests - UI component testing
- β Integration Tests - End-to-end flow testing
- β Test Helpers - Reusable test utilities and fixtures
- Flutter - UI framework
- flutter_bloc - State management for all feature logic (auth, groups, expenses, payments, balances)
- Riverpod - Infrastructure providers, routing, and the authβrouter bridge
- GetIt - Service locator for repositories and BLoC construction
- Supabase - PostgreSQL, Auth, and Realtime backend (all data access goes through it)
- Dio - HTTP client (scaffolding only β currently unused, see Network Layer above)
- Freezed - Code generation for immutable classes
- Equatable - Value equality comparison
- Firebase Core - Firebase initialization
- Firebase Remote Config - Remote feature flags
- Firebase Performance - Performance monitoring and tracking
- flutter_secure_storage - Secure storage for sensitive data
- shared_preferences - Simple key-value storage
- flutter_localizations - Flutter localization support
- intl - Internationalization utilities
- go_router - Declarative routing with deep linking
- logger - Comprehensive logging solution
- path_provider - File system access for log files
- build_runner - Code generation runner
- very_good_analysis - Linting rules
- mocktail - Testing and mocking
lib/
βββ core/ # Core infrastructure
β βββ config/ # Configuration system
β βββ constants/ # App constants
β βββ di/ # Dependency injection (Riverpod providers + GetIt)
β βββ errors/ # Error handling
β βββ feature_flags/ # Feature flags infrastructure
β βββ localization/ # Localization service
β βββ logging/ # Logging service
β βββ network/ # Network layer (Dio setup)
β βββ performance/ # Performance monitoring
β βββ routing/ # Routing system (go_router)
β βββ storage/ # Storage services (with migration)
β βββ utils/ # Utility functions
β
βββ features/ # Feature modules (Clean Architecture)
β βββ auth/ # Authentication feature with social login
β β βββ data/ # Data layer (models, data sources, repositories)
β β β βββ handlers/ # OAuth deep link handlers
β β β βββ models/ # User, profile, social auth models
β β β βββ repositories/ # Social auth and user repositories
β β βββ domain/ # Domain layer (entities, use cases, repository interfaces)
β β β βββ entities/ # User, SocialAuthProvider, ProfileSetupData
β β β βββ repositories/ # SocialAuthRepository interface
β β βββ presentation/ # Presentation layer (screens, widgets, providers)
β β βββ pages/ # Login, register, profile setup pages
β β βββ widgets/ # Social login buttons, dialogs, error widgets
β βββ feature_flags/ # Feature flags feature
β β βββ presentation/ # Feature flags UI
β βββ groups/ # Group management
β βββ expenses/ # Expense tracking
β βββ payments/ # Built-in payments tracking
β βββ balances/ # Balance calculation engine
β βββ export/ # Data export utilities
β
βββ shared/ # Shared resources
β βββ accessibility/ # Accessibility utilities
β βββ extensions/ # Dart extensions
β βββ theme/ # App theme configuration
β βββ widgets/ # Reusable widgets
β
βββ l10n/ # Localization files (generated)
βββ main.dart # App entry point
- Flutter SDK (>=3.0.0)
- Dart SDK (>=3.0.0)
- Android Studio / VS Code with Flutter extensions
- Xcode (for iOS development on macOS)
For fully offline development using a local Supabase instance:
-
Install Supabase CLI
npm install -g supabase
-
Start local Supabase
supabase start
The CLI will print the API URL and anon key once running.
-
Configure
.envfor localENVIRONMENT=development SUPABASE_URL=http://localhost:54321 SUPABASE_ANON_KEY=<anon key from supabase start output>
The default anon key is already available in
.env.exampleunderSUPABASE_LOCAL_ANON_KEY. -
Apply migrations (if any)
supabase db reset
-
Run the app
flutter run
-
Stop local Supabase when done
supabase stop
Note: When using Android Emulator, replace
localhostwith10.0.2.2:SUPABASE_URL=http://10.0.2.2:54321
-
Create repository from template (if using GitHub template)
- Click "Use this template" button on GitHub
- Create a new repository from this template
- Clone your new repository:
git clone <your-repository-url> cd <your-project-name>
OR clone directly (if not using template):
git clone <repository-url> cd grex
-
Install dependencies
flutter pub get
-
Generate code (Freezed, JSON serialization)
flutter pub run build_runner build --delete-conflicting-outputs
-
Set up environment configuration β required, the build fails without it
# Copy the example environment file cp .env.example .env # Edit .env with your configuration β at minimum SUPABASE_URL and # SUPABASE_ANON_KEY. See Configuration System section below.
.envis gitignored but declared as a Flutter asset inpubspec.yaml, so a fresh clone without it fails at bundle time withNo file or variants found for asset: .envβ before any Dart code runs. Creating the file (even empty) is mandatory;--dart-definealone is not enough. See SETUP.md.β οΈ Do not putSUPABASE_SERVICE_ROLE_KEYin.env. Because.envships as an app asset, that key would be extractable from any release build and bypasses all RLS. See F4 in the code audit. -
Set up Git hooks (optional but recommended)
Linux/macOS:
./scripts/linux/development/setup-git-hooks.sh
Windows:
.\scripts\windows\development\setup-git-hooks.ps1
This will install Git hooks for:
- Code formatting checks (pre-commit)
- Commit message validation (commit-msg)
- Test execution (pre-push)
-
Run the app
flutter run
The app includes comprehensive social login integration with Google OAuth and Apple Sign In.
-
Google OAuth Setup:
- Create OAuth 2.0 Client ID in Google Cloud Console
- Add authorized redirect URIs:
https://[project-id].supabase.co/auth/v1/callback - Configure in Supabase Dashboard β Authentication β Providers
-
Apple Sign In Setup:
- Create Services ID in Apple Developer Portal
- Configure Sign In with Apple
- Generate private key (.p8 file)
- Configure in Supabase Dashboard β Authentication β Providers
Android (android/app/src/main/AndroidManifest.xml):
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="io.supabase.grex"
android:host="login-callback" />
</intent-filter>iOS (ios/Runner/Info.plist):
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>io.supabase.grex</string>
<key>CFBundleURLSchemes</key>
<array>
<string>io.supabase.grex</string>
</array>
</dict>
</array>- OAuth Integration: Google and Apple OAuth with external browser launch
- Account Linking: Link social providers to existing email accounts
- Profile Setup: Guided profile completion for new social users
- Deep Link Handling: Fast OAuth callback processing (< 1 second)
- Session Management: Persistent sessions with automatic refresh
- Error Handling: User-friendly error messages with retry options
- Localization: Multi-language support for all social login UI
- Security: HTTPS-only, minimal scopes, secure token storage
- Performance: OAuth flow completion < 5 seconds after authorization
For detailed implementation guide, see Social Login Developer Guide.
- Rename the project (if needed) - Update package name from
grexto your project name - Configure your environment - See Configuration System below
- Set up Firebase (optional) - For remote feature flags and performance monitoring
- Add
google-services.json(Android) andGoogleService-Info.plist(iOS) - Initialize Firebase in your app
- Add
- Customize the theme - Edit
lib/shared/theme/app_theme.dart - Explore example features - Check out
lib/features/for examples:- Auth - Authentication flow with social login
- Groups & Expenses - Core expense sharing implementation
- Feature Flags - Conditional UI rendering based on flags
- Add your first feature - Follow the pattern in example features
- Read the documentation - Check out
docs/folder for detailed guides
This project includes a production-ready, multi-environment configuration system that supports:
- Local Development:
.envfiles for easy local configuration - CI/CD:
--dart-defineflags for build-time configuration - Fallback Chain:
.envβ--dart-defineβ defaults - Environment-Aware Defaults: Different configurations per environment
- Feature Flags: Enable/disable features per environment
- Network Configuration: Timeout settings for API calls
- Debug Utilities: Tools for inspecting configuration
The configuration system consists of two main classes:
-
EnvConfig(lib/core/config/env_config.dart): Low-level environment variable loader- Loads from
.envfiles usingflutter_dotenv - Reads from
--dart-defineflags - Provides fallback chain:
.envβ--dart-defineβ defaults
- Loads from
-
AppConfig(lib/core/config/app_config.dart): High-level application configuration- Uses
EnvConfigto get values - Provides typed getters (String, bool, int)
- Environment-aware defaults
- Feature flags
- Network timeout configuration
- Debug utilities
- Uses
# Copy the example file
cp .env.example .env
# Edit .env with your values
# The .env file is gitignored and won't be committedEdit .env with your configuration:
ENVIRONMENT=development
BASE_URL=http://localhost:3000
ENABLE_LOGGING=true
ENABLE_ANALYTICS=false- Create
.envfile from.env.example - Fill in your values
- Run the app normally:
flutter runThe app will automatically load values from .env.
For CI/CD or when you don't want to use .env files:
flutter run \
--dart-define=ENVIRONMENT=staging \
--dart-define=BASE_URL=https://api-staging.example.com \
--dart-define=ENABLE_ANALYTICS=trueflutter build apk \
--dart-define=ENVIRONMENT=production \
--dart-define=BASE_URL=https://api.example.com \
--dart-define=ENABLE_ANALYTICS=true \
--dart-define=ENABLE_CRASH_REPORTING=trueimport 'package:grex/core/config/app_config.dart';
// Get environment
final env = AppConfig.environment; // 'development', 'staging', or 'production'
// Check environment
if (AppConfig.isDevelopment) {
// Development-specific code
}
// Get API base URL
final baseUrl = AppConfig.baseUrl;
// Check feature flags
if (AppConfig.enableLogging) {
logger.info('App started');
}
if (AppConfig.enableAnalytics) {
analytics.trackEvent('app_opened');
}import 'package:grex/core/config/app_config.dart';
import 'package:dio/dio.dart';
final dio = Dio(
BaseOptions(
baseUrl: AppConfig.baseUrl,
connectTimeout: Duration(seconds: AppConfig.apiConnectTimeout),
receiveTimeout: Duration(seconds: AppConfig.apiReceiveTimeout),
sendTimeout: Duration(seconds: AppConfig.apiSendTimeout),
),
);import 'package:grex/core/config/app_config.dart';
// Print configuration to console (only in debug mode)
AppConfig.printConfig();
// Get configuration as a map
final config = AppConfig.getDebugInfo();
print(config);| Variable | Type | Default | Description |
|---|---|---|---|
ENVIRONMENT |
String | development |
Environment name: development, staging, or production |
BASE_URL |
String | Environment-aware | API base URL (see defaults below) |
API_TIMEOUT |
int | 30 |
API timeout in seconds |
API_CONNECT_TIMEOUT |
int | 10 |
API connect timeout in seconds |
API_RECEIVE_TIMEOUT |
int | 30 |
API receive timeout in seconds |
API_SEND_TIMEOUT |
int | 30 |
API send timeout in seconds |
ENABLE_LOGGING |
bool | Environment-aware | Enable logging (default: true in dev/staging) |
ENABLE_ANALYTICS |
bool | Environment-aware | Enable analytics (default: true in staging/prod) |
ENABLE_CRASH_REPORTING |
bool | Environment-aware | Enable crash reporting (default: true in staging/prod) |
ENABLE_PERFORMANCE_MONITORING |
bool | Environment-aware | Enable performance monitoring (default: true in staging/prod) |
ENABLE_DEBUG_FEATURES |
bool | Environment-aware | Enable debug features (default: true in dev) |
ENABLE_HTTP_LOGGING |
bool | Environment-aware | Enable HTTP request/response logging (default: true in dev) |
APP_VERSION |
String | 0.0.1 |
App version |
APP_BUILD_NUMBER |
String | 1 |
App build number |
BASE_URL defaults:
- Development:
http://localhost:3000 - Staging:
https://api-staging.example.com - Production:
https://api.example.com
Feature Flag defaults:
- Logging: Enabled in
developmentandstaging - Analytics: Enabled in
stagingandproduction - Crash Reporting: Enabled in
stagingandproduction - Performance Monitoring: Enabled in
stagingandproduction - Debug Features: Enabled in
developmentonly - HTTP Logging: Enabled in
developmentonly
- Never commit
.envfiles: They contain sensitive information and are gitignored - Use
.env.exampleas a template: Commit this file with placeholder values - Use
.envfor local development: Easy to change values without rebuilding - Use
--dart-definefor CI/CD: More secure and doesn't require file management - Set environment-specific defaults: Let the system handle defaults based on environment
- Use feature flags: Enable/disable features per environment without code changes
- Ensure
EnvConfig.load()is called inmain()beforerunApp() - Check that
.envfile exists in the project root - Verify
pubspec.yamlincludes.envin assets - Run
flutter pub getafter addingflutter_dotenv
- Hot reload doesn't reload environment variables - do a full restart
- For
--dart-definevalues, rebuild the app - Check that you're using the correct variable name (case-sensitive)
Use AppConfig.printConfig() in debug mode to see all configuration values:
if (AppConfig.isDebugMode) {
AppConfig.printConfig();
}This will print all configuration values to the console, helping you verify what values are being used.
# Run all tests
flutter test
# Run tests with coverage
flutter test --coverage
# Run specific test file
flutter test test/features/auth/domain/usecases/login_test.dartTests follow the same structure as the source code:
- 160 test files β 1308 passing, 572 skipped, 0 failing (2026-08-04)
- Unit tests for use cases and utilities
- Widget tests for UI components
- Integration tests for end-to-end flows
- Property-based tests for social login (35 properties with 100+ iterations each)
- Test helpers and fixtures for reusable test utilities
The social login feature includes extensive testing:
# Run social login tests specifically
flutter test test/features/auth/data/repositories/social_auth_repository_test.dart
flutter test test/features/auth/presentation/widgets/social_login_button_test.dart
# Run property-based tests (100+ iterations each)
flutter test test/features/auth/property_tests/Property Tests Include:
- OAuth flow completion within performance requirements
- Profile setup data preservation
- Account linking detection and handling
- Session persistence across app restarts
- Error handling for all failure scenarios
The project includes:
- β Domain layer tests (use cases, entities)
- β Data layer tests (repositories, data sources, models)
- β Presentation layer tests (screens, widgets, providers)
- β Core infrastructure tests (config, network, storage, logging, performance)
- β Integration tests for complete flows
# Debug APK
flutter build apk --debug
# Release APK
flutter build apk --release
# App Bundle (for Play Store)
flutter build appbundle --release# Debug
flutter build ios --debug
# Release
flutter build ios --release# Debug
flutter build web --debug
# Release
flutter build web --release- Architecture Documentation - Complete architecture documentation index
- Architecture Overview - Why Clean Architecture, benefits, trade-offs, and learning resources
- Design Decisions - Detailed rationale for routing, state management, error handling, logging, storage, and HTTP client choices
- Getting Started - Step-by-step setup guide
- Understanding the Codebase - Architecture and patterns
- Common Tasks - Frequently performed tasks
- Routing Guide - GoRouter navigation and deep linking
- Git Hooks Setup - Setup Git hooks for code quality (similar to Husky)
- Adding Features - How to add new features
- Social Login - Complete social login implementation guide
- Feature Flags - Feature flags system documentation
- [Expense Sharing Engine] - Core sharing models
- Localization - i18n setup and usage
- Logging - Logging system documentation
- Performance - Performance monitoring guides
- Routing - Routing and navigation guide
- Deployment Guide - Complete deployment documentation
- Quick Start - Get started in 5 minutes
- Android Deployment - Android-specific guide
- iOS Deployment - iOS-specific guide
- Web Deployment - Web-specific guide
- Release Process - Version management and releases
- Monitoring & Analytics - Crashlytics and analytics setup
- API Overview - API documentation index
- Examples - Code examples and patterns
We welcome contributions! Please see our Contributing Guide for details on:
- How to report bugs
- How to suggest enhancements
- Development setup and workflow
- Coding standards and guidelines
- Testing requirements
- Commit message conventions
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Make your changes following our coding standards
- Write or update tests
- Commit your changes using conventional commits
- Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
For detailed guidelines, please read CONTRIBUTING.md.
This project is licensed under the MIT License - see the LICENSE file for details.
- Flutter - The framework
- Riverpod - State management
- Very Good Ventures - Linting rules and best practices
- Freezed - Code generation
For questions, issues, or contributions, please open an issue on GitHub.
Made with β€οΈ using Flutter