lib/main.dartwires the app manually: initialize SQLite (DatabaseHelper), construct every DAO/provider, preload species names, then pass everything throughMultiProvider.lib/main_screen.dartis the top-level shell. It owns navigation between the five feature areas: inventories, nests, specimens, field journal, and statistics.- Core persistence is local-first SQLite via
sqflite; schema lives inlib/data/database/database_helper.dart(current DB version:23). Most user data is offline and stored locally.
- Feature pattern is
screens/→providers/→data/daos/→data/models/. Example:lib/screens/specimen/specimens_screen.dartusesSpecimenProvider, which delegates toSpecimenDao, which mapsSpecimenobjects to SQLite. Inventoryis the most stateful model. Inlib/data/models/inventory.dartit owns timer logic, pause/resume bookkeeping, auto-finish rules, and local notifications. Changes to inventory timing usually span model + provider +main_screen.dartresume logic.- Providers are long-lived and injected as values, not recreated per screen.
InventoryProvider.fetchInventories()intentionally merges DB rows into existing in-memory objects so active timers/notifiers survive refreshes. - Cross-table imports are transaction-based in DAOs.
InventoryDao.importInventory()inserts the inventory plus species, POIs, vegetation, and weather in one transaction. - Images are file-backed plus DB-indexed. The
imagestable stores absolute file paths;backup_utils.dartzips the DB and those image files together.
- Localized strings use
S.of(context)/S.currentfromlib/generated/l10n.dart; enums map to user-facing labels inlib/core/core_consts.dart. - Do not hand-edit generated localization files under
lib/generated/orlib/generated/intl/. - Species autocomplete data is asset-driven, not remote.
loadSpeciesSearchData()readsassets/checklists/species_data_<country>.jsonbased onSharedPreferences['user_country']. - Settings in
lib/screens/settings/settings_screen.dartdrive behavior across the app: observer initials, startup module (kStartupModulePreferenceKey), country checklist, export number formatting, default durations, reminders, theme. - Field journal notes are rich-text Delta JSON strings (Fleather), not plain text.
AddJournalScreenserializes notes withjsonEncode(_notesController.document.toDelta().toList()); editing paths decode viaParchmentDocument.fromJson(...). - Many flows show errors via persistent
SnackBars rather than dialogs; preserve that style when extending existing screens. - Responsive layout uses shared breakpoints from
lib/core/core_consts.dart: tablet600, desktop840, side sheet width360.
- JSON import/export uses a shared envelope from
lib/utils/export_utils.dart:{source, schema, schemaVersion, records}withsource == 'Xolmis Mobile'. - Schemas are feature-specific (
inventories,nests,specimens). Keep envelope compatibility if you add fields. - Backup/restore is ZIP-based (
lib/utils/backup_utils.dart), not just raw DB copy; it must keep image files in sync with DB paths. - Species taxonomy updates are asset-driven migrations.
lib/services/species_update_service.dartappliesassets/updates/species_update_<year>.jsonon startup whenkCurrentSpeciesUpdateVersionincreases. - Platform permissions are already declared for notifications, location, camera, and media access in
android/app/src/main/AndroidManifest.xmlandios/Runner/Info.plist.
- Before changing persistence, inspect
DatabaseHelper._createTables,_upgradeTables, and_createPerformanceIndexes; schema/index changes must stay aligned with DB versioning and migrations. - When touching inventory lifecycle code, also inspect
_resumeAllActiveTimers()inlib/main_screen.dart; foreground/background recovery is part of the feature. - Prefer extending existing utils (
export_utils.dart,import_utils.dart,backup_utils.dart,utils.dart) instead of duplicating file/permission/share logic inside screens. - Preserve the provider/DAO split: screens should not talk to SQLite directly.
- If you add user-facing text, update the ARB files in
lib/l10n/and regenerate localization output instead of editing generated Dart. - Add documentation comments (Dartdoc) to new methods and classes, especially in data models and providers, to clarify their purpose and usage for future maintainers.
- Install/refresh deps:
flutter pub get - Run static analysis:
flutter analyze - Run checklist integrity test only before build:
flutter test test/checklists_integrity_test.dart - Run utils tests only when modified
lib/utils/files:flutter test test/utils/utils_methods_test.dart - Launch locally:
flutter run - Generate localization output after ARB changes:
flutter pub global run intl_utils:generate
flutter analyzecurrently reports many pre-existing infos/warnings, including generated localization files and async-context lint noise; do not assume a clean analyzer baseline.- The supported-country species checklist automated check is
test/checklists_integrity_test.dart, which verifies every checklist asset exists and has the expected JSON structure. - The utils test suite in
test/utils/utils_methods_test.dartcovers species name matching, string formatting, and statistics logic.