- project Structure
- Architecture
lib/
├── main.dart # App entry point
├── core/
│ ├── data/
│ │ ├── database.dart # Drift database definition
│ │ └── database.g.dart # Autogenerated database code - ignore
│ ├── models/
| | ├── models # Data models in the services (and db/external fetches) (Participant, Account, etc.)
| | ├── client_models # Data models in btw view and view model
| ├── Widgets/ # globally acessible widgets
│ │ ├── app_header.dart
│ │ ├── *
│ ├── services/ # Business logic services
│ │ ├── service_locator.dart # Dependency injection
│ │ ├── participant_service.dart
│ │ ├── budget_service.dart # facade for all budgeting related services
│ │ | ├── transaction_service.dart
│ │ | ├── template_service.dart
│ │ | ├── account_service.dart
│ │ | ├── category_service.dart
│ │ ├── sync_service.dart
│ │ ├── remote_service.dart # none existant currently
│ │ ├── google_sheets_service.dart # none existant currently
│ │ └── parsers/ # PDF parsing system
│ │ | ├── pdf_parser_interface.dart
│ │ | ├── parser_factory.dart
│ │ | ├── hsbc_parser.dart
│ │ | ├── mpesa_parser.dart
│ │ | ├── equity_parser.dart
│ │ | ├── coop_parser.dart # not yet implemented
│ │ | ├── generic_parser.dart # not yet implemented
│ │ └── budget_spreadsheet_mapper.dart # not yet implemented
│ └── routing/
│ | ├── app_router.dart # Navigation setup
└── features/ # Feature-based organization
├── onboarding/
│ └── widgets/
│ └── onboarding_view.dart
│ └── onboarding_viewmodel.dart
├── home/
│ └── widgets/
│ └── home_view.dart
│ └── home_viewmodel.dart
├── budgeting/
│ └── widgets/
│ └── budgeting_page.dart
│ └── budgeting_viewmodel.dart
└── audit/
├── views/
│ └── audit_page.dart
└── viewmodels/
└── audit_viewmodel.dart
- Models: Data structures (in
core/models/) - Views: UI components (in
features/*/views/) - ViewModels: Business logic and state management (in
features/*/viewmodels/)
- Provider: For dependency injection and state management
- ChangeNotifier: ViewModels extend this for reactive updates
- Context: For within session shared data
- Drift: Type-safe SQLite database with code generation
- Repository Pattern: Services abstract data access
- go_router: Declarative routing with deep linking support
- Desktop-first with navigation rail
- Mobile-friendly with drawer navigation
- Create feature folder structure
features/
└── new_feature/
├── views/
│ └── new_feature_page.dart
├── viewmodels/
│ └── new_feature_viewmodel.dart
└── widgets/
└── custom_widget.dart
- Create ViewModel (extends ChangeNotifier)
class NewFeatureViewModel extends ChangeNotifier {
// State
bool _isLoading = false;
// Getters
bool get isLoading => _isLoading;
// Methods
Future<void> loadData() async {
_isLoading = true;
notifyListeners();
// Business logic here
_isLoading = false;
notifyListeners();
}
}- Create View
class NewFeaturePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<NewFeatureViewModel>(
builder: (context, viewModel, child) {
return Scaffold(
// UI here
);
},
);
}
}- Add route in
app_router.dart
- Modify tables in
lib/core/data/database.dart - Update schema version
- Add migration logic in
onUpgrade - Regenerate code:
flutter pub run build_runner build --delete-conflicting-outputs- Create new parser class implementing
BankStatementParser - Add to
ParserFactory.getParser() - Implement bank-specific parsing logic
Primary: Windows (Desktop-first design)
Secondary: Android, macOS, iOS
Web: Not recommended (file system limitations)
For issues with:
- Syncfusion: https://support.syncfusion.com/
- Google APIs: https://support.google.com/cloud
- Flutter: https://docs.flutter.dev/
