diff --git a/apps/lib/features/calendar/data/repositories/calendar_repository.dart b/apps/lib/features/calendar/data/repositories/calendar_repository.dart index de3ce67..7055b0a 100644 --- a/apps/lib/features/calendar/data/repositories/calendar_repository.dart +++ b/apps/lib/features/calendar/data/repositories/calendar_repository.dart @@ -4,11 +4,13 @@ import '../../../../data/cache/cache_scope.dart'; import '../../../../data/network/i_api_client.dart'; import '../../../../core/notification/models/reminder_alarm.dart'; import '../../../../core/notification/services/reminder_reconcile_service.dart'; +import '../../../../core/logging/logger.dart'; import '../models/schedule_item_model.dart'; class CalendarRepository extends CachedRepository> { final IApiClient _apiClient; final ReminderReconcileService? _reminderReconcileService; + final Logger _logger = getLogger('features.calendar.repository'); static const _prefix = '/api/v1/schedule-items'; CalendarRepository({ @@ -70,14 +72,28 @@ class CalendarRepository extends CachedRepository> { } 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'); + try { + final response = await _apiClient.get>( + '$_prefix/$id', + ); + final data = response.data; + if (data == null) { + throw StateError('Invalid getEventById response: empty payload'); + } + final event = ScheduleItemModel.fromJson(data); + await _reminderReconcileService?.reconcileEvent( + _toReminderSnapshot(event), + ); + return event; + } catch (e, stackTrace) { + _logger.error( + message: 'Failed to get event by id', + error: e, + stackTrace: stackTrace, + extra: {'event_id': id}, + ); + rethrow; } - final event = ScheduleItemModel.fromJson(data); - await _reminderReconcileService?.reconcileEvent(_toReminderSnapshot(event)); - return event; } Future getById(String id) { @@ -111,31 +127,54 @@ class CalendarRepository extends CachedRepository> { required bool accept, }) async { final action = accept ? 'accept' : 'reject'; - await _apiClient.post('$_prefix/$itemId/$action'); - await store.clearByPrefix('cache:${CacheScope.token()}:calendar:'); + try { + await _apiClient.post('$_prefix/$itemId/$action'); + await store.clearByPrefix('cache:${CacheScope.token()}:calendar:'); + } catch (e, stackTrace) { + _logger.error( + message: 'Failed to $action subscription', + error: e, + stackTrace: stackTrace, + extra: {'item_id': itemId, 'action': action}, + ); + rethrow; + } } 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'); + try { + 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'); + } + final events = data + .whereType>() + .map(ScheduleItemModel.fromJson) + .toList(growable: false); + await _reminderReconcileService?.reconcileEvents( + events.map(_toReminderSnapshot).toList(growable: false), + ); + return events; + } catch (e, stackTrace) { + _logger.error( + message: 'Failed to list events by range', + error: e, + stackTrace: stackTrace, + extra: { + 'start_at': startAt.toIso8601String(), + 'end_at': endAt.toIso8601String(), + }, + ); + rethrow; } - final events = data - .whereType>() - .map(ScheduleItemModel.fromJson) - .toList(growable: false); - await _reminderReconcileService?.reconcileEvents( - events.map(_toReminderSnapshot).toList(growable: false), - ); - return events; } ReminderEventSnapshot _toReminderSnapshot(ScheduleItemModel event) {