import '../../core/exceptions.dart'; import '../api/projects_api.dart'; import '../local/database.dart'; import '../models/project.dart'; /// Projects repository with read-through caching for Tier 2 offline support. /// Mirrors the pattern in NotesRepository — see that file for full notes. /// /// `getAll`'s sort/order/status query parameters are server-side filters; the /// cache stores the unfiltered list as last seen. Offline fallback returns /// the full cache regardless of the requested filters — close enough for a /// "view what you had" experience while disconnected. class ProjectsRepository { final ProjectsApi _api; final FabledDatabase _db; const ProjectsRepository(this._api, this._db); Future> getAll({ String? status, String sort = 'updated_at', String order = 'desc', }) async { try { final projects = await _api.getAll(status: status, sort: sort, order: order); // Only refresh the cache on the unfiltered default fetch — otherwise a // status=archived call would clobber the active-projects cache. if (status == null) { await _db.replaceAllProjects(projects); } else { for (final p in projects) { await _db.upsertProject(p); } } return projects; } on NetworkException { final cached = await _db.getAllProjects(); if (cached.isEmpty) rethrow; if (status != null) { return cached.where((p) => p.status == status).toList(); } return cached; } } Future getOne(int id) async { try { final project = await _api.getOne(id); await _db.upsertProject(project); return project; } on NetworkException { final cached = await _db.getProject(id); if (cached == null) rethrow; return cached; } } Future create({ required String title, String? description, String? goal, String? color, String status = 'active', }) async { final project = await _api.create( title: title, description: description, goal: goal, color: color, status: status, ); await _db.upsertProject(project); return project; } Future update(int id, Map fields) async { final updated = await _api.update(id, fields); await _db.upsertProject(updated); return updated; } Future delete(int id) async { await _api.delete(id); await _db.deleteProject(id); } }