import '../cache/cache_policy.dart'; import '../cache/cached_repository.dart'; import '../../core/network/i_api_client.dart'; import 'models/schedule_item_model.dart'; class CalendarRepository extends CachedRepository> { final IApiClient _apiClient; static const _prefix = '/api/v1/schedule-items'; CalendarRepository({ required super.store, required IApiClient apiClient, CachePolicy? policy, super.now, }) : _apiClient = apiClient, super( policy: policy ?? const CachePolicy( softTtl: Duration(minutes: 2), hardTtl: Duration(minutes: 30), minRefreshInterval: Duration(minutes: 1), ), ); static String dayKey(DateTime date) { final day = '${date.year}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}'; return 'calendar:day:$day'; } static String monthKey(DateTime date) { return 'calendar:month:${date.year}-${date.month.toString().padLeft(2, '0')}'; } Future> getDayEvents( DateTime date, { bool forceRefresh = false, }) async { final key = dayKey(date); final start = DateTime(date.year, date.month, date.day); final end = DateTime(date.year, date.month, date.day, 23, 59, 59); return getOrLoad( key: key, forceRefresh: forceRefresh, loadFromRemote: () => _listByRange(startAt: start, endAt: end), ); } Future> getMonthEvents( DateTime monthStart, { bool forceRefresh = false, }) async { final key = monthKey(monthStart); final start = DateTime(monthStart.year, monthStart.month, 1); final end = DateTime(monthStart.year, monthStart.month + 1, 0, 23, 59, 59); return getOrLoad( key: key, forceRefresh: forceRefresh, loadFromRemote: () => _listByRange(startAt: start, endAt: end), ); } Future getEventById(String id) async { final response = await _apiClient.get>('$_prefix/$id'); final data = response.data; if (data == null) { throw StateError('Invalid getEventById response: empty payload'); } return ScheduleItemModel.fromJson(data); } Future> listEventsByRange({ required DateTime start, required DateTime end, }) { return _listByRange(startAt: start, endAt: end); } Future> _listByRange({ required DateTime startAt, required DateTime endAt, }) async { final start = Uri.encodeQueryComponent(startAt.toUtc().toIso8601String()); final end = Uri.encodeQueryComponent(endAt.toUtc().toIso8601String()); final response = await _apiClient.get>( '$_prefix?start_at=$start&end_at=$end', ); final data = response.data; if (data == null) { throw StateError('Invalid listByRange response: empty payload'); } return data .whereType>() .map(ScheduleItemModel.fromJson) .toList(growable: false); } }