import 'dart:io'; import 'package:commons_core/commons_core.dart'; import 'package:get_it/get_it.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; import '../data/species_catalog.dart'; import '../data/species_repository.dart'; import '../data/variety_repository.dart'; import '../db/database.dart'; import '../db/encrypted_executor.dart'; import '../security/secret_store.dart'; import '../security/secure_key_store.dart'; import '../services/export_import_service.dart'; import '../services/file_picker_file_service.dart'; import '../services/file_service.dart'; /// The app's service locator. Kept to the composition root — widgets get their /// repositories from here (or via BlocProvider), never by reaching into it deep /// in the tree. final GetIt getIt = GetIt.instance; /// Wires the encrypted DB, keystore and repositories. Call once from `main` /// before `runApp`; the DB key must exist before the DB opens. Future configureDependencies() async { final keyStore = SecureKeyStore(store: FlutterSecretStore()); final dbKeyHex = await keyStore.databaseKeyHex(); final rootSeedHex = await keyStore.rootSeedHex(); final database = AppDatabase( openEncryptedExecutor(await _databaseFile(), dbKeyHex), ); // Until real key derivation lands, the node/author id is a stable per-install // slice of the root seed. It becomes the user's public key in the social layer. final nodeId = rootSeedHex.substring(0, 16); // Seed the bundled species catalog (idempotent) before the UI opens. final speciesRepository = SpeciesRepository(database, idGen: IdGen()); await speciesRepository.seedBundled(await loadBundledSpecies()); final varietyRepository = VarietyRepository( database, idGen: IdGen(), nodeId: nodeId, ); const fileService = FilePickerFileService(); getIt ..registerSingleton(keyStore) ..registerSingleton(database) ..registerSingleton(speciesRepository) ..registerSingleton(varietyRepository) ..registerSingleton(fileService) ..registerSingleton( ExportImportService(repository: varietyRepository, files: fileService), ); } Future _databaseFile() async { final dir = await getApplicationDocumentsDirectory(); return File(p.join(dir.path, 'tane_inventory.sqlite')); }