A local-first weight tracking application built with Flutter using Clean Architecture and BLoC.
Clean Architecture strictly organized under a Feature-First (vertical slice) layout:
lib/
├── app.dart # Root application widget
├── main.dart # App entry point & database initialization
├── core/ # Cross-cutting concerns
│ ├── database/ # Database module & recovery logic
│ ├── integrations/ # Native platform & 3rd-party services
│ │ ├── biometrics/ # Local authentication & lock observer
│ │ ├── csv/ # CSV import/export pipelines
│ │ ├── health/ # Apple HealthKit & Android Health Connect
│ │ └── notifications/ # Scheduled daily local reminders
│ ├── models/ # Core models (MeasurementUnit)
│ └── utils/ # Shared utilities (FieldCipher, UnitConverter)
├── features/ # Feature modules
│ ├── calendar/ # Calendar view and historical day entries
│ ├── dashboard/ # Today's overview, BMI, and quick-add
│ ├── navigation/ # Main bottom navigation scaffold
│ ├── onboarding/ # 8-step initial setup wizard
│ ├── settings/ # User preferences & configuration
│ ├── statistics/ # Analytical charts and history trends
│ └── weight/ # Core weight tracking domain & data
│ ├── data/ # WeightEntryModel (Isar) & Repositories
│ ├── domain/ # Entities, Domain Contracts, Error Types
│ └── presentation/ # Shared WeightBloc & Events
├── l10n/ # Localization ARB assets (app_en.arb, app_pl.arb)
└── presentation/ # Global UI & App-level components
├── core/ # ClampedLayout responsive wrapper
├── screens/ # AppSplash, InitializationError, BiometricShield
├── theme/ # AppTheme (Light & Dark Material 3)
└── widgets/ # Shared global widgets (AppTopBar, StateMessageCard)
- Local-first: All weight entries persist on-device using Isar (
isar_community). No cloud dependency. - Feature-First: Strict vertical slicing. Features (
calendar,dashboard,settings, etc.) encapsulate their own presentation boundaries, while core business logic remains in theweightdomain. - Dependency Inversion: Domain defines repository contracts; data layer provides concrete implementations.
- State Management:
flutter_blocwithhydrated_blocfor persistent application configuration. - Dependency Injection: Manual DI in
main.dart— dependencies instantiated explicitly and passed down via widget constructors and BLoC providers.
| Category | Package | Purpose |
|---|---|---|
| Framework | Flutter 3.44 | Cross-platform UI framework |
| State Management | flutter_bloc, hydrated_bloc | BLoC pattern with automated JSON hydration |
| Dependency Injection | Manual DI | Dependencies wired explicitly in main.dart, passed via constructors and BLoC providers |
| Database | isar_community | High-performance local NoSQL database |
| Charts | fl_chart | Interactive weight history visualizations |
| Biometrics | local_auth | Native biometric authentication (Face ID, Touch ID, fingerprint) |
| Health | health | Integration with Apple HealthKit & Android Health Connect |
| CSV Handling | csv | CSV encoding and parsing pipeline |
| Localization | flutter_localizations + gen-l10n | Internationalization (English, Polish) |
| Notifications | flutter_local_notifications | Local scheduled daily reminders |
- Log daily weight measurements with optional text notes.
- Interactive line charts powered by
fl_chartwith daily entry aggregation. - Filter data by timeframe (
Week,Month,Year,All). - Summary metrics: BMI calculation, BMI category badge, target weight progress, and remaining weight delta.
- Automated BMI calculation from configured height.
- Health Sync: Native synchronization with Apple Health (iOS) and Health Connect (Android).
- CSV Import: Batch import entries via
CsvImporterwith row validation and isolate background parsing. - CSV Export: Export entries via
CsvExporterto a CSV file on disk and share via native OS share dialog.- Column format:
ID,Date,Weight (kg),Note
- Column format:
- Unit System: Seamless switching between Metric (kg, cm) and Imperial (lb, ft/in).
- 8-Step Onboarding: A comprehensive wizard guiding users through unit selection, initial logging, CSV imports, and permission setups.
- Theme Options: Light, Dark, or System mode.
- Target Tracking: Configurable target weight goals.
- Reminders: Daily reminder notifications with custom time selection.
- Biometric Lock: Native biometric lock shielding on app cold start and backgrounding with
persistAcrossBackgroundingset tofalse.
- Flutter SDK >= 3.12
- Xcode (iOS) / Android Studio (Android)
flutter pub get
dart run build_runner buildflutter run- Isar schema configuration uses the
balance_v1store name (encrypted schema; legacypure_weight_v1andpure_weight_v2stores are quarantined on first launch). DatabaseModulemanages initialization, integrity verification, and fallback database recovery (.isar.bak).- Native database-level sorting via
.where().sortByDateTimeDesc()runs directly inside Isar query streams.
WeightBloc: Controls weight entries and chart period filtering.- Events:
SubscribeToWeightChanges,UpdateUserHeight,AddWeight,DeleteWeight,ChangeChartFilter,RefreshWeightData - States:
WeightInitial,WeightLoading,WeightLoaded,WeightError
- Events:
AppSettingsBloc: Manages user configuration viaHydratedBloc.- Events:
UpdateTheme,UpdateMeasurementUnit,UpdateHeight,TargetWeightChanged,UpdateBiometricLock,ToggleNotifications,UpdateNotificationTime,SetLocked, etc. - State:
AppSettingsState(persisted to storage).
- Events:
Generate code for Isar schema models:
dart run build_runner buildRun full verification suite (over 500+ tests):
./before_push.shOr execute unit/widget tests directly:
flutter testCSV import and export conform to the following 4-column layout:
ID,Date,Weight (kg),Note
1,2026-07-29 08:00,72.5,Morning weigh-in
2,2026-07-28 08:00,73.0,ID: Auto-increment integer primary key.Date: Timestamp formatted asyyyy-MM-dd HH:mm.Weight (kg): Numeric value in kilograms (1 decimal place).Note: Optional user note string.
iOS: Include NSFaceIDUsageDescription in ios/Runner/Info.plist.
Android: Declare <uses-permission android:name="android.permission.USE_BIOMETRIC" /> in android/app/src/main/AndroidManifest.xml.
Private / All rights reserved.