Project Structure & Architecture Conventions¶
TrueLedger follows a Clean Architecture approach with strict separation of concerns. This ensures scalability, testability, and maintainability.
Directory Structure¶
We use a Layer-First organization (Standard Flutter Clean Arch), gradually moving towards Feature-First where possible.
lib/
├── core/ # Infrastructure & Shared Utilities
│ ├── config/ # App-wide vars (Version, Constants)
│ ├── error/ # Failure/Exception classes
│ ├── services/ # External services (Notification, Intelligence)
│ ├── theme/ # AppTheme & AppColors
│ └── utils/ # Helpers (Date, Currency, Platform)
│
├── data/ # Data Layer (Implements Domain Interfaces)
│ ├── datasources/ # Low-level data access (Database, SharedPreferences)
│ └── repositories/ # Implementation of Domain Repositories
│
├── domain/ # Business Logic (Pure Dart, No Flutter)
│ ├── models/ # Entities / Data Classes
│ ├── repositories/ # Interfaces (Contracts)
│ └── usecases/ # Business Logic Units (Single Responsibility)
│
├── presentation/ # UI Layer (Widgets & State)
│ ├── providers/ # Riverpod Providers (State Management)
│ ├── screens/ # Full-screen Widgets
│ │ ├── dashboard/
│ │ ├── transactions/
│ │ └── ...
│ └── widgets/ # Shared/Reusable UI Components
│
└── main.dart # Entry Point
Architecture Rules¶
-
Dependency Rule: Dependencies point INWARDS.
Presentationdepends onDomain.Datadepends onDomain.Domaindepends on NOTHING (pure Dart).
-
State Management: Riverpod
- UI Widgets (
ConsumerWidget) must never call Repositories directly. - UI must watch Providers.
- Providers use UseCases.
- UseCases use Repositories.
- UI Widgets (
-
Data Flow:
UI->Provider->UseCase->Repository->DataSource->Database
-
Testing:
- Unit Tests: Domain layer (UseCases, Models) and Logic.
- Widget Tests: Presentation layer (Screens, Widgets).
- Integration Tests: Data layer (Repositories with in-memory DB).
Naming Conventions¶
- Files:
snake_case.dart - Classes:
PascalCase - Variables:
camelCase - Repositories:
IFinancialRepository(Interface),FinancialRepositoryImpl(Impl). - UseCases:
VerbSubjectUseCase(e.g.,GetMonthlySummaryUseCase).