import 'package:drift/drift.dart' as drift; import 'package:drift/native.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../core/constants.dart'; import '../core/time.dart'; import '../data/db/app_database.dart'; import '../data/db/daos/habit_dao.dart'; import '../data/db/daos/meta_dao.dart'; import '../data/db/daos/tracker_dao.dart'; import '../data/seed/seed_importer.dart'; /// Override in tests with an in-memory database. final appDatabaseProvider = Provider((ref) { throw UnimplementedError('appDatabaseProvider must be overridden in main()'); }); Future openProductionDatabase() async { final file = await appDatabaseFile(); return AppDatabase(NativeDatabase.createInBackground(file)); } final habitDaoProvider = Provider((ref) { return HabitDao(ref.watch(appDatabaseProvider)); }); final trackerDaoProvider = Provider((ref) { return TrackerDao(ref.watch(appDatabaseProvider)); }); final metaDaoProvider = Provider((ref) { return MetaDao(ref.watch(appDatabaseProvider)); }); /// One-time bootstrap: ensure default user row + seed catalogs. final bootstrapProvider = FutureProvider((ref) async { final db = ref.watch(appDatabaseProvider); // Ensure default user. final existing = await (db.select(db.users) ..where((t) => t.id.equals(kLocalDefaultUserId))) .getSingleOrNull(); if (existing == null) { await db.into(db.users).insert(UsersCompanion.insert( id: kLocalDefaultUserId, displayName: const drift.Value('You'), createdAt: nowKst().toIso8601String(), )); } // Seed catalogs (idempotent). await SeedImporter(db).importIfNeeded(); if (kDebugMode) { debugPrint('bootstrap done'); } }); /// Active habits stream for current user. final activeHabitsProvider = StreamProvider>((ref) { final db = ref.watch(appDatabaseProvider); return (db.select(db.habits) ..where((t) => t.userId.equals(kLocalDefaultUserId)) ..where((t) => t.status.equals('active')) ..orderBy([(t) => drift.OrderingTerm.asc(t.startedAt)])) .watch(); });