From 4023df420479d9ac5e6d40d2e37d6ac0e722a7f0 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Fri, 26 Sep 2025 17:03:34 +0900 Subject: [PATCH 01/27] feat: add LoggingTransformer for request payload logging - Introduced LoggingTransformer to log serialized request payloads for better debugging and monitoring. - Updated AppDio to utilize LoggingTransformer, enhancing the request transformation process. - This addition improves visibility into the data being sent over the network. --- lib/core/dio/app_dio.dart | 3 ++ .../dio/transformers/logging_transformer.dart | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 lib/core/dio/transformers/logging_transformer.dart diff --git a/lib/core/dio/app_dio.dart b/lib/core/dio/app_dio.dart index a6d99b85..2369a3b1 100644 --- a/lib/core/dio/app_dio.dart +++ b/lib/core/dio/app_dio.dart @@ -4,12 +4,15 @@ import 'package:on_time_front/core/constants/environment_variable.dart'; import 'package:on_time_front/core/dio/adapters/shared.dart'; import 'package:on_time_front/core/dio/interceptors/logger_interceptor.dart'; import 'package:on_time_front/core/dio/interceptors/token_interceptor.dart'; +import 'package:on_time_front/core/dio/transformers/logging_transformer.dart'; @Injectable(as: Dio) class AppDio with DioMixin implements Dio { AppDio() { httpClientAdapter = getAdapter(); + transformer = LoggingTransformer(inner: BackgroundTransformer()); options = BaseOptions( + contentType: Headers.jsonContentType, baseUrl: EnvironmentVariable.restApiUrl, connectTimeout: const Duration(milliseconds: 30000), receiveTimeout: const Duration(milliseconds: 30000), diff --git a/lib/core/dio/transformers/logging_transformer.dart b/lib/core/dio/transformers/logging_transformer.dart new file mode 100644 index 00000000..79074bb8 --- /dev/null +++ b/lib/core/dio/transformers/logging_transformer.dart @@ -0,0 +1,28 @@ +import 'dart:developer'; + +import 'package:dio/dio.dart'; + +/// A wrapper transformer that logs the exact serialized request payload +/// produced by Dio's inner transformer. This reflects the precise string +/// sent over the wire (JSON, form-url-encoded, etc.). +class LoggingTransformer implements Transformer { + final Transformer _inner; + + LoggingTransformer({Transformer? inner}) + : _inner = inner ?? BackgroundTransformer(); + + @override + Future transformRequest(RequestOptions options) async { + final body = await _inner.transformRequest(options); + try { + log('🧾 Serialized body (${options.method} ${options.uri}): $body'); + } catch (_) {} + return body; + } + + @override + Future transformResponse( + RequestOptions options, ResponseBody responseBody) async { + return _inner.transformResponse(options, responseBody); + } +} From 7c178114e9e92a1dc86ef65ea46cc2d430c733f8 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Fri, 26 Sep 2025 17:28:38 +0900 Subject: [PATCH 02/27] feat: add finishSchedule functionality to manage schedule completion - Introduced finishSchedule method in ScheduleRemoteDataSource and its implementation in ScheduleRepositoryImpl to handle finishing schedules with a lateness time. - Added FinishScheduleUseCase to encapsulate the logic for finishing a schedule, enhancing the architecture and separation of concerns. - Updated Endpoint class to include a new endpoint for finishing schedules. --- lib/core/constants/endpoint.dart | 1 + .../schedule_remote_data_source.dart | 22 +++++++++++++++++++ .../schedule_repository_impl.dart | 9 ++++++++ .../repositories/schedule_repository.dart | 3 +++ .../use-cases/finish_schedule_use_case.dart | 13 +++++++++++ 5 files changed, 48 insertions(+) create mode 100644 lib/domain/use-cases/finish_schedule_use_case.dart diff --git a/lib/core/constants/endpoint.dart b/lib/core/constants/endpoint.dart index acf590d4..55f5efce 100644 --- a/lib/core/constants/endpoint.dart +++ b/lib/core/constants/endpoint.dart @@ -23,6 +23,7 @@ class Endpoint { static get createSchedule => _schedules; static updateSchedule(String scheduleId) => '$_schedules/$scheduleId'; static deleteScheduleById(String scheduleId) => '$_schedules/$scheduleId'; + static finishSchedule(String scheduleId) => '$_schedules/$scheduleId/finish'; // preparation static const _createDefaultPreparation = diff --git a/lib/data/data_sources/schedule_remote_data_source.dart b/lib/data/data_sources/schedule_remote_data_source.dart index db57f325..d854f9e4 100644 --- a/lib/data/data_sources/schedule_remote_data_source.dart +++ b/lib/data/data_sources/schedule_remote_data_source.dart @@ -19,6 +19,8 @@ abstract interface class ScheduleRemoteDataSource { Future updateSchedule(ScheduleEntity schedule); Future deleteSchedule(ScheduleEntity schedule); + + Future finishSchedule(String scheduleId, int latenessTime); } @Injectable(as: ScheduleRemoteDataSource) @@ -74,6 +76,26 @@ class ScheduleRemoteDataSourceImpl implements ScheduleRemoteDataSource { } } + @override + Future finishSchedule(String scheduleId, int latenessTime) async { + try { + final result = await dio.post( + Endpoint.finishSchedule(scheduleId), + data: { + 'scheduleId': scheduleId, + 'latenessTime': latenessTime, + }, + ); + if (result.statusCode == 200) { + return; + } else { + throw Exception('Error finishing schedule'); + } + } catch (e) { + rethrow; + } + } + @override Future getScheduleById(String id) async { try { diff --git a/lib/data/repositories/schedule_repository_impl.dart b/lib/data/repositories/schedule_repository_impl.dart index 6e529b3c..79f9c3dc 100644 --- a/lib/data/repositories/schedule_repository_impl.dart +++ b/lib/data/repositories/schedule_repository_impl.dart @@ -89,4 +89,13 @@ class ScheduleRepositoryImpl implements ScheduleRepository { rethrow; } } + + @override + Future finishSchedule(String scheduleId, int latenessTime) async { + try { + await scheduleRemoteDataSource.finishSchedule(scheduleId, latenessTime); + } catch (e) { + rethrow; + } + } } diff --git a/lib/domain/repositories/schedule_repository.dart b/lib/domain/repositories/schedule_repository.dart index ae41d408..65dbf351 100644 --- a/lib/domain/repositories/schedule_repository.dart +++ b/lib/domain/repositories/schedule_repository.dart @@ -24,4 +24,7 @@ abstract interface class ScheduleRepository { /// Delete a schedule /// This is for deleting a schedule Future deleteSchedule(ScheduleEntity schedule); + + /// Finish a schedule with lateness time + Future finishSchedule(String scheduleId, int latenessTime); } diff --git a/lib/domain/use-cases/finish_schedule_use_case.dart b/lib/domain/use-cases/finish_schedule_use_case.dart new file mode 100644 index 00000000..e96c49e1 --- /dev/null +++ b/lib/domain/use-cases/finish_schedule_use_case.dart @@ -0,0 +1,13 @@ +import 'package:injectable/injectable.dart'; +import 'package:on_time_front/domain/repositories/schedule_repository.dart'; + +@Injectable() +class FinishScheduleUseCase { + final ScheduleRepository _scheduleRepository; + + FinishScheduleUseCase(this._scheduleRepository); + + Future call(String scheduleId, int latenessTime) async { + await _scheduleRepository.finishSchedule(scheduleId, latenessTime); + } +} From 87ceaa21979fe2bbcc93cff0a1bb160353ae3e56 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Fri, 26 Sep 2025 17:28:45 +0900 Subject: [PATCH 03/27] feat: implement ScheduleFinished event to handle schedule completion - Added ScheduleFinished event to trigger the completion of a schedule with a lateness time. - Updated ScheduleBloc to process the ScheduleFinished event, integrating the new FinishScheduleUseCase for managing schedule finalization. - Enhanced AlarmScreen to calculate and dispatch lateness minutes upon preparation completion, improving user feedback on schedule adherence. --- .../alarm/screens/alarm_screen.dart | 3 +++ .../app/bloc/schedule/schedule_bloc.dart | 20 ++++++++++++++++++- .../app/bloc/schedule/schedule_event.dart | 9 +++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/presentation/alarm/screens/alarm_screen.dart b/lib/presentation/alarm/screens/alarm_screen.dart index 7daa04b0..ea487eac 100644 --- a/lib/presentation/alarm/screens/alarm_screen.dart +++ b/lib/presentation/alarm/screens/alarm_screen.dart @@ -19,6 +19,9 @@ class _AlarmScreenState extends State { bool _hasShownCompletionDialog = false; void _onPreparationFinished( BuildContext context, Duration timeRemainingBeforeLeaving, bool isLate) { + final latenessMinutes = + isLate ? (timeRemainingBeforeLeaving.inMinutes.abs()) : 0; + context.read().add(ScheduleFinished(latenessMinutes)); context.go( '/earlyLate', extra: { diff --git a/lib/presentation/app/bloc/schedule/schedule_bloc.dart b/lib/presentation/app/bloc/schedule/schedule_bloc.dart index 6ad49815..a573d0b6 100644 --- a/lib/presentation/app/bloc/schedule/schedule_bloc.dart +++ b/lib/presentation/app/bloc/schedule/schedule_bloc.dart @@ -8,6 +8,7 @@ import 'package:on_time_front/core/services/navigation_service.dart'; import 'package:on_time_front/domain/entities/schedule_with_preparation_entity.dart'; import 'package:on_time_front/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart'; import 'package:on_time_front/domain/use-cases/save_timed_preparation_use_case.dart'; +import 'package:on_time_front/domain/use-cases/finish_schedule_use_case.dart'; part 'schedule_event.dart'; part 'schedule_state.dart'; @@ -15,18 +16,20 @@ part 'schedule_state.dart'; @Singleton() class ScheduleBloc extends Bloc { ScheduleBloc(this._getNearestUpcomingScheduleUseCase, this._navigationService, - this._saveTimedPreparationUseCase) + this._saveTimedPreparationUseCase, this._finishScheduleUseCase) : super(const ScheduleState.initial()) { on(_onSubscriptionRequested); on(_onUpcomingReceived); on(_onScheduleStarted); on(_onTick); on(_onStepSkipped); + on(_onFinished); } final GetNearestUpcomingScheduleUseCase _getNearestUpcomingScheduleUseCase; final NavigationService _navigationService; final SaveTimedPreparationUseCase _saveTimedPreparationUseCase; + final FinishScheduleUseCase _finishScheduleUseCase; StreamSubscription? _upcomingScheduleSubscription; Timer? _scheduleStartTimer; @@ -105,6 +108,21 @@ class ScheduleBloc extends Bloc { await _saveTimedPreparationUseCase(state.schedule!.id, updated); } + Future _onFinished( + ScheduleFinished event, Emitter emit) async { + if (state.schedule == null) return; + final scheduleId = state.schedule!.id; + try { + await _finishScheduleUseCase(scheduleId, event.latenessTime); + // After finishing, clear timers and set state to notExists + _preparationTimer?.cancel(); + _scheduleStartTimer?.cancel(); + emit(const ScheduleState.notExists()); + } catch (_) { + // Keep current state on error; optionally handle error UI elsewhere + } + } + void _startScheduleTimer(ScheduleWithPreparationEntity schedule) { final duration = state.durationUntilPreparationStart; if (duration == null) return; diff --git a/lib/presentation/app/bloc/schedule/schedule_event.dart b/lib/presentation/app/bloc/schedule/schedule_event.dart index dabf9130..3b66d98c 100644 --- a/lib/presentation/app/bloc/schedule/schedule_event.dart +++ b/lib/presentation/app/bloc/schedule/schedule_event.dart @@ -51,3 +51,12 @@ final class ScheduleTick extends ScheduleEvent { final class ScheduleStepSkipped extends ScheduleEvent { const ScheduleStepSkipped(); } + +final class ScheduleFinished extends ScheduleEvent { + final int latenessTime; + + const ScheduleFinished(this.latenessTime); + + @override + List get props => [latenessTime]; +} From 3d50539fd7fdde4e1b3d4d7d709e91be44d957b8 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Fri, 26 Sep 2025 18:45:59 +0900 Subject: [PATCH 04/27] feat: add doneStatus to schedule models for completion tracking - Introduced doneStatus property in GetScheduleResponseModel and ScheduleEntity to track the completion status of schedules. - Implemented _mapDoneStatus function to map server values to ScheduleDoneStatus enum, enhancing status management. - Default value for doneStatus is set to 'NOT_ENDED' in GetScheduleResponseModel and ScheduleEntity, improving initial state handling. --- .../models/get_schedule_response_model.dart | 17 +++++++++++++++++ lib/domain/entities/schedule_entity.dart | 11 +++++++++++ 2 files changed, 28 insertions(+) diff --git a/lib/data/models/get_schedule_response_model.dart b/lib/data/models/get_schedule_response_model.dart index f75c637c..33647443 100644 --- a/lib/data/models/get_schedule_response_model.dart +++ b/lib/data/models/get_schedule_response_model.dart @@ -14,6 +14,7 @@ class GetScheduleResponseModel { final int scheduleSpareTime; final String scheduleNote; final int? latenessTime; + final String? doneStatus; const GetScheduleResponseModel({ required this.scheduleId, @@ -24,6 +25,7 @@ class GetScheduleResponseModel { required this.scheduleSpareTime, required this.scheduleNote, this.latenessTime = 0, + this.doneStatus = 'NOT_ENDED', }); ScheduleEntity toEntity() { @@ -38,6 +40,7 @@ class GetScheduleResponseModel { scheduleSpareTime: Duration(minutes: scheduleSpareTime), scheduleNote: scheduleNote, latenessTime: latenessTime ?? -1, + doneStatus: _mapDoneStatus(doneStatus), ); } @@ -46,3 +49,17 @@ class GetScheduleResponseModel { Map toJson() => _$GetScheduleResponseModelToJson(this); } + +ScheduleDoneStatus _mapDoneStatus(String? serverValue) { + switch (serverValue) { + case 'LATE': + return ScheduleDoneStatus.lateEnd; + case 'NORMAL': + return ScheduleDoneStatus.normalEnd; + case 'ABNORMAL': + return ScheduleDoneStatus.abnormalEnd; + case 'NOT_ENDED': + default: + return ScheduleDoneStatus.notEnded; + } +} diff --git a/lib/domain/entities/schedule_entity.dart b/lib/domain/entities/schedule_entity.dart index 31efac81..079841c2 100644 --- a/lib/domain/entities/schedule_entity.dart +++ b/lib/domain/entities/schedule_entity.dart @@ -15,6 +15,7 @@ class ScheduleEntity extends Equatable { final Duration? scheduleSpareTime; final String scheduleNote; final int latenessTime; + final ScheduleDoneStatus doneStatus; const ScheduleEntity({ required this.id, @@ -27,6 +28,7 @@ class ScheduleEntity extends Equatable { required this.scheduleSpareTime, required this.scheduleNote, this.latenessTime = 0, + this.doneStatus = ScheduleDoneStatus.notEnded, }); static ScheduleEntity fromScheduleWithPlaceModel( @@ -44,6 +46,7 @@ class ScheduleEntity extends Equatable { scheduleSpareTime: schedule.scheduleSpareTime, scheduleNote: schedule.scheduleNote ?? '', latenessTime: schedule.latenessTime, + doneStatus: ScheduleDoneStatus.notEnded, ); } @@ -98,5 +101,13 @@ class ScheduleEntity extends Equatable { scheduleSpareTime, scheduleNote, latenessTime, + doneStatus, ]; } + +enum ScheduleDoneStatus { + lateEnd, // LATE // 지각종료 + normalEnd, // NORMAL // 지각 안 한 종료 + abnormalEnd, // ABNORMAL // 비정상종료 + notEnded, // NOT_ENDED +} From 72c5a4f5f671f4b82824963b2cdcdc6a42fd08e4 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Wed, 29 Oct 2025 12:41:31 +0900 Subject: [PATCH 05/27] fix: remove unnecessary elapsedTime assignment in PreparationWithTimeEntity - Eliminated the assignment of elapsedTime from the current preparation step, streamlining the state management logic. - This change enhances the clarity and efficiency of the preparation handling within the entity. --- lib/domain/entities/preparation_with_time_entity.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/domain/entities/preparation_with_time_entity.dart b/lib/domain/entities/preparation_with_time_entity.dart index 3ca4e80b..96329ecb 100644 --- a/lib/domain/entities/preparation_with_time_entity.dart +++ b/lib/domain/entities/preparation_with_time_entity.dart @@ -171,7 +171,6 @@ class PreparationWithTimeEntity extends PreparationEntity implements Equatable { } final updatedCurrentStep = current.copyWith( - elapsedTime: current.preparationTime, isDone: true, ); return copyWith( From 6def5cc9845eb207e70853f7f8339d85c34c93f4 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Wed, 5 Nov 2025 16:49:31 +0900 Subject: [PATCH 06/27] fix: update finishSchedule method to use PUT request for schedule completion - Changed the HTTP method from POST to PUT in the finishSchedule implementation to align with RESTful conventions for updating resources. - This adjustment ensures proper handling of schedule completion requests, enhancing the API interaction. --- lib/data/data_sources/schedule_remote_data_source.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/data/data_sources/schedule_remote_data_source.dart b/lib/data/data_sources/schedule_remote_data_source.dart index d854f9e4..b828009e 100644 --- a/lib/data/data_sources/schedule_remote_data_source.dart +++ b/lib/data/data_sources/schedule_remote_data_source.dart @@ -79,7 +79,7 @@ class ScheduleRemoteDataSourceImpl implements ScheduleRemoteDataSource { @override Future finishSchedule(String scheduleId, int latenessTime) async { try { - final result = await dio.post( + final result = await dio.put( Endpoint.finishSchedule(scheduleId), data: { 'scheduleId': scheduleId, From e64381ddcb874a1c407489b3c2c005e308133c36 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Wed, 5 Nov 2025 16:52:38 +0900 Subject: [PATCH 07/27] feat: enhance AlarmScreen navigation and state management for preparation completion - Introduced navigation logic in AlarmScreen to handle transitions after preparation completion, improving user experience. - Added state variables to manage pending early/late status and reset navigation state effectively. - Refactored the build method to utilize BlocListener for handling schedule state changes, ensuring timely navigation to the early/late screen. - Improved the preparation completion dialog handling to provide better feedback upon finishing preparation steps. --- .../alarm/screens/alarm_screen.dart | 103 +++++++++++------- .../app/bloc/schedule/schedule_bloc.dart | 2 +- 2 files changed, 66 insertions(+), 39 deletions(-) diff --git a/lib/presentation/alarm/screens/alarm_screen.dart b/lib/presentation/alarm/screens/alarm_screen.dart index ea487eac..67d9b379 100644 --- a/lib/presentation/alarm/screens/alarm_screen.dart +++ b/lib/presentation/alarm/screens/alarm_screen.dart @@ -17,18 +17,24 @@ class AlarmScreen extends StatefulWidget { class _AlarmScreenState extends State { bool _hasShownCompletionDialog = false; + bool _navigateAfterFinish = false; + int? _pendingEarlyLateSeconds; + bool? _pendingIsLate; + + void _resetFinishNavigation() { + _navigateAfterFinish = false; + _pendingEarlyLateSeconds = null; + _pendingIsLate = null; + } + void _onPreparationFinished( BuildContext context, Duration timeRemainingBeforeLeaving, bool isLate) { final latenessMinutes = isLate ? (timeRemainingBeforeLeaving.inMinutes.abs()) : 0; + _pendingEarlyLateSeconds = timeRemainingBeforeLeaving.inSeconds; + _pendingIsLate = isLate; + _navigateAfterFinish = true; context.read().add(ScheduleFinished(latenessMinutes)); - context.go( - '/earlyLate', - extra: { - 'earlyLateTime': timeRemainingBeforeLeaving.inSeconds, - 'isLate': isLate, - }, - ); } @override @@ -43,40 +49,61 @@ class _AlarmScreenState extends State { @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, scheduleState) { - if (scheduleState.status == ScheduleStatus.ongoing || - scheduleState.status == ScheduleStatus.started) { - final schedule = scheduleState.schedule!; - final preparation = schedule.preparation; - - if (preparation.isAllStepsDone && !_hasShownCompletionDialog) { - _hasShownCompletionDialog = true; - WidgetsBinding.instance.addPostFrameCallback((_) { - if (!mounted) return; - showPreparationCompletionDialog( - context: context, - onFinish: () { - _onPreparationFinished( - context, - schedule.timeRemainingBeforeLeaving, - schedule.isLate, - ); - }, - ); - }); - } - - return _buildAlarmScreen( - schedule: schedule, - ); - } else { - return const Scaffold( - backgroundColor: Color(0xff5C79FB), - body: Center(child: CircularProgressIndicator()), + return BlocListener( + listenWhen: (previous, current) { + return _navigateAfterFinish && + previous.status != ScheduleStatus.notExists && + current.status == ScheduleStatus.notExists; + }, + listener: (context, scheduleState) { + final earlyLateSeconds = _pendingEarlyLateSeconds; + final isLate = _pendingIsLate; + _resetFinishNavigation(); + if (earlyLateSeconds != null && isLate != null) { + context.go( + '/earlyLate', + extra: { + 'earlyLateTime': earlyLateSeconds, + 'isLate': isLate, + }, ); } }, + child: BlocBuilder( + builder: (context, scheduleState) { + if (scheduleState.status == ScheduleStatus.ongoing || + scheduleState.status == ScheduleStatus.started) { + final schedule = scheduleState.schedule!; + final preparation = schedule.preparation; + + if (preparation.isAllStepsDone && !_hasShownCompletionDialog) { + _hasShownCompletionDialog = true; + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; + showPreparationCompletionDialog( + context: context, + onFinish: () { + _onPreparationFinished( + context, + schedule.timeRemainingBeforeLeaving, + schedule.isLate, + ); + }, + ); + }); + } + + return _buildAlarmScreen( + schedule: schedule, + ); + } else { + return const Scaffold( + backgroundColor: Color(0xff5C79FB), + body: Center(child: CircularProgressIndicator()), + ); + } + }, + ), ); } diff --git a/lib/presentation/app/bloc/schedule/schedule_bloc.dart b/lib/presentation/app/bloc/schedule/schedule_bloc.dart index a573d0b6..0475c84c 100644 --- a/lib/presentation/app/bloc/schedule/schedule_bloc.dart +++ b/lib/presentation/app/bloc/schedule/schedule_bloc.dart @@ -119,7 +119,7 @@ class ScheduleBloc extends Bloc { _scheduleStartTimer?.cancel(); emit(const ScheduleState.notExists()); } catch (_) { - // Keep current state on error; optionally handle error UI elsewhere + debugPrint('error finishing schedule: $_'); } } From e71d9fd9d14c5ef5c071f7286d0d5decf9898428 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Fri, 21 Nov 2025 12:51:51 +0900 Subject: [PATCH 08/27] feat: conditionally display edit action in schedule detail based on status - Added logic to determine if the edit action should be displayed based on the schedule's doneStatus and scheduleTime. - This enhancement improves user interaction by preventing edits on completed schedules or those that are past their scheduled time. --- .../calendar/component/schedule_detail.dart | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/presentation/calendar/component/schedule_detail.dart b/lib/presentation/calendar/component/schedule_detail.dart index ad6f4770..53c718d6 100644 --- a/lib/presentation/calendar/component/schedule_detail.dart +++ b/lib/presentation/calendar/component/schedule_detail.dart @@ -75,6 +75,8 @@ class _ScheduleDetailState extends State { List _buildSwipeActions(BuildContext context) { final theme = Theme.of(context); + final canEdit = widget.schedule.doneStatus == ScheduleDoneStatus.notEnded && + !widget.schedule.scheduleTime.isBefore(DateTime.now()); return [ SwipeAction( onTap: (controller) => widget.onDeleted?.call(), @@ -84,15 +86,16 @@ class _ScheduleDetailState extends State { color: theme.colorScheme.error, ), ), - SwipeAction( - widthSpace: 96, - onTap: (controller) => widget.onEdit?.call(), - color: Colors.transparent, - content: _SwipeActionContent( - icon: const _EditPencilSvg(), - color: theme.colorScheme.outline, + if (canEdit) + SwipeAction( + widthSpace: 96, + onTap: (controller) => widget.onEdit?.call(), + color: Colors.transparent, + content: _SwipeActionContent( + icon: const _EditPencilSvg(), + color: theme.colorScheme.outline, + ), ), - ), ]; } From 8b37cc4703ec1f936d75b67ae4cdb232243ae6f6 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Fri, 21 Nov 2025 12:52:13 +0900 Subject: [PATCH 09/27] feat: add coverage reports and assets for improved testing visibility --- coverage/html/amber.png | Bin 0 -> 141 bytes coverage/html/cmd_line | 1 + .../core/constants/endpoint.dart.gcov.html | 130 + coverage/html/core/constants/index.html | 98 + .../core/database/database.dart.gcov.html | 143 + .../core/database/database.g.dart.gcov.html | 3526 +++++++++++++ coverage/html/core/database/index-sort-f.html | 125 + coverage/html/core/database/index-sort-l.html | 125 + coverage/html/core/database/index.html | 125 + .../core/database/riverpod.dart.gcov.html | 86 + .../core/database/riverpod.g.dart.gcov.html | 102 + coverage/html/core/di/di_setup.dart.gcov.html | 88 + coverage/html/core/di/index.html | 98 + coverage/html/core/dio/adapters/index.html | 98 + .../adapters/mobile_adapter.dart.gcov.html | 82 + coverage/html/core/dio/app_dio.dart.gcov.html | 105 + coverage/html/core/dio/index.html | 98 + .../core/dio/interceptors/index-sort-f.html | 107 + .../core/dio/interceptors/index-sort-l.html | 107 + .../html/core/dio/interceptors/index.html | 107 + .../logger_interceptor.dart.gcov.html | 119 + .../token_interceptor.dart.gcov.html | 206 + .../html/core/dio/transformers/index.html | 98 + .../logging_transformer.dart.gcov.html | 104 + coverage/html/core/services/index.html | 98 + .../navigation_service.dart.gcov.html | 88 + .../duration_json_converters.dart.gcov.html | 92 + .../core/utils/json_converters/index.html | 98 + coverage/html/data/daos/index-sort-f.html | 179 + coverage/html/data/daos/index-sort-l.html | 179 + coverage/html/data/daos/index.html | 179 + .../html/data/daos/place_dao.dart.gcov.html | 99 + .../html/data/daos/place_dao.g.dart.gcov.html | 84 + .../preparation_schedule_dao.dart.gcov.html | 214 + .../preparation_schedule_dao.g.dart.gcov.html | 88 + .../daos/preparation_user_dao.dart.gcov.html | 206 + .../preparation_user_dao.g.dart.gcov.html | 86 + .../data/daos/schedule_dao.dart.gcov.html | 171 + .../data/daos/schedule_dao.g.dart.gcov.html | 85 + .../html/data/daos/user_dao.dart.gcov.html | 109 + .../html/data/daos/user_dao.g.dart.gcov.html | 84 + ...tication_remote_data_source.dart.gcov.html | 209 + .../html/data/data_sources/index-sort-f.html | 161 + .../html/data/data_sources/index-sort-l.html | 161 + coverage/html/data/data_sources/index.html | 161 + ...fication_remote_data_source.dart.gcov.html | 107 + ...eparation_local_data_source.dart.gcov.html | 166 + ...paration_remote_data_source.dart.gcov.html | 233 + ...with_time_local_data_source.dart.gcov.html | 149 + .../schedule_local_data_source.dart.gcov.html | 136 + ...schedule_remote_data_source.dart.gcov.html | 213 + .../token_local_data_source.dart.gcov.html | 126 + ...t_preparation_request_model.dart.gcov.html | 114 + ...preparation_request_model.g.dart.gcov.html | 102 + ...tion_schedule_request_model.dart.gcov.html | 137 + ...on_schedule_request_model.g.dart.gcov.html | 102 + ...paration_step_request_model.dart.gcov.html | 122 + ...ration_step_request_model.g.dart.gcov.html | 101 + ...eate_schedule_request_model.dart.gcov.html | 127 + ...te_schedule_request_model.g.dart.gcov.html | 113 + ...oken_register_request_model.dart.gcov.html | 92 + ...en_register_request_model.g.dart.gcov.html | 95 + .../get_place_response_model.dart.gcov.html | 110 + .../get_place_response_model.g.dart.gcov.html | 97 + ...aration_step_response_model.dart.gcov.html | 130 + ...ation_step_response_model.g.dart.gcov.html | 101 + ...get_schedule_response_model.dart.gcov.html | 141 + ...t_schedule_response_model.g.dart.gcov.html | 112 + .../get_user_response_model.dart.gcov.html | 118 + .../get_user_response_model.g.dart.gcov.html | 107 + coverage/html/data/models/index-sort-f.html | 359 ++ coverage/html/data/models/index-sort-l.html | 359 ++ coverage/html/data/models/index.html | 359 ++ ...sign_in_user_response_model.dart.gcov.html | 118 + ...gn_in_user_response_model.g.dart.gcov.html | 107 + ...in_with_apple_request_model.dart.gcov.html | 106 + ..._with_apple_request_model.g.dart.gcov.html | 101 + ...n_with_google_request_model.dart.gcov.html | 95 + ...with_google_request_model.g.dart.gcov.html | 95 + ...tion_schedule_request_model.dart.gcov.html | 137 + ...on_schedule_request_model.g.dart.gcov.html | 102 + ...paration_user_request_model.dart.gcov.html | 136 + ...ration_user_request_model.g.dart.gcov.html | 101 + ...date_schedule_request_model.dart.gcov.html | 124 + ...te_schedule_request_model.g.dart.gcov.html | 111 + .../html/data/repositories/index-sort-f.html | 125 + .../html/data/repositories/index-sort-l.html | 125 + coverage/html/data/repositories/index.html | 125 + ...preparation_repository_impl.dart.gcov.html | 170 + .../schedule_repository_impl.dart.gcov.html | 177 + ...preparation_repository_impl.dart.gcov.html | 103 + .../user_repository_impl.dart.gcov.html | 203 + coverage/html/data/tables/index-sort-f.html | 143 + coverage/html/data/tables/index-sort-l.html | 143 + coverage/html/data/tables/index.html | 143 + .../data/tables/places_table.dart.gcov.html | 86 + .../preparation_schedule_table.dart.gcov.html | 91 + .../preparation_user_table.dart.gcov.html | 91 + .../schedule_with_place_model.dart.gcov.html | 95 + .../tables/schedules_table.dart.gcov.html | 97 + .../data/tables/user_table.dart.gcov.html | 90 + .../html/domain/entities/index-sort-f.html | 170 + .../html/domain/entities/index-sort-l.html | 170 + coverage/html/domain/entities/index.html | 170 + .../entities/place_entity.dart.gcov.html | 101 + .../preparation_entity.dart.gcov.html | 101 + .../preparation_step_entity.dart.gcov.html | 135 + ...ation_step_with_time_entity.dart.gcov.html | 134 + ...reparation_with_time_entity.dart.gcov.html | 267 + .../entities/schedule_entity.dart.gcov.html | 189 + ...ule_with_preparation_entity.dart.gcov.html | 147 + .../entities/token_entity.dart.gcov.html | 98 + .../entities/user_entity.dart.gcov.html | 121 + ...custom_preparation_use_case.dart.gcov.html | 92 + ...chedule_with_place_use_case.dart.gcov.html | 90 + .../delete_schedule_use_case.dart.gcov.html | 90 + .../finish_schedule_use_case.dart.gcov.html | 89 + ...efault_preparation_use_case.dart.gcov.html | 90 + ..._upcoming_schedule_use_case.dart.gcov.html | 133 + ...ion_by_schedule_id_use_case.dart.gcov.html | 90 + ...get_schedule_by_id_use_case.dart.gcov.html | 90 + ..._schedules_by_date_use_case.dart.gcov.html | 101 + .../html/domain/use-cases/index-sort-f.html | 260 + .../html/domain/use-cases/index-sort-l.html | 260 + coverage/html/domain/use-cases/index.html | 260 + ...chedules_for_month_use_case.dart.gcov.html | 92 + ...schedules_for_week_use_case.dart.gcov.html | 91 + .../load_user_use_case.dart.gcov.html | 89 + .../use-cases/onboard_use_case.dart.gcov.html | 97 + ..._timed_preparation_use_case.dart.gcov.html | 91 + .../sign_out_use_case.dart.gcov.html | 89 + .../stream_user_use_case.dart.gcov.html | 90 + ...efault_preparation_use_case.dart.gcov.html | 90 + ...ion_by_schedule_id_use_case.dart.gcov.html | 92 + .../update_schedule_use_case.dart.gcov.html | 90 + coverage/html/emerald.png | Bin 0 -> 141 bytes coverage/html/gcov.css | 1125 +++++ coverage/html/glass.png | Bin 0 -> 167 bytes coverage/html/index-sort-f.html | 350 ++ coverage/html/index-sort-l.html | 350 ++ coverage/html/index.html | 350 ++ .../app/bloc/auth/auth_bloc.dart.gcov.html | 146 + .../app/bloc/auth/auth_event.dart.gcov.html | 89 + .../app/bloc/auth/auth_state.dart.gcov.html | 117 + .../app/bloc/auth/index-sort-f.html | 116 + .../app/bloc/auth/index-sort-l.html | 116 + .../presentation/app/bloc/auth/index.html | 116 + .../app/bloc/schedule/index-sort-f.html | 116 + .../app/bloc/schedule/index-sort-l.html | 116 + .../presentation/app/bloc/schedule/index.html | 116 + .../schedule/schedule_bloc.dart.gcov.html | 242 + .../schedule/schedule_event.dart.gcov.html | 138 + .../schedule/schedule_state.dart.gcov.html | 129 + .../calendar/bloc/index-sort-f.html | 116 + .../calendar/bloc/index-sort-l.html | 116 + .../presentation/calendar/bloc/index.html | 116 + .../monthly_schedules_bloc.dart.gcov.html | 230 + .../monthly_schedules_event.dart.gcov.html | 118 + .../monthly_schedules_state.dart.gcov.html | 116 + .../early_late_screen_bloc.dart.gcov.html | 140 + .../early_late_screen_event.dart.gcov.html | 111 + .../early_late_screen_state.dart.gcov.html | 108 + .../early_late/bloc/index-sort-f.html | 116 + .../early_late/bloc/index-sort-l.html | 116 + .../presentation/early_late/bloc/index.html | 116 + .../presentation/home/bloc/index-sort-f.html | 116 + .../presentation/home/bloc/index-sort-l.html | 116 + .../html/presentation/home/bloc/index.html | 116 + .../bloc/weekly_schedules_bloc.dart.gcov.html | 117 + .../weekly_schedules_event.dart.gcov.html | 96 + .../weekly_schedules_state.dart.gcov.html | 115 + ...ration_spare_time_form_bloc.dart.gcov.html | 172 + ...ation_spare_time_form_event.dart.gcov.html | 115 + ...ation_spare_time_form_state.dart.gcov.html | 110 + .../bloc/index-sort-f.html | 116 + .../bloc/index-sort-l.html | 116 + .../bloc/index.html | 116 + .../onboarding/cubit/index-sort-f.html | 107 + .../onboarding/cubit/index-sort-l.html | 107 + .../presentation/onboarding/cubit/index.html | 107 + .../cubit/onboarding_cubit.dart.gcov.html | 115 + .../cubit/onboarding_state.dart.gcov.html | 153 + .../input_models/index.html | 98 + ...reparation_name_input_model.dart.gcov.html | 93 + .../preparation_time/input_models/index.html | 98 + ...reparation_time_input_model.dart.gcov.html | 95 + .../schedule_create/bloc/index-sort-f.html | 116 + .../schedule_create/bloc/index-sort-l.html | 116 + .../schedule_create/bloc/index.html | 116 + .../bloc/schedule_form_bloc.dart.gcov.html | 272 + .../bloc/schedule_form_event.dart.gcov.html | 170 + .../bloc/schedule_form_state.dart.gcov.html | 172 + .../preparation_form/bloc/index-sort-f.html | 116 + .../preparation_form/bloc/index-sort-l.html | 116 + .../preparation_form/bloc/index.html | 116 + .../bloc/preparation_form_bloc.dart.gcov.html | 232 + .../preparation_form_event.dart.gcov.html | 153 + .../preparation_form_state.dart.gcov.html | 153 + .../preparation_form/cubit/index-sort-f.html | 107 + .../preparation_form/cubit/index-sort-l.html | 107 + .../preparation_form/cubit/index.html | 107 + ...preparation_step_form_cubit.dart.gcov.html | 111 + ...preparation_step_form_state.dart.gcov.html | 108 + .../early_late_text_images.dart.gcov.html | 184 + .../presentation/shared/constants/index.html | 98 + coverage/html/ruby.png | Bin 0 -> 141 bytes coverage/html/snow.png | Bin 0 -> 141 bytes coverage/html/updown.png | Bin 0 -> 117 bytes coverage/lcov.info | 4368 +++++++++++++++++ .../Flutter/GeneratedPluginRegistrant.swift | 2 + widgetbook/pubspec.lock | 24 + 211 files changed, 35345 insertions(+) create mode 100644 coverage/html/amber.png create mode 100644 coverage/html/cmd_line create mode 100644 coverage/html/core/constants/endpoint.dart.gcov.html create mode 100644 coverage/html/core/constants/index.html create mode 100644 coverage/html/core/database/database.dart.gcov.html create mode 100644 coverage/html/core/database/database.g.dart.gcov.html create mode 100644 coverage/html/core/database/index-sort-f.html create mode 100644 coverage/html/core/database/index-sort-l.html create mode 100644 coverage/html/core/database/index.html create mode 100644 coverage/html/core/database/riverpod.dart.gcov.html create mode 100644 coverage/html/core/database/riverpod.g.dart.gcov.html create mode 100644 coverage/html/core/di/di_setup.dart.gcov.html create mode 100644 coverage/html/core/di/index.html create mode 100644 coverage/html/core/dio/adapters/index.html create mode 100644 coverage/html/core/dio/adapters/mobile_adapter.dart.gcov.html create mode 100644 coverage/html/core/dio/app_dio.dart.gcov.html create mode 100644 coverage/html/core/dio/index.html create mode 100644 coverage/html/core/dio/interceptors/index-sort-f.html create mode 100644 coverage/html/core/dio/interceptors/index-sort-l.html create mode 100644 coverage/html/core/dio/interceptors/index.html create mode 100644 coverage/html/core/dio/interceptors/logger_interceptor.dart.gcov.html create mode 100644 coverage/html/core/dio/interceptors/token_interceptor.dart.gcov.html create mode 100644 coverage/html/core/dio/transformers/index.html create mode 100644 coverage/html/core/dio/transformers/logging_transformer.dart.gcov.html create mode 100644 coverage/html/core/services/index.html create mode 100644 coverage/html/core/services/navigation_service.dart.gcov.html create mode 100644 coverage/html/core/utils/json_converters/duration_json_converters.dart.gcov.html create mode 100644 coverage/html/core/utils/json_converters/index.html create mode 100644 coverage/html/data/daos/index-sort-f.html create mode 100644 coverage/html/data/daos/index-sort-l.html create mode 100644 coverage/html/data/daos/index.html create mode 100644 coverage/html/data/daos/place_dao.dart.gcov.html create mode 100644 coverage/html/data/daos/place_dao.g.dart.gcov.html create mode 100644 coverage/html/data/daos/preparation_schedule_dao.dart.gcov.html create mode 100644 coverage/html/data/daos/preparation_schedule_dao.g.dart.gcov.html create mode 100644 coverage/html/data/daos/preparation_user_dao.dart.gcov.html create mode 100644 coverage/html/data/daos/preparation_user_dao.g.dart.gcov.html create mode 100644 coverage/html/data/daos/schedule_dao.dart.gcov.html create mode 100644 coverage/html/data/daos/schedule_dao.g.dart.gcov.html create mode 100644 coverage/html/data/daos/user_dao.dart.gcov.html create mode 100644 coverage/html/data/daos/user_dao.g.dart.gcov.html create mode 100644 coverage/html/data/data_sources/authentication_remote_data_source.dart.gcov.html create mode 100644 coverage/html/data/data_sources/index-sort-f.html create mode 100644 coverage/html/data/data_sources/index-sort-l.html create mode 100644 coverage/html/data/data_sources/index.html create mode 100644 coverage/html/data/data_sources/notification_remote_data_source.dart.gcov.html create mode 100644 coverage/html/data/data_sources/preparation_local_data_source.dart.gcov.html create mode 100644 coverage/html/data/data_sources/preparation_remote_data_source.dart.gcov.html create mode 100644 coverage/html/data/data_sources/preparation_with_time_local_data_source.dart.gcov.html create mode 100644 coverage/html/data/data_sources/schedule_local_data_source.dart.gcov.html create mode 100644 coverage/html/data/data_sources/schedule_remote_data_source.dart.gcov.html create mode 100644 coverage/html/data/data_sources/token_local_data_source.dart.gcov.html create mode 100644 coverage/html/data/models/create_defualt_preparation_request_model.dart.gcov.html create mode 100644 coverage/html/data/models/create_defualt_preparation_request_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/create_preparation_schedule_request_model.dart.gcov.html create mode 100644 coverage/html/data/models/create_preparation_schedule_request_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/create_preparation_step_request_model.dart.gcov.html create mode 100644 coverage/html/data/models/create_preparation_step_request_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/create_schedule_request_model.dart.gcov.html create mode 100644 coverage/html/data/models/create_schedule_request_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/fcm_token_register_request_model.dart.gcov.html create mode 100644 coverage/html/data/models/fcm_token_register_request_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/get_place_response_model.dart.gcov.html create mode 100644 coverage/html/data/models/get_place_response_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/get_preparation_step_response_model.dart.gcov.html create mode 100644 coverage/html/data/models/get_preparation_step_response_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/get_schedule_response_model.dart.gcov.html create mode 100644 coverage/html/data/models/get_schedule_response_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/get_user_response_model.dart.gcov.html create mode 100644 coverage/html/data/models/get_user_response_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/index-sort-f.html create mode 100644 coverage/html/data/models/index-sort-l.html create mode 100644 coverage/html/data/models/index.html create mode 100644 coverage/html/data/models/sign_in_user_response_model.dart.gcov.html create mode 100644 coverage/html/data/models/sign_in_user_response_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/sign_in_with_apple_request_model.dart.gcov.html create mode 100644 coverage/html/data/models/sign_in_with_apple_request_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/sign_in_with_google_request_model.dart.gcov.html create mode 100644 coverage/html/data/models/sign_in_with_google_request_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/update_preparation_schedule_request_model.dart.gcov.html create mode 100644 coverage/html/data/models/update_preparation_schedule_request_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/update_preparation_user_request_model.dart.gcov.html create mode 100644 coverage/html/data/models/update_preparation_user_request_model.g.dart.gcov.html create mode 100644 coverage/html/data/models/update_schedule_request_model.dart.gcov.html create mode 100644 coverage/html/data/models/update_schedule_request_model.g.dart.gcov.html create mode 100644 coverage/html/data/repositories/index-sort-f.html create mode 100644 coverage/html/data/repositories/index-sort-l.html create mode 100644 coverage/html/data/repositories/index.html create mode 100644 coverage/html/data/repositories/preparation_repository_impl.dart.gcov.html create mode 100644 coverage/html/data/repositories/schedule_repository_impl.dart.gcov.html create mode 100644 coverage/html/data/repositories/timed_preparation_repository_impl.dart.gcov.html create mode 100644 coverage/html/data/repositories/user_repository_impl.dart.gcov.html create mode 100644 coverage/html/data/tables/index-sort-f.html create mode 100644 coverage/html/data/tables/index-sort-l.html create mode 100644 coverage/html/data/tables/index.html create mode 100644 coverage/html/data/tables/places_table.dart.gcov.html create mode 100644 coverage/html/data/tables/preparation_schedule_table.dart.gcov.html create mode 100644 coverage/html/data/tables/preparation_user_table.dart.gcov.html create mode 100644 coverage/html/data/tables/schedule_with_place_model.dart.gcov.html create mode 100644 coverage/html/data/tables/schedules_table.dart.gcov.html create mode 100644 coverage/html/data/tables/user_table.dart.gcov.html create mode 100644 coverage/html/domain/entities/index-sort-f.html create mode 100644 coverage/html/domain/entities/index-sort-l.html create mode 100644 coverage/html/domain/entities/index.html create mode 100644 coverage/html/domain/entities/place_entity.dart.gcov.html create mode 100644 coverage/html/domain/entities/preparation_entity.dart.gcov.html create mode 100644 coverage/html/domain/entities/preparation_step_entity.dart.gcov.html create mode 100644 coverage/html/domain/entities/preparation_step_with_time_entity.dart.gcov.html create mode 100644 coverage/html/domain/entities/preparation_with_time_entity.dart.gcov.html create mode 100644 coverage/html/domain/entities/schedule_entity.dart.gcov.html create mode 100644 coverage/html/domain/entities/schedule_with_preparation_entity.dart.gcov.html create mode 100644 coverage/html/domain/entities/token_entity.dart.gcov.html create mode 100644 coverage/html/domain/entities/user_entity.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/create_custom_preparation_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/create_schedule_with_place_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/delete_schedule_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/finish_schedule_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/get_default_preparation_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/get_preparation_by_schedule_id_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/get_schedule_by_id_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/get_schedules_by_date_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/index-sort-f.html create mode 100644 coverage/html/domain/use-cases/index-sort-l.html create mode 100644 coverage/html/domain/use-cases/index.html create mode 100644 coverage/html/domain/use-cases/load_schedules_for_month_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/load_schedules_for_week_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/load_user_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/onboard_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/save_timed_preparation_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/sign_out_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/stream_user_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/update_default_preparation_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/update_preparation_by_schedule_id_use_case.dart.gcov.html create mode 100644 coverage/html/domain/use-cases/update_schedule_use_case.dart.gcov.html create mode 100644 coverage/html/emerald.png create mode 100644 coverage/html/gcov.css create mode 100644 coverage/html/glass.png create mode 100644 coverage/html/index-sort-f.html create mode 100644 coverage/html/index-sort-l.html create mode 100644 coverage/html/index.html create mode 100644 coverage/html/presentation/app/bloc/auth/auth_bloc.dart.gcov.html create mode 100644 coverage/html/presentation/app/bloc/auth/auth_event.dart.gcov.html create mode 100644 coverage/html/presentation/app/bloc/auth/auth_state.dart.gcov.html create mode 100644 coverage/html/presentation/app/bloc/auth/index-sort-f.html create mode 100644 coverage/html/presentation/app/bloc/auth/index-sort-l.html create mode 100644 coverage/html/presentation/app/bloc/auth/index.html create mode 100644 coverage/html/presentation/app/bloc/schedule/index-sort-f.html create mode 100644 coverage/html/presentation/app/bloc/schedule/index-sort-l.html create mode 100644 coverage/html/presentation/app/bloc/schedule/index.html create mode 100644 coverage/html/presentation/app/bloc/schedule/schedule_bloc.dart.gcov.html create mode 100644 coverage/html/presentation/app/bloc/schedule/schedule_event.dart.gcov.html create mode 100644 coverage/html/presentation/app/bloc/schedule/schedule_state.dart.gcov.html create mode 100644 coverage/html/presentation/calendar/bloc/index-sort-f.html create mode 100644 coverage/html/presentation/calendar/bloc/index-sort-l.html create mode 100644 coverage/html/presentation/calendar/bloc/index.html create mode 100644 coverage/html/presentation/calendar/bloc/monthly_schedules_bloc.dart.gcov.html create mode 100644 coverage/html/presentation/calendar/bloc/monthly_schedules_event.dart.gcov.html create mode 100644 coverage/html/presentation/calendar/bloc/monthly_schedules_state.dart.gcov.html create mode 100644 coverage/html/presentation/early_late/bloc/early_late_screen_bloc.dart.gcov.html create mode 100644 coverage/html/presentation/early_late/bloc/early_late_screen_event.dart.gcov.html create mode 100644 coverage/html/presentation/early_late/bloc/early_late_screen_state.dart.gcov.html create mode 100644 coverage/html/presentation/early_late/bloc/index-sort-f.html create mode 100644 coverage/html/presentation/early_late/bloc/index-sort-l.html create mode 100644 coverage/html/presentation/early_late/bloc/index.html create mode 100644 coverage/html/presentation/home/bloc/index-sort-f.html create mode 100644 coverage/html/presentation/home/bloc/index-sort-l.html create mode 100644 coverage/html/presentation/home/bloc/index.html create mode 100644 coverage/html/presentation/home/bloc/weekly_schedules_bloc.dart.gcov.html create mode 100644 coverage/html/presentation/home/bloc/weekly_schedules_event.dart.gcov.html create mode 100644 coverage/html/presentation/home/bloc/weekly_schedules_state.dart.gcov.html create mode 100644 coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_bloc.dart.gcov.html create mode 100644 coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_event.dart.gcov.html create mode 100644 coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_state.dart.gcov.html create mode 100644 coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index-sort-f.html create mode 100644 coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index-sort-l.html create mode 100644 coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index.html create mode 100644 coverage/html/presentation/onboarding/cubit/index-sort-f.html create mode 100644 coverage/html/presentation/onboarding/cubit/index-sort-l.html create mode 100644 coverage/html/presentation/onboarding/cubit/index.html create mode 100644 coverage/html/presentation/onboarding/cubit/onboarding_cubit.dart.gcov.html create mode 100644 coverage/html/presentation/onboarding/cubit/onboarding_state.dart.gcov.html create mode 100644 coverage/html/presentation/onboarding/preparation_name_select/input_models/index.html create mode 100644 coverage/html/presentation/onboarding/preparation_name_select/input_models/preparation_name_input_model.dart.gcov.html create mode 100644 coverage/html/presentation/onboarding/preparation_time/input_models/index.html create mode 100644 coverage/html/presentation/onboarding/preparation_time/input_models/preparation_time_input_model.dart.gcov.html create mode 100644 coverage/html/presentation/schedule_create/bloc/index-sort-f.html create mode 100644 coverage/html/presentation/schedule_create/bloc/index-sort-l.html create mode 100644 coverage/html/presentation/schedule_create/bloc/index.html create mode 100644 coverage/html/presentation/schedule_create/bloc/schedule_form_bloc.dart.gcov.html create mode 100644 coverage/html/presentation/schedule_create/bloc/schedule_form_event.dart.gcov.html create mode 100644 coverage/html/presentation/schedule_create/bloc/schedule_form_state.dart.gcov.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index-sort-f.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index-sort-l.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart.gcov.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_event.dart.gcov.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_state.dart.gcov.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index-sort-f.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index-sort-l.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart.gcov.html create mode 100644 coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_state.dart.gcov.html create mode 100644 coverage/html/presentation/shared/constants/early_late_text_images.dart.gcov.html create mode 100644 coverage/html/presentation/shared/constants/index.html create mode 100644 coverage/html/ruby.png create mode 100644 coverage/html/snow.png create mode 100644 coverage/html/updown.png create mode 100644 coverage/lcov.info diff --git a/coverage/html/amber.png b/coverage/html/amber.png new file mode 100644 index 0000000000000000000000000000000000000000..2cab170d8359081983a4e343848dfe06bc490f12 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^G2tW}LqE04T&+ z;1OBOz`!j8!i<;h*8KqrvZOouIx;Y9?C1WI$O`1M1^9%x{(levWG + + + + + + LCOV - lcov.info - core/constants/endpoint.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/constants - endpoint.dartCoverageTotalHit
Test:lcov.infoLines:39.1 %239
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:core';
+       2              : 
+       3              : class Endpoint {
+       4              :   //user
+       5              :   static const _signIn = '/login';
+       6              :   static const _signUp = '/sign-up';
+       7              :   static const _signInWithGoogle = '/oauth2/google/login';
+       8              :   static const _signInWithApple = '/oauth2/apple/login';
+       9              :   static const _getUser = '/users/me';
+      10              : 
+      11            0 :   static get signIn => _signIn;
+      12            0 :   static get signUp => _signUp;
+      13            0 :   static get signInWithGoogle => _signInWithGoogle;
+      14            0 :   static get signInWithApple => _signInWithApple;
+      15            0 :   static get getUser => _getUser;
+      16              : 
+      17              :   // schedule
+      18              :   static const _schedules = '/schedules';
+      19              : 
+      20            0 :   static getScheduleById(String scheduleId) => '$_schedules/$scheduleId';
+      21            0 :   static get getSchedulesByDate => _schedules;
+      22              : 
+      23            1 :   static get createSchedule => _schedules;
+      24            0 :   static updateSchedule(String scheduleId) => '$_schedules/$scheduleId';
+      25            2 :   static deleteScheduleById(String scheduleId) => '$_schedules/$scheduleId';
+      26            0 :   static finishSchedule(String scheduleId) => '$_schedules/$scheduleId/finish';
+      27              : 
+      28              :   // preparation
+      29              :   static const _createDefaultPreparation =
+      30              :       '$_getUser/onboarding'; // 사용자 준비과정 첫 세팅
+      31              : 
+      32              :   static const _defaultPreparation = '/users/preparations'; // 사용자 기본 준비과정 조회
+      33              : 
+      34            1 :   static get createDefaultPreparation => _createDefaultPreparation;
+      35              : 
+      36            1 :   static _prepartionByScheduleId(String scheduleId) =>
+      37            1 :       '$_schedules/$scheduleId/preparations';
+      38              : 
+      39            1 :   static getCreateCustomPreparation(String scheduleId) =>
+      40            1 :       _prepartionByScheduleId(scheduleId);
+      41              : 
+      42            1 :   static getPreparationByScheduleId(String scheduleId) =>
+      43            1 :       _prepartionByScheduleId(scheduleId);
+      44              : 
+      45            0 :   static updatePreparationByScheduleId(String scheduleId) =>
+      46            0 :       _prepartionByScheduleId(scheduleId);
+      47              : 
+      48            0 :   static get getDefaultPreparation => _defaultPreparation;
+      49              : 
+      50            0 :   static get updateDefaultPreparation => _defaultPreparation;
+      51              : 
+      52              :   static const _fcmToken = '/firebase-token'; // 사용자 fcm 토큰 등록
+      53            0 :   static get fcmTokenRegister => _fcmToken;
+      54              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/constants/index.html b/coverage/html/core/constants/index.html new file mode 100644 index 00000000..54ccd511 --- /dev/null +++ b/coverage/html/core/constants/index.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - core/constants + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/constantsCoverageTotalHit
Test:lcov.infoLines:39.1 %239
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
endpoint.dart +
39.1%39.1%
+
39.1 %239
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/database/database.dart.gcov.html b/coverage/html/core/database/database.dart.gcov.html new file mode 100644 index 00000000..f3dcaa1d --- /dev/null +++ b/coverage/html/core/database/database.dart.gcov.html @@ -0,0 +1,143 @@ + + + + + + + LCOV - lcov.info - core/database/database.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/database - database.dartCoverageTotalHit
Test:lcov.infoLines:77.8 %1814
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:drift/drift.dart';
+       2              : import 'package:drift_flutter/drift_flutter.dart';
+       3              : import 'package:injectable/injectable.dart';
+       4              : import 'package:on_time_front/core/utils/json_converters/duration_json_converters.dart';
+       5              : import 'package:on_time_front/data/daos/place_dao.dart';
+       6              : import 'package:on_time_front/data/daos/preparation_schedule_dao.dart';
+       7              : import 'package:on_time_front/data/daos/preparation_user_dao.dart';
+       8              : 
+       9              : import 'package:on_time_front/data/daos/schedule_dao.dart';
+      10              : import 'package:on_time_front/data/daos/user_dao.dart';
+      11              : import 'package:on_time_front/data/tables/places_table.dart';
+      12              : import 'package:on_time_front/data/tables/preparation_schedule_table.dart';
+      13              : import 'package:on_time_front/data/tables/preparation_user_table.dart';
+      14              : import 'package:on_time_front/data/tables/schedules_table.dart';
+      15              : import 'package:on_time_front/data/tables/user_table.dart';
+      16              : import 'package:uuid/uuid.dart';
+      17              : 
+      18              : part 'database.g.dart';
+      19              : 
+      20              : @Singleton()
+      21              : @DriftDatabase(tables: [
+      22              :   Places,
+      23              :   Schedules,
+      24              :   Users,
+      25              :   PreparationSchedules,
+      26              :   PreparationUsers,
+      27              : ], daos: [
+      28              :   ScheduleDao,
+      29              :   PlaceDao,
+      30              :   UserDao,
+      31              :   PreparationScheduleDao,
+      32              :   PreparationUserDao
+      33              : ])
+      34              : class AppDatabase extends _$AppDatabase {
+      35            3 :   AppDatabase() : super(_openConnection());
+      36              : 
+      37            3 :   AppDatabase.forTesting(super.e);
+      38              : 
+      39            3 :   @override
+      40              :   int get schemaVersion => 3;
+      41              : 
+      42            3 :   @override
+      43            3 :   MigrationStrategy get migration => MigrationStrategy(
+      44            3 :         onCreate: (Migrator m) async {
+      45            3 :           await m.createAll();
+      46              :         },
+      47            0 :         onUpgrade: (Migrator m, int from, int to) async {
+      48            0 :           if (from == 1) {
+      49            0 :             await m.createTable(preparationSchedules);
+      50            0 :             await m.createTable(preparationUsers);
+      51              :           }
+      52              :         },
+      53            3 :         beforeOpen: (details) async {
+      54            3 :           await customStatement('PRAGMA foreign_keys = ON');
+      55              :         },
+      56              :       );
+      57              : 
+      58            1 :   static QueryExecutor _openConnection() {
+      59            1 :     return driftDatabase(
+      60              :       name: 'my_database',
+      61            1 :       web: DriftWebOptions(
+      62            1 :         sqlite3Wasm: Uri.parse('sqlite3.wasm'),
+      63            1 :         driftWorker: Uri.parse('drift_worker.dart.js'),
+      64              :       ),
+      65              :     );
+      66              :   }
+      67              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/database/database.g.dart.gcov.html b/coverage/html/core/database/database.g.dart.gcov.html new file mode 100644 index 00000000..84649719 --- /dev/null +++ b/coverage/html/core/database/database.g.dart.gcov.html @@ -0,0 +1,3526 @@ + + + + + + + LCOV - lcov.info - core/database/database.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/database - database.g.dartCoverageTotalHit
Test:lcov.infoLines:24.0 %1601385
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'database.dart';
+       4              : 
+       5              : // ignore_for_file: type=lint
+       6              : class $PlacesTable extends Places with TableInfo<$PlacesTable, Place> {
+       7              :   @override
+       8              :   final GeneratedDatabase attachedDatabase;
+       9              :   final String? _alias;
+      10            3 :   $PlacesTable(this.attachedDatabase, [this._alias]);
+      11              :   static const VerificationMeta _idMeta = const VerificationMeta('id');
+      12              :   @override
+      13            6 :   late final GeneratedColumn<String> id = GeneratedColumn<String>(
+      14            3 :       'id', aliasedName, false,
+      15              :       type: DriftSqlType.string,
+      16              :       requiredDuringInsert: false,
+      17            0 :       clientDefault: () => Uuid().v7());
+      18              :   static const VerificationMeta _placeNameMeta =
+      19              :       const VerificationMeta('placeName');
+      20              :   @override
+      21            6 :   late final GeneratedColumn<String> placeName = GeneratedColumn<String>(
+      22            3 :       'place_name', aliasedName, false,
+      23              :       additionalChecks:
+      24            3 :           GeneratedColumn.checkTextLength(minTextLength: 1, maxTextLength: 30),
+      25              :       type: DriftSqlType.string,
+      26              :       requiredDuringInsert: true);
+      27            3 :   @override
+      28            9 :   List<GeneratedColumn> get $columns => [id, placeName];
+      29            3 :   @override
+      30            6 :   String get aliasedName => _alias ?? actualTableName;
+      31            3 :   @override
+      32              :   String get actualTableName => $name;
+      33              :   static const String $name = 'places';
+      34            2 :   @override
+      35              :   VerificationContext validateIntegrity(Insertable<Place> instance,
+      36              :       {bool isInserting = false}) {
+      37            2 :     final context = VerificationContext();
+      38            2 :     final data = instance.toColumns(true);
+      39            2 :     if (data.containsKey('id')) {
+      40            8 :       context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
+      41              :     }
+      42            2 :     if (data.containsKey('place_name')) {
+      43            2 :       context.handle(_placeNameMeta,
+      44            6 :           placeName.isAcceptableOrUnknown(data['place_name']!, _placeNameMeta));
+      45              :     } else if (isInserting) {
+      46            0 :       context.missing(_placeNameMeta);
+      47              :     }
+      48              :     return context;
+      49              :   }
+      50              : 
+      51            3 :   @override
+      52            3 :   Set<GeneratedColumn> get $primaryKey => {id};
+      53            1 :   @override
+      54              :   Place map(Map<String, dynamic> data, {String? tablePrefix}) {
+      55            1 :     final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
+      56            1 :     return Place(
+      57            2 :       id: attachedDatabase.typeMapping
+      58            3 :           .read(DriftSqlType.string, data['${effectivePrefix}id'])!,
+      59            2 :       placeName: attachedDatabase.typeMapping
+      60            3 :           .read(DriftSqlType.string, data['${effectivePrefix}place_name'])!,
+      61              :     );
+      62              :   }
+      63              : 
+      64            0 :   @override
+      65              :   $PlacesTable createAlias(String alias) {
+      66            0 :     return $PlacesTable(attachedDatabase, alias);
+      67              :   }
+      68              : }
+      69              : 
+      70              : class Place extends DataClass implements Insertable<Place> {
+      71              :   final String id;
+      72              :   final String placeName;
+      73            1 :   const Place({required this.id, required this.placeName});
+      74            0 :   @override
+      75              :   Map<String, Expression> toColumns(bool nullToAbsent) {
+      76            0 :     final map = <String, Expression>{};
+      77            0 :     map['id'] = Variable<String>(id);
+      78            0 :     map['place_name'] = Variable<String>(placeName);
+      79              :     return map;
+      80              :   }
+      81              : 
+      82            1 :   PlacesCompanion toCompanion(bool nullToAbsent) {
+      83            1 :     return PlacesCompanion(
+      84            2 :       id: Value(id),
+      85            2 :       placeName: Value(placeName),
+      86              :     );
+      87              :   }
+      88              : 
+      89            0 :   factory Place.fromJson(Map<String, dynamic> json,
+      90              :       {ValueSerializer? serializer}) {
+      91            0 :     serializer ??= driftRuntimeOptions.defaultSerializer;
+      92            0 :     return Place(
+      93            0 :       id: serializer.fromJson<String>(json['id']),
+      94            0 :       placeName: serializer.fromJson<String>(json['placeName']),
+      95              :     );
+      96              :   }
+      97            0 :   @override
+      98              :   Map<String, dynamic> toJson({ValueSerializer? serializer}) {
+      99            0 :     serializer ??= driftRuntimeOptions.defaultSerializer;
+     100            0 :     return <String, dynamic>{
+     101            0 :       'id': serializer.toJson<String>(id),
+     102            0 :       'placeName': serializer.toJson<String>(placeName),
+     103              :     };
+     104              :   }
+     105              : 
+     106            0 :   Place copyWith({String? id, String? placeName}) => Place(
+     107            0 :         id: id ?? this.id,
+     108            0 :         placeName: placeName ?? this.placeName,
+     109              :       );
+     110            0 :   Place copyWithCompanion(PlacesCompanion data) {
+     111            0 :     return Place(
+     112            0 :       id: data.id.present ? data.id.value : this.id,
+     113            0 :       placeName: data.placeName.present ? data.placeName.value : this.placeName,
+     114              :     );
+     115              :   }
+     116              : 
+     117            0 :   @override
+     118              :   String toString() {
+     119            0 :     return (StringBuffer('Place(')
+     120            0 :           ..write('id: $id, ')
+     121            0 :           ..write('placeName: $placeName')
+     122            0 :           ..write(')'))
+     123            0 :         .toString();
+     124              :   }
+     125              : 
+     126            0 :   @override
+     127            0 :   int get hashCode => Object.hash(id, placeName);
+     128            1 :   @override
+     129              :   bool operator ==(Object other) =>
+     130              :       identical(this, other) ||
+     131            1 :       (other is Place &&
+     132            3 :           other.id == this.id &&
+     133            3 :           other.placeName == this.placeName);
+     134              : }
+     135              : 
+     136              : class PlacesCompanion extends UpdateCompanion<Place> {
+     137              :   final Value<String> id;
+     138              :   final Value<String> placeName;
+     139              :   final Value<int> rowid;
+     140            2 :   const PlacesCompanion({
+     141              :     this.id = const Value.absent(),
+     142              :     this.placeName = const Value.absent(),
+     143              :     this.rowid = const Value.absent(),
+     144              :   });
+     145            0 :   PlacesCompanion.insert({
+     146              :     this.id = const Value.absent(),
+     147              :     required String placeName,
+     148              :     this.rowid = const Value.absent(),
+     149            0 :   }) : placeName = Value(placeName);
+     150            0 :   static Insertable<Place> custom({
+     151              :     Expression<String>? id,
+     152              :     Expression<String>? placeName,
+     153              :     Expression<int>? rowid,
+     154              :   }) {
+     155            0 :     return RawValuesInsertable({
+     156            0 :       if (id != null) 'id': id,
+     157            0 :       if (placeName != null) 'place_name': placeName,
+     158            0 :       if (rowid != null) 'rowid': rowid,
+     159              :     });
+     160              :   }
+     161              : 
+     162            0 :   PlacesCompanion copyWith(
+     163              :       {Value<String>? id, Value<String>? placeName, Value<int>? rowid}) {
+     164            0 :     return PlacesCompanion(
+     165            0 :       id: id ?? this.id,
+     166            0 :       placeName: placeName ?? this.placeName,
+     167            0 :       rowid: rowid ?? this.rowid,
+     168              :     );
+     169              :   }
+     170              : 
+     171            2 :   @override
+     172              :   Map<String, Expression> toColumns(bool nullToAbsent) {
+     173            2 :     final map = <String, Expression>{};
+     174            4 :     if (id.present) {
+     175            8 :       map['id'] = Variable<String>(id.value);
+     176              :     }
+     177            4 :     if (placeName.present) {
+     178            8 :       map['place_name'] = Variable<String>(placeName.value);
+     179              :     }
+     180            4 :     if (rowid.present) {
+     181            0 :       map['rowid'] = Variable<int>(rowid.value);
+     182              :     }
+     183              :     return map;
+     184              :   }
+     185              : 
+     186            0 :   @override
+     187              :   String toString() {
+     188            0 :     return (StringBuffer('PlacesCompanion(')
+     189            0 :           ..write('id: $id, ')
+     190            0 :           ..write('placeName: $placeName, ')
+     191            0 :           ..write('rowid: $rowid')
+     192            0 :           ..write(')'))
+     193            0 :         .toString();
+     194              :   }
+     195              : }
+     196              : 
+     197              : class $SchedulesTable extends Schedules
+     198              :     with TableInfo<$SchedulesTable, Schedule> {
+     199              :   @override
+     200              :   final GeneratedDatabase attachedDatabase;
+     201              :   final String? _alias;
+     202            3 :   $SchedulesTable(this.attachedDatabase, [this._alias]);
+     203              :   static const VerificationMeta _idMeta = const VerificationMeta('id');
+     204              :   @override
+     205            6 :   late final GeneratedColumn<String> id = GeneratedColumn<String>(
+     206            3 :       'id', aliasedName, false,
+     207              :       type: DriftSqlType.string,
+     208              :       requiredDuringInsert: false,
+     209            0 :       clientDefault: () => Uuid().v7());
+     210              :   static const VerificationMeta _placeIdMeta =
+     211              :       const VerificationMeta('placeId');
+     212              :   @override
+     213            6 :   late final GeneratedColumn<String> placeId = GeneratedColumn<String>(
+     214            3 :       'place_id', aliasedName, false,
+     215              :       type: DriftSqlType.string,
+     216              :       requiredDuringInsert: true,
+     217              :       defaultConstraints:
+     218            3 :           GeneratedColumn.constraintIsAlways('REFERENCES places (id)'));
+     219              :   static const VerificationMeta _scheduleNameMeta =
+     220              :       const VerificationMeta('scheduleName');
+     221              :   @override
+     222            6 :   late final GeneratedColumn<String> scheduleName = GeneratedColumn<String>(
+     223            3 :       'schedule_name', aliasedName, false,
+     224              :       type: DriftSqlType.string, requiredDuringInsert: true);
+     225              :   static const VerificationMeta _scheduleTimeMeta =
+     226              :       const VerificationMeta('scheduleTime');
+     227              :   @override
+     228            6 :   late final GeneratedColumn<DateTime> scheduleTime = GeneratedColumn<DateTime>(
+     229            3 :       'schedule_time', aliasedName, false,
+     230              :       type: DriftSqlType.dateTime, requiredDuringInsert: true);
+     231              :   static const VerificationMeta _moveTimeMeta =
+     232              :       const VerificationMeta('moveTime');
+     233              :   @override
+     234            3 :   late final GeneratedColumnWithTypeConverter<Duration, int> moveTime =
+     235            6 :       GeneratedColumn<int>('move_time', aliasedName, false,
+     236              :               type: DriftSqlType.int, requiredDuringInsert: true)
+     237            6 :           .withConverter<Duration>($SchedulesTable.$convertermoveTime);
+     238              :   static const VerificationMeta _isChangedMeta =
+     239              :       const VerificationMeta('isChanged');
+     240              :   @override
+     241            6 :   late final GeneratedColumn<bool> isChanged = GeneratedColumn<bool>(
+     242            3 :       'is_changed', aliasedName, false,
+     243              :       type: DriftSqlType.bool,
+     244              :       requiredDuringInsert: false,
+     245              :       defaultConstraints:
+     246            3 :           GeneratedColumn.constraintIsAlways('CHECK ("is_changed" IN (0, 1))'),
+     247              :       defaultValue: const Constant(false));
+     248              :   static const VerificationMeta _isStartedMeta =
+     249              :       const VerificationMeta('isStarted');
+     250              :   @override
+     251            6 :   late final GeneratedColumn<bool> isStarted = GeneratedColumn<bool>(
+     252            3 :       'is_started', aliasedName, false,
+     253              :       type: DriftSqlType.bool,
+     254              :       requiredDuringInsert: false,
+     255              :       defaultConstraints:
+     256            3 :           GeneratedColumn.constraintIsAlways('CHECK ("is_started" IN (0, 1))'),
+     257              :       defaultValue: const Constant(false));
+     258              :   static const VerificationMeta _scheduleSpareTimeMeta =
+     259              :       const VerificationMeta('scheduleSpareTime');
+     260              :   @override
+     261              :   late final GeneratedColumnWithTypeConverter<Duration?, int>
+     262            6 :       scheduleSpareTime = GeneratedColumn<int>(
+     263            3 :               'schedule_spare_time', aliasedName, true,
+     264              :               type: DriftSqlType.int, requiredDuringInsert: false)
+     265            3 :           .withConverter<Duration?>(
+     266            3 :               $SchedulesTable.$converterscheduleSpareTimen);
+     267              :   static const VerificationMeta _scheduleNoteMeta =
+     268              :       const VerificationMeta('scheduleNote');
+     269              :   @override
+     270            6 :   late final GeneratedColumn<String> scheduleNote = GeneratedColumn<String>(
+     271            3 :       'schedule_note', aliasedName, true,
+     272              :       type: DriftSqlType.string, requiredDuringInsert: false);
+     273              :   static const VerificationMeta _latenessTimeMeta =
+     274              :       const VerificationMeta('latenessTime');
+     275              :   @override
+     276            6 :   late final GeneratedColumn<int> latenessTime = GeneratedColumn<int>(
+     277            3 :       'lateness_time', aliasedName, false,
+     278              :       type: DriftSqlType.int,
+     279              :       requiredDuringInsert: false,
+     280              :       defaultValue: const Constant(-1));
+     281            3 :   @override
+     282            3 :   List<GeneratedColumn> get $columns => [
+     283            3 :         id,
+     284            3 :         placeId,
+     285            3 :         scheduleName,
+     286            3 :         scheduleTime,
+     287            3 :         moveTime,
+     288            3 :         isChanged,
+     289            3 :         isStarted,
+     290            3 :         scheduleSpareTime,
+     291            3 :         scheduleNote,
+     292            3 :         latenessTime
+     293              :       ];
+     294            3 :   @override
+     295            6 :   String get aliasedName => _alias ?? actualTableName;
+     296            3 :   @override
+     297              :   String get actualTableName => $name;
+     298              :   static const String $name = 'schedules';
+     299            2 :   @override
+     300              :   VerificationContext validateIntegrity(Insertable<Schedule> instance,
+     301              :       {bool isInserting = false}) {
+     302            2 :     final context = VerificationContext();
+     303            2 :     final data = instance.toColumns(true);
+     304            2 :     if (data.containsKey('id')) {
+     305            8 :       context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
+     306              :     }
+     307            2 :     if (data.containsKey('place_id')) {
+     308            2 :       context.handle(_placeIdMeta,
+     309            6 :           placeId.isAcceptableOrUnknown(data['place_id']!, _placeIdMeta));
+     310              :     } else if (isInserting) {
+     311            0 :       context.missing(_placeIdMeta);
+     312              :     }
+     313            2 :     if (data.containsKey('schedule_name')) {
+     314            2 :       context.handle(
+     315              :           _scheduleNameMeta,
+     316            4 :           scheduleName.isAcceptableOrUnknown(
+     317            2 :               data['schedule_name']!, _scheduleNameMeta));
+     318              :     } else if (isInserting) {
+     319            0 :       context.missing(_scheduleNameMeta);
+     320              :     }
+     321            2 :     if (data.containsKey('schedule_time')) {
+     322            2 :       context.handle(
+     323              :           _scheduleTimeMeta,
+     324            4 :           scheduleTime.isAcceptableOrUnknown(
+     325            2 :               data['schedule_time']!, _scheduleTimeMeta));
+     326              :     } else if (isInserting) {
+     327            0 :       context.missing(_scheduleTimeMeta);
+     328              :     }
+     329            2 :     context.handle(_moveTimeMeta, const VerificationResult.success());
+     330            2 :     if (data.containsKey('is_changed')) {
+     331            2 :       context.handle(_isChangedMeta,
+     332            6 :           isChanged.isAcceptableOrUnknown(data['is_changed']!, _isChangedMeta));
+     333              :     }
+     334            2 :     if (data.containsKey('is_started')) {
+     335            2 :       context.handle(_isStartedMeta,
+     336            6 :           isStarted.isAcceptableOrUnknown(data['is_started']!, _isStartedMeta));
+     337              :     }
+     338            2 :     context.handle(_scheduleSpareTimeMeta, const VerificationResult.success());
+     339            2 :     if (data.containsKey('schedule_note')) {
+     340            2 :       context.handle(
+     341              :           _scheduleNoteMeta,
+     342            4 :           scheduleNote.isAcceptableOrUnknown(
+     343            2 :               data['schedule_note']!, _scheduleNoteMeta));
+     344              :     }
+     345            2 :     if (data.containsKey('lateness_time')) {
+     346            2 :       context.handle(
+     347              :           _latenessTimeMeta,
+     348            4 :           latenessTime.isAcceptableOrUnknown(
+     349            2 :               data['lateness_time']!, _latenessTimeMeta));
+     350              :     }
+     351              :     return context;
+     352              :   }
+     353              : 
+     354            3 :   @override
+     355            3 :   Set<GeneratedColumn> get $primaryKey => {id};
+     356            1 :   @override
+     357              :   Schedule map(Map<String, dynamic> data, {String? tablePrefix}) {
+     358            1 :     final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
+     359            1 :     return Schedule(
+     360            2 :       id: attachedDatabase.typeMapping
+     361            3 :           .read(DriftSqlType.string, data['${effectivePrefix}id'])!,
+     362            2 :       placeId: attachedDatabase.typeMapping
+     363            3 :           .read(DriftSqlType.string, data['${effectivePrefix}place_id'])!,
+     364            2 :       scheduleName: attachedDatabase.typeMapping
+     365            3 :           .read(DriftSqlType.string, data['${effectivePrefix}schedule_name'])!,
+     366            3 :       scheduleTime: attachedDatabase.typeMapping.read(
+     367            2 :           DriftSqlType.dateTime, data['${effectivePrefix}schedule_time'])!,
+     368            3 :       moveTime: $SchedulesTable.$convertermoveTime.fromSql(attachedDatabase
+     369            1 :           .typeMapping
+     370            3 :           .read(DriftSqlType.int, data['${effectivePrefix}move_time'])!),
+     371            2 :       isChanged: attachedDatabase.typeMapping
+     372            3 :           .read(DriftSqlType.bool, data['${effectivePrefix}is_changed'])!,
+     373            2 :       isStarted: attachedDatabase.typeMapping
+     374            3 :           .read(DriftSqlType.bool, data['${effectivePrefix}is_started'])!,
+     375            2 :       scheduleSpareTime: $SchedulesTable.$converterscheduleSpareTimen.fromSql(
+     376            3 :           attachedDatabase.typeMapping.read(
+     377            2 :               DriftSqlType.int, data['${effectivePrefix}schedule_spare_time'])),
+     378            2 :       scheduleNote: attachedDatabase.typeMapping
+     379            3 :           .read(DriftSqlType.string, data['${effectivePrefix}schedule_note']),
+     380            2 :       latenessTime: attachedDatabase.typeMapping
+     381            3 :           .read(DriftSqlType.int, data['${effectivePrefix}lateness_time'])!,
+     382              :     );
+     383              :   }
+     384              : 
+     385            0 :   @override
+     386              :   $SchedulesTable createAlias(String alias) {
+     387            0 :     return $SchedulesTable(attachedDatabase, alias);
+     388              :   }
+     389              : 
+     390            6 :   static JsonTypeConverter2<Duration, int, int> $convertermoveTime =
+     391            3 :       DurationSqlConverter();
+     392            6 :   static JsonTypeConverter2<Duration, int, int> $converterscheduleSpareTime =
+     393            3 :       DurationSqlConverter();
+     394              :   static JsonTypeConverter2<Duration?, int?, int?>
+     395            6 :       $converterscheduleSpareTimen =
+     396            6 :       JsonTypeConverter2.asNullable($converterscheduleSpareTime);
+     397              : }
+     398              : 
+     399              : class Schedule extends DataClass implements Insertable<Schedule> {
+     400              :   final String id;
+     401              :   final String placeId;
+     402              :   final String scheduleName;
+     403              :   final DateTime scheduleTime;
+     404              :   final Duration moveTime;
+     405              :   final bool isChanged;
+     406              :   final bool isStarted;
+     407              :   final Duration? scheduleSpareTime;
+     408              :   final String? scheduleNote;
+     409              :   final int latenessTime;
+     410            1 :   const Schedule(
+     411              :       {required this.id,
+     412              :       required this.placeId,
+     413              :       required this.scheduleName,
+     414              :       required this.scheduleTime,
+     415              :       required this.moveTime,
+     416              :       required this.isChanged,
+     417              :       required this.isStarted,
+     418              :       this.scheduleSpareTime,
+     419              :       this.scheduleNote,
+     420              :       required this.latenessTime});
+     421            0 :   @override
+     422              :   Map<String, Expression> toColumns(bool nullToAbsent) {
+     423            0 :     final map = <String, Expression>{};
+     424            0 :     map['id'] = Variable<String>(id);
+     425            0 :     map['place_id'] = Variable<String>(placeId);
+     426            0 :     map['schedule_name'] = Variable<String>(scheduleName);
+     427            0 :     map['schedule_time'] = Variable<DateTime>(scheduleTime);
+     428              :     {
+     429            0 :       map['move_time'] =
+     430            0 :           Variable<int>($SchedulesTable.$convertermoveTime.toSql(moveTime));
+     431              :     }
+     432            0 :     map['is_changed'] = Variable<bool>(isChanged);
+     433            0 :     map['is_started'] = Variable<bool>(isStarted);
+     434            0 :     if (!nullToAbsent || scheduleSpareTime != null) {
+     435            0 :       map['schedule_spare_time'] = Variable<int>($SchedulesTable
+     436            0 :           .$converterscheduleSpareTimen
+     437            0 :           .toSql(scheduleSpareTime));
+     438              :     }
+     439            0 :     if (!nullToAbsent || scheduleNote != null) {
+     440            0 :       map['schedule_note'] = Variable<String>(scheduleNote);
+     441              :     }
+     442            0 :     map['lateness_time'] = Variable<int>(latenessTime);
+     443              :     return map;
+     444              :   }
+     445              : 
+     446            1 :   SchedulesCompanion toCompanion(bool nullToAbsent) {
+     447            1 :     return SchedulesCompanion(
+     448            2 :       id: Value(id),
+     449            2 :       placeId: Value(placeId),
+     450            2 :       scheduleName: Value(scheduleName),
+     451            2 :       scheduleTime: Value(scheduleTime),
+     452            2 :       moveTime: Value(moveTime),
+     453            2 :       isChanged: Value(isChanged),
+     454            2 :       isStarted: Value(isStarted),
+     455            1 :       scheduleSpareTime: scheduleSpareTime == null && nullToAbsent
+     456              :           ? const Value.absent()
+     457            2 :           : Value(scheduleSpareTime),
+     458            1 :       scheduleNote: scheduleNote == null && nullToAbsent
+     459              :           ? const Value.absent()
+     460            2 :           : Value(scheduleNote),
+     461            2 :       latenessTime: Value(latenessTime),
+     462              :     );
+     463              :   }
+     464              : 
+     465            0 :   factory Schedule.fromJson(Map<String, dynamic> json,
+     466              :       {ValueSerializer? serializer}) {
+     467            0 :     serializer ??= driftRuntimeOptions.defaultSerializer;
+     468            0 :     return Schedule(
+     469            0 :       id: serializer.fromJson<String>(json['id']),
+     470            0 :       placeId: serializer.fromJson<String>(json['placeId']),
+     471            0 :       scheduleName: serializer.fromJson<String>(json['scheduleName']),
+     472            0 :       scheduleTime: serializer.fromJson<DateTime>(json['scheduleTime']),
+     473            0 :       moveTime: $SchedulesTable.$convertermoveTime
+     474            0 :           .fromJson(serializer.fromJson<int>(json['moveTime'])),
+     475            0 :       isChanged: serializer.fromJson<bool>(json['isChanged']),
+     476            0 :       isStarted: serializer.fromJson<bool>(json['isStarted']),
+     477            0 :       scheduleSpareTime: $SchedulesTable.$converterscheduleSpareTimen
+     478            0 :           .fromJson(serializer.fromJson<int?>(json['scheduleSpareTime'])),
+     479            0 :       scheduleNote: serializer.fromJson<String?>(json['scheduleNote']),
+     480            0 :       latenessTime: serializer.fromJson<int>(json['latenessTime']),
+     481              :     );
+     482              :   }
+     483            0 :   @override
+     484              :   Map<String, dynamic> toJson({ValueSerializer? serializer}) {
+     485            0 :     serializer ??= driftRuntimeOptions.defaultSerializer;
+     486            0 :     return <String, dynamic>{
+     487            0 :       'id': serializer.toJson<String>(id),
+     488            0 :       'placeId': serializer.toJson<String>(placeId),
+     489            0 :       'scheduleName': serializer.toJson<String>(scheduleName),
+     490            0 :       'scheduleTime': serializer.toJson<DateTime>(scheduleTime),
+     491              :       'moveTime': serializer
+     492            0 :           .toJson<int>($SchedulesTable.$convertermoveTime.toJson(moveTime)),
+     493            0 :       'isChanged': serializer.toJson<bool>(isChanged),
+     494            0 :       'isStarted': serializer.toJson<bool>(isStarted),
+     495            0 :       'scheduleSpareTime': serializer.toJson<int?>($SchedulesTable
+     496            0 :           .$converterscheduleSpareTimen
+     497            0 :           .toJson(scheduleSpareTime)),
+     498            0 :       'scheduleNote': serializer.toJson<String?>(scheduleNote),
+     499            0 :       'latenessTime': serializer.toJson<int>(latenessTime),
+     500              :     };
+     501              :   }
+     502              : 
+     503            1 :   Schedule copyWith(
+     504              :           {String? id,
+     505              :           String? placeId,
+     506              :           String? scheduleName,
+     507              :           DateTime? scheduleTime,
+     508              :           Duration? moveTime,
+     509              :           bool? isChanged,
+     510              :           bool? isStarted,
+     511              :           Value<Duration?> scheduleSpareTime = const Value.absent(),
+     512              :           Value<String?> scheduleNote = const Value.absent(),
+     513              :           int? latenessTime}) =>
+     514            1 :       Schedule(
+     515            1 :         id: id ?? this.id,
+     516            1 :         placeId: placeId ?? this.placeId,
+     517            1 :         scheduleName: scheduleName ?? this.scheduleName,
+     518            1 :         scheduleTime: scheduleTime ?? this.scheduleTime,
+     519            1 :         moveTime: moveTime ?? this.moveTime,
+     520            1 :         isChanged: isChanged ?? this.isChanged,
+     521            1 :         isStarted: isStarted ?? this.isStarted,
+     522            1 :         scheduleSpareTime: scheduleSpareTime.present
+     523            0 :             ? scheduleSpareTime.value
+     524            1 :             : this.scheduleSpareTime,
+     525              :         scheduleNote:
+     526            2 :             scheduleNote.present ? scheduleNote.value : this.scheduleNote,
+     527            1 :         latenessTime: latenessTime ?? this.latenessTime,
+     528              :       );
+     529            0 :   Schedule copyWithCompanion(SchedulesCompanion data) {
+     530            0 :     return Schedule(
+     531            0 :       id: data.id.present ? data.id.value : this.id,
+     532            0 :       placeId: data.placeId.present ? data.placeId.value : this.placeId,
+     533            0 :       scheduleName: data.scheduleName.present
+     534            0 :           ? data.scheduleName.value
+     535            0 :           : this.scheduleName,
+     536            0 :       scheduleTime: data.scheduleTime.present
+     537            0 :           ? data.scheduleTime.value
+     538            0 :           : this.scheduleTime,
+     539            0 :       moveTime: data.moveTime.present ? data.moveTime.value : this.moveTime,
+     540            0 :       isChanged: data.isChanged.present ? data.isChanged.value : this.isChanged,
+     541            0 :       isStarted: data.isStarted.present ? data.isStarted.value : this.isStarted,
+     542            0 :       scheduleSpareTime: data.scheduleSpareTime.present
+     543            0 :           ? data.scheduleSpareTime.value
+     544            0 :           : this.scheduleSpareTime,
+     545            0 :       scheduleNote: data.scheduleNote.present
+     546            0 :           ? data.scheduleNote.value
+     547            0 :           : this.scheduleNote,
+     548            0 :       latenessTime: data.latenessTime.present
+     549            0 :           ? data.latenessTime.value
+     550            0 :           : this.latenessTime,
+     551              :     );
+     552              :   }
+     553              : 
+     554            0 :   @override
+     555              :   String toString() {
+     556            0 :     return (StringBuffer('Schedule(')
+     557            0 :           ..write('id: $id, ')
+     558            0 :           ..write('placeId: $placeId, ')
+     559            0 :           ..write('scheduleName: $scheduleName, ')
+     560            0 :           ..write('scheduleTime: $scheduleTime, ')
+     561            0 :           ..write('moveTime: $moveTime, ')
+     562            0 :           ..write('isChanged: $isChanged, ')
+     563            0 :           ..write('isStarted: $isStarted, ')
+     564            0 :           ..write('scheduleSpareTime: $scheduleSpareTime, ')
+     565            0 :           ..write('scheduleNote: $scheduleNote, ')
+     566            0 :           ..write('latenessTime: $latenessTime')
+     567            0 :           ..write(')'))
+     568            0 :         .toString();
+     569              :   }
+     570              : 
+     571            0 :   @override
+     572            0 :   int get hashCode => Object.hash(
+     573            0 :       id,
+     574            0 :       placeId,
+     575            0 :       scheduleName,
+     576            0 :       scheduleTime,
+     577            0 :       moveTime,
+     578            0 :       isChanged,
+     579            0 :       isStarted,
+     580            0 :       scheduleSpareTime,
+     581            0 :       scheduleNote,
+     582            0 :       latenessTime);
+     583            1 :   @override
+     584              :   bool operator ==(Object other) =>
+     585              :       identical(this, other) ||
+     586            1 :       (other is Schedule &&
+     587            3 :           other.id == this.id &&
+     588            3 :           other.placeId == this.placeId &&
+     589            3 :           other.scheduleName == this.scheduleName &&
+     590            3 :           other.scheduleTime == this.scheduleTime &&
+     591            3 :           other.moveTime == this.moveTime &&
+     592            3 :           other.isChanged == this.isChanged &&
+     593            3 :           other.isStarted == this.isStarted &&
+     594            3 :           other.scheduleSpareTime == this.scheduleSpareTime &&
+     595            3 :           other.scheduleNote == this.scheduleNote &&
+     596            3 :           other.latenessTime == this.latenessTime);
+     597              : }
+     598              : 
+     599              : class SchedulesCompanion extends UpdateCompanion<Schedule> {
+     600              :   final Value<String> id;
+     601              :   final Value<String> placeId;
+     602              :   final Value<String> scheduleName;
+     603              :   final Value<DateTime> scheduleTime;
+     604              :   final Value<Duration> moveTime;
+     605              :   final Value<bool> isChanged;
+     606              :   final Value<bool> isStarted;
+     607              :   final Value<Duration?> scheduleSpareTime;
+     608              :   final Value<String?> scheduleNote;
+     609              :   final Value<int> latenessTime;
+     610              :   final Value<int> rowid;
+     611            2 :   const SchedulesCompanion({
+     612              :     this.id = const Value.absent(),
+     613              :     this.placeId = const Value.absent(),
+     614              :     this.scheduleName = const Value.absent(),
+     615              :     this.scheduleTime = const Value.absent(),
+     616              :     this.moveTime = const Value.absent(),
+     617              :     this.isChanged = const Value.absent(),
+     618              :     this.isStarted = const Value.absent(),
+     619              :     this.scheduleSpareTime = const Value.absent(),
+     620              :     this.scheduleNote = const Value.absent(),
+     621              :     this.latenessTime = const Value.absent(),
+     622              :     this.rowid = const Value.absent(),
+     623              :   });
+     624            0 :   SchedulesCompanion.insert({
+     625              :     this.id = const Value.absent(),
+     626              :     required String placeId,
+     627              :     required String scheduleName,
+     628              :     required DateTime scheduleTime,
+     629              :     required Duration moveTime,
+     630              :     this.isChanged = const Value.absent(),
+     631              :     this.isStarted = const Value.absent(),
+     632              :     this.scheduleSpareTime = const Value.absent(),
+     633              :     this.scheduleNote = const Value.absent(),
+     634              :     this.latenessTime = const Value.absent(),
+     635              :     this.rowid = const Value.absent(),
+     636            0 :   })  : placeId = Value(placeId),
+     637            0 :         scheduleName = Value(scheduleName),
+     638            0 :         scheduleTime = Value(scheduleTime),
+     639            0 :         moveTime = Value(moveTime);
+     640            0 :   static Insertable<Schedule> custom({
+     641              :     Expression<String>? id,
+     642              :     Expression<String>? placeId,
+     643              :     Expression<String>? scheduleName,
+     644              :     Expression<DateTime>? scheduleTime,
+     645              :     Expression<int>? moveTime,
+     646              :     Expression<bool>? isChanged,
+     647              :     Expression<bool>? isStarted,
+     648              :     Expression<int>? scheduleSpareTime,
+     649              :     Expression<String>? scheduleNote,
+     650              :     Expression<int>? latenessTime,
+     651              :     Expression<int>? rowid,
+     652              :   }) {
+     653            0 :     return RawValuesInsertable({
+     654            0 :       if (id != null) 'id': id,
+     655            0 :       if (placeId != null) 'place_id': placeId,
+     656            0 :       if (scheduleName != null) 'schedule_name': scheduleName,
+     657            0 :       if (scheduleTime != null) 'schedule_time': scheduleTime,
+     658            0 :       if (moveTime != null) 'move_time': moveTime,
+     659            0 :       if (isChanged != null) 'is_changed': isChanged,
+     660            0 :       if (isStarted != null) 'is_started': isStarted,
+     661            0 :       if (scheduleSpareTime != null) 'schedule_spare_time': scheduleSpareTime,
+     662            0 :       if (scheduleNote != null) 'schedule_note': scheduleNote,
+     663            0 :       if (latenessTime != null) 'lateness_time': latenessTime,
+     664            0 :       if (rowid != null) 'rowid': rowid,
+     665              :     });
+     666              :   }
+     667              : 
+     668            0 :   SchedulesCompanion copyWith(
+     669              :       {Value<String>? id,
+     670              :       Value<String>? placeId,
+     671              :       Value<String>? scheduleName,
+     672              :       Value<DateTime>? scheduleTime,
+     673              :       Value<Duration>? moveTime,
+     674              :       Value<bool>? isChanged,
+     675              :       Value<bool>? isStarted,
+     676              :       Value<Duration?>? scheduleSpareTime,
+     677              :       Value<String?>? scheduleNote,
+     678              :       Value<int>? latenessTime,
+     679              :       Value<int>? rowid}) {
+     680            0 :     return SchedulesCompanion(
+     681            0 :       id: id ?? this.id,
+     682            0 :       placeId: placeId ?? this.placeId,
+     683            0 :       scheduleName: scheduleName ?? this.scheduleName,
+     684            0 :       scheduleTime: scheduleTime ?? this.scheduleTime,
+     685            0 :       moveTime: moveTime ?? this.moveTime,
+     686            0 :       isChanged: isChanged ?? this.isChanged,
+     687            0 :       isStarted: isStarted ?? this.isStarted,
+     688            0 :       scheduleSpareTime: scheduleSpareTime ?? this.scheduleSpareTime,
+     689            0 :       scheduleNote: scheduleNote ?? this.scheduleNote,
+     690            0 :       latenessTime: latenessTime ?? this.latenessTime,
+     691            0 :       rowid: rowid ?? this.rowid,
+     692              :     );
+     693              :   }
+     694              : 
+     695            2 :   @override
+     696              :   Map<String, Expression> toColumns(bool nullToAbsent) {
+     697            2 :     final map = <String, Expression>{};
+     698            4 :     if (id.present) {
+     699            8 :       map['id'] = Variable<String>(id.value);
+     700              :     }
+     701            4 :     if (placeId.present) {
+     702            8 :       map['place_id'] = Variable<String>(placeId.value);
+     703              :     }
+     704            4 :     if (scheduleName.present) {
+     705            8 :       map['schedule_name'] = Variable<String>(scheduleName.value);
+     706              :     }
+     707            4 :     if (scheduleTime.present) {
+     708            8 :       map['schedule_time'] = Variable<DateTime>(scheduleTime.value);
+     709              :     }
+     710            4 :     if (moveTime.present) {
+     711            4 :       map['move_time'] = Variable<int>(
+     712            8 :           $SchedulesTable.$convertermoveTime.toSql(moveTime.value));
+     713              :     }
+     714            4 :     if (isChanged.present) {
+     715            8 :       map['is_changed'] = Variable<bool>(isChanged.value);
+     716              :     }
+     717            4 :     if (isStarted.present) {
+     718            8 :       map['is_started'] = Variable<bool>(isStarted.value);
+     719              :     }
+     720            4 :     if (scheduleSpareTime.present) {
+     721            4 :       map['schedule_spare_time'] = Variable<int>($SchedulesTable
+     722            2 :           .$converterscheduleSpareTimen
+     723            6 :           .toSql(scheduleSpareTime.value));
+     724              :     }
+     725            4 :     if (scheduleNote.present) {
+     726            8 :       map['schedule_note'] = Variable<String>(scheduleNote.value);
+     727              :     }
+     728            4 :     if (latenessTime.present) {
+     729            8 :       map['lateness_time'] = Variable<int>(latenessTime.value);
+     730              :     }
+     731            4 :     if (rowid.present) {
+     732            0 :       map['rowid'] = Variable<int>(rowid.value);
+     733              :     }
+     734              :     return map;
+     735              :   }
+     736              : 
+     737            0 :   @override
+     738              :   String toString() {
+     739            0 :     return (StringBuffer('SchedulesCompanion(')
+     740            0 :           ..write('id: $id, ')
+     741            0 :           ..write('placeId: $placeId, ')
+     742            0 :           ..write('scheduleName: $scheduleName, ')
+     743            0 :           ..write('scheduleTime: $scheduleTime, ')
+     744            0 :           ..write('moveTime: $moveTime, ')
+     745            0 :           ..write('isChanged: $isChanged, ')
+     746            0 :           ..write('isStarted: $isStarted, ')
+     747            0 :           ..write('scheduleSpareTime: $scheduleSpareTime, ')
+     748            0 :           ..write('scheduleNote: $scheduleNote, ')
+     749            0 :           ..write('latenessTime: $latenessTime, ')
+     750            0 :           ..write('rowid: $rowid')
+     751            0 :           ..write(')'))
+     752            0 :         .toString();
+     753              :   }
+     754              : }
+     755              : 
+     756              : class $UsersTable extends Users with TableInfo<$UsersTable, User> {
+     757              :   @override
+     758              :   final GeneratedDatabase attachedDatabase;
+     759              :   final String? _alias;
+     760            3 :   $UsersTable(this.attachedDatabase, [this._alias]);
+     761              :   static const VerificationMeta _idMeta = const VerificationMeta('id');
+     762              :   @override
+     763            6 :   late final GeneratedColumn<String> id = GeneratedColumn<String>(
+     764            3 :       'id', aliasedName, false,
+     765              :       type: DriftSqlType.string,
+     766              :       requiredDuringInsert: false,
+     767            0 :       clientDefault: () => Uuid().v7());
+     768              :   static const VerificationMeta _emailMeta = const VerificationMeta('email');
+     769              :   @override
+     770            6 :   late final GeneratedColumn<String> email = GeneratedColumn<String>(
+     771            3 :       'email', aliasedName, false,
+     772              :       additionalChecks:
+     773            3 :           GeneratedColumn.checkTextLength(minTextLength: 1, maxTextLength: 320),
+     774              :       type: DriftSqlType.string,
+     775              :       requiredDuringInsert: true);
+     776              :   static const VerificationMeta _nameMeta = const VerificationMeta('name');
+     777              :   @override
+     778            6 :   late final GeneratedColumn<String> name = GeneratedColumn<String>(
+     779            3 :       'name', aliasedName, false,
+     780              :       additionalChecks:
+     781            3 :           GeneratedColumn.checkTextLength(minTextLength: 1, maxTextLength: 30),
+     782              :       type: DriftSqlType.string,
+     783              :       requiredDuringInsert: true);
+     784              :   static const VerificationMeta _spareTimeMeta =
+     785              :       const VerificationMeta('spareTime');
+     786              :   @override
+     787            6 :   late final GeneratedColumn<int> spareTime = GeneratedColumn<int>(
+     788            3 :       'spare_time', aliasedName, false,
+     789              :       type: DriftSqlType.int, requiredDuringInsert: true);
+     790              :   static const VerificationMeta _noteMeta = const VerificationMeta('note');
+     791              :   @override
+     792            6 :   late final GeneratedColumn<String> note = GeneratedColumn<String>(
+     793            3 :       'note', aliasedName, false,
+     794              :       type: DriftSqlType.string, requiredDuringInsert: true);
+     795              :   static const VerificationMeta _scoreMeta = const VerificationMeta('score');
+     796              :   @override
+     797            6 :   late final GeneratedColumn<double> score = GeneratedColumn<double>(
+     798            3 :       'score', aliasedName, false,
+     799              :       type: DriftSqlType.double, requiredDuringInsert: true);
+     800            3 :   @override
+     801              :   List<GeneratedColumn> get $columns =>
+     802           21 :       [id, email, name, spareTime, note, score];
+     803            3 :   @override
+     804            6 :   String get aliasedName => _alias ?? actualTableName;
+     805            3 :   @override
+     806              :   String get actualTableName => $name;
+     807              :   static const String $name = 'users';
+     808            2 :   @override
+     809              :   VerificationContext validateIntegrity(Insertable<User> instance,
+     810              :       {bool isInserting = false}) {
+     811            2 :     final context = VerificationContext();
+     812            2 :     final data = instance.toColumns(true);
+     813            2 :     if (data.containsKey('id')) {
+     814            8 :       context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
+     815              :     }
+     816            2 :     if (data.containsKey('email')) {
+     817            2 :       context.handle(
+     818            6 :           _emailMeta, email.isAcceptableOrUnknown(data['email']!, _emailMeta));
+     819              :     } else if (isInserting) {
+     820            0 :       context.missing(_emailMeta);
+     821              :     }
+     822            2 :     if (data.containsKey('name')) {
+     823            2 :       context.handle(
+     824            6 :           _nameMeta, name.isAcceptableOrUnknown(data['name']!, _nameMeta));
+     825              :     } else if (isInserting) {
+     826            0 :       context.missing(_nameMeta);
+     827              :     }
+     828            2 :     if (data.containsKey('spare_time')) {
+     829            2 :       context.handle(_spareTimeMeta,
+     830            6 :           spareTime.isAcceptableOrUnknown(data['spare_time']!, _spareTimeMeta));
+     831              :     } else if (isInserting) {
+     832            0 :       context.missing(_spareTimeMeta);
+     833              :     }
+     834            2 :     if (data.containsKey('note')) {
+     835            2 :       context.handle(
+     836            6 :           _noteMeta, note.isAcceptableOrUnknown(data['note']!, _noteMeta));
+     837              :     } else if (isInserting) {
+     838            0 :       context.missing(_noteMeta);
+     839              :     }
+     840            2 :     if (data.containsKey('score')) {
+     841            2 :       context.handle(
+     842            6 :           _scoreMeta, score.isAcceptableOrUnknown(data['score']!, _scoreMeta));
+     843              :     } else if (isInserting) {
+     844            0 :       context.missing(_scoreMeta);
+     845              :     }
+     846              :     return context;
+     847              :   }
+     848              : 
+     849            3 :   @override
+     850            3 :   Set<GeneratedColumn> get $primaryKey => {id};
+     851            0 :   @override
+     852              :   User map(Map<String, dynamic> data, {String? tablePrefix}) {
+     853            0 :     final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
+     854            0 :     return User(
+     855            0 :       id: attachedDatabase.typeMapping
+     856            0 :           .read(DriftSqlType.string, data['${effectivePrefix}id'])!,
+     857            0 :       email: attachedDatabase.typeMapping
+     858            0 :           .read(DriftSqlType.string, data['${effectivePrefix}email'])!,
+     859            0 :       name: attachedDatabase.typeMapping
+     860            0 :           .read(DriftSqlType.string, data['${effectivePrefix}name'])!,
+     861            0 :       spareTime: attachedDatabase.typeMapping
+     862            0 :           .read(DriftSqlType.int, data['${effectivePrefix}spare_time'])!,
+     863            0 :       note: attachedDatabase.typeMapping
+     864            0 :           .read(DriftSqlType.string, data['${effectivePrefix}note'])!,
+     865            0 :       score: attachedDatabase.typeMapping
+     866            0 :           .read(DriftSqlType.double, data['${effectivePrefix}score'])!,
+     867              :     );
+     868              :   }
+     869              : 
+     870            0 :   @override
+     871              :   $UsersTable createAlias(String alias) {
+     872            0 :     return $UsersTable(attachedDatabase, alias);
+     873              :   }
+     874              : }
+     875              : 
+     876              : class User extends DataClass implements Insertable<User> {
+     877              :   final String id;
+     878              :   final String email;
+     879              :   final String name;
+     880              :   final int spareTime;
+     881              :   final String note;
+     882              :   final double score;
+     883            0 :   const User(
+     884              :       {required this.id,
+     885              :       required this.email,
+     886              :       required this.name,
+     887              :       required this.spareTime,
+     888              :       required this.note,
+     889              :       required this.score});
+     890            0 :   @override
+     891              :   Map<String, Expression> toColumns(bool nullToAbsent) {
+     892            0 :     final map = <String, Expression>{};
+     893            0 :     map['id'] = Variable<String>(id);
+     894            0 :     map['email'] = Variable<String>(email);
+     895            0 :     map['name'] = Variable<String>(name);
+     896            0 :     map['spare_time'] = Variable<int>(spareTime);
+     897            0 :     map['note'] = Variable<String>(note);
+     898            0 :     map['score'] = Variable<double>(score);
+     899              :     return map;
+     900              :   }
+     901              : 
+     902            0 :   UsersCompanion toCompanion(bool nullToAbsent) {
+     903            0 :     return UsersCompanion(
+     904            0 :       id: Value(id),
+     905            0 :       email: Value(email),
+     906            0 :       name: Value(name),
+     907            0 :       spareTime: Value(spareTime),
+     908            0 :       note: Value(note),
+     909            0 :       score: Value(score),
+     910              :     );
+     911              :   }
+     912              : 
+     913            0 :   factory User.fromJson(Map<String, dynamic> json,
+     914              :       {ValueSerializer? serializer}) {
+     915            0 :     serializer ??= driftRuntimeOptions.defaultSerializer;
+     916            0 :     return User(
+     917            0 :       id: serializer.fromJson<String>(json['id']),
+     918            0 :       email: serializer.fromJson<String>(json['email']),
+     919            0 :       name: serializer.fromJson<String>(json['name']),
+     920            0 :       spareTime: serializer.fromJson<int>(json['spareTime']),
+     921            0 :       note: serializer.fromJson<String>(json['note']),
+     922            0 :       score: serializer.fromJson<double>(json['score']),
+     923              :     );
+     924              :   }
+     925            0 :   @override
+     926              :   Map<String, dynamic> toJson({ValueSerializer? serializer}) {
+     927            0 :     serializer ??= driftRuntimeOptions.defaultSerializer;
+     928            0 :     return <String, dynamic>{
+     929            0 :       'id': serializer.toJson<String>(id),
+     930            0 :       'email': serializer.toJson<String>(email),
+     931            0 :       'name': serializer.toJson<String>(name),
+     932            0 :       'spareTime': serializer.toJson<int>(spareTime),
+     933            0 :       'note': serializer.toJson<String>(note),
+     934            0 :       'score': serializer.toJson<double>(score),
+     935              :     };
+     936              :   }
+     937              : 
+     938            0 :   User copyWith(
+     939              :           {String? id,
+     940              :           String? email,
+     941              :           String? name,
+     942              :           int? spareTime,
+     943              :           String? note,
+     944              :           double? score}) =>
+     945            0 :       User(
+     946            0 :         id: id ?? this.id,
+     947            0 :         email: email ?? this.email,
+     948            0 :         name: name ?? this.name,
+     949            0 :         spareTime: spareTime ?? this.spareTime,
+     950            0 :         note: note ?? this.note,
+     951            0 :         score: score ?? this.score,
+     952              :       );
+     953            0 :   User copyWithCompanion(UsersCompanion data) {
+     954            0 :     return User(
+     955            0 :       id: data.id.present ? data.id.value : this.id,
+     956            0 :       email: data.email.present ? data.email.value : this.email,
+     957            0 :       name: data.name.present ? data.name.value : this.name,
+     958            0 :       spareTime: data.spareTime.present ? data.spareTime.value : this.spareTime,
+     959            0 :       note: data.note.present ? data.note.value : this.note,
+     960            0 :       score: data.score.present ? data.score.value : this.score,
+     961              :     );
+     962              :   }
+     963              : 
+     964            0 :   @override
+     965              :   String toString() {
+     966            0 :     return (StringBuffer('User(')
+     967            0 :           ..write('id: $id, ')
+     968            0 :           ..write('email: $email, ')
+     969            0 :           ..write('name: $name, ')
+     970            0 :           ..write('spareTime: $spareTime, ')
+     971            0 :           ..write('note: $note, ')
+     972            0 :           ..write('score: $score')
+     973            0 :           ..write(')'))
+     974            0 :         .toString();
+     975              :   }
+     976              : 
+     977            0 :   @override
+     978            0 :   int get hashCode => Object.hash(id, email, name, spareTime, note, score);
+     979            0 :   @override
+     980              :   bool operator ==(Object other) =>
+     981              :       identical(this, other) ||
+     982            0 :       (other is User &&
+     983            0 :           other.id == this.id &&
+     984            0 :           other.email == this.email &&
+     985            0 :           other.name == this.name &&
+     986            0 :           other.spareTime == this.spareTime &&
+     987            0 :           other.note == this.note &&
+     988            0 :           other.score == this.score);
+     989              : }
+     990              : 
+     991              : class UsersCompanion extends UpdateCompanion<User> {
+     992              :   final Value<String> id;
+     993              :   final Value<String> email;
+     994              :   final Value<String> name;
+     995              :   final Value<int> spareTime;
+     996              :   final Value<String> note;
+     997              :   final Value<double> score;
+     998              :   final Value<int> rowid;
+     999            2 :   const UsersCompanion({
+    1000              :     this.id = const Value.absent(),
+    1001              :     this.email = const Value.absent(),
+    1002              :     this.name = const Value.absent(),
+    1003              :     this.spareTime = const Value.absent(),
+    1004              :     this.note = const Value.absent(),
+    1005              :     this.score = const Value.absent(),
+    1006              :     this.rowid = const Value.absent(),
+    1007              :   });
+    1008            0 :   UsersCompanion.insert({
+    1009              :     this.id = const Value.absent(),
+    1010              :     required String email,
+    1011              :     required String name,
+    1012              :     required int spareTime,
+    1013              :     required String note,
+    1014              :     required double score,
+    1015              :     this.rowid = const Value.absent(),
+    1016            0 :   })  : email = Value(email),
+    1017            0 :         name = Value(name),
+    1018            0 :         spareTime = Value(spareTime),
+    1019            0 :         note = Value(note),
+    1020            0 :         score = Value(score);
+    1021            0 :   static Insertable<User> custom({
+    1022              :     Expression<String>? id,
+    1023              :     Expression<String>? email,
+    1024              :     Expression<String>? name,
+    1025              :     Expression<int>? spareTime,
+    1026              :     Expression<String>? note,
+    1027              :     Expression<double>? score,
+    1028              :     Expression<int>? rowid,
+    1029              :   }) {
+    1030            0 :     return RawValuesInsertable({
+    1031            0 :       if (id != null) 'id': id,
+    1032            0 :       if (email != null) 'email': email,
+    1033            0 :       if (name != null) 'name': name,
+    1034            0 :       if (spareTime != null) 'spare_time': spareTime,
+    1035            0 :       if (note != null) 'note': note,
+    1036            0 :       if (score != null) 'score': score,
+    1037            0 :       if (rowid != null) 'rowid': rowid,
+    1038              :     });
+    1039              :   }
+    1040              : 
+    1041            0 :   UsersCompanion copyWith(
+    1042              :       {Value<String>? id,
+    1043              :       Value<String>? email,
+    1044              :       Value<String>? name,
+    1045              :       Value<int>? spareTime,
+    1046              :       Value<String>? note,
+    1047              :       Value<double>? score,
+    1048              :       Value<int>? rowid}) {
+    1049            0 :     return UsersCompanion(
+    1050            0 :       id: id ?? this.id,
+    1051            0 :       email: email ?? this.email,
+    1052            0 :       name: name ?? this.name,
+    1053            0 :       spareTime: spareTime ?? this.spareTime,
+    1054            0 :       note: note ?? this.note,
+    1055            0 :       score: score ?? this.score,
+    1056            0 :       rowid: rowid ?? this.rowid,
+    1057              :     );
+    1058              :   }
+    1059              : 
+    1060            2 :   @override
+    1061              :   Map<String, Expression> toColumns(bool nullToAbsent) {
+    1062            2 :     final map = <String, Expression>{};
+    1063            4 :     if (id.present) {
+    1064            8 :       map['id'] = Variable<String>(id.value);
+    1065              :     }
+    1066            4 :     if (email.present) {
+    1067            8 :       map['email'] = Variable<String>(email.value);
+    1068              :     }
+    1069            4 :     if (name.present) {
+    1070            8 :       map['name'] = Variable<String>(name.value);
+    1071              :     }
+    1072            4 :     if (spareTime.present) {
+    1073            8 :       map['spare_time'] = Variable<int>(spareTime.value);
+    1074              :     }
+    1075            4 :     if (note.present) {
+    1076            8 :       map['note'] = Variable<String>(note.value);
+    1077              :     }
+    1078            4 :     if (score.present) {
+    1079            8 :       map['score'] = Variable<double>(score.value);
+    1080              :     }
+    1081            4 :     if (rowid.present) {
+    1082            0 :       map['rowid'] = Variable<int>(rowid.value);
+    1083              :     }
+    1084              :     return map;
+    1085              :   }
+    1086              : 
+    1087            0 :   @override
+    1088              :   String toString() {
+    1089            0 :     return (StringBuffer('UsersCompanion(')
+    1090            0 :           ..write('id: $id, ')
+    1091            0 :           ..write('email: $email, ')
+    1092            0 :           ..write('name: $name, ')
+    1093            0 :           ..write('spareTime: $spareTime, ')
+    1094            0 :           ..write('note: $note, ')
+    1095            0 :           ..write('score: $score, ')
+    1096            0 :           ..write('rowid: $rowid')
+    1097            0 :           ..write(')'))
+    1098            0 :         .toString();
+    1099              :   }
+    1100              : }
+    1101              : 
+    1102              : class $PreparationSchedulesTable extends PreparationSchedules
+    1103              :     with TableInfo<$PreparationSchedulesTable, PreparationSchedule> {
+    1104              :   @override
+    1105              :   final GeneratedDatabase attachedDatabase;
+    1106              :   final String? _alias;
+    1107            3 :   $PreparationSchedulesTable(this.attachedDatabase, [this._alias]);
+    1108              :   static const VerificationMeta _idMeta = const VerificationMeta('id');
+    1109              :   @override
+    1110            6 :   late final GeneratedColumn<String> id = GeneratedColumn<String>(
+    1111            3 :       'id', aliasedName, false,
+    1112              :       type: DriftSqlType.string,
+    1113              :       requiredDuringInsert: false,
+    1114            0 :       clientDefault: () => Uuid().v7());
+    1115              :   static const VerificationMeta _scheduleIdMeta =
+    1116              :       const VerificationMeta('scheduleId');
+    1117              :   @override
+    1118            6 :   late final GeneratedColumn<String> scheduleId = GeneratedColumn<String>(
+    1119            3 :       'schedule_id', aliasedName, false,
+    1120              :       type: DriftSqlType.string,
+    1121              :       requiredDuringInsert: true,
+    1122              :       defaultConstraints:
+    1123            3 :           GeneratedColumn.constraintIsAlways('REFERENCES schedules (id)'));
+    1124              :   static const VerificationMeta _preparationNameMeta =
+    1125              :       const VerificationMeta('preparationName');
+    1126              :   @override
+    1127            6 :   late final GeneratedColumn<String> preparationName = GeneratedColumn<String>(
+    1128            3 :       'preparation_name', aliasedName, false,
+    1129              :       additionalChecks:
+    1130            3 :           GeneratedColumn.checkTextLength(minTextLength: 1, maxTextLength: 30),
+    1131              :       type: DriftSqlType.string,
+    1132              :       requiredDuringInsert: true);
+    1133              :   static const VerificationMeta _preparationTimeMeta =
+    1134              :       const VerificationMeta('preparationTime');
+    1135              :   @override
+    1136            6 :   late final GeneratedColumn<int> preparationTime = GeneratedColumn<int>(
+    1137            3 :       'preparation_time', aliasedName, false,
+    1138              :       type: DriftSqlType.int, requiredDuringInsert: true);
+    1139              :   static const VerificationMeta _nextPreparationIdMeta =
+    1140              :       const VerificationMeta('nextPreparationId');
+    1141              :   @override
+    1142            3 :   late final GeneratedColumn<String> nextPreparationId =
+    1143            6 :       GeneratedColumn<String>('next_preparation_id', aliasedName, true,
+    1144              :           type: DriftSqlType.string,
+    1145              :           requiredDuringInsert: false,
+    1146            3 :           defaultConstraints: GeneratedColumn.constraintIsAlways(
+    1147              :               'REFERENCES preparation_schedules (id)'));
+    1148            3 :   @override
+    1149              :   List<GeneratedColumn> get $columns =>
+    1150           18 :       [id, scheduleId, preparationName, preparationTime, nextPreparationId];
+    1151            3 :   @override
+    1152            6 :   String get aliasedName => _alias ?? actualTableName;
+    1153            3 :   @override
+    1154              :   String get actualTableName => $name;
+    1155              :   static const String $name = 'preparation_schedules';
+    1156            0 :   @override
+    1157              :   VerificationContext validateIntegrity(
+    1158              :       Insertable<PreparationSchedule> instance,
+    1159              :       {bool isInserting = false}) {
+    1160            0 :     final context = VerificationContext();
+    1161            0 :     final data = instance.toColumns(true);
+    1162            0 :     if (data.containsKey('id')) {
+    1163            0 :       context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
+    1164              :     }
+    1165            0 :     if (data.containsKey('schedule_id')) {
+    1166            0 :       context.handle(
+    1167              :           _scheduleIdMeta,
+    1168            0 :           scheduleId.isAcceptableOrUnknown(
+    1169            0 :               data['schedule_id']!, _scheduleIdMeta));
+    1170              :     } else if (isInserting) {
+    1171            0 :       context.missing(_scheduleIdMeta);
+    1172              :     }
+    1173            0 :     if (data.containsKey('preparation_name')) {
+    1174            0 :       context.handle(
+    1175              :           _preparationNameMeta,
+    1176            0 :           preparationName.isAcceptableOrUnknown(
+    1177            0 :               data['preparation_name']!, _preparationNameMeta));
+    1178              :     } else if (isInserting) {
+    1179            0 :       context.missing(_preparationNameMeta);
+    1180              :     }
+    1181            0 :     if (data.containsKey('preparation_time')) {
+    1182            0 :       context.handle(
+    1183              :           _preparationTimeMeta,
+    1184            0 :           preparationTime.isAcceptableOrUnknown(
+    1185            0 :               data['preparation_time']!, _preparationTimeMeta));
+    1186              :     } else if (isInserting) {
+    1187            0 :       context.missing(_preparationTimeMeta);
+    1188              :     }
+    1189            0 :     if (data.containsKey('next_preparation_id')) {
+    1190            0 :       context.handle(
+    1191              :           _nextPreparationIdMeta,
+    1192            0 :           nextPreparationId.isAcceptableOrUnknown(
+    1193            0 :               data['next_preparation_id']!, _nextPreparationIdMeta));
+    1194              :     }
+    1195              :     return context;
+    1196              :   }
+    1197              : 
+    1198            3 :   @override
+    1199            3 :   Set<GeneratedColumn> get $primaryKey => {id};
+    1200            0 :   @override
+    1201              :   PreparationSchedule map(Map<String, dynamic> data, {String? tablePrefix}) {
+    1202            0 :     final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
+    1203            0 :     return PreparationSchedule(
+    1204            0 :       id: attachedDatabase.typeMapping
+    1205            0 :           .read(DriftSqlType.string, data['${effectivePrefix}id'])!,
+    1206            0 :       scheduleId: attachedDatabase.typeMapping
+    1207            0 :           .read(DriftSqlType.string, data['${effectivePrefix}schedule_id'])!,
+    1208            0 :       preparationName: attachedDatabase.typeMapping.read(
+    1209            0 :           DriftSqlType.string, data['${effectivePrefix}preparation_name'])!,
+    1210            0 :       preparationTime: attachedDatabase.typeMapping
+    1211            0 :           .read(DriftSqlType.int, data['${effectivePrefix}preparation_time'])!,
+    1212            0 :       nextPreparationId: attachedDatabase.typeMapping.read(
+    1213            0 :           DriftSqlType.string, data['${effectivePrefix}next_preparation_id']),
+    1214              :     );
+    1215              :   }
+    1216              : 
+    1217            0 :   @override
+    1218              :   $PreparationSchedulesTable createAlias(String alias) {
+    1219            0 :     return $PreparationSchedulesTable(attachedDatabase, alias);
+    1220              :   }
+    1221              : }
+    1222              : 
+    1223              : class PreparationSchedule extends DataClass
+    1224              :     implements Insertable<PreparationSchedule> {
+    1225              :   final String id;
+    1226              :   final String scheduleId;
+    1227              :   final String preparationName;
+    1228              :   final int preparationTime;
+    1229              :   final String? nextPreparationId;
+    1230            0 :   const PreparationSchedule(
+    1231              :       {required this.id,
+    1232              :       required this.scheduleId,
+    1233              :       required this.preparationName,
+    1234              :       required this.preparationTime,
+    1235              :       this.nextPreparationId});
+    1236            0 :   @override
+    1237              :   Map<String, Expression> toColumns(bool nullToAbsent) {
+    1238            0 :     final map = <String, Expression>{};
+    1239            0 :     map['id'] = Variable<String>(id);
+    1240            0 :     map['schedule_id'] = Variable<String>(scheduleId);
+    1241            0 :     map['preparation_name'] = Variable<String>(preparationName);
+    1242            0 :     map['preparation_time'] = Variable<int>(preparationTime);
+    1243            0 :     if (!nullToAbsent || nextPreparationId != null) {
+    1244            0 :       map['next_preparation_id'] = Variable<String>(nextPreparationId);
+    1245              :     }
+    1246              :     return map;
+    1247              :   }
+    1248              : 
+    1249            0 :   PreparationSchedulesCompanion toCompanion(bool nullToAbsent) {
+    1250            0 :     return PreparationSchedulesCompanion(
+    1251            0 :       id: Value(id),
+    1252            0 :       scheduleId: Value(scheduleId),
+    1253            0 :       preparationName: Value(preparationName),
+    1254            0 :       preparationTime: Value(preparationTime),
+    1255            0 :       nextPreparationId: nextPreparationId == null && nullToAbsent
+    1256              :           ? const Value.absent()
+    1257            0 :           : Value(nextPreparationId),
+    1258              :     );
+    1259              :   }
+    1260              : 
+    1261            0 :   factory PreparationSchedule.fromJson(Map<String, dynamic> json,
+    1262              :       {ValueSerializer? serializer}) {
+    1263            0 :     serializer ??= driftRuntimeOptions.defaultSerializer;
+    1264            0 :     return PreparationSchedule(
+    1265            0 :       id: serializer.fromJson<String>(json['id']),
+    1266            0 :       scheduleId: serializer.fromJson<String>(json['scheduleId']),
+    1267            0 :       preparationName: serializer.fromJson<String>(json['preparationName']),
+    1268            0 :       preparationTime: serializer.fromJson<int>(json['preparationTime']),
+    1269              :       nextPreparationId:
+    1270            0 :           serializer.fromJson<String?>(json['nextPreparationId']),
+    1271              :     );
+    1272              :   }
+    1273            0 :   @override
+    1274              :   Map<String, dynamic> toJson({ValueSerializer? serializer}) {
+    1275            0 :     serializer ??= driftRuntimeOptions.defaultSerializer;
+    1276            0 :     return <String, dynamic>{
+    1277            0 :       'id': serializer.toJson<String>(id),
+    1278            0 :       'scheduleId': serializer.toJson<String>(scheduleId),
+    1279            0 :       'preparationName': serializer.toJson<String>(preparationName),
+    1280            0 :       'preparationTime': serializer.toJson<int>(preparationTime),
+    1281            0 :       'nextPreparationId': serializer.toJson<String?>(nextPreparationId),
+    1282              :     };
+    1283              :   }
+    1284              : 
+    1285            0 :   PreparationSchedule copyWith(
+    1286              :           {String? id,
+    1287              :           String? scheduleId,
+    1288              :           String? preparationName,
+    1289              :           int? preparationTime,
+    1290              :           Value<String?> nextPreparationId = const Value.absent()}) =>
+    1291            0 :       PreparationSchedule(
+    1292            0 :         id: id ?? this.id,
+    1293            0 :         scheduleId: scheduleId ?? this.scheduleId,
+    1294            0 :         preparationName: preparationName ?? this.preparationName,
+    1295            0 :         preparationTime: preparationTime ?? this.preparationTime,
+    1296            0 :         nextPreparationId: nextPreparationId.present
+    1297            0 :             ? nextPreparationId.value
+    1298            0 :             : this.nextPreparationId,
+    1299              :       );
+    1300            0 :   PreparationSchedule copyWithCompanion(PreparationSchedulesCompanion data) {
+    1301            0 :     return PreparationSchedule(
+    1302            0 :       id: data.id.present ? data.id.value : this.id,
+    1303              :       scheduleId:
+    1304            0 :           data.scheduleId.present ? data.scheduleId.value : this.scheduleId,
+    1305            0 :       preparationName: data.preparationName.present
+    1306            0 :           ? data.preparationName.value
+    1307            0 :           : this.preparationName,
+    1308            0 :       preparationTime: data.preparationTime.present
+    1309            0 :           ? data.preparationTime.value
+    1310            0 :           : this.preparationTime,
+    1311            0 :       nextPreparationId: data.nextPreparationId.present
+    1312            0 :           ? data.nextPreparationId.value
+    1313            0 :           : this.nextPreparationId,
+    1314              :     );
+    1315              :   }
+    1316              : 
+    1317            0 :   @override
+    1318              :   String toString() {
+    1319            0 :     return (StringBuffer('PreparationSchedule(')
+    1320            0 :           ..write('id: $id, ')
+    1321            0 :           ..write('scheduleId: $scheduleId, ')
+    1322            0 :           ..write('preparationName: $preparationName, ')
+    1323            0 :           ..write('preparationTime: $preparationTime, ')
+    1324            0 :           ..write('nextPreparationId: $nextPreparationId')
+    1325            0 :           ..write(')'))
+    1326            0 :         .toString();
+    1327              :   }
+    1328              : 
+    1329            0 :   @override
+    1330            0 :   int get hashCode => Object.hash(
+    1331            0 :       id, scheduleId, preparationName, preparationTime, nextPreparationId);
+    1332            0 :   @override
+    1333              :   bool operator ==(Object other) =>
+    1334              :       identical(this, other) ||
+    1335            0 :       (other is PreparationSchedule &&
+    1336            0 :           other.id == this.id &&
+    1337            0 :           other.scheduleId == this.scheduleId &&
+    1338            0 :           other.preparationName == this.preparationName &&
+    1339            0 :           other.preparationTime == this.preparationTime &&
+    1340            0 :           other.nextPreparationId == this.nextPreparationId);
+    1341              : }
+    1342              : 
+    1343              : class PreparationSchedulesCompanion
+    1344              :     extends UpdateCompanion<PreparationSchedule> {
+    1345              :   final Value<String> id;
+    1346              :   final Value<String> scheduleId;
+    1347              :   final Value<String> preparationName;
+    1348              :   final Value<int> preparationTime;
+    1349              :   final Value<String?> nextPreparationId;
+    1350              :   final Value<int> rowid;
+    1351            0 :   const PreparationSchedulesCompanion({
+    1352              :     this.id = const Value.absent(),
+    1353              :     this.scheduleId = const Value.absent(),
+    1354              :     this.preparationName = const Value.absent(),
+    1355              :     this.preparationTime = const Value.absent(),
+    1356              :     this.nextPreparationId = const Value.absent(),
+    1357              :     this.rowid = const Value.absent(),
+    1358              :   });
+    1359            0 :   PreparationSchedulesCompanion.insert({
+    1360              :     this.id = const Value.absent(),
+    1361              :     required String scheduleId,
+    1362              :     required String preparationName,
+    1363              :     required int preparationTime,
+    1364              :     this.nextPreparationId = const Value.absent(),
+    1365              :     this.rowid = const Value.absent(),
+    1366            0 :   })  : scheduleId = Value(scheduleId),
+    1367            0 :         preparationName = Value(preparationName),
+    1368            0 :         preparationTime = Value(preparationTime);
+    1369            0 :   static Insertable<PreparationSchedule> custom({
+    1370              :     Expression<String>? id,
+    1371              :     Expression<String>? scheduleId,
+    1372              :     Expression<String>? preparationName,
+    1373              :     Expression<int>? preparationTime,
+    1374              :     Expression<String>? nextPreparationId,
+    1375              :     Expression<int>? rowid,
+    1376              :   }) {
+    1377            0 :     return RawValuesInsertable({
+    1378            0 :       if (id != null) 'id': id,
+    1379            0 :       if (scheduleId != null) 'schedule_id': scheduleId,
+    1380            0 :       if (preparationName != null) 'preparation_name': preparationName,
+    1381            0 :       if (preparationTime != null) 'preparation_time': preparationTime,
+    1382            0 :       if (nextPreparationId != null) 'next_preparation_id': nextPreparationId,
+    1383            0 :       if (rowid != null) 'rowid': rowid,
+    1384              :     });
+    1385              :   }
+    1386              : 
+    1387            0 :   PreparationSchedulesCompanion copyWith(
+    1388              :       {Value<String>? id,
+    1389              :       Value<String>? scheduleId,
+    1390              :       Value<String>? preparationName,
+    1391              :       Value<int>? preparationTime,
+    1392              :       Value<String?>? nextPreparationId,
+    1393              :       Value<int>? rowid}) {
+    1394            0 :     return PreparationSchedulesCompanion(
+    1395            0 :       id: id ?? this.id,
+    1396            0 :       scheduleId: scheduleId ?? this.scheduleId,
+    1397            0 :       preparationName: preparationName ?? this.preparationName,
+    1398            0 :       preparationTime: preparationTime ?? this.preparationTime,
+    1399            0 :       nextPreparationId: nextPreparationId ?? this.nextPreparationId,
+    1400            0 :       rowid: rowid ?? this.rowid,
+    1401              :     );
+    1402              :   }
+    1403              : 
+    1404            0 :   @override
+    1405              :   Map<String, Expression> toColumns(bool nullToAbsent) {
+    1406            0 :     final map = <String, Expression>{};
+    1407            0 :     if (id.present) {
+    1408            0 :       map['id'] = Variable<String>(id.value);
+    1409              :     }
+    1410            0 :     if (scheduleId.present) {
+    1411            0 :       map['schedule_id'] = Variable<String>(scheduleId.value);
+    1412              :     }
+    1413            0 :     if (preparationName.present) {
+    1414            0 :       map['preparation_name'] = Variable<String>(preparationName.value);
+    1415              :     }
+    1416            0 :     if (preparationTime.present) {
+    1417            0 :       map['preparation_time'] = Variable<int>(preparationTime.value);
+    1418              :     }
+    1419            0 :     if (nextPreparationId.present) {
+    1420            0 :       map['next_preparation_id'] = Variable<String>(nextPreparationId.value);
+    1421              :     }
+    1422            0 :     if (rowid.present) {
+    1423            0 :       map['rowid'] = Variable<int>(rowid.value);
+    1424              :     }
+    1425              :     return map;
+    1426              :   }
+    1427              : 
+    1428            0 :   @override
+    1429              :   String toString() {
+    1430            0 :     return (StringBuffer('PreparationSchedulesCompanion(')
+    1431            0 :           ..write('id: $id, ')
+    1432            0 :           ..write('scheduleId: $scheduleId, ')
+    1433            0 :           ..write('preparationName: $preparationName, ')
+    1434            0 :           ..write('preparationTime: $preparationTime, ')
+    1435            0 :           ..write('nextPreparationId: $nextPreparationId, ')
+    1436            0 :           ..write('rowid: $rowid')
+    1437            0 :           ..write(')'))
+    1438            0 :         .toString();
+    1439              :   }
+    1440              : }
+    1441              : 
+    1442              : class $PreparationUsersTable extends PreparationUsers
+    1443              :     with TableInfo<$PreparationUsersTable, PreparationUser> {
+    1444              :   @override
+    1445              :   final GeneratedDatabase attachedDatabase;
+    1446              :   final String? _alias;
+    1447            3 :   $PreparationUsersTable(this.attachedDatabase, [this._alias]);
+    1448              :   static const VerificationMeta _idMeta = const VerificationMeta('id');
+    1449              :   @override
+    1450            6 :   late final GeneratedColumn<String> id = GeneratedColumn<String>(
+    1451            3 :       'id', aliasedName, false,
+    1452              :       type: DriftSqlType.string,
+    1453              :       requiredDuringInsert: false,
+    1454            0 :       clientDefault: () => Uuid().v7());
+    1455              :   static const VerificationMeta _userIdMeta = const VerificationMeta('userId');
+    1456              :   @override
+    1457            6 :   late final GeneratedColumn<String> userId = GeneratedColumn<String>(
+    1458            3 :       'user_id', aliasedName, false,
+    1459              :       type: DriftSqlType.string,
+    1460              :       requiredDuringInsert: true,
+    1461              :       defaultConstraints:
+    1462            3 :           GeneratedColumn.constraintIsAlways('REFERENCES users (id)'));
+    1463              :   static const VerificationMeta _preparationNameMeta =
+    1464              :       const VerificationMeta('preparationName');
+    1465              :   @override
+    1466            6 :   late final GeneratedColumn<String> preparationName = GeneratedColumn<String>(
+    1467            3 :       'preparation_name', aliasedName, false,
+    1468              :       additionalChecks:
+    1469            3 :           GeneratedColumn.checkTextLength(minTextLength: 1, maxTextLength: 30),
+    1470              :       type: DriftSqlType.string,
+    1471              :       requiredDuringInsert: true);
+    1472              :   static const VerificationMeta _preparationTimeMeta =
+    1473              :       const VerificationMeta('preparationTime');
+    1474              :   @override
+    1475            6 :   late final GeneratedColumn<int> preparationTime = GeneratedColumn<int>(
+    1476            3 :       'preparation_time', aliasedName, false,
+    1477              :       type: DriftSqlType.int, requiredDuringInsert: true);
+    1478              :   static const VerificationMeta _nextPreparationIdMeta =
+    1479              :       const VerificationMeta('nextPreparationId');
+    1480              :   @override
+    1481            3 :   late final GeneratedColumn<String> nextPreparationId =
+    1482            6 :       GeneratedColumn<String>('next_preparation_id', aliasedName, true,
+    1483              :           type: DriftSqlType.string,
+    1484              :           requiredDuringInsert: false,
+    1485            3 :           defaultConstraints: GeneratedColumn.constraintIsAlways(
+    1486              :               'REFERENCES preparation_users (id)'));
+    1487            3 :   @override
+    1488              :   List<GeneratedColumn> get $columns =>
+    1489           18 :       [id, userId, preparationName, preparationTime, nextPreparationId];
+    1490            3 :   @override
+    1491            6 :   String get aliasedName => _alias ?? actualTableName;
+    1492            3 :   @override
+    1493              :   String get actualTableName => $name;
+    1494              :   static const String $name = 'preparation_users';
+    1495            2 :   @override
+    1496              :   VerificationContext validateIntegrity(Insertable<PreparationUser> instance,
+    1497              :       {bool isInserting = false}) {
+    1498            2 :     final context = VerificationContext();
+    1499            2 :     final data = instance.toColumns(true);
+    1500            2 :     if (data.containsKey('id')) {
+    1501            8 :       context.handle(_idMeta, id.isAcceptableOrUnknown(data['id']!, _idMeta));
+    1502              :     }
+    1503            2 :     if (data.containsKey('user_id')) {
+    1504            2 :       context.handle(_userIdMeta,
+    1505            6 :           userId.isAcceptableOrUnknown(data['user_id']!, _userIdMeta));
+    1506              :     } else if (isInserting) {
+    1507            0 :       context.missing(_userIdMeta);
+    1508              :     }
+    1509            2 :     if (data.containsKey('preparation_name')) {
+    1510            2 :       context.handle(
+    1511              :           _preparationNameMeta,
+    1512            4 :           preparationName.isAcceptableOrUnknown(
+    1513            2 :               data['preparation_name']!, _preparationNameMeta));
+    1514              :     } else if (isInserting) {
+    1515            0 :       context.missing(_preparationNameMeta);
+    1516              :     }
+    1517            2 :     if (data.containsKey('preparation_time')) {
+    1518            2 :       context.handle(
+    1519              :           _preparationTimeMeta,
+    1520            4 :           preparationTime.isAcceptableOrUnknown(
+    1521            2 :               data['preparation_time']!, _preparationTimeMeta));
+    1522              :     } else if (isInserting) {
+    1523            0 :       context.missing(_preparationTimeMeta);
+    1524              :     }
+    1525            2 :     if (data.containsKey('next_preparation_id')) {
+    1526            2 :       context.handle(
+    1527              :           _nextPreparationIdMeta,
+    1528            4 :           nextPreparationId.isAcceptableOrUnknown(
+    1529            2 :               data['next_preparation_id']!, _nextPreparationIdMeta));
+    1530              :     }
+    1531              :     return context;
+    1532              :   }
+    1533              : 
+    1534            3 :   @override
+    1535            3 :   Set<GeneratedColumn> get $primaryKey => {id};
+    1536            2 :   @override
+    1537              :   PreparationUser map(Map<String, dynamic> data, {String? tablePrefix}) {
+    1538            0 :     final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
+    1539            2 :     return PreparationUser(
+    1540            4 :       id: attachedDatabase.typeMapping
+    1541            6 :           .read(DriftSqlType.string, data['${effectivePrefix}id'])!,
+    1542            4 :       userId: attachedDatabase.typeMapping
+    1543            6 :           .read(DriftSqlType.string, data['${effectivePrefix}user_id'])!,
+    1544            6 :       preparationName: attachedDatabase.typeMapping.read(
+    1545            4 :           DriftSqlType.string, data['${effectivePrefix}preparation_name'])!,
+    1546            4 :       preparationTime: attachedDatabase.typeMapping
+    1547            6 :           .read(DriftSqlType.int, data['${effectivePrefix}preparation_time'])!,
+    1548            6 :       nextPreparationId: attachedDatabase.typeMapping.read(
+    1549            4 :           DriftSqlType.string, data['${effectivePrefix}next_preparation_id']),
+    1550              :     );
+    1551              :   }
+    1552              : 
+    1553            0 :   @override
+    1554              :   $PreparationUsersTable createAlias(String alias) {
+    1555            0 :     return $PreparationUsersTable(attachedDatabase, alias);
+    1556              :   }
+    1557              : }
+    1558              : 
+    1559              : class PreparationUser extends DataClass implements Insertable<PreparationUser> {
+    1560              :   final String id;
+    1561              :   final String userId;
+    1562              :   final String preparationName;
+    1563              :   final int preparationTime;
+    1564              :   final String? nextPreparationId;
+    1565            2 :   const PreparationUser(
+    1566              :       {required this.id,
+    1567              :       required this.userId,
+    1568              :       required this.preparationName,
+    1569              :       required this.preparationTime,
+    1570              :       this.nextPreparationId});
+    1571            0 :   @override
+    1572              :   Map<String, Expression> toColumns(bool nullToAbsent) {
+    1573            0 :     final map = <String, Expression>{};
+    1574            0 :     map['id'] = Variable<String>(id);
+    1575            0 :     map['user_id'] = Variable<String>(userId);
+    1576            0 :     map['preparation_name'] = Variable<String>(preparationName);
+    1577            0 :     map['preparation_time'] = Variable<int>(preparationTime);
+    1578            0 :     if (!nullToAbsent || nextPreparationId != null) {
+    1579            0 :       map['next_preparation_id'] = Variable<String>(nextPreparationId);
+    1580              :     }
+    1581              :     return map;
+    1582              :   }
+    1583              : 
+    1584            2 :   PreparationUsersCompanion toCompanion(bool nullToAbsent) {
+    1585            2 :     return PreparationUsersCompanion(
+    1586            4 :       id: Value(id),
+    1587            4 :       userId: Value(userId),
+    1588            4 :       preparationName: Value(preparationName),
+    1589            4 :       preparationTime: Value(preparationTime),
+    1590            2 :       nextPreparationId: nextPreparationId == null && nullToAbsent
+    1591              :           ? const Value.absent()
+    1592            4 :           : Value(nextPreparationId),
+    1593              :     );
+    1594              :   }
+    1595              : 
+    1596            0 :   factory PreparationUser.fromJson(Map<String, dynamic> json,
+    1597              :       {ValueSerializer? serializer}) {
+    1598            0 :     serializer ??= driftRuntimeOptions.defaultSerializer;
+    1599            0 :     return PreparationUser(
+    1600            0 :       id: serializer.fromJson<String>(json['id']),
+    1601            0 :       userId: serializer.fromJson<String>(json['userId']),
+    1602            0 :       preparationName: serializer.fromJson<String>(json['preparationName']),
+    1603            0 :       preparationTime: serializer.fromJson<int>(json['preparationTime']),
+    1604              :       nextPreparationId:
+    1605            0 :           serializer.fromJson<String?>(json['nextPreparationId']),
+    1606              :     );
+    1607              :   }
+    1608            0 :   @override
+    1609              :   Map<String, dynamic> toJson({ValueSerializer? serializer}) {
+    1610            0 :     serializer ??= driftRuntimeOptions.defaultSerializer;
+    1611            0 :     return <String, dynamic>{
+    1612            0 :       'id': serializer.toJson<String>(id),
+    1613            0 :       'userId': serializer.toJson<String>(userId),
+    1614            0 :       'preparationName': serializer.toJson<String>(preparationName),
+    1615            0 :       'preparationTime': serializer.toJson<int>(preparationTime),
+    1616            0 :       'nextPreparationId': serializer.toJson<String?>(nextPreparationId),
+    1617              :     };
+    1618              :   }
+    1619              : 
+    1620            0 :   PreparationUser copyWith(
+    1621              :           {String? id,
+    1622              :           String? userId,
+    1623              :           String? preparationName,
+    1624              :           int? preparationTime,
+    1625              :           Value<String?> nextPreparationId = const Value.absent()}) =>
+    1626            0 :       PreparationUser(
+    1627            0 :         id: id ?? this.id,
+    1628            0 :         userId: userId ?? this.userId,
+    1629            0 :         preparationName: preparationName ?? this.preparationName,
+    1630            0 :         preparationTime: preparationTime ?? this.preparationTime,
+    1631            0 :         nextPreparationId: nextPreparationId.present
+    1632            0 :             ? nextPreparationId.value
+    1633            0 :             : this.nextPreparationId,
+    1634              :       );
+    1635            0 :   PreparationUser copyWithCompanion(PreparationUsersCompanion data) {
+    1636            0 :     return PreparationUser(
+    1637            0 :       id: data.id.present ? data.id.value : this.id,
+    1638            0 :       userId: data.userId.present ? data.userId.value : this.userId,
+    1639            0 :       preparationName: data.preparationName.present
+    1640            0 :           ? data.preparationName.value
+    1641            0 :           : this.preparationName,
+    1642            0 :       preparationTime: data.preparationTime.present
+    1643            0 :           ? data.preparationTime.value
+    1644            0 :           : this.preparationTime,
+    1645            0 :       nextPreparationId: data.nextPreparationId.present
+    1646            0 :           ? data.nextPreparationId.value
+    1647            0 :           : this.nextPreparationId,
+    1648              :     );
+    1649              :   }
+    1650              : 
+    1651            0 :   @override
+    1652              :   String toString() {
+    1653            0 :     return (StringBuffer('PreparationUser(')
+    1654            0 :           ..write('id: $id, ')
+    1655            0 :           ..write('userId: $userId, ')
+    1656            0 :           ..write('preparationName: $preparationName, ')
+    1657            0 :           ..write('preparationTime: $preparationTime, ')
+    1658            0 :           ..write('nextPreparationId: $nextPreparationId')
+    1659            0 :           ..write(')'))
+    1660            0 :         .toString();
+    1661              :   }
+    1662              : 
+    1663            0 :   @override
+    1664            0 :   int get hashCode => Object.hash(
+    1665            0 :       id, userId, preparationName, preparationTime, nextPreparationId);
+    1666            0 :   @override
+    1667              :   bool operator ==(Object other) =>
+    1668              :       identical(this, other) ||
+    1669            0 :       (other is PreparationUser &&
+    1670            0 :           other.id == this.id &&
+    1671            0 :           other.userId == this.userId &&
+    1672            0 :           other.preparationName == this.preparationName &&
+    1673            0 :           other.preparationTime == this.preparationTime &&
+    1674            0 :           other.nextPreparationId == this.nextPreparationId);
+    1675              : }
+    1676              : 
+    1677              : class PreparationUsersCompanion extends UpdateCompanion<PreparationUser> {
+    1678              :   final Value<String> id;
+    1679              :   final Value<String> userId;
+    1680              :   final Value<String> preparationName;
+    1681              :   final Value<int> preparationTime;
+    1682              :   final Value<String?> nextPreparationId;
+    1683              :   final Value<int> rowid;
+    1684            2 :   const PreparationUsersCompanion({
+    1685              :     this.id = const Value.absent(),
+    1686              :     this.userId = const Value.absent(),
+    1687              :     this.preparationName = const Value.absent(),
+    1688              :     this.preparationTime = const Value.absent(),
+    1689              :     this.nextPreparationId = const Value.absent(),
+    1690              :     this.rowid = const Value.absent(),
+    1691              :   });
+    1692            0 :   PreparationUsersCompanion.insert({
+    1693              :     this.id = const Value.absent(),
+    1694              :     required String userId,
+    1695              :     required String preparationName,
+    1696              :     required int preparationTime,
+    1697              :     this.nextPreparationId = const Value.absent(),
+    1698              :     this.rowid = const Value.absent(),
+    1699            0 :   })  : userId = Value(userId),
+    1700            0 :         preparationName = Value(preparationName),
+    1701            0 :         preparationTime = Value(preparationTime);
+    1702            0 :   static Insertable<PreparationUser> custom({
+    1703              :     Expression<String>? id,
+    1704              :     Expression<String>? userId,
+    1705              :     Expression<String>? preparationName,
+    1706              :     Expression<int>? preparationTime,
+    1707              :     Expression<String>? nextPreparationId,
+    1708              :     Expression<int>? rowid,
+    1709              :   }) {
+    1710            0 :     return RawValuesInsertable({
+    1711            0 :       if (id != null) 'id': id,
+    1712            0 :       if (userId != null) 'user_id': userId,
+    1713            0 :       if (preparationName != null) 'preparation_name': preparationName,
+    1714            0 :       if (preparationTime != null) 'preparation_time': preparationTime,
+    1715            0 :       if (nextPreparationId != null) 'next_preparation_id': nextPreparationId,
+    1716            0 :       if (rowid != null) 'rowid': rowid,
+    1717              :     });
+    1718              :   }
+    1719              : 
+    1720            0 :   PreparationUsersCompanion copyWith(
+    1721              :       {Value<String>? id,
+    1722              :       Value<String>? userId,
+    1723              :       Value<String>? preparationName,
+    1724              :       Value<int>? preparationTime,
+    1725              :       Value<String?>? nextPreparationId,
+    1726              :       Value<int>? rowid}) {
+    1727            0 :     return PreparationUsersCompanion(
+    1728            0 :       id: id ?? this.id,
+    1729            0 :       userId: userId ?? this.userId,
+    1730            0 :       preparationName: preparationName ?? this.preparationName,
+    1731            0 :       preparationTime: preparationTime ?? this.preparationTime,
+    1732            0 :       nextPreparationId: nextPreparationId ?? this.nextPreparationId,
+    1733            0 :       rowid: rowid ?? this.rowid,
+    1734              :     );
+    1735              :   }
+    1736              : 
+    1737            2 :   @override
+    1738              :   Map<String, Expression> toColumns(bool nullToAbsent) {
+    1739            2 :     final map = <String, Expression>{};
+    1740            4 :     if (id.present) {
+    1741            8 :       map['id'] = Variable<String>(id.value);
+    1742              :     }
+    1743            4 :     if (userId.present) {
+    1744            8 :       map['user_id'] = Variable<String>(userId.value);
+    1745              :     }
+    1746            4 :     if (preparationName.present) {
+    1747            8 :       map['preparation_name'] = Variable<String>(preparationName.value);
+    1748              :     }
+    1749            4 :     if (preparationTime.present) {
+    1750            8 :       map['preparation_time'] = Variable<int>(preparationTime.value);
+    1751              :     }
+    1752            4 :     if (nextPreparationId.present) {
+    1753            8 :       map['next_preparation_id'] = Variable<String>(nextPreparationId.value);
+    1754              :     }
+    1755            4 :     if (rowid.present) {
+    1756            0 :       map['rowid'] = Variable<int>(rowid.value);
+    1757              :     }
+    1758              :     return map;
+    1759              :   }
+    1760              : 
+    1761            0 :   @override
+    1762              :   String toString() {
+    1763            0 :     return (StringBuffer('PreparationUsersCompanion(')
+    1764            0 :           ..write('id: $id, ')
+    1765            0 :           ..write('userId: $userId, ')
+    1766            0 :           ..write('preparationName: $preparationName, ')
+    1767            0 :           ..write('preparationTime: $preparationTime, ')
+    1768            0 :           ..write('nextPreparationId: $nextPreparationId, ')
+    1769            0 :           ..write('rowid: $rowid')
+    1770            0 :           ..write(')'))
+    1771            0 :         .toString();
+    1772              :   }
+    1773              : }
+    1774              : 
+    1775              : abstract class _$AppDatabase extends GeneratedDatabase {
+    1776            8 :   _$AppDatabase(QueryExecutor e) : super(e);
+    1777            0 :   $AppDatabaseManager get managers => $AppDatabaseManager(this);
+    1778            6 :   late final $PlacesTable places = $PlacesTable(this);
+    1779            6 :   late final $SchedulesTable schedules = $SchedulesTable(this);
+    1780            6 :   late final $UsersTable users = $UsersTable(this);
+    1781            3 :   late final $PreparationSchedulesTable preparationSchedules =
+    1782            3 :       $PreparationSchedulesTable(this);
+    1783            3 :   late final $PreparationUsersTable preparationUsers =
+    1784            3 :       $PreparationUsersTable(this);
+    1785              :   late final ScheduleDao scheduleDao = ScheduleDao(this as AppDatabase);
+    1786            2 :   late final PlaceDao placeDao = PlaceDao(this as AppDatabase);
+    1787              :   late final UserDao userDao = UserDao(this as AppDatabase);
+    1788              :   late final PreparationScheduleDao preparationScheduleDao =
+    1789              :       PreparationScheduleDao(this as AppDatabase);
+    1790              :   late final PreparationUserDao preparationUserDao =
+    1791              :       PreparationUserDao(this as AppDatabase);
+    1792            0 :   @override
+    1793              :   Iterable<TableInfo<Table, Object?>> get allTables =>
+    1794            0 :       allSchemaEntities.whereType<TableInfo<Table, Object?>>();
+    1795            3 :   @override
+    1796              :   List<DatabaseSchemaEntity> get allSchemaEntities =>
+    1797           18 :       [places, schedules, users, preparationSchedules, preparationUsers];
+    1798              : }
+    1799              : 
+    1800              : typedef $$PlacesTableCreateCompanionBuilder = PlacesCompanion Function({
+    1801              :   Value<String> id,
+    1802              :   required String placeName,
+    1803              :   Value<int> rowid,
+    1804              : });
+    1805              : typedef $$PlacesTableUpdateCompanionBuilder = PlacesCompanion Function({
+    1806              :   Value<String> id,
+    1807              :   Value<String> placeName,
+    1808              :   Value<int> rowid,
+    1809              : });
+    1810              : 
+    1811              : final class $$PlacesTableReferences
+    1812              :     extends BaseReferences<_$AppDatabase, $PlacesTable, Place> {
+    1813            0 :   $$PlacesTableReferences(super.$_db, super.$_table, super.$_typedResult);
+    1814              : 
+    1815            0 :   static MultiTypedResultKey<$SchedulesTable, List<Schedule>>
+    1816            0 :       _schedulesRefsTable(_$AppDatabase db) => MultiTypedResultKey.fromTable(
+    1817            0 :           db.schedules,
+    1818            0 :           aliasName: $_aliasNameGenerator(db.places.id, db.schedules.placeId));
+    1819              : 
+    1820            0 :   $$SchedulesTableProcessedTableManager get schedulesRefs {
+    1821            0 :     final manager = $$SchedulesTableTableManager($_db, $_db.schedules)
+    1822            0 :         .filter((f) => f.placeId.id.sqlEquals($_itemColumn<String>('id')!));
+    1823              : 
+    1824            0 :     final cache = $_typedResult.readTableOrNull(_schedulesRefsTable($_db));
+    1825            0 :     return ProcessedTableManager(
+    1826            0 :         manager.$state.copyWith(prefetchedData: cache));
+    1827              :   }
+    1828              : }
+    1829              : 
+    1830              : class $$PlacesTableFilterComposer
+    1831              :     extends Composer<_$AppDatabase, $PlacesTable> {
+    1832            0 :   $$PlacesTableFilterComposer({
+    1833              :     required super.$db,
+    1834              :     required super.$table,
+    1835              :     super.joinBuilder,
+    1836              :     super.$addJoinBuilderToRootComposer,
+    1837              :     super.$removeJoinBuilderFromRootComposer,
+    1838              :   });
+    1839            0 :   ColumnFilters<String> get id => $composableBuilder(
+    1840            0 :       column: $table.id, builder: (column) => ColumnFilters(column));
+    1841              : 
+    1842            0 :   ColumnFilters<String> get placeName => $composableBuilder(
+    1843            0 :       column: $table.placeName, builder: (column) => ColumnFilters(column));
+    1844              : 
+    1845            0 :   Expression<bool> schedulesRefs(
+    1846              :       Expression<bool> Function($$SchedulesTableFilterComposer f) f) {
+    1847            0 :     final $$SchedulesTableFilterComposer composer = $composerBuilder(
+    1848              :         composer: this,
+    1849            0 :         getCurrentColumn: (t) => t.id,
+    1850            0 :         referencedTable: $db.schedules,
+    1851            0 :         getReferencedColumn: (t) => t.placeId,
+    1852            0 :         builder: (joinBuilder,
+    1853              :                 {$addJoinBuilderToRootComposer,
+    1854              :                 $removeJoinBuilderFromRootComposer}) =>
+    1855            0 :             $$SchedulesTableFilterComposer(
+    1856            0 :               $db: $db,
+    1857            0 :               $table: $db.schedules,
+    1858              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    1859              :               joinBuilder: joinBuilder,
+    1860              :               $removeJoinBuilderFromRootComposer:
+    1861              :                   $removeJoinBuilderFromRootComposer,
+    1862              :             ));
+    1863            0 :     return f(composer);
+    1864              :   }
+    1865              : }
+    1866              : 
+    1867              : class $$PlacesTableOrderingComposer
+    1868              :     extends Composer<_$AppDatabase, $PlacesTable> {
+    1869            0 :   $$PlacesTableOrderingComposer({
+    1870              :     required super.$db,
+    1871              :     required super.$table,
+    1872              :     super.joinBuilder,
+    1873              :     super.$addJoinBuilderToRootComposer,
+    1874              :     super.$removeJoinBuilderFromRootComposer,
+    1875              :   });
+    1876            0 :   ColumnOrderings<String> get id => $composableBuilder(
+    1877            0 :       column: $table.id, builder: (column) => ColumnOrderings(column));
+    1878              : 
+    1879            0 :   ColumnOrderings<String> get placeName => $composableBuilder(
+    1880            0 :       column: $table.placeName, builder: (column) => ColumnOrderings(column));
+    1881              : }
+    1882              : 
+    1883              : class $$PlacesTableAnnotationComposer
+    1884              :     extends Composer<_$AppDatabase, $PlacesTable> {
+    1885            0 :   $$PlacesTableAnnotationComposer({
+    1886              :     required super.$db,
+    1887              :     required super.$table,
+    1888              :     super.joinBuilder,
+    1889              :     super.$addJoinBuilderToRootComposer,
+    1890              :     super.$removeJoinBuilderFromRootComposer,
+    1891              :   });
+    1892            0 :   GeneratedColumn<String> get id =>
+    1893            0 :       $composableBuilder(column: $table.id, builder: (column) => column);
+    1894              : 
+    1895            0 :   GeneratedColumn<String> get placeName =>
+    1896            0 :       $composableBuilder(column: $table.placeName, builder: (column) => column);
+    1897              : 
+    1898            0 :   Expression<T> schedulesRefs<T extends Object>(
+    1899              :       Expression<T> Function($$SchedulesTableAnnotationComposer a) f) {
+    1900            0 :     final $$SchedulesTableAnnotationComposer composer = $composerBuilder(
+    1901              :         composer: this,
+    1902            0 :         getCurrentColumn: (t) => t.id,
+    1903            0 :         referencedTable: $db.schedules,
+    1904            0 :         getReferencedColumn: (t) => t.placeId,
+    1905            0 :         builder: (joinBuilder,
+    1906              :                 {$addJoinBuilderToRootComposer,
+    1907              :                 $removeJoinBuilderFromRootComposer}) =>
+    1908            0 :             $$SchedulesTableAnnotationComposer(
+    1909            0 :               $db: $db,
+    1910            0 :               $table: $db.schedules,
+    1911              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    1912              :               joinBuilder: joinBuilder,
+    1913              :               $removeJoinBuilderFromRootComposer:
+    1914              :                   $removeJoinBuilderFromRootComposer,
+    1915              :             ));
+    1916            0 :     return f(composer);
+    1917              :   }
+    1918              : }
+    1919              : 
+    1920              : class $$PlacesTableTableManager extends RootTableManager<
+    1921              :     _$AppDatabase,
+    1922              :     $PlacesTable,
+    1923              :     Place,
+    1924              :     $$PlacesTableFilterComposer,
+    1925              :     $$PlacesTableOrderingComposer,
+    1926              :     $$PlacesTableAnnotationComposer,
+    1927              :     $$PlacesTableCreateCompanionBuilder,
+    1928              :     $$PlacesTableUpdateCompanionBuilder,
+    1929              :     (Place, $$PlacesTableReferences),
+    1930              :     Place,
+    1931              :     PrefetchHooks Function({bool schedulesRefs})> {
+    1932            0 :   $$PlacesTableTableManager(_$AppDatabase db, $PlacesTable table)
+    1933            0 :       : super(TableManagerState(
+    1934              :           db: db,
+    1935              :           table: table,
+    1936            0 :           createFilteringComposer: () =>
+    1937            0 :               $$PlacesTableFilterComposer($db: db, $table: table),
+    1938            0 :           createOrderingComposer: () =>
+    1939            0 :               $$PlacesTableOrderingComposer($db: db, $table: table),
+    1940            0 :           createComputedFieldComposer: () =>
+    1941            0 :               $$PlacesTableAnnotationComposer($db: db, $table: table),
+    1942            0 :           updateCompanionCallback: ({
+    1943              :             Value<String> id = const Value.absent(),
+    1944              :             Value<String> placeName = const Value.absent(),
+    1945              :             Value<int> rowid = const Value.absent(),
+    1946              :           }) =>
+    1947            0 :               PlacesCompanion(
+    1948              :             id: id,
+    1949              :             placeName: placeName,
+    1950              :             rowid: rowid,
+    1951              :           ),
+    1952            0 :           createCompanionCallback: ({
+    1953              :             Value<String> id = const Value.absent(),
+    1954              :             required String placeName,
+    1955              :             Value<int> rowid = const Value.absent(),
+    1956              :           }) =>
+    1957            0 :               PlacesCompanion.insert(
+    1958              :             id: id,
+    1959              :             placeName: placeName,
+    1960              :             rowid: rowid,
+    1961              :           ),
+    1962            0 :           withReferenceMapper: (p0) => p0
+    1963            0 :               .map((e) =>
+    1964            0 :                   (e.readTable(table), $$PlacesTableReferences(db, table, e)))
+    1965            0 :               .toList(),
+    1966            0 :           prefetchHooksCallback: ({schedulesRefs = false}) {
+    1967            0 :             return PrefetchHooks(
+    1968              :               db: db,
+    1969            0 :               explicitlyWatchedTables: [if (schedulesRefs) db.schedules],
+    1970              :               addJoins: null,
+    1971            0 :               getPrefetchedDataCallback: (items) async {
+    1972            0 :                 return [
+    1973              :                   if (schedulesRefs)
+    1974            0 :                     await $_getPrefetchedData<Place, $PlacesTable, Schedule>(
+    1975              :                         currentTable: table,
+    1976              :                         referencedTable:
+    1977            0 :                             $$PlacesTableReferences._schedulesRefsTable(db),
+    1978            0 :                         managerFromTypedResult: (p0) =>
+    1979            0 :                             $$PlacesTableReferences(db, table, p0)
+    1980            0 :                                 .schedulesRefs,
+    1981            0 :                         referencedItemsForCurrentItem: (item,
+    1982              :                                 referencedItems) =>
+    1983            0 :                             referencedItems.where((e) => e.placeId == item.id),
+    1984              :                         typedResults: items)
+    1985              :                 ];
+    1986              :               },
+    1987              :             );
+    1988              :           },
+    1989              :         ));
+    1990              : }
+    1991              : 
+    1992              : typedef $$PlacesTableProcessedTableManager = ProcessedTableManager<
+    1993              :     _$AppDatabase,
+    1994              :     $PlacesTable,
+    1995              :     Place,
+    1996              :     $$PlacesTableFilterComposer,
+    1997              :     $$PlacesTableOrderingComposer,
+    1998              :     $$PlacesTableAnnotationComposer,
+    1999              :     $$PlacesTableCreateCompanionBuilder,
+    2000              :     $$PlacesTableUpdateCompanionBuilder,
+    2001              :     (Place, $$PlacesTableReferences),
+    2002              :     Place,
+    2003              :     PrefetchHooks Function({bool schedulesRefs})>;
+    2004              : typedef $$SchedulesTableCreateCompanionBuilder = SchedulesCompanion Function({
+    2005              :   Value<String> id,
+    2006              :   required String placeId,
+    2007              :   required String scheduleName,
+    2008              :   required DateTime scheduleTime,
+    2009              :   required Duration moveTime,
+    2010              :   Value<bool> isChanged,
+    2011              :   Value<bool> isStarted,
+    2012              :   Value<Duration?> scheduleSpareTime,
+    2013              :   Value<String?> scheduleNote,
+    2014              :   Value<int> latenessTime,
+    2015              :   Value<int> rowid,
+    2016              : });
+    2017              : typedef $$SchedulesTableUpdateCompanionBuilder = SchedulesCompanion Function({
+    2018              :   Value<String> id,
+    2019              :   Value<String> placeId,
+    2020              :   Value<String> scheduleName,
+    2021              :   Value<DateTime> scheduleTime,
+    2022              :   Value<Duration> moveTime,
+    2023              :   Value<bool> isChanged,
+    2024              :   Value<bool> isStarted,
+    2025              :   Value<Duration?> scheduleSpareTime,
+    2026              :   Value<String?> scheduleNote,
+    2027              :   Value<int> latenessTime,
+    2028              :   Value<int> rowid,
+    2029              : });
+    2030              : 
+    2031              : final class $$SchedulesTableReferences
+    2032              :     extends BaseReferences<_$AppDatabase, $SchedulesTable, Schedule> {
+    2033            0 :   $$SchedulesTableReferences(super.$_db, super.$_table, super.$_typedResult);
+    2034              : 
+    2035            0 :   static $PlacesTable _placeIdTable(_$AppDatabase db) => db.places
+    2036            0 :       .createAlias($_aliasNameGenerator(db.schedules.placeId, db.places.id));
+    2037              : 
+    2038            0 :   $$PlacesTableProcessedTableManager get placeId {
+    2039            0 :     final $_column = $_itemColumn<String>('place_id')!;
+    2040              : 
+    2041            0 :     final manager = $$PlacesTableTableManager($_db, $_db.places)
+    2042            0 :         .filter((f) => f.id.sqlEquals($_column));
+    2043            0 :     final item = $_typedResult.readTableOrNull(_placeIdTable($_db));
+    2044              :     if (item == null) return manager;
+    2045            0 :     return ProcessedTableManager(
+    2046            0 :         manager.$state.copyWith(prefetchedData: [item]));
+    2047              :   }
+    2048              : 
+    2049            0 :   static MultiTypedResultKey<$PreparationSchedulesTable,
+    2050              :       List<PreparationSchedule>> _preparationSchedulesRefsTable(
+    2051              :           _$AppDatabase db) =>
+    2052            0 :       MultiTypedResultKey.fromTable(db.preparationSchedules,
+    2053            0 :           aliasName: $_aliasNameGenerator(
+    2054            0 :               db.schedules.id, db.preparationSchedules.scheduleId));
+    2055              : 
+    2056            0 :   $$PreparationSchedulesTableProcessedTableManager
+    2057              :       get preparationSchedulesRefs {
+    2058            0 :     final manager = $$PreparationSchedulesTableTableManager(
+    2059            0 :             $_db, $_db.preparationSchedules)
+    2060            0 :         .filter((f) => f.scheduleId.id.sqlEquals($_itemColumn<String>('id')!));
+    2061              : 
+    2062              :     final cache =
+    2063            0 :         $_typedResult.readTableOrNull(_preparationSchedulesRefsTable($_db));
+    2064            0 :     return ProcessedTableManager(
+    2065            0 :         manager.$state.copyWith(prefetchedData: cache));
+    2066              :   }
+    2067              : }
+    2068              : 
+    2069              : class $$SchedulesTableFilterComposer
+    2070              :     extends Composer<_$AppDatabase, $SchedulesTable> {
+    2071            0 :   $$SchedulesTableFilterComposer({
+    2072              :     required super.$db,
+    2073              :     required super.$table,
+    2074              :     super.joinBuilder,
+    2075              :     super.$addJoinBuilderToRootComposer,
+    2076              :     super.$removeJoinBuilderFromRootComposer,
+    2077              :   });
+    2078            0 :   ColumnFilters<String> get id => $composableBuilder(
+    2079            0 :       column: $table.id, builder: (column) => ColumnFilters(column));
+    2080              : 
+    2081            0 :   ColumnFilters<String> get scheduleName => $composableBuilder(
+    2082            0 :       column: $table.scheduleName, builder: (column) => ColumnFilters(column));
+    2083              : 
+    2084            0 :   ColumnFilters<DateTime> get scheduleTime => $composableBuilder(
+    2085            0 :       column: $table.scheduleTime, builder: (column) => ColumnFilters(column));
+    2086              : 
+    2087            0 :   ColumnWithTypeConverterFilters<Duration, Duration, int> get moveTime =>
+    2088            0 :       $composableBuilder(
+    2089            0 :           column: $table.moveTime,
+    2090            0 :           builder: (column) => ColumnWithTypeConverterFilters(column));
+    2091              : 
+    2092            0 :   ColumnFilters<bool> get isChanged => $composableBuilder(
+    2093            0 :       column: $table.isChanged, builder: (column) => ColumnFilters(column));
+    2094              : 
+    2095            0 :   ColumnFilters<bool> get isStarted => $composableBuilder(
+    2096            0 :       column: $table.isStarted, builder: (column) => ColumnFilters(column));
+    2097              : 
+    2098            0 :   ColumnWithTypeConverterFilters<Duration?, Duration, int>
+    2099            0 :       get scheduleSpareTime => $composableBuilder(
+    2100            0 :           column: $table.scheduleSpareTime,
+    2101            0 :           builder: (column) => ColumnWithTypeConverterFilters(column));
+    2102              : 
+    2103            0 :   ColumnFilters<String> get scheduleNote => $composableBuilder(
+    2104            0 :       column: $table.scheduleNote, builder: (column) => ColumnFilters(column));
+    2105              : 
+    2106            0 :   ColumnFilters<int> get latenessTime => $composableBuilder(
+    2107            0 :       column: $table.latenessTime, builder: (column) => ColumnFilters(column));
+    2108              : 
+    2109            0 :   $$PlacesTableFilterComposer get placeId {
+    2110            0 :     final $$PlacesTableFilterComposer composer = $composerBuilder(
+    2111              :         composer: this,
+    2112            0 :         getCurrentColumn: (t) => t.placeId,
+    2113            0 :         referencedTable: $db.places,
+    2114            0 :         getReferencedColumn: (t) => t.id,
+    2115            0 :         builder: (joinBuilder,
+    2116              :                 {$addJoinBuilderToRootComposer,
+    2117              :                 $removeJoinBuilderFromRootComposer}) =>
+    2118            0 :             $$PlacesTableFilterComposer(
+    2119            0 :               $db: $db,
+    2120            0 :               $table: $db.places,
+    2121              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2122              :               joinBuilder: joinBuilder,
+    2123              :               $removeJoinBuilderFromRootComposer:
+    2124              :                   $removeJoinBuilderFromRootComposer,
+    2125              :             ));
+    2126              :     return composer;
+    2127              :   }
+    2128              : 
+    2129            0 :   Expression<bool> preparationSchedulesRefs(
+    2130              :       Expression<bool> Function($$PreparationSchedulesTableFilterComposer f)
+    2131              :           f) {
+    2132            0 :     final $$PreparationSchedulesTableFilterComposer composer = $composerBuilder(
+    2133              :         composer: this,
+    2134            0 :         getCurrentColumn: (t) => t.id,
+    2135            0 :         referencedTable: $db.preparationSchedules,
+    2136            0 :         getReferencedColumn: (t) => t.scheduleId,
+    2137            0 :         builder: (joinBuilder,
+    2138              :                 {$addJoinBuilderToRootComposer,
+    2139              :                 $removeJoinBuilderFromRootComposer}) =>
+    2140            0 :             $$PreparationSchedulesTableFilterComposer(
+    2141            0 :               $db: $db,
+    2142            0 :               $table: $db.preparationSchedules,
+    2143              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2144              :               joinBuilder: joinBuilder,
+    2145              :               $removeJoinBuilderFromRootComposer:
+    2146              :                   $removeJoinBuilderFromRootComposer,
+    2147              :             ));
+    2148            0 :     return f(composer);
+    2149              :   }
+    2150              : }
+    2151              : 
+    2152              : class $$SchedulesTableOrderingComposer
+    2153              :     extends Composer<_$AppDatabase, $SchedulesTable> {
+    2154            0 :   $$SchedulesTableOrderingComposer({
+    2155              :     required super.$db,
+    2156              :     required super.$table,
+    2157              :     super.joinBuilder,
+    2158              :     super.$addJoinBuilderToRootComposer,
+    2159              :     super.$removeJoinBuilderFromRootComposer,
+    2160              :   });
+    2161            0 :   ColumnOrderings<String> get id => $composableBuilder(
+    2162            0 :       column: $table.id, builder: (column) => ColumnOrderings(column));
+    2163              : 
+    2164            0 :   ColumnOrderings<String> get scheduleName => $composableBuilder(
+    2165            0 :       column: $table.scheduleName,
+    2166            0 :       builder: (column) => ColumnOrderings(column));
+    2167              : 
+    2168            0 :   ColumnOrderings<DateTime> get scheduleTime => $composableBuilder(
+    2169            0 :       column: $table.scheduleTime,
+    2170            0 :       builder: (column) => ColumnOrderings(column));
+    2171              : 
+    2172            0 :   ColumnOrderings<int> get moveTime => $composableBuilder(
+    2173            0 :       column: $table.moveTime, builder: (column) => ColumnOrderings(column));
+    2174              : 
+    2175            0 :   ColumnOrderings<bool> get isChanged => $composableBuilder(
+    2176            0 :       column: $table.isChanged, builder: (column) => ColumnOrderings(column));
+    2177              : 
+    2178            0 :   ColumnOrderings<bool> get isStarted => $composableBuilder(
+    2179            0 :       column: $table.isStarted, builder: (column) => ColumnOrderings(column));
+    2180              : 
+    2181            0 :   ColumnOrderings<int> get scheduleSpareTime => $composableBuilder(
+    2182            0 :       column: $table.scheduleSpareTime,
+    2183            0 :       builder: (column) => ColumnOrderings(column));
+    2184              : 
+    2185            0 :   ColumnOrderings<String> get scheduleNote => $composableBuilder(
+    2186            0 :       column: $table.scheduleNote,
+    2187            0 :       builder: (column) => ColumnOrderings(column));
+    2188              : 
+    2189            0 :   ColumnOrderings<int> get latenessTime => $composableBuilder(
+    2190            0 :       column: $table.latenessTime,
+    2191            0 :       builder: (column) => ColumnOrderings(column));
+    2192              : 
+    2193            0 :   $$PlacesTableOrderingComposer get placeId {
+    2194            0 :     final $$PlacesTableOrderingComposer composer = $composerBuilder(
+    2195              :         composer: this,
+    2196            0 :         getCurrentColumn: (t) => t.placeId,
+    2197            0 :         referencedTable: $db.places,
+    2198            0 :         getReferencedColumn: (t) => t.id,
+    2199            0 :         builder: (joinBuilder,
+    2200              :                 {$addJoinBuilderToRootComposer,
+    2201              :                 $removeJoinBuilderFromRootComposer}) =>
+    2202            0 :             $$PlacesTableOrderingComposer(
+    2203            0 :               $db: $db,
+    2204            0 :               $table: $db.places,
+    2205              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2206              :               joinBuilder: joinBuilder,
+    2207              :               $removeJoinBuilderFromRootComposer:
+    2208              :                   $removeJoinBuilderFromRootComposer,
+    2209              :             ));
+    2210              :     return composer;
+    2211              :   }
+    2212              : }
+    2213              : 
+    2214              : class $$SchedulesTableAnnotationComposer
+    2215              :     extends Composer<_$AppDatabase, $SchedulesTable> {
+    2216            0 :   $$SchedulesTableAnnotationComposer({
+    2217              :     required super.$db,
+    2218              :     required super.$table,
+    2219              :     super.joinBuilder,
+    2220              :     super.$addJoinBuilderToRootComposer,
+    2221              :     super.$removeJoinBuilderFromRootComposer,
+    2222              :   });
+    2223            0 :   GeneratedColumn<String> get id =>
+    2224            0 :       $composableBuilder(column: $table.id, builder: (column) => column);
+    2225              : 
+    2226            0 :   GeneratedColumn<String> get scheduleName => $composableBuilder(
+    2227            0 :       column: $table.scheduleName, builder: (column) => column);
+    2228              : 
+    2229            0 :   GeneratedColumn<DateTime> get scheduleTime => $composableBuilder(
+    2230            0 :       column: $table.scheduleTime, builder: (column) => column);
+    2231              : 
+    2232            0 :   GeneratedColumnWithTypeConverter<Duration, int> get moveTime =>
+    2233            0 :       $composableBuilder(column: $table.moveTime, builder: (column) => column);
+    2234              : 
+    2235            0 :   GeneratedColumn<bool> get isChanged =>
+    2236            0 :       $composableBuilder(column: $table.isChanged, builder: (column) => column);
+    2237              : 
+    2238            0 :   GeneratedColumn<bool> get isStarted =>
+    2239            0 :       $composableBuilder(column: $table.isStarted, builder: (column) => column);
+    2240              : 
+    2241            0 :   GeneratedColumnWithTypeConverter<Duration?, int> get scheduleSpareTime =>
+    2242            0 :       $composableBuilder(
+    2243            0 :           column: $table.scheduleSpareTime, builder: (column) => column);
+    2244              : 
+    2245            0 :   GeneratedColumn<String> get scheduleNote => $composableBuilder(
+    2246            0 :       column: $table.scheduleNote, builder: (column) => column);
+    2247              : 
+    2248            0 :   GeneratedColumn<int> get latenessTime => $composableBuilder(
+    2249            0 :       column: $table.latenessTime, builder: (column) => column);
+    2250              : 
+    2251            0 :   $$PlacesTableAnnotationComposer get placeId {
+    2252            0 :     final $$PlacesTableAnnotationComposer composer = $composerBuilder(
+    2253              :         composer: this,
+    2254            0 :         getCurrentColumn: (t) => t.placeId,
+    2255            0 :         referencedTable: $db.places,
+    2256            0 :         getReferencedColumn: (t) => t.id,
+    2257            0 :         builder: (joinBuilder,
+    2258              :                 {$addJoinBuilderToRootComposer,
+    2259              :                 $removeJoinBuilderFromRootComposer}) =>
+    2260            0 :             $$PlacesTableAnnotationComposer(
+    2261            0 :               $db: $db,
+    2262            0 :               $table: $db.places,
+    2263              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2264              :               joinBuilder: joinBuilder,
+    2265              :               $removeJoinBuilderFromRootComposer:
+    2266              :                   $removeJoinBuilderFromRootComposer,
+    2267              :             ));
+    2268              :     return composer;
+    2269              :   }
+    2270              : 
+    2271            0 :   Expression<T> preparationSchedulesRefs<T extends Object>(
+    2272              :       Expression<T> Function($$PreparationSchedulesTableAnnotationComposer a)
+    2273              :           f) {
+    2274              :     final $$PreparationSchedulesTableAnnotationComposer composer =
+    2275            0 :         $composerBuilder(
+    2276              :             composer: this,
+    2277            0 :             getCurrentColumn: (t) => t.id,
+    2278            0 :             referencedTable: $db.preparationSchedules,
+    2279            0 :             getReferencedColumn: (t) => t.scheduleId,
+    2280            0 :             builder: (joinBuilder,
+    2281              :                     {$addJoinBuilderToRootComposer,
+    2282              :                     $removeJoinBuilderFromRootComposer}) =>
+    2283            0 :                 $$PreparationSchedulesTableAnnotationComposer(
+    2284            0 :                   $db: $db,
+    2285            0 :                   $table: $db.preparationSchedules,
+    2286              :                   $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2287              :                   joinBuilder: joinBuilder,
+    2288              :                   $removeJoinBuilderFromRootComposer:
+    2289              :                       $removeJoinBuilderFromRootComposer,
+    2290              :                 ));
+    2291            0 :     return f(composer);
+    2292              :   }
+    2293              : }
+    2294              : 
+    2295              : class $$SchedulesTableTableManager extends RootTableManager<
+    2296              :     _$AppDatabase,
+    2297              :     $SchedulesTable,
+    2298              :     Schedule,
+    2299              :     $$SchedulesTableFilterComposer,
+    2300              :     $$SchedulesTableOrderingComposer,
+    2301              :     $$SchedulesTableAnnotationComposer,
+    2302              :     $$SchedulesTableCreateCompanionBuilder,
+    2303              :     $$SchedulesTableUpdateCompanionBuilder,
+    2304              :     (Schedule, $$SchedulesTableReferences),
+    2305              :     Schedule,
+    2306              :     PrefetchHooks Function({bool placeId, bool preparationSchedulesRefs})> {
+    2307            0 :   $$SchedulesTableTableManager(_$AppDatabase db, $SchedulesTable table)
+    2308            0 :       : super(TableManagerState(
+    2309              :           db: db,
+    2310              :           table: table,
+    2311            0 :           createFilteringComposer: () =>
+    2312            0 :               $$SchedulesTableFilterComposer($db: db, $table: table),
+    2313            0 :           createOrderingComposer: () =>
+    2314            0 :               $$SchedulesTableOrderingComposer($db: db, $table: table),
+    2315            0 :           createComputedFieldComposer: () =>
+    2316            0 :               $$SchedulesTableAnnotationComposer($db: db, $table: table),
+    2317            0 :           updateCompanionCallback: ({
+    2318              :             Value<String> id = const Value.absent(),
+    2319              :             Value<String> placeId = const Value.absent(),
+    2320              :             Value<String> scheduleName = const Value.absent(),
+    2321              :             Value<DateTime> scheduleTime = const Value.absent(),
+    2322              :             Value<Duration> moveTime = const Value.absent(),
+    2323              :             Value<bool> isChanged = const Value.absent(),
+    2324              :             Value<bool> isStarted = const Value.absent(),
+    2325              :             Value<Duration?> scheduleSpareTime = const Value.absent(),
+    2326              :             Value<String?> scheduleNote = const Value.absent(),
+    2327              :             Value<int> latenessTime = const Value.absent(),
+    2328              :             Value<int> rowid = const Value.absent(),
+    2329              :           }) =>
+    2330            0 :               SchedulesCompanion(
+    2331              :             id: id,
+    2332              :             placeId: placeId,
+    2333              :             scheduleName: scheduleName,
+    2334              :             scheduleTime: scheduleTime,
+    2335              :             moveTime: moveTime,
+    2336              :             isChanged: isChanged,
+    2337              :             isStarted: isStarted,
+    2338              :             scheduleSpareTime: scheduleSpareTime,
+    2339              :             scheduleNote: scheduleNote,
+    2340              :             latenessTime: latenessTime,
+    2341              :             rowid: rowid,
+    2342              :           ),
+    2343            0 :           createCompanionCallback: ({
+    2344              :             Value<String> id = const Value.absent(),
+    2345              :             required String placeId,
+    2346              :             required String scheduleName,
+    2347              :             required DateTime scheduleTime,
+    2348              :             required Duration moveTime,
+    2349              :             Value<bool> isChanged = const Value.absent(),
+    2350              :             Value<bool> isStarted = const Value.absent(),
+    2351              :             Value<Duration?> scheduleSpareTime = const Value.absent(),
+    2352              :             Value<String?> scheduleNote = const Value.absent(),
+    2353              :             Value<int> latenessTime = const Value.absent(),
+    2354              :             Value<int> rowid = const Value.absent(),
+    2355              :           }) =>
+    2356            0 :               SchedulesCompanion.insert(
+    2357              :             id: id,
+    2358              :             placeId: placeId,
+    2359              :             scheduleName: scheduleName,
+    2360              :             scheduleTime: scheduleTime,
+    2361              :             moveTime: moveTime,
+    2362              :             isChanged: isChanged,
+    2363              :             isStarted: isStarted,
+    2364              :             scheduleSpareTime: scheduleSpareTime,
+    2365              :             scheduleNote: scheduleNote,
+    2366              :             latenessTime: latenessTime,
+    2367              :             rowid: rowid,
+    2368              :           ),
+    2369            0 :           withReferenceMapper: (p0) => p0
+    2370            0 :               .map((e) => (
+    2371            0 :                     e.readTable(table),
+    2372            0 :                     $$SchedulesTableReferences(db, table, e)
+    2373              :                   ))
+    2374            0 :               .toList(),
+    2375            0 :           prefetchHooksCallback: (
+    2376              :               {placeId = false, preparationSchedulesRefs = false}) {
+    2377            0 :             return PrefetchHooks(
+    2378              :               db: db,
+    2379            0 :               explicitlyWatchedTables: [
+    2380            0 :                 if (preparationSchedulesRefs) db.preparationSchedules
+    2381              :               ],
+    2382              :               addJoins: <
+    2383              :                   T extends TableManagerState<
+    2384              :                       dynamic,
+    2385              :                       dynamic,
+    2386              :                       dynamic,
+    2387              :                       dynamic,
+    2388              :                       dynamic,
+    2389              :                       dynamic,
+    2390              :                       dynamic,
+    2391              :                       dynamic,
+    2392              :                       dynamic,
+    2393              :                       dynamic,
+    2394            0 :                       dynamic>>(state) {
+    2395              :                 if (placeId) {
+    2396            0 :                   state = state.withJoin(
+    2397              :                     currentTable: table,
+    2398            0 :                     currentColumn: table.placeId,
+    2399              :                     referencedTable:
+    2400            0 :                         $$SchedulesTableReferences._placeIdTable(db),
+    2401              :                     referencedColumn:
+    2402            0 :                         $$SchedulesTableReferences._placeIdTable(db).id,
+    2403              :                   ) as T;
+    2404              :                 }
+    2405              : 
+    2406              :                 return state;
+    2407              :               },
+    2408            0 :               getPrefetchedDataCallback: (items) async {
+    2409            0 :                 return [
+    2410              :                   if (preparationSchedulesRefs)
+    2411            0 :                     await $_getPrefetchedData<Schedule, $SchedulesTable,
+    2412              :                             PreparationSchedule>(
+    2413              :                         currentTable: table,
+    2414              :                         referencedTable: $$SchedulesTableReferences
+    2415            0 :                             ._preparationSchedulesRefsTable(db),
+    2416            0 :                         managerFromTypedResult: (p0) =>
+    2417            0 :                             $$SchedulesTableReferences(db, table, p0)
+    2418            0 :                                 .preparationSchedulesRefs,
+    2419              :                         referencedItemsForCurrentItem:
+    2420            0 :                             (item, referencedItems) => referencedItems
+    2421            0 :                                 .where((e) => e.scheduleId == item.id),
+    2422              :                         typedResults: items)
+    2423              :                 ];
+    2424              :               },
+    2425              :             );
+    2426              :           },
+    2427              :         ));
+    2428              : }
+    2429              : 
+    2430              : typedef $$SchedulesTableProcessedTableManager = ProcessedTableManager<
+    2431              :     _$AppDatabase,
+    2432              :     $SchedulesTable,
+    2433              :     Schedule,
+    2434              :     $$SchedulesTableFilterComposer,
+    2435              :     $$SchedulesTableOrderingComposer,
+    2436              :     $$SchedulesTableAnnotationComposer,
+    2437              :     $$SchedulesTableCreateCompanionBuilder,
+    2438              :     $$SchedulesTableUpdateCompanionBuilder,
+    2439              :     (Schedule, $$SchedulesTableReferences),
+    2440              :     Schedule,
+    2441              :     PrefetchHooks Function({bool placeId, bool preparationSchedulesRefs})>;
+    2442              : typedef $$UsersTableCreateCompanionBuilder = UsersCompanion Function({
+    2443              :   Value<String> id,
+    2444              :   required String email,
+    2445              :   required String name,
+    2446              :   required int spareTime,
+    2447              :   required String note,
+    2448              :   required double score,
+    2449              :   Value<int> rowid,
+    2450              : });
+    2451              : typedef $$UsersTableUpdateCompanionBuilder = UsersCompanion Function({
+    2452              :   Value<String> id,
+    2453              :   Value<String> email,
+    2454              :   Value<String> name,
+    2455              :   Value<int> spareTime,
+    2456              :   Value<String> note,
+    2457              :   Value<double> score,
+    2458              :   Value<int> rowid,
+    2459              : });
+    2460              : 
+    2461              : final class $$UsersTableReferences
+    2462              :     extends BaseReferences<_$AppDatabase, $UsersTable, User> {
+    2463            0 :   $$UsersTableReferences(super.$_db, super.$_table, super.$_typedResult);
+    2464              : 
+    2465            0 :   static MultiTypedResultKey<$PreparationUsersTable, List<PreparationUser>>
+    2466              :       _preparationUsersRefsTable(_$AppDatabase db) =>
+    2467            0 :           MultiTypedResultKey.fromTable(db.preparationUsers,
+    2468            0 :               aliasName: $_aliasNameGenerator(
+    2469            0 :                   db.users.id, db.preparationUsers.userId));
+    2470              : 
+    2471            0 :   $$PreparationUsersTableProcessedTableManager get preparationUsersRefs {
+    2472              :     final manager =
+    2473            0 :         $$PreparationUsersTableTableManager($_db, $_db.preparationUsers)
+    2474            0 :             .filter((f) => f.userId.id.sqlEquals($_itemColumn<String>('id')!));
+    2475              : 
+    2476              :     final cache =
+    2477            0 :         $_typedResult.readTableOrNull(_preparationUsersRefsTable($_db));
+    2478            0 :     return ProcessedTableManager(
+    2479            0 :         manager.$state.copyWith(prefetchedData: cache));
+    2480              :   }
+    2481              : }
+    2482              : 
+    2483              : class $$UsersTableFilterComposer extends Composer<_$AppDatabase, $UsersTable> {
+    2484            0 :   $$UsersTableFilterComposer({
+    2485              :     required super.$db,
+    2486              :     required super.$table,
+    2487              :     super.joinBuilder,
+    2488              :     super.$addJoinBuilderToRootComposer,
+    2489              :     super.$removeJoinBuilderFromRootComposer,
+    2490              :   });
+    2491            0 :   ColumnFilters<String> get id => $composableBuilder(
+    2492            0 :       column: $table.id, builder: (column) => ColumnFilters(column));
+    2493              : 
+    2494            0 :   ColumnFilters<String> get email => $composableBuilder(
+    2495            0 :       column: $table.email, builder: (column) => ColumnFilters(column));
+    2496              : 
+    2497            0 :   ColumnFilters<String> get name => $composableBuilder(
+    2498            0 :       column: $table.name, builder: (column) => ColumnFilters(column));
+    2499              : 
+    2500            0 :   ColumnFilters<int> get spareTime => $composableBuilder(
+    2501            0 :       column: $table.spareTime, builder: (column) => ColumnFilters(column));
+    2502              : 
+    2503            0 :   ColumnFilters<String> get note => $composableBuilder(
+    2504            0 :       column: $table.note, builder: (column) => ColumnFilters(column));
+    2505              : 
+    2506            0 :   ColumnFilters<double> get score => $composableBuilder(
+    2507            0 :       column: $table.score, builder: (column) => ColumnFilters(column));
+    2508              : 
+    2509            0 :   Expression<bool> preparationUsersRefs(
+    2510              :       Expression<bool> Function($$PreparationUsersTableFilterComposer f) f) {
+    2511            0 :     final $$PreparationUsersTableFilterComposer composer = $composerBuilder(
+    2512              :         composer: this,
+    2513            0 :         getCurrentColumn: (t) => t.id,
+    2514            0 :         referencedTable: $db.preparationUsers,
+    2515            0 :         getReferencedColumn: (t) => t.userId,
+    2516            0 :         builder: (joinBuilder,
+    2517              :                 {$addJoinBuilderToRootComposer,
+    2518              :                 $removeJoinBuilderFromRootComposer}) =>
+    2519            0 :             $$PreparationUsersTableFilterComposer(
+    2520            0 :               $db: $db,
+    2521            0 :               $table: $db.preparationUsers,
+    2522              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2523              :               joinBuilder: joinBuilder,
+    2524              :               $removeJoinBuilderFromRootComposer:
+    2525              :                   $removeJoinBuilderFromRootComposer,
+    2526              :             ));
+    2527            0 :     return f(composer);
+    2528              :   }
+    2529              : }
+    2530              : 
+    2531              : class $$UsersTableOrderingComposer
+    2532              :     extends Composer<_$AppDatabase, $UsersTable> {
+    2533            0 :   $$UsersTableOrderingComposer({
+    2534              :     required super.$db,
+    2535              :     required super.$table,
+    2536              :     super.joinBuilder,
+    2537              :     super.$addJoinBuilderToRootComposer,
+    2538              :     super.$removeJoinBuilderFromRootComposer,
+    2539              :   });
+    2540            0 :   ColumnOrderings<String> get id => $composableBuilder(
+    2541            0 :       column: $table.id, builder: (column) => ColumnOrderings(column));
+    2542              : 
+    2543            0 :   ColumnOrderings<String> get email => $composableBuilder(
+    2544            0 :       column: $table.email, builder: (column) => ColumnOrderings(column));
+    2545              : 
+    2546            0 :   ColumnOrderings<String> get name => $composableBuilder(
+    2547            0 :       column: $table.name, builder: (column) => ColumnOrderings(column));
+    2548              : 
+    2549            0 :   ColumnOrderings<int> get spareTime => $composableBuilder(
+    2550            0 :       column: $table.spareTime, builder: (column) => ColumnOrderings(column));
+    2551              : 
+    2552            0 :   ColumnOrderings<String> get note => $composableBuilder(
+    2553            0 :       column: $table.note, builder: (column) => ColumnOrderings(column));
+    2554              : 
+    2555            0 :   ColumnOrderings<double> get score => $composableBuilder(
+    2556            0 :       column: $table.score, builder: (column) => ColumnOrderings(column));
+    2557              : }
+    2558              : 
+    2559              : class $$UsersTableAnnotationComposer
+    2560              :     extends Composer<_$AppDatabase, $UsersTable> {
+    2561            0 :   $$UsersTableAnnotationComposer({
+    2562              :     required super.$db,
+    2563              :     required super.$table,
+    2564              :     super.joinBuilder,
+    2565              :     super.$addJoinBuilderToRootComposer,
+    2566              :     super.$removeJoinBuilderFromRootComposer,
+    2567              :   });
+    2568            0 :   GeneratedColumn<String> get id =>
+    2569            0 :       $composableBuilder(column: $table.id, builder: (column) => column);
+    2570              : 
+    2571            0 :   GeneratedColumn<String> get email =>
+    2572            0 :       $composableBuilder(column: $table.email, builder: (column) => column);
+    2573              : 
+    2574            0 :   GeneratedColumn<String> get name =>
+    2575            0 :       $composableBuilder(column: $table.name, builder: (column) => column);
+    2576              : 
+    2577            0 :   GeneratedColumn<int> get spareTime =>
+    2578            0 :       $composableBuilder(column: $table.spareTime, builder: (column) => column);
+    2579              : 
+    2580            0 :   GeneratedColumn<String> get note =>
+    2581            0 :       $composableBuilder(column: $table.note, builder: (column) => column);
+    2582              : 
+    2583            0 :   GeneratedColumn<double> get score =>
+    2584            0 :       $composableBuilder(column: $table.score, builder: (column) => column);
+    2585              : 
+    2586            0 :   Expression<T> preparationUsersRefs<T extends Object>(
+    2587              :       Expression<T> Function($$PreparationUsersTableAnnotationComposer a) f) {
+    2588            0 :     final $$PreparationUsersTableAnnotationComposer composer = $composerBuilder(
+    2589              :         composer: this,
+    2590            0 :         getCurrentColumn: (t) => t.id,
+    2591            0 :         referencedTable: $db.preparationUsers,
+    2592            0 :         getReferencedColumn: (t) => t.userId,
+    2593            0 :         builder: (joinBuilder,
+    2594              :                 {$addJoinBuilderToRootComposer,
+    2595              :                 $removeJoinBuilderFromRootComposer}) =>
+    2596            0 :             $$PreparationUsersTableAnnotationComposer(
+    2597            0 :               $db: $db,
+    2598            0 :               $table: $db.preparationUsers,
+    2599              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2600              :               joinBuilder: joinBuilder,
+    2601              :               $removeJoinBuilderFromRootComposer:
+    2602              :                   $removeJoinBuilderFromRootComposer,
+    2603              :             ));
+    2604            0 :     return f(composer);
+    2605              :   }
+    2606              : }
+    2607              : 
+    2608              : class $$UsersTableTableManager extends RootTableManager<
+    2609              :     _$AppDatabase,
+    2610              :     $UsersTable,
+    2611              :     User,
+    2612              :     $$UsersTableFilterComposer,
+    2613              :     $$UsersTableOrderingComposer,
+    2614              :     $$UsersTableAnnotationComposer,
+    2615              :     $$UsersTableCreateCompanionBuilder,
+    2616              :     $$UsersTableUpdateCompanionBuilder,
+    2617              :     (User, $$UsersTableReferences),
+    2618              :     User,
+    2619              :     PrefetchHooks Function({bool preparationUsersRefs})> {
+    2620            0 :   $$UsersTableTableManager(_$AppDatabase db, $UsersTable table)
+    2621            0 :       : super(TableManagerState(
+    2622              :           db: db,
+    2623              :           table: table,
+    2624            0 :           createFilteringComposer: () =>
+    2625            0 :               $$UsersTableFilterComposer($db: db, $table: table),
+    2626            0 :           createOrderingComposer: () =>
+    2627            0 :               $$UsersTableOrderingComposer($db: db, $table: table),
+    2628            0 :           createComputedFieldComposer: () =>
+    2629            0 :               $$UsersTableAnnotationComposer($db: db, $table: table),
+    2630            0 :           updateCompanionCallback: ({
+    2631              :             Value<String> id = const Value.absent(),
+    2632              :             Value<String> email = const Value.absent(),
+    2633              :             Value<String> name = const Value.absent(),
+    2634              :             Value<int> spareTime = const Value.absent(),
+    2635              :             Value<String> note = const Value.absent(),
+    2636              :             Value<double> score = const Value.absent(),
+    2637              :             Value<int> rowid = const Value.absent(),
+    2638              :           }) =>
+    2639            0 :               UsersCompanion(
+    2640              :             id: id,
+    2641              :             email: email,
+    2642              :             name: name,
+    2643              :             spareTime: spareTime,
+    2644              :             note: note,
+    2645              :             score: score,
+    2646              :             rowid: rowid,
+    2647              :           ),
+    2648            0 :           createCompanionCallback: ({
+    2649              :             Value<String> id = const Value.absent(),
+    2650              :             required String email,
+    2651              :             required String name,
+    2652              :             required int spareTime,
+    2653              :             required String note,
+    2654              :             required double score,
+    2655              :             Value<int> rowid = const Value.absent(),
+    2656              :           }) =>
+    2657            0 :               UsersCompanion.insert(
+    2658              :             id: id,
+    2659              :             email: email,
+    2660              :             name: name,
+    2661              :             spareTime: spareTime,
+    2662              :             note: note,
+    2663              :             score: score,
+    2664              :             rowid: rowid,
+    2665              :           ),
+    2666            0 :           withReferenceMapper: (p0) => p0
+    2667            0 :               .map((e) =>
+    2668            0 :                   (e.readTable(table), $$UsersTableReferences(db, table, e)))
+    2669            0 :               .toList(),
+    2670            0 :           prefetchHooksCallback: ({preparationUsersRefs = false}) {
+    2671            0 :             return PrefetchHooks(
+    2672              :               db: db,
+    2673            0 :               explicitlyWatchedTables: [
+    2674            0 :                 if (preparationUsersRefs) db.preparationUsers
+    2675              :               ],
+    2676              :               addJoins: null,
+    2677            0 :               getPrefetchedDataCallback: (items) async {
+    2678            0 :                 return [
+    2679              :                   if (preparationUsersRefs)
+    2680            0 :                     await $_getPrefetchedData<User, $UsersTable,
+    2681              :                             PreparationUser>(
+    2682              :                         currentTable: table,
+    2683              :                         referencedTable: $$UsersTableReferences
+    2684            0 :                             ._preparationUsersRefsTable(db),
+    2685            0 :                         managerFromTypedResult: (p0) =>
+    2686            0 :                             $$UsersTableReferences(db, table, p0)
+    2687            0 :                                 .preparationUsersRefs,
+    2688            0 :                         referencedItemsForCurrentItem: (item,
+    2689              :                                 referencedItems) =>
+    2690            0 :                             referencedItems.where((e) => e.userId == item.id),
+    2691              :                         typedResults: items)
+    2692              :                 ];
+    2693              :               },
+    2694              :             );
+    2695              :           },
+    2696              :         ));
+    2697              : }
+    2698              : 
+    2699              : typedef $$UsersTableProcessedTableManager = ProcessedTableManager<
+    2700              :     _$AppDatabase,
+    2701              :     $UsersTable,
+    2702              :     User,
+    2703              :     $$UsersTableFilterComposer,
+    2704              :     $$UsersTableOrderingComposer,
+    2705              :     $$UsersTableAnnotationComposer,
+    2706              :     $$UsersTableCreateCompanionBuilder,
+    2707              :     $$UsersTableUpdateCompanionBuilder,
+    2708              :     (User, $$UsersTableReferences),
+    2709              :     User,
+    2710              :     PrefetchHooks Function({bool preparationUsersRefs})>;
+    2711              : typedef $$PreparationSchedulesTableCreateCompanionBuilder
+    2712              :     = PreparationSchedulesCompanion Function({
+    2713              :   Value<String> id,
+    2714              :   required String scheduleId,
+    2715              :   required String preparationName,
+    2716              :   required int preparationTime,
+    2717              :   Value<String?> nextPreparationId,
+    2718              :   Value<int> rowid,
+    2719              : });
+    2720              : typedef $$PreparationSchedulesTableUpdateCompanionBuilder
+    2721              :     = PreparationSchedulesCompanion Function({
+    2722              :   Value<String> id,
+    2723              :   Value<String> scheduleId,
+    2724              :   Value<String> preparationName,
+    2725              :   Value<int> preparationTime,
+    2726              :   Value<String?> nextPreparationId,
+    2727              :   Value<int> rowid,
+    2728              : });
+    2729              : 
+    2730              : final class $$PreparationSchedulesTableReferences extends BaseReferences<
+    2731              :     _$AppDatabase, $PreparationSchedulesTable, PreparationSchedule> {
+    2732            0 :   $$PreparationSchedulesTableReferences(
+    2733              :       super.$_db, super.$_table, super.$_typedResult);
+    2734              : 
+    2735            0 :   static $SchedulesTable _scheduleIdTable(_$AppDatabase db) =>
+    2736            0 :       db.schedules.createAlias($_aliasNameGenerator(
+    2737            0 :           db.preparationSchedules.scheduleId, db.schedules.id));
+    2738              : 
+    2739            0 :   $$SchedulesTableProcessedTableManager get scheduleId {
+    2740            0 :     final $_column = $_itemColumn<String>('schedule_id')!;
+    2741              : 
+    2742            0 :     final manager = $$SchedulesTableTableManager($_db, $_db.schedules)
+    2743            0 :         .filter((f) => f.id.sqlEquals($_column));
+    2744            0 :     final item = $_typedResult.readTableOrNull(_scheduleIdTable($_db));
+    2745              :     if (item == null) return manager;
+    2746            0 :     return ProcessedTableManager(
+    2747            0 :         manager.$state.copyWith(prefetchedData: [item]));
+    2748              :   }
+    2749              : 
+    2750            0 :   static $PreparationSchedulesTable _nextPreparationIdTable(_$AppDatabase db) =>
+    2751            0 :       db.preparationSchedules.createAlias($_aliasNameGenerator(
+    2752            0 :           db.preparationSchedules.nextPreparationId,
+    2753            0 :           db.preparationSchedules.id));
+    2754              : 
+    2755            0 :   $$PreparationSchedulesTableProcessedTableManager? get nextPreparationId {
+    2756            0 :     final $_column = $_itemColumn<String>('next_preparation_id');
+    2757              :     if ($_column == null) return null;
+    2758              :     final manager =
+    2759            0 :         $$PreparationSchedulesTableTableManager($_db, $_db.preparationSchedules)
+    2760            0 :             .filter((f) => f.id.sqlEquals($_column));
+    2761            0 :     final item = $_typedResult.readTableOrNull(_nextPreparationIdTable($_db));
+    2762              :     if (item == null) return manager;
+    2763            0 :     return ProcessedTableManager(
+    2764            0 :         manager.$state.copyWith(prefetchedData: [item]));
+    2765              :   }
+    2766              : }
+    2767              : 
+    2768              : class $$PreparationSchedulesTableFilterComposer
+    2769              :     extends Composer<_$AppDatabase, $PreparationSchedulesTable> {
+    2770            0 :   $$PreparationSchedulesTableFilterComposer({
+    2771              :     required super.$db,
+    2772              :     required super.$table,
+    2773              :     super.joinBuilder,
+    2774              :     super.$addJoinBuilderToRootComposer,
+    2775              :     super.$removeJoinBuilderFromRootComposer,
+    2776              :   });
+    2777            0 :   ColumnFilters<String> get id => $composableBuilder(
+    2778            0 :       column: $table.id, builder: (column) => ColumnFilters(column));
+    2779              : 
+    2780            0 :   ColumnFilters<String> get preparationName => $composableBuilder(
+    2781            0 :       column: $table.preparationName,
+    2782            0 :       builder: (column) => ColumnFilters(column));
+    2783              : 
+    2784            0 :   ColumnFilters<int> get preparationTime => $composableBuilder(
+    2785            0 :       column: $table.preparationTime,
+    2786            0 :       builder: (column) => ColumnFilters(column));
+    2787              : 
+    2788            0 :   $$SchedulesTableFilterComposer get scheduleId {
+    2789            0 :     final $$SchedulesTableFilterComposer composer = $composerBuilder(
+    2790              :         composer: this,
+    2791            0 :         getCurrentColumn: (t) => t.scheduleId,
+    2792            0 :         referencedTable: $db.schedules,
+    2793            0 :         getReferencedColumn: (t) => t.id,
+    2794            0 :         builder: (joinBuilder,
+    2795              :                 {$addJoinBuilderToRootComposer,
+    2796              :                 $removeJoinBuilderFromRootComposer}) =>
+    2797            0 :             $$SchedulesTableFilterComposer(
+    2798            0 :               $db: $db,
+    2799            0 :               $table: $db.schedules,
+    2800              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2801              :               joinBuilder: joinBuilder,
+    2802              :               $removeJoinBuilderFromRootComposer:
+    2803              :                   $removeJoinBuilderFromRootComposer,
+    2804              :             ));
+    2805              :     return composer;
+    2806              :   }
+    2807              : 
+    2808            0 :   $$PreparationSchedulesTableFilterComposer get nextPreparationId {
+    2809            0 :     final $$PreparationSchedulesTableFilterComposer composer = $composerBuilder(
+    2810              :         composer: this,
+    2811            0 :         getCurrentColumn: (t) => t.nextPreparationId,
+    2812            0 :         referencedTable: $db.preparationSchedules,
+    2813            0 :         getReferencedColumn: (t) => t.id,
+    2814            0 :         builder: (joinBuilder,
+    2815              :                 {$addJoinBuilderToRootComposer,
+    2816              :                 $removeJoinBuilderFromRootComposer}) =>
+    2817            0 :             $$PreparationSchedulesTableFilterComposer(
+    2818            0 :               $db: $db,
+    2819            0 :               $table: $db.preparationSchedules,
+    2820              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2821              :               joinBuilder: joinBuilder,
+    2822              :               $removeJoinBuilderFromRootComposer:
+    2823              :                   $removeJoinBuilderFromRootComposer,
+    2824              :             ));
+    2825              :     return composer;
+    2826              :   }
+    2827              : }
+    2828              : 
+    2829              : class $$PreparationSchedulesTableOrderingComposer
+    2830              :     extends Composer<_$AppDatabase, $PreparationSchedulesTable> {
+    2831            0 :   $$PreparationSchedulesTableOrderingComposer({
+    2832              :     required super.$db,
+    2833              :     required super.$table,
+    2834              :     super.joinBuilder,
+    2835              :     super.$addJoinBuilderToRootComposer,
+    2836              :     super.$removeJoinBuilderFromRootComposer,
+    2837              :   });
+    2838            0 :   ColumnOrderings<String> get id => $composableBuilder(
+    2839            0 :       column: $table.id, builder: (column) => ColumnOrderings(column));
+    2840              : 
+    2841            0 :   ColumnOrderings<String> get preparationName => $composableBuilder(
+    2842            0 :       column: $table.preparationName,
+    2843            0 :       builder: (column) => ColumnOrderings(column));
+    2844              : 
+    2845            0 :   ColumnOrderings<int> get preparationTime => $composableBuilder(
+    2846            0 :       column: $table.preparationTime,
+    2847            0 :       builder: (column) => ColumnOrderings(column));
+    2848              : 
+    2849            0 :   $$SchedulesTableOrderingComposer get scheduleId {
+    2850            0 :     final $$SchedulesTableOrderingComposer composer = $composerBuilder(
+    2851              :         composer: this,
+    2852            0 :         getCurrentColumn: (t) => t.scheduleId,
+    2853            0 :         referencedTable: $db.schedules,
+    2854            0 :         getReferencedColumn: (t) => t.id,
+    2855            0 :         builder: (joinBuilder,
+    2856              :                 {$addJoinBuilderToRootComposer,
+    2857              :                 $removeJoinBuilderFromRootComposer}) =>
+    2858            0 :             $$SchedulesTableOrderingComposer(
+    2859            0 :               $db: $db,
+    2860            0 :               $table: $db.schedules,
+    2861              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2862              :               joinBuilder: joinBuilder,
+    2863              :               $removeJoinBuilderFromRootComposer:
+    2864              :                   $removeJoinBuilderFromRootComposer,
+    2865              :             ));
+    2866              :     return composer;
+    2867              :   }
+    2868              : 
+    2869            0 :   $$PreparationSchedulesTableOrderingComposer get nextPreparationId {
+    2870              :     final $$PreparationSchedulesTableOrderingComposer composer =
+    2871            0 :         $composerBuilder(
+    2872              :             composer: this,
+    2873            0 :             getCurrentColumn: (t) => t.nextPreparationId,
+    2874            0 :             referencedTable: $db.preparationSchedules,
+    2875            0 :             getReferencedColumn: (t) => t.id,
+    2876            0 :             builder: (joinBuilder,
+    2877              :                     {$addJoinBuilderToRootComposer,
+    2878              :                     $removeJoinBuilderFromRootComposer}) =>
+    2879            0 :                 $$PreparationSchedulesTableOrderingComposer(
+    2880            0 :                   $db: $db,
+    2881            0 :                   $table: $db.preparationSchedules,
+    2882              :                   $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2883              :                   joinBuilder: joinBuilder,
+    2884              :                   $removeJoinBuilderFromRootComposer:
+    2885              :                       $removeJoinBuilderFromRootComposer,
+    2886              :                 ));
+    2887              :     return composer;
+    2888              :   }
+    2889              : }
+    2890              : 
+    2891              : class $$PreparationSchedulesTableAnnotationComposer
+    2892              :     extends Composer<_$AppDatabase, $PreparationSchedulesTable> {
+    2893            0 :   $$PreparationSchedulesTableAnnotationComposer({
+    2894              :     required super.$db,
+    2895              :     required super.$table,
+    2896              :     super.joinBuilder,
+    2897              :     super.$addJoinBuilderToRootComposer,
+    2898              :     super.$removeJoinBuilderFromRootComposer,
+    2899              :   });
+    2900            0 :   GeneratedColumn<String> get id =>
+    2901            0 :       $composableBuilder(column: $table.id, builder: (column) => column);
+    2902              : 
+    2903            0 :   GeneratedColumn<String> get preparationName => $composableBuilder(
+    2904            0 :       column: $table.preparationName, builder: (column) => column);
+    2905              : 
+    2906            0 :   GeneratedColumn<int> get preparationTime => $composableBuilder(
+    2907            0 :       column: $table.preparationTime, builder: (column) => column);
+    2908              : 
+    2909            0 :   $$SchedulesTableAnnotationComposer get scheduleId {
+    2910            0 :     final $$SchedulesTableAnnotationComposer composer = $composerBuilder(
+    2911              :         composer: this,
+    2912            0 :         getCurrentColumn: (t) => t.scheduleId,
+    2913            0 :         referencedTable: $db.schedules,
+    2914            0 :         getReferencedColumn: (t) => t.id,
+    2915            0 :         builder: (joinBuilder,
+    2916              :                 {$addJoinBuilderToRootComposer,
+    2917              :                 $removeJoinBuilderFromRootComposer}) =>
+    2918            0 :             $$SchedulesTableAnnotationComposer(
+    2919            0 :               $db: $db,
+    2920            0 :               $table: $db.schedules,
+    2921              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2922              :               joinBuilder: joinBuilder,
+    2923              :               $removeJoinBuilderFromRootComposer:
+    2924              :                   $removeJoinBuilderFromRootComposer,
+    2925              :             ));
+    2926              :     return composer;
+    2927              :   }
+    2928              : 
+    2929            0 :   $$PreparationSchedulesTableAnnotationComposer get nextPreparationId {
+    2930              :     final $$PreparationSchedulesTableAnnotationComposer composer =
+    2931            0 :         $composerBuilder(
+    2932              :             composer: this,
+    2933            0 :             getCurrentColumn: (t) => t.nextPreparationId,
+    2934            0 :             referencedTable: $db.preparationSchedules,
+    2935            0 :             getReferencedColumn: (t) => t.id,
+    2936            0 :             builder: (joinBuilder,
+    2937              :                     {$addJoinBuilderToRootComposer,
+    2938              :                     $removeJoinBuilderFromRootComposer}) =>
+    2939            0 :                 $$PreparationSchedulesTableAnnotationComposer(
+    2940            0 :                   $db: $db,
+    2941            0 :                   $table: $db.preparationSchedules,
+    2942              :                   $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    2943              :                   joinBuilder: joinBuilder,
+    2944              :                   $removeJoinBuilderFromRootComposer:
+    2945              :                       $removeJoinBuilderFromRootComposer,
+    2946              :                 ));
+    2947              :     return composer;
+    2948              :   }
+    2949              : }
+    2950              : 
+    2951              : class $$PreparationSchedulesTableTableManager extends RootTableManager<
+    2952              :     _$AppDatabase,
+    2953              :     $PreparationSchedulesTable,
+    2954              :     PreparationSchedule,
+    2955              :     $$PreparationSchedulesTableFilterComposer,
+    2956              :     $$PreparationSchedulesTableOrderingComposer,
+    2957              :     $$PreparationSchedulesTableAnnotationComposer,
+    2958              :     $$PreparationSchedulesTableCreateCompanionBuilder,
+    2959              :     $$PreparationSchedulesTableUpdateCompanionBuilder,
+    2960              :     (PreparationSchedule, $$PreparationSchedulesTableReferences),
+    2961              :     PreparationSchedule,
+    2962              :     PrefetchHooks Function({bool scheduleId, bool nextPreparationId})> {
+    2963            0 :   $$PreparationSchedulesTableTableManager(
+    2964              :       _$AppDatabase db, $PreparationSchedulesTable table)
+    2965            0 :       : super(TableManagerState(
+    2966              :           db: db,
+    2967              :           table: table,
+    2968            0 :           createFilteringComposer: () =>
+    2969            0 :               $$PreparationSchedulesTableFilterComposer($db: db, $table: table),
+    2970            0 :           createOrderingComposer: () =>
+    2971            0 :               $$PreparationSchedulesTableOrderingComposer(
+    2972              :                   $db: db, $table: table),
+    2973            0 :           createComputedFieldComposer: () =>
+    2974            0 :               $$PreparationSchedulesTableAnnotationComposer(
+    2975              :                   $db: db, $table: table),
+    2976            0 :           updateCompanionCallback: ({
+    2977              :             Value<String> id = const Value.absent(),
+    2978              :             Value<String> scheduleId = const Value.absent(),
+    2979              :             Value<String> preparationName = const Value.absent(),
+    2980              :             Value<int> preparationTime = const Value.absent(),
+    2981              :             Value<String?> nextPreparationId = const Value.absent(),
+    2982              :             Value<int> rowid = const Value.absent(),
+    2983              :           }) =>
+    2984            0 :               PreparationSchedulesCompanion(
+    2985              :             id: id,
+    2986              :             scheduleId: scheduleId,
+    2987              :             preparationName: preparationName,
+    2988              :             preparationTime: preparationTime,
+    2989              :             nextPreparationId: nextPreparationId,
+    2990              :             rowid: rowid,
+    2991              :           ),
+    2992            0 :           createCompanionCallback: ({
+    2993              :             Value<String> id = const Value.absent(),
+    2994              :             required String scheduleId,
+    2995              :             required String preparationName,
+    2996              :             required int preparationTime,
+    2997              :             Value<String?> nextPreparationId = const Value.absent(),
+    2998              :             Value<int> rowid = const Value.absent(),
+    2999              :           }) =>
+    3000            0 :               PreparationSchedulesCompanion.insert(
+    3001              :             id: id,
+    3002              :             scheduleId: scheduleId,
+    3003              :             preparationName: preparationName,
+    3004              :             preparationTime: preparationTime,
+    3005              :             nextPreparationId: nextPreparationId,
+    3006              :             rowid: rowid,
+    3007              :           ),
+    3008            0 :           withReferenceMapper: (p0) => p0
+    3009            0 :               .map((e) => (
+    3010            0 :                     e.readTable(table),
+    3011            0 :                     $$PreparationSchedulesTableReferences(db, table, e)
+    3012              :                   ))
+    3013            0 :               .toList(),
+    3014            0 :           prefetchHooksCallback: (
+    3015              :               {scheduleId = false, nextPreparationId = false}) {
+    3016            0 :             return PrefetchHooks(
+    3017              :               db: db,
+    3018            0 :               explicitlyWatchedTables: [],
+    3019              :               addJoins: <
+    3020              :                   T extends TableManagerState<
+    3021              :                       dynamic,
+    3022              :                       dynamic,
+    3023              :                       dynamic,
+    3024              :                       dynamic,
+    3025              :                       dynamic,
+    3026              :                       dynamic,
+    3027              :                       dynamic,
+    3028              :                       dynamic,
+    3029              :                       dynamic,
+    3030              :                       dynamic,
+    3031            0 :                       dynamic>>(state) {
+    3032              :                 if (scheduleId) {
+    3033            0 :                   state = state.withJoin(
+    3034              :                     currentTable: table,
+    3035            0 :                     currentColumn: table.scheduleId,
+    3036              :                     referencedTable: $$PreparationSchedulesTableReferences
+    3037            0 :                         ._scheduleIdTable(db),
+    3038              :                     referencedColumn: $$PreparationSchedulesTableReferences
+    3039            0 :                         ._scheduleIdTable(db)
+    3040            0 :                         .id,
+    3041              :                   ) as T;
+    3042              :                 }
+    3043              :                 if (nextPreparationId) {
+    3044            0 :                   state = state.withJoin(
+    3045              :                     currentTable: table,
+    3046            0 :                     currentColumn: table.nextPreparationId,
+    3047              :                     referencedTable: $$PreparationSchedulesTableReferences
+    3048            0 :                         ._nextPreparationIdTable(db),
+    3049              :                     referencedColumn: $$PreparationSchedulesTableReferences
+    3050            0 :                         ._nextPreparationIdTable(db)
+    3051            0 :                         .id,
+    3052              :                   ) as T;
+    3053              :                 }
+    3054              : 
+    3055              :                 return state;
+    3056              :               },
+    3057            0 :               getPrefetchedDataCallback: (items) async {
+    3058            0 :                 return [];
+    3059              :               },
+    3060              :             );
+    3061              :           },
+    3062              :         ));
+    3063              : }
+    3064              : 
+    3065              : typedef $$PreparationSchedulesTableProcessedTableManager
+    3066              :     = ProcessedTableManager<
+    3067              :         _$AppDatabase,
+    3068              :         $PreparationSchedulesTable,
+    3069              :         PreparationSchedule,
+    3070              :         $$PreparationSchedulesTableFilterComposer,
+    3071              :         $$PreparationSchedulesTableOrderingComposer,
+    3072              :         $$PreparationSchedulesTableAnnotationComposer,
+    3073              :         $$PreparationSchedulesTableCreateCompanionBuilder,
+    3074              :         $$PreparationSchedulesTableUpdateCompanionBuilder,
+    3075              :         (PreparationSchedule, $$PreparationSchedulesTableReferences),
+    3076              :         PreparationSchedule,
+    3077              :         PrefetchHooks Function({bool scheduleId, bool nextPreparationId})>;
+    3078              : typedef $$PreparationUsersTableCreateCompanionBuilder
+    3079              :     = PreparationUsersCompanion Function({
+    3080              :   Value<String> id,
+    3081              :   required String userId,
+    3082              :   required String preparationName,
+    3083              :   required int preparationTime,
+    3084              :   Value<String?> nextPreparationId,
+    3085              :   Value<int> rowid,
+    3086              : });
+    3087              : typedef $$PreparationUsersTableUpdateCompanionBuilder
+    3088              :     = PreparationUsersCompanion Function({
+    3089              :   Value<String> id,
+    3090              :   Value<String> userId,
+    3091              :   Value<String> preparationName,
+    3092              :   Value<int> preparationTime,
+    3093              :   Value<String?> nextPreparationId,
+    3094              :   Value<int> rowid,
+    3095              : });
+    3096              : 
+    3097              : final class $$PreparationUsersTableReferences extends BaseReferences<
+    3098              :     _$AppDatabase, $PreparationUsersTable, PreparationUser> {
+    3099            0 :   $$PreparationUsersTableReferences(
+    3100              :       super.$_db, super.$_table, super.$_typedResult);
+    3101              : 
+    3102            0 :   static $UsersTable _userIdTable(_$AppDatabase db) => db.users.createAlias(
+    3103            0 :       $_aliasNameGenerator(db.preparationUsers.userId, db.users.id));
+    3104              : 
+    3105            0 :   $$UsersTableProcessedTableManager get userId {
+    3106            0 :     final $_column = $_itemColumn<String>('user_id')!;
+    3107              : 
+    3108            0 :     final manager = $$UsersTableTableManager($_db, $_db.users)
+    3109            0 :         .filter((f) => f.id.sqlEquals($_column));
+    3110            0 :     final item = $_typedResult.readTableOrNull(_userIdTable($_db));
+    3111              :     if (item == null) return manager;
+    3112            0 :     return ProcessedTableManager(
+    3113            0 :         manager.$state.copyWith(prefetchedData: [item]));
+    3114              :   }
+    3115              : 
+    3116            0 :   static $PreparationUsersTable _nextPreparationIdTable(_$AppDatabase db) =>
+    3117            0 :       db.preparationUsers.createAlias($_aliasNameGenerator(
+    3118            0 :           db.preparationUsers.nextPreparationId, db.preparationUsers.id));
+    3119              : 
+    3120            0 :   $$PreparationUsersTableProcessedTableManager? get nextPreparationId {
+    3121            0 :     final $_column = $_itemColumn<String>('next_preparation_id');
+    3122              :     if ($_column == null) return null;
+    3123              :     final manager =
+    3124            0 :         $$PreparationUsersTableTableManager($_db, $_db.preparationUsers)
+    3125            0 :             .filter((f) => f.id.sqlEquals($_column));
+    3126            0 :     final item = $_typedResult.readTableOrNull(_nextPreparationIdTable($_db));
+    3127              :     if (item == null) return manager;
+    3128            0 :     return ProcessedTableManager(
+    3129            0 :         manager.$state.copyWith(prefetchedData: [item]));
+    3130              :   }
+    3131              : }
+    3132              : 
+    3133              : class $$PreparationUsersTableFilterComposer
+    3134              :     extends Composer<_$AppDatabase, $PreparationUsersTable> {
+    3135            0 :   $$PreparationUsersTableFilterComposer({
+    3136              :     required super.$db,
+    3137              :     required super.$table,
+    3138              :     super.joinBuilder,
+    3139              :     super.$addJoinBuilderToRootComposer,
+    3140              :     super.$removeJoinBuilderFromRootComposer,
+    3141              :   });
+    3142            0 :   ColumnFilters<String> get id => $composableBuilder(
+    3143            0 :       column: $table.id, builder: (column) => ColumnFilters(column));
+    3144              : 
+    3145            0 :   ColumnFilters<String> get preparationName => $composableBuilder(
+    3146            0 :       column: $table.preparationName,
+    3147            0 :       builder: (column) => ColumnFilters(column));
+    3148              : 
+    3149            0 :   ColumnFilters<int> get preparationTime => $composableBuilder(
+    3150            0 :       column: $table.preparationTime,
+    3151            0 :       builder: (column) => ColumnFilters(column));
+    3152              : 
+    3153            0 :   $$UsersTableFilterComposer get userId {
+    3154            0 :     final $$UsersTableFilterComposer composer = $composerBuilder(
+    3155              :         composer: this,
+    3156            0 :         getCurrentColumn: (t) => t.userId,
+    3157            0 :         referencedTable: $db.users,
+    3158            0 :         getReferencedColumn: (t) => t.id,
+    3159            0 :         builder: (joinBuilder,
+    3160              :                 {$addJoinBuilderToRootComposer,
+    3161              :                 $removeJoinBuilderFromRootComposer}) =>
+    3162            0 :             $$UsersTableFilterComposer(
+    3163            0 :               $db: $db,
+    3164            0 :               $table: $db.users,
+    3165              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    3166              :               joinBuilder: joinBuilder,
+    3167              :               $removeJoinBuilderFromRootComposer:
+    3168              :                   $removeJoinBuilderFromRootComposer,
+    3169              :             ));
+    3170              :     return composer;
+    3171              :   }
+    3172              : 
+    3173            0 :   $$PreparationUsersTableFilterComposer get nextPreparationId {
+    3174            0 :     final $$PreparationUsersTableFilterComposer composer = $composerBuilder(
+    3175              :         composer: this,
+    3176            0 :         getCurrentColumn: (t) => t.nextPreparationId,
+    3177            0 :         referencedTable: $db.preparationUsers,
+    3178            0 :         getReferencedColumn: (t) => t.id,
+    3179            0 :         builder: (joinBuilder,
+    3180              :                 {$addJoinBuilderToRootComposer,
+    3181              :                 $removeJoinBuilderFromRootComposer}) =>
+    3182            0 :             $$PreparationUsersTableFilterComposer(
+    3183            0 :               $db: $db,
+    3184            0 :               $table: $db.preparationUsers,
+    3185              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    3186              :               joinBuilder: joinBuilder,
+    3187              :               $removeJoinBuilderFromRootComposer:
+    3188              :                   $removeJoinBuilderFromRootComposer,
+    3189              :             ));
+    3190              :     return composer;
+    3191              :   }
+    3192              : }
+    3193              : 
+    3194              : class $$PreparationUsersTableOrderingComposer
+    3195              :     extends Composer<_$AppDatabase, $PreparationUsersTable> {
+    3196            0 :   $$PreparationUsersTableOrderingComposer({
+    3197              :     required super.$db,
+    3198              :     required super.$table,
+    3199              :     super.joinBuilder,
+    3200              :     super.$addJoinBuilderToRootComposer,
+    3201              :     super.$removeJoinBuilderFromRootComposer,
+    3202              :   });
+    3203            0 :   ColumnOrderings<String> get id => $composableBuilder(
+    3204            0 :       column: $table.id, builder: (column) => ColumnOrderings(column));
+    3205              : 
+    3206            0 :   ColumnOrderings<String> get preparationName => $composableBuilder(
+    3207            0 :       column: $table.preparationName,
+    3208            0 :       builder: (column) => ColumnOrderings(column));
+    3209              : 
+    3210            0 :   ColumnOrderings<int> get preparationTime => $composableBuilder(
+    3211            0 :       column: $table.preparationTime,
+    3212            0 :       builder: (column) => ColumnOrderings(column));
+    3213              : 
+    3214            0 :   $$UsersTableOrderingComposer get userId {
+    3215            0 :     final $$UsersTableOrderingComposer composer = $composerBuilder(
+    3216              :         composer: this,
+    3217            0 :         getCurrentColumn: (t) => t.userId,
+    3218            0 :         referencedTable: $db.users,
+    3219            0 :         getReferencedColumn: (t) => t.id,
+    3220            0 :         builder: (joinBuilder,
+    3221              :                 {$addJoinBuilderToRootComposer,
+    3222              :                 $removeJoinBuilderFromRootComposer}) =>
+    3223            0 :             $$UsersTableOrderingComposer(
+    3224            0 :               $db: $db,
+    3225            0 :               $table: $db.users,
+    3226              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    3227              :               joinBuilder: joinBuilder,
+    3228              :               $removeJoinBuilderFromRootComposer:
+    3229              :                   $removeJoinBuilderFromRootComposer,
+    3230              :             ));
+    3231              :     return composer;
+    3232              :   }
+    3233              : 
+    3234            0 :   $$PreparationUsersTableOrderingComposer get nextPreparationId {
+    3235            0 :     final $$PreparationUsersTableOrderingComposer composer = $composerBuilder(
+    3236              :         composer: this,
+    3237            0 :         getCurrentColumn: (t) => t.nextPreparationId,
+    3238            0 :         referencedTable: $db.preparationUsers,
+    3239            0 :         getReferencedColumn: (t) => t.id,
+    3240            0 :         builder: (joinBuilder,
+    3241              :                 {$addJoinBuilderToRootComposer,
+    3242              :                 $removeJoinBuilderFromRootComposer}) =>
+    3243            0 :             $$PreparationUsersTableOrderingComposer(
+    3244            0 :               $db: $db,
+    3245            0 :               $table: $db.preparationUsers,
+    3246              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    3247              :               joinBuilder: joinBuilder,
+    3248              :               $removeJoinBuilderFromRootComposer:
+    3249              :                   $removeJoinBuilderFromRootComposer,
+    3250              :             ));
+    3251              :     return composer;
+    3252              :   }
+    3253              : }
+    3254              : 
+    3255              : class $$PreparationUsersTableAnnotationComposer
+    3256              :     extends Composer<_$AppDatabase, $PreparationUsersTable> {
+    3257            0 :   $$PreparationUsersTableAnnotationComposer({
+    3258              :     required super.$db,
+    3259              :     required super.$table,
+    3260              :     super.joinBuilder,
+    3261              :     super.$addJoinBuilderToRootComposer,
+    3262              :     super.$removeJoinBuilderFromRootComposer,
+    3263              :   });
+    3264            0 :   GeneratedColumn<String> get id =>
+    3265            0 :       $composableBuilder(column: $table.id, builder: (column) => column);
+    3266              : 
+    3267            0 :   GeneratedColumn<String> get preparationName => $composableBuilder(
+    3268            0 :       column: $table.preparationName, builder: (column) => column);
+    3269              : 
+    3270            0 :   GeneratedColumn<int> get preparationTime => $composableBuilder(
+    3271            0 :       column: $table.preparationTime, builder: (column) => column);
+    3272              : 
+    3273            0 :   $$UsersTableAnnotationComposer get userId {
+    3274            0 :     final $$UsersTableAnnotationComposer composer = $composerBuilder(
+    3275              :         composer: this,
+    3276            0 :         getCurrentColumn: (t) => t.userId,
+    3277            0 :         referencedTable: $db.users,
+    3278            0 :         getReferencedColumn: (t) => t.id,
+    3279            0 :         builder: (joinBuilder,
+    3280              :                 {$addJoinBuilderToRootComposer,
+    3281              :                 $removeJoinBuilderFromRootComposer}) =>
+    3282            0 :             $$UsersTableAnnotationComposer(
+    3283            0 :               $db: $db,
+    3284            0 :               $table: $db.users,
+    3285              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    3286              :               joinBuilder: joinBuilder,
+    3287              :               $removeJoinBuilderFromRootComposer:
+    3288              :                   $removeJoinBuilderFromRootComposer,
+    3289              :             ));
+    3290              :     return composer;
+    3291              :   }
+    3292              : 
+    3293            0 :   $$PreparationUsersTableAnnotationComposer get nextPreparationId {
+    3294            0 :     final $$PreparationUsersTableAnnotationComposer composer = $composerBuilder(
+    3295              :         composer: this,
+    3296            0 :         getCurrentColumn: (t) => t.nextPreparationId,
+    3297            0 :         referencedTable: $db.preparationUsers,
+    3298            0 :         getReferencedColumn: (t) => t.id,
+    3299            0 :         builder: (joinBuilder,
+    3300              :                 {$addJoinBuilderToRootComposer,
+    3301              :                 $removeJoinBuilderFromRootComposer}) =>
+    3302            0 :             $$PreparationUsersTableAnnotationComposer(
+    3303            0 :               $db: $db,
+    3304            0 :               $table: $db.preparationUsers,
+    3305              :               $addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
+    3306              :               joinBuilder: joinBuilder,
+    3307              :               $removeJoinBuilderFromRootComposer:
+    3308              :                   $removeJoinBuilderFromRootComposer,
+    3309              :             ));
+    3310              :     return composer;
+    3311              :   }
+    3312              : }
+    3313              : 
+    3314              : class $$PreparationUsersTableTableManager extends RootTableManager<
+    3315              :     _$AppDatabase,
+    3316              :     $PreparationUsersTable,
+    3317              :     PreparationUser,
+    3318              :     $$PreparationUsersTableFilterComposer,
+    3319              :     $$PreparationUsersTableOrderingComposer,
+    3320              :     $$PreparationUsersTableAnnotationComposer,
+    3321              :     $$PreparationUsersTableCreateCompanionBuilder,
+    3322              :     $$PreparationUsersTableUpdateCompanionBuilder,
+    3323              :     (PreparationUser, $$PreparationUsersTableReferences),
+    3324              :     PreparationUser,
+    3325              :     PrefetchHooks Function({bool userId, bool nextPreparationId})> {
+    3326            0 :   $$PreparationUsersTableTableManager(
+    3327              :       _$AppDatabase db, $PreparationUsersTable table)
+    3328            0 :       : super(TableManagerState(
+    3329              :           db: db,
+    3330              :           table: table,
+    3331            0 :           createFilteringComposer: () =>
+    3332            0 :               $$PreparationUsersTableFilterComposer($db: db, $table: table),
+    3333            0 :           createOrderingComposer: () =>
+    3334            0 :               $$PreparationUsersTableOrderingComposer($db: db, $table: table),
+    3335            0 :           createComputedFieldComposer: () =>
+    3336            0 :               $$PreparationUsersTableAnnotationComposer($db: db, $table: table),
+    3337            0 :           updateCompanionCallback: ({
+    3338              :             Value<String> id = const Value.absent(),
+    3339              :             Value<String> userId = const Value.absent(),
+    3340              :             Value<String> preparationName = const Value.absent(),
+    3341              :             Value<int> preparationTime = const Value.absent(),
+    3342              :             Value<String?> nextPreparationId = const Value.absent(),
+    3343              :             Value<int> rowid = const Value.absent(),
+    3344              :           }) =>
+    3345            0 :               PreparationUsersCompanion(
+    3346              :             id: id,
+    3347              :             userId: userId,
+    3348              :             preparationName: preparationName,
+    3349              :             preparationTime: preparationTime,
+    3350              :             nextPreparationId: nextPreparationId,
+    3351              :             rowid: rowid,
+    3352              :           ),
+    3353            0 :           createCompanionCallback: ({
+    3354              :             Value<String> id = const Value.absent(),
+    3355              :             required String userId,
+    3356              :             required String preparationName,
+    3357              :             required int preparationTime,
+    3358              :             Value<String?> nextPreparationId = const Value.absent(),
+    3359              :             Value<int> rowid = const Value.absent(),
+    3360              :           }) =>
+    3361            0 :               PreparationUsersCompanion.insert(
+    3362              :             id: id,
+    3363              :             userId: userId,
+    3364              :             preparationName: preparationName,
+    3365              :             preparationTime: preparationTime,
+    3366              :             nextPreparationId: nextPreparationId,
+    3367              :             rowid: rowid,
+    3368              :           ),
+    3369            0 :           withReferenceMapper: (p0) => p0
+    3370            0 :               .map((e) => (
+    3371            0 :                     e.readTable(table),
+    3372            0 :                     $$PreparationUsersTableReferences(db, table, e)
+    3373              :                   ))
+    3374            0 :               .toList(),
+    3375            0 :           prefetchHooksCallback: ({userId = false, nextPreparationId = false}) {
+    3376            0 :             return PrefetchHooks(
+    3377              :               db: db,
+    3378            0 :               explicitlyWatchedTables: [],
+    3379              :               addJoins: <
+    3380              :                   T extends TableManagerState<
+    3381              :                       dynamic,
+    3382              :                       dynamic,
+    3383              :                       dynamic,
+    3384              :                       dynamic,
+    3385              :                       dynamic,
+    3386              :                       dynamic,
+    3387              :                       dynamic,
+    3388              :                       dynamic,
+    3389              :                       dynamic,
+    3390              :                       dynamic,
+    3391            0 :                       dynamic>>(state) {
+    3392              :                 if (userId) {
+    3393            0 :                   state = state.withJoin(
+    3394              :                     currentTable: table,
+    3395            0 :                     currentColumn: table.userId,
+    3396              :                     referencedTable:
+    3397            0 :                         $$PreparationUsersTableReferences._userIdTable(db),
+    3398              :                     referencedColumn:
+    3399            0 :                         $$PreparationUsersTableReferences._userIdTable(db).id,
+    3400              :                   ) as T;
+    3401              :                 }
+    3402              :                 if (nextPreparationId) {
+    3403            0 :                   state = state.withJoin(
+    3404              :                     currentTable: table,
+    3405            0 :                     currentColumn: table.nextPreparationId,
+    3406              :                     referencedTable: $$PreparationUsersTableReferences
+    3407            0 :                         ._nextPreparationIdTable(db),
+    3408              :                     referencedColumn: $$PreparationUsersTableReferences
+    3409            0 :                         ._nextPreparationIdTable(db)
+    3410            0 :                         .id,
+    3411              :                   ) as T;
+    3412              :                 }
+    3413              : 
+    3414              :                 return state;
+    3415              :               },
+    3416            0 :               getPrefetchedDataCallback: (items) async {
+    3417            0 :                 return [];
+    3418              :               },
+    3419              :             );
+    3420              :           },
+    3421              :         ));
+    3422              : }
+    3423              : 
+    3424              : typedef $$PreparationUsersTableProcessedTableManager = ProcessedTableManager<
+    3425              :     _$AppDatabase,
+    3426              :     $PreparationUsersTable,
+    3427              :     PreparationUser,
+    3428              :     $$PreparationUsersTableFilterComposer,
+    3429              :     $$PreparationUsersTableOrderingComposer,
+    3430              :     $$PreparationUsersTableAnnotationComposer,
+    3431              :     $$PreparationUsersTableCreateCompanionBuilder,
+    3432              :     $$PreparationUsersTableUpdateCompanionBuilder,
+    3433              :     (PreparationUser, $$PreparationUsersTableReferences),
+    3434              :     PreparationUser,
+    3435              :     PrefetchHooks Function({bool userId, bool nextPreparationId})>;
+    3436              : 
+    3437              : class $AppDatabaseManager {
+    3438              :   final _$AppDatabase _db;
+    3439            0 :   $AppDatabaseManager(this._db);
+    3440            0 :   $$PlacesTableTableManager get places =>
+    3441            0 :       $$PlacesTableTableManager(_db, _db.places);
+    3442            0 :   $$SchedulesTableTableManager get schedules =>
+    3443            0 :       $$SchedulesTableTableManager(_db, _db.schedules);
+    3444            0 :   $$UsersTableTableManager get users =>
+    3445            0 :       $$UsersTableTableManager(_db, _db.users);
+    3446            0 :   $$PreparationSchedulesTableTableManager get preparationSchedules =>
+    3447            0 :       $$PreparationSchedulesTableTableManager(_db, _db.preparationSchedules);
+    3448            0 :   $$PreparationUsersTableTableManager get preparationUsers =>
+    3449            0 :       $$PreparationUsersTableTableManager(_db, _db.preparationUsers);
+    3450              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/database/index-sort-f.html b/coverage/html/core/database/index-sort-f.html new file mode 100644 index 00000000..a55ddac7 --- /dev/null +++ b/coverage/html/core/database/index-sort-f.html @@ -0,0 +1,125 @@ + + + + + + + LCOV - lcov.info - core/database + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/databaseCoverageTotalHit
Test:lcov.infoLines:24.8 %1623403
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
database.dart +
77.8%77.8%
+
77.8 %1814
database.g.dart +
24.0%24.0%
+
24.0 %1601385
riverpod.dart +
100.0%
+
100.0 %22
riverpod.g.dart +
100.0%
+
100.0 %22
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/database/index-sort-l.html b/coverage/html/core/database/index-sort-l.html new file mode 100644 index 00000000..6d00e945 --- /dev/null +++ b/coverage/html/core/database/index-sort-l.html @@ -0,0 +1,125 @@ + + + + + + + LCOV - lcov.info - core/database + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/databaseCoverageTotalHit
Test:lcov.infoLines:24.8 %1623403
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
database.g.dart +
24.0%24.0%
+
24.0 %1601385
database.dart +
77.8%77.8%
+
77.8 %1814
riverpod.dart +
100.0%
+
100.0 %22
riverpod.g.dart +
100.0%
+
100.0 %22
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/database/index.html b/coverage/html/core/database/index.html new file mode 100644 index 00000000..fdd57aa6 --- /dev/null +++ b/coverage/html/core/database/index.html @@ -0,0 +1,125 @@ + + + + + + + LCOV - lcov.info - core/database + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/databaseCoverageTotalHit
Test:lcov.infoLines:24.8 %1623403
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
database.dart +
77.8%77.8%
+
77.8 %1814
database.g.dart +
24.0%24.0%
+
24.0 %1601385
riverpod.dart +
100.0%
+
100.0 %22
riverpod.g.dart +
100.0%
+
100.0 %22
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/database/riverpod.dart.gcov.html b/coverage/html/core/database/riverpod.dart.gcov.html new file mode 100644 index 00000000..92b29873 --- /dev/null +++ b/coverage/html/core/database/riverpod.dart.gcov.html @@ -0,0 +1,86 @@ + + + + + + + LCOV - lcov.info - core/database/riverpod.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/database - riverpod.dartCoverageTotalHit
Test:lcov.infoLines:100.0 %22
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:flutter_riverpod/flutter_riverpod.dart';
+       2              : import 'package:on_time_front/core/database/database.dart';
+       3              : import 'package:riverpod_annotation/riverpod_annotation.dart';
+       4              : 
+       5              : part 'riverpod.g.dart';
+       6              : 
+       7            1 : @riverpod
+       8              : AppDatabase appDatabse(Ref ref) {
+       9            1 :   return AppDatabase();
+      10              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/database/riverpod.g.dart.gcov.html b/coverage/html/core/database/riverpod.g.dart.gcov.html new file mode 100644 index 00000000..bf06576e --- /dev/null +++ b/coverage/html/core/database/riverpod.g.dart.gcov.html @@ -0,0 +1,102 @@ + + + + + + + LCOV - lcov.info - core/database/riverpod.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/database - riverpod.g.dartCoverageTotalHit
Test:lcov.infoLines:100.0 %22
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'riverpod.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // RiverpodGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            1 : String _$appDatabseHash() => r'11e4bffa40c627871fb1cd794de2bbd10801eba0';
+      10              : 
+      11              : /// See also [appDatabse].
+      12              : @ProviderFor(appDatabse)
+      13            3 : final appDatabseProvider = AutoDisposeProvider<AppDatabase>.internal(
+      14              :   appDatabse,
+      15              :   name: r'appDatabseProvider',
+      16              :   debugGetCreateSourceHash:
+      17              :       const bool.fromEnvironment('dart.vm.product') ? null : _$appDatabseHash,
+      18              :   dependencies: null,
+      19              :   allTransitiveDependencies: null,
+      20              : );
+      21              : 
+      22              : @Deprecated('Will be removed in 3.0. Use Ref instead')
+      23              : // ignore: unused_element
+      24              : typedef AppDatabseRef = AutoDisposeProviderRef<AppDatabase>;
+      25              : // ignore_for_file: type=lint
+      26              : // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/di/di_setup.dart.gcov.html b/coverage/html/core/di/di_setup.dart.gcov.html new file mode 100644 index 00000000..02823144 --- /dev/null +++ b/coverage/html/core/di/di_setup.dart.gcov.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - lcov.info - core/di/di_setup.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/di - di_setup.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:get_it/get_it.dart';
+       2              : import 'package:injectable/injectable.dart';
+       3              : import 'di_setup.config.dart';
+       4              : 
+       5            0 : final getIt = GetIt.instance;
+       6              : 
+       7            0 : @InjectableInit(
+       8              :   initializerName: 'init', // default
+       9              :   preferRelativeImports: true, // default
+      10              :   asExtension: true, // default
+      11              : )
+      12            0 : void configureDependencies() => getIt.init();
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/di/index.html b/coverage/html/core/di/index.html new file mode 100644 index 00000000..cd6bdbde --- /dev/null +++ b/coverage/html/core/di/index.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - core/di + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/diCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
di_setup.dart +
0.0%
+
0.0 %3
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/adapters/index.html b/coverage/html/core/dio/adapters/index.html new file mode 100644 index 00000000..816f9433 --- /dev/null +++ b/coverage/html/core/dio/adapters/index.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - core/dio/adapters + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dio/adaptersCoverageTotalHit
Test:lcov.infoLines:0.0 %20
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
mobile_adapter.dart +
0.0%
+
0.0 %2
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/adapters/mobile_adapter.dart.gcov.html b/coverage/html/core/dio/adapters/mobile_adapter.dart.gcov.html new file mode 100644 index 00000000..0ec29762 --- /dev/null +++ b/coverage/html/core/dio/adapters/mobile_adapter.dart.gcov.html @@ -0,0 +1,82 @@ + + + + + + + LCOV - lcov.info - core/dio/adapters/mobile_adapter.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dio/adapters - mobile_adapter.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %20
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:dio/dio.dart';
+       2              : import 'package:dio/io.dart';
+       3              : 
+       4            0 : HttpClientAdapter getAdapter() {
+       5            0 :   return IOHttpClientAdapter();
+       6              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/app_dio.dart.gcov.html b/coverage/html/core/dio/app_dio.dart.gcov.html new file mode 100644 index 00000000..ae1a16f9 --- /dev/null +++ b/coverage/html/core/dio/app_dio.dart.gcov.html @@ -0,0 +1,105 @@ + + + + + + + LCOV - lcov.info - core/dio/app_dio.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dio - app_dio.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %60
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:dio/dio.dart';
+       2              : import 'package:injectable/injectable.dart';
+       3              : import 'package:on_time_front/core/constants/environment_variable.dart';
+       4              : import 'package:on_time_front/core/dio/adapters/shared.dart';
+       5              : import 'package:on_time_front/core/dio/interceptors/logger_interceptor.dart';
+       6              : import 'package:on_time_front/core/dio/interceptors/token_interceptor.dart';
+       7              : import 'package:on_time_front/core/dio/transformers/logging_transformer.dart';
+       8              : 
+       9              : @Injectable(as: Dio)
+      10              : class AppDio with DioMixin implements Dio {
+      11            0 :   AppDio() {
+      12            0 :     httpClientAdapter = getAdapter();
+      13            0 :     transformer = LoggingTransformer(inner: BackgroundTransformer());
+      14            0 :     options = BaseOptions(
+      15              :         contentType: Headers.jsonContentType,
+      16              :         baseUrl: EnvironmentVariable.restApiUrl,
+      17              :         connectTimeout: const Duration(milliseconds: 30000),
+      18              :         receiveTimeout: const Duration(milliseconds: 30000),
+      19              :         sendTimeout: const Duration(milliseconds: 30000),
+      20              :         receiveDataWhenStatusError: true,
+      21              :         followRedirects: false,
+      22            0 :         headers: {
+      23              :           "Accept": "application/json",
+      24              :           "Authorization": EnvironmentVariable.restAuthToken
+      25              :         });
+      26              : 
+      27            0 :     interceptors.addAll([TokenInterceptor(this), LoggerInterceptor()]);
+      28              :   }
+      29              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/index.html b/coverage/html/core/dio/index.html new file mode 100644 index 00000000..d1917488 --- /dev/null +++ b/coverage/html/core/dio/index.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - core/dio + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dioCoverageTotalHit
Test:lcov.infoLines:0.0 %60
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
app_dio.dart +
0.0%
+
0.0 %6
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/interceptors/index-sort-f.html b/coverage/html/core/dio/interceptors/index-sort-f.html new file mode 100644 index 00000000..cc130de0 --- /dev/null +++ b/coverage/html/core/dio/interceptors/index-sort-f.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - core/dio/interceptors + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dio/interceptorsCoverageTotalHit
Test:lcov.infoLines:0.0 %660
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
logger_interceptor.dart +
0.0%
+
0.0 %23
token_interceptor.dart +
0.0%
+
0.0 %43
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/interceptors/index-sort-l.html b/coverage/html/core/dio/interceptors/index-sort-l.html new file mode 100644 index 00000000..ff2d0c30 --- /dev/null +++ b/coverage/html/core/dio/interceptors/index-sort-l.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - core/dio/interceptors + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dio/interceptorsCoverageTotalHit
Test:lcov.infoLines:0.0 %660
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
logger_interceptor.dart +
0.0%
+
0.0 %23
token_interceptor.dart +
0.0%
+
0.0 %43
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/interceptors/index.html b/coverage/html/core/dio/interceptors/index.html new file mode 100644 index 00000000..854523cc --- /dev/null +++ b/coverage/html/core/dio/interceptors/index.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - core/dio/interceptors + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dio/interceptorsCoverageTotalHit
Test:lcov.infoLines:0.0 %660
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
logger_interceptor.dart +
0.0%
+
0.0 %23
token_interceptor.dart +
0.0%
+
0.0 %43
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/interceptors/logger_interceptor.dart.gcov.html b/coverage/html/core/dio/interceptors/logger_interceptor.dart.gcov.html new file mode 100644 index 00000000..c80612d9 --- /dev/null +++ b/coverage/html/core/dio/interceptors/logger_interceptor.dart.gcov.html @@ -0,0 +1,119 @@ + + + + + + + LCOV - lcov.info - core/dio/interceptors/logger_interceptor.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dio/interceptors - logger_interceptor.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %230
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:developer';
+       2              : 
+       3              : import 'package:dio/dio.dart';
+       4              : 
+       5              : class LoggerInterceptor implements Interceptor {
+       6            0 :   @override
+       7              :   void onError(DioException err, ErrorInterceptorHandler handler) {
+       8            0 :     log('❌ Dio Error!');
+       9            0 :     log('❌ Url: ${err.requestOptions.uri}');
+      10            0 :     log('❌ Data: ${err.requestOptions.data}');
+      11            0 :     log('❌ ${err.stackTrace}');
+      12            0 :     log('❌ Response Error: ${err.response?.data}');
+      13            0 :     log('❌ Response Message: ${err.message}');
+      14            0 :     return handler.next(err);
+      15              :   }
+      16              : 
+      17            0 :   @override
+      18              :   void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
+      19            0 :     log('🌍 Sending network request: ${options.baseUrl}${options.path}');
+      20            0 :     log('🌍 Header: ${options.headers}');
+      21            0 :     log('🌍 Query: ${options.queryParameters}');
+      22            0 :     log('🌍 Data: ${options.data}');
+      23              : 
+      24            0 :     return handler.next(options);
+      25              :   }
+      26              : 
+      27            0 :   @override
+      28              :   void onResponse(
+      29              :     Response<dynamic> response,
+      30              :     ResponseInterceptorHandler handler,
+      31              :   ) {
+      32            0 :     log('⬅️ Received network response');
+      33            0 :     if (response.data is Map && response.data['status'] != null) {
+      34            0 :       log('${'✅ ${response.data['status']} ✅'} ${response.requestOptions.baseUrl}${response.requestOptions.path}');
+      35              :     } else {
+      36            0 :       log('${'✅ ${response.statusCode} ✅'} ${response.requestOptions.baseUrl}${response.requestOptions.path}');
+      37              :     }
+      38            0 :     log('Query params: ${response.requestOptions.queryParameters}');
+      39            0 :     log('Response Data: ${response.data}');
+      40            0 :     log('-------------------------');
+      41            0 :     return handler.next(response);
+      42              :   }
+      43              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/interceptors/token_interceptor.dart.gcov.html b/coverage/html/core/dio/interceptors/token_interceptor.dart.gcov.html new file mode 100644 index 00000000..52e20a74 --- /dev/null +++ b/coverage/html/core/dio/interceptors/token_interceptor.dart.gcov.html @@ -0,0 +1,206 @@ + + + + + + + LCOV - lcov.info - core/dio/interceptors/token_interceptor.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dio/interceptors - token_interceptor.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %430
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:dio/dio.dart';
+       2              : import 'package:flutter/material.dart';
+       3              : import 'package:on_time_front/data/data_sources/token_local_data_source.dart';
+       4              : import 'package:on_time_front/core/di/di_setup.dart';
+       5              : import 'package:on_time_front/domain/use-cases/sign_out_use_case.dart';
+       6              : 
+       7              : class TokenInterceptor implements InterceptorsWrapper {
+       8              :   final Dio dio;
+       9            0 :   TokenInterceptor(this.dio);
+      10              :   final TokenLocalDataSource tokenLocalDataSource =
+      11              :       getIt.get<TokenLocalDataSource>();
+      12              : 
+      13              :   // when accessToken is expired & having multiple requests call
+      14              :   // this variable to lock others request to make sure only trigger call refresh token 01 times
+      15              :   // to prevent duplicate refresh call
+      16              :   bool _isRefreshing = false;
+      17              : 
+      18              :   // when having multiple requests call at the same time, you need to store them in a list
+      19              :   // then loop this list to retry every request later, after call refresh token success
+      20              :   final _requestsNeedRetry =
+      21              :       <({RequestOptions options, ErrorInterceptorHandler handler})>[];
+      22              : 
+      23            0 :   @override
+      24              :   void onRequest(
+      25              :       RequestOptions options, RequestInterceptorHandler handler) async {
+      26              :     try {
+      27            0 :       final token = await tokenLocalDataSource.getToken();
+      28              : 
+      29            0 :       options.headers['Authorization'] = 'Bearer ${token.accessToken}';
+      30              :     } catch (e) {
+      31            0 :       debugPrint(e.toString());
+      32              :     }
+      33            0 :     handler.next(options);
+      34              :   }
+      35              : 
+      36            0 :   @override
+      37              :   void onError(DioException err, ErrorInterceptorHandler handler) async {
+      38            0 :     final response = err.response;
+      39              :     if (response != null &&
+      40              :         // status code for unauthorized usually 401
+      41            0 :         response.statusCode == 401 &&
+      42              :         // refresh token call maybe fail by it self
+      43              :         // eg: when refreshToken also is expired -> can't get new accessToken
+      44              :         // usually server also return 401 unauthorized for this case
+      45              :         // need to exlude it to prevent loop infinite call
+      46            0 :         response.requestOptions.path != "/refresh-token") {
+      47              :       // if hasn't not refreshing yet, let's start it
+      48            0 :       if (!_isRefreshing) {
+      49            0 :         _isRefreshing = true;
+      50              : 
+      51              :         // add request (requestOptions and handler) to queue and wait to retry later
+      52            0 :         _requestsNeedRetry
+      53            0 :             .add((options: response.requestOptions, handler: handler));
+      54              : 
+      55              :         // call api refresh token
+      56            0 :         final isRefreshSuccess = await _refreshToken();
+      57              : 
+      58              :         if (isRefreshSuccess) {
+      59              :           // refresh success, loop requests need retry
+      60            0 :           for (var requestNeedRetry in _requestsNeedRetry) {
+      61              :             // don't need set new accessToken to header here, because these retry
+      62              :             // will go through onRequest callback above (where new accessToken will be set to header)
+      63              : 
+      64              :             // won't use await because this loop will take longer -> maybe throw: Unhandled Exception: Concurrent modification during iteration
+      65              :             // because method _requestsNeedRetry.add() is called at the same time
+      66              :             // final response = await dio.fetch(requestNeedRetry.options);
+      67              :             // requestNeedRetry.handler.resolve(response);
+      68              : 
+      69            0 :             dio.fetch(requestNeedRetry.options).then((response) {
+      70            0 :               requestNeedRetry.handler.resolve(response);
+      71            0 :             }).catchError((_) {});
+      72              :           }
+      73              : 
+      74            0 :           _requestsNeedRetry.clear();
+      75            0 :           _isRefreshing = false;
+      76              :         } else {
+      77            0 :           _requestsNeedRetry.clear();
+      78              :           // if refresh fail, force logout user here
+      79              :           try {
+      80            0 :             await getIt.get<SignOutUseCase>().call();
+      81              :           } catch (_) {
+      82            0 :             await tokenLocalDataSource.deleteToken();
+      83              :           }
+      84            0 :           _isRefreshing = false;
+      85              :         }
+      86              :       } else {
+      87              :         // if refresh flow is processing, add this request to queue and wait to retry later
+      88            0 :         _requestsNeedRetry
+      89            0 :             .add((options: response.requestOptions, handler: handler));
+      90              :       }
+      91              :     } else {
+      92              :       // ignore other error is not unauthorized
+      93            0 :       return handler.next(err);
+      94              :     }
+      95              :   }
+      96              : 
+      97            0 :   Future<bool> _refreshToken() async {
+      98              :     try {
+      99            0 :       final tokenEntity = await tokenLocalDataSource.getToken();
+     100            0 :       final refreshToken = tokenEntity.refreshToken;
+     101              : 
+     102            0 :       final res = await dio.get(
+     103              :         '/refresh-token',
+     104            0 :         options: Options(
+     105            0 :           headers: {
+     106            0 :             'Authorization-refresh': 'Bearer $refreshToken',
+     107              :           },
+     108              :         ),
+     109              :       );
+     110            0 :       if (res.statusCode == 200) {
+     111            0 :         debugPrint("token refreshing success");
+     112            0 :         final authToken = res.headers['authorization']![0];
+     113              :         // save new access + refresh token to your local storage for using later
+     114            0 :         await tokenLocalDataSource.storeAuthToken(authToken);
+     115              :         return true;
+     116              :       } else {
+     117            0 :         debugPrint("refresh token fail ${res.statusMessage ?? res.toString()}");
+     118              :         return false;
+     119              :       }
+     120              :     } catch (error) {
+     121            0 :       debugPrint("refresh token fail $error");
+     122              :       return false;
+     123              :     }
+     124              :   }
+     125              : 
+     126            0 :   @override
+     127              :   void onResponse(Response response, ResponseInterceptorHandler handler) {
+     128            0 :     handler.next(response);
+     129              :   }
+     130              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/transformers/index.html b/coverage/html/core/dio/transformers/index.html new file mode 100644 index 00000000..41338e22 --- /dev/null +++ b/coverage/html/core/dio/transformers/index.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - core/dio/transformers + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dio/transformersCoverageTotalHit
Test:lcov.infoLines:0.0 %70
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
logging_transformer.dart +
0.0%
+
0.0 %7
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/dio/transformers/logging_transformer.dart.gcov.html b/coverage/html/core/dio/transformers/logging_transformer.dart.gcov.html new file mode 100644 index 00000000..73045036 --- /dev/null +++ b/coverage/html/core/dio/transformers/logging_transformer.dart.gcov.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - lcov.info - core/dio/transformers/logging_transformer.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/dio/transformers - logging_transformer.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %70
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:developer';
+       2              : 
+       3              : import 'package:dio/dio.dart';
+       4              : 
+       5              : /// A wrapper transformer that logs the exact serialized request payload
+       6              : /// produced by Dio's inner transformer. This reflects the precise string
+       7              : /// sent over the wire (JSON, form-url-encoded, etc.).
+       8              : class LoggingTransformer implements Transformer {
+       9              :   final Transformer _inner;
+      10              : 
+      11            0 :   LoggingTransformer({Transformer? inner})
+      12            0 :       : _inner = inner ?? BackgroundTransformer();
+      13              : 
+      14            0 :   @override
+      15              :   Future<String> transformRequest(RequestOptions options) async {
+      16            0 :     final body = await _inner.transformRequest(options);
+      17              :     try {
+      18            0 :       log('🧾 Serialized body (${options.method} ${options.uri}): $body');
+      19              :     } catch (_) {}
+      20              :     return body;
+      21              :   }
+      22              : 
+      23            0 :   @override
+      24              :   Future transformResponse(
+      25              :       RequestOptions options, ResponseBody responseBody) async {
+      26            0 :     return _inner.transformResponse(options, responseBody);
+      27              :   }
+      28              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/services/index.html b/coverage/html/core/services/index.html new file mode 100644 index 00000000..ecc446ba --- /dev/null +++ b/coverage/html/core/services/index.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - core/services + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/servicesCoverageTotalHit
Test:lcov.infoLines:0.0 %20
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
navigation_service.dart +
0.0%
+
0.0 %2
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/services/navigation_service.dart.gcov.html b/coverage/html/core/services/navigation_service.dart.gcov.html new file mode 100644 index 00000000..37ec8cd5 --- /dev/null +++ b/coverage/html/core/services/navigation_service.dart.gcov.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - lcov.info - core/services/navigation_service.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/services - navigation_service.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %20
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:flutter/widgets.dart';
+       2              : import 'package:go_router/go_router.dart';
+       3              : import 'package:injectable/injectable.dart';
+       4              : 
+       5              : @Singleton()
+       6              : class NavigationService {
+       7              :   final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
+       8              : 
+       9            0 :   void push(String routeName, {Object? extra}) {
+      10            0 :     GoRouter.of(navigatorKey.currentContext!).push(routeName, extra: extra);
+      11              :   }
+      12              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/utils/json_converters/duration_json_converters.dart.gcov.html b/coverage/html/core/utils/json_converters/duration_json_converters.dart.gcov.html new file mode 100644 index 00000000..3c7c4ea0 --- /dev/null +++ b/coverage/html/core/utils/json_converters/duration_json_converters.dart.gcov.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - lcov.info - core/utils/json_converters/duration_json_converters.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/utils/json_converters - duration_json_converters.dartCoverageTotalHit
Test:lcov.infoLines:100.0 %55
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:drift/drift.dart';
+       2              : 
+       3              : class DurationSqlConverter extends TypeConverter<Duration, int>
+       4              :     with JsonTypeConverter<Duration, int> {
+       5            3 :   DurationSqlConverter();
+       6              : 
+       7            1 :   @override
+       8              :   Duration fromSql(int fromDb) {
+       9            1 :     return Duration(milliseconds: fromDb);
+      10              :   }
+      11              : 
+      12            2 :   @override
+      13              :   int toSql(Duration value) {
+      14            2 :     return value.inMilliseconds;
+      15              :   }
+      16              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/core/utils/json_converters/index.html b/coverage/html/core/utils/json_converters/index.html new file mode 100644 index 00000000..3f2b56c6 --- /dev/null +++ b/coverage/html/core/utils/json_converters/index.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - core/utils/json_converters + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core/utils/json_convertersCoverageTotalHit
Test:lcov.infoLines:100.0 %55
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
duration_json_converters.dart +
100.0%
+
100.0 %55
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/index-sort-f.html b/coverage/html/data/daos/index-sort-f.html new file mode 100644 index 00000000..a596c442 --- /dev/null +++ b/coverage/html/data/daos/index-sort-f.html @@ -0,0 +1,179 @@ + + + + + + + LCOV - lcov.info - data/daos + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daosCoverageTotalHit
Test:lcov.infoLines:44.4 %19687
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
place_dao.dart +
57.1%57.1%
+
57.1 %74
place_dao.g.dart +
0.0%
+
0.0 %1
preparation_schedule_dao.dart +
0.0%
+
0.0 %62
preparation_schedule_dao.g.dart +
0.0%
+
0.0 %5
preparation_user_dao.dart +
79.7%79.7%
+
79.7 %5947
preparation_user_dao.g.dart +
0.0%
+
0.0 %3
schedule_dao.dart +
80.0%80.0%
+
80.0 %4536
schedule_dao.g.dart +
0.0%
+
0.0 %2
user_dao.dart +
0.0%
+
0.0 %11
user_dao.g.dart +
0.0%
+
0.0 %1
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/index-sort-l.html b/coverage/html/data/daos/index-sort-l.html new file mode 100644 index 00000000..c4d8763e --- /dev/null +++ b/coverage/html/data/daos/index-sort-l.html @@ -0,0 +1,179 @@ + + + + + + + LCOV - lcov.info - data/daos + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daosCoverageTotalHit
Test:lcov.infoLines:44.4 %19687
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
place_dao.g.dart +
0.0%
+
0.0 %1
user_dao.g.dart +
0.0%
+
0.0 %1
schedule_dao.g.dart +
0.0%
+
0.0 %2
preparation_user_dao.g.dart +
0.0%
+
0.0 %3
preparation_schedule_dao.g.dart +
0.0%
+
0.0 %5
user_dao.dart +
0.0%
+
0.0 %11
preparation_schedule_dao.dart +
0.0%
+
0.0 %62
place_dao.dart +
57.1%57.1%
+
57.1 %74
preparation_user_dao.dart +
79.7%79.7%
+
79.7 %5947
schedule_dao.dart +
80.0%80.0%
+
80.0 %4536
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/index.html b/coverage/html/data/daos/index.html new file mode 100644 index 00000000..ea84c278 --- /dev/null +++ b/coverage/html/data/daos/index.html @@ -0,0 +1,179 @@ + + + + + + + LCOV - lcov.info - data/daos + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daosCoverageTotalHit
Test:lcov.infoLines:44.4 %19687
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
place_dao.dart +
57.1%57.1%
+
57.1 %74
place_dao.g.dart +
0.0%
+
0.0 %1
preparation_schedule_dao.dart +
0.0%
+
0.0 %62
preparation_schedule_dao.g.dart +
0.0%
+
0.0 %5
preparation_user_dao.dart +
79.7%79.7%
+
79.7 %5947
preparation_user_dao.g.dart +
0.0%
+
0.0 %3
schedule_dao.dart +
80.0%80.0%
+
80.0 %4536
schedule_dao.g.dart +
0.0%
+
0.0 %2
user_dao.dart +
0.0%
+
0.0 %11
user_dao.g.dart +
0.0%
+
0.0 %1
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/place_dao.dart.gcov.html b/coverage/html/data/daos/place_dao.dart.gcov.html new file mode 100644 index 00000000..1c2e55a9 --- /dev/null +++ b/coverage/html/data/daos/place_dao.dart.gcov.html @@ -0,0 +1,99 @@ + + + + + + + LCOV - lcov.info - data/daos/place_dao.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daos - place_dao.dartCoverageTotalHit
Test:lcov.infoLines:57.1 %74
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:drift/drift.dart';
+       2              : import '/core/database/database.dart';
+       3              : import 'package:on_time_front/data/tables/places_table.dart';
+       4              : 
+       5              : part 'place_dao.g.dart';
+       6              : 
+       7              : @DriftAccessor(tables: [Places])
+       8              : class PlaceDao extends DatabaseAccessor<AppDatabase> with _$PlaceDaoMixin {
+       9              :   final AppDatabase db;
+      10              : 
+      11            2 :   PlaceDao(this.db) : super(db);
+      12              : 
+      13            1 :   Future<Place> createPlace(Place placeModel) async {
+      14            4 :     return await into(db.places).insertReturning(
+      15            1 :       placeModel.toCompanion(false),
+      16              :     );
+      17              :   }
+      18              : 
+      19            0 :   Future<List<Place>> getAllPlaces() async {
+      20            0 :     final places = await select(db.places).get();
+      21            0 :     return places.toList();
+      22              :   }
+      23              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/place_dao.g.dart.gcov.html b/coverage/html/data/daos/place_dao.g.dart.gcov.html new file mode 100644 index 00000000..bc87c438 --- /dev/null +++ b/coverage/html/data/daos/place_dao.g.dart.gcov.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - lcov.info - data/daos/place_dao.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daos - place_dao.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %10
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'place_dao.dart';
+       4              : 
+       5              : // ignore_for_file: type=lint
+       6              : mixin _$PlaceDaoMixin on DatabaseAccessor<AppDatabase> {
+       7            0 :   $PlacesTable get places => attachedDatabase.places;
+       8              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/preparation_schedule_dao.dart.gcov.html b/coverage/html/data/daos/preparation_schedule_dao.dart.gcov.html new file mode 100644 index 00000000..c16d81f2 --- /dev/null +++ b/coverage/html/data/daos/preparation_schedule_dao.dart.gcov.html @@ -0,0 +1,214 @@ + + + + + + + LCOV - lcov.info - data/daos/preparation_schedule_dao.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daos - preparation_schedule_dao.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %620
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:collection/collection.dart';
+       2              : import 'package:drift/drift.dart';
+       3              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       4              : import '/core/database/database.dart';
+       5              : 
+       6              : import 'package:on_time_front/data/tables/preparation_schedule_table.dart';
+       7              : import 'package:on_time_front/data/tables/schedules_table.dart';
+       8              : import 'package:on_time_front/data/tables/user_table.dart';
+       9              : import 'package:on_time_front/data/tables/places_table.dart';
+      10              : 
+      11              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+      12              : 
+      13              : part 'preparation_schedule_dao.g.dart';
+      14              : 
+      15              : @DriftAccessor(tables: [PreparationSchedules, Schedules, Users, Places])
+      16              : class PreparationScheduleDao extends DatabaseAccessor<AppDatabase>
+      17              :     with _$PreparationScheduleDaoMixin {
+      18              :   final AppDatabase db;
+      19              : 
+      20            0 :   PreparationScheduleDao(this.db) : super(db);
+      21              : 
+      22            0 :   Future<void> createPreparationSchedule(
+      23              :       PreparationEntity preparationEntity, String scheduleId) async {
+      24              :     String? previousStepId;
+      25              : 
+      26            0 :     for (var step in preparationEntity.preparationStepList) {
+      27              :       // Step 1: Insert the current preparation step
+      28            0 :       final insertedStep = await into(db.preparationSchedules).insertReturning(
+      29            0 :         step.toPreparationScheduleModel(scheduleId).toCompanion(false),
+      30              :       );
+      31              : 
+      32              :       // Step 2: Update the `nextPreparationId` of the previous step
+      33              :       if (previousStepId != null) {
+      34            0 :         await (update(db.preparationSchedules)
+      35            0 :               ..where((tbl) => tbl.id.equals(previousStepId!)))
+      36            0 :             .write(
+      37            0 :           PreparationSchedulesCompanion(
+      38            0 :               nextPreparationId: Value(insertedStep.id)),
+      39              :         );
+      40              :       }
+      41              : 
+      42              :       // Step 3: Set the current step's ID as the previous step ID for the next iteration
+      43            0 :       previousStepId = insertedStep.id;
+      44              :     }
+      45              :   }
+      46              : 
+      47            0 :   Future<PreparationEntity> getPreparationSchedulesByScheduleId(
+      48              :       String scheduleId) async {
+      49            0 :     final allSteps = await (select(db.preparationSchedules)
+      50            0 :           ..where((tbl) => tbl.scheduleId.equals(scheduleId)))
+      51            0 :         .get();
+      52              : 
+      53            0 :     if (allSteps.isEmpty) {
+      54            0 :       return PreparationEntity(preparationStepList: []);
+      55              :     }
+      56              : 
+      57            0 :     final firstStep = allSteps.firstWhere(
+      58            0 :       (step) => allSteps.every((other) => other.nextPreparationId != step.id),
+      59            0 :       orElse: () => allSteps.first,
+      60              :     );
+      61              : 
+      62            0 :     final List<PreparationStepEntity> orderedSteps = [];
+      63              :     PreparationSchedule? currentStep = firstStep;
+      64              : 
+      65              :     while (currentStep != null) {
+      66            0 :       orderedSteps.add(
+      67            0 :         PreparationStepEntity(
+      68            0 :           id: currentStep.id,
+      69            0 :           preparationName: currentStep.preparationName,
+      70            0 :           preparationTime: Duration(minutes: currentStep.preparationTime),
+      71            0 :           nextPreparationId: currentStep.nextPreparationId,
+      72              :         ),
+      73              :       );
+      74            0 :       currentStep = allSteps.firstWhereOrNull(
+      75            0 :         (step) => step.id == currentStep!.nextPreparationId,
+      76              :       );
+      77              :     }
+      78              : 
+      79            0 :     return PreparationEntity(preparationStepList: orderedSteps);
+      80              :   }
+      81              : 
+      82            0 :   Future<PreparationStepEntity> getPreparationStepById(
+      83              :       String preparationStepId) async {
+      84            0 :     final result = await (select(db.preparationSchedules)
+      85            0 :           ..where((tbl) => tbl.id.equals(preparationStepId)))
+      86            0 :         .getSingleOrNull();
+      87              : 
+      88              :     if (result == null) {
+      89            0 :       throw Exception("Preparation step not found");
+      90              :     }
+      91              : 
+      92            0 :     return PreparationStepEntity(
+      93            0 :       id: result.id,
+      94            0 :       preparationName: result.preparationName,
+      95            0 :       preparationTime: Duration(minutes: result.preparationTime),
+      96            0 :       nextPreparationId: result.nextPreparationId,
+      97              :     );
+      98              :   }
+      99              : 
+     100            0 :   Future<void> updatePreparationSchedule(
+     101              :       PreparationStepEntity stepEntity, String scheduleId) async {
+     102            0 :     await (update(db.preparationSchedules)
+     103            0 :           ..where((tbl) => tbl.id.equals(stepEntity.id)))
+     104            0 :         .write(
+     105            0 :       PreparationSchedulesCompanion(
+     106            0 :         preparationName: Value(stepEntity.preparationName),
+     107            0 :         preparationTime: Value(stepEntity.preparationTime.inMinutes),
+     108            0 :         nextPreparationId: Value(stepEntity.nextPreparationId),
+     109              :       ),
+     110              :     );
+     111              :   }
+     112              : 
+     113            0 :   Future<PreparationEntity> deletePreparationSchedule(
+     114              :       String preparationId) async {
+     115              :     // Step 1: 삭제할 준비 과정을 가져오기
+     116            0 :     final preparationToDelete = await (select(db.preparationSchedules)
+     117            0 :           ..where((tbl) => tbl.id.equals(preparationId)))
+     118            0 :         .getSingle();
+     119              : 
+     120              :     // Step 2: 이전 노드의 nextPreparationId를 업데이트
+     121            0 :     await (update(db.preparationSchedules)
+     122            0 :           ..where((tbl) => tbl.nextPreparationId.equals(preparationId)))
+     123            0 :         .write(
+     124            0 :       PreparationSchedulesCompanion(
+     125            0 :         nextPreparationId: Value(preparationToDelete.nextPreparationId),
+     126              :       ),
+     127              :     );
+     128              : 
+     129              :     // Step 3: 해당 노드 삭제
+     130            0 :     await (delete(db.preparationSchedules)
+     131            0 :           ..where((tbl) => tbl.id.equals(preparationId)))
+     132            0 :         .go();
+     133              : 
+     134              :     // Step 4: 재정렬된 PreparationEntity 반환
+     135            0 :     return await getPreparationSchedulesByScheduleId(
+     136            0 :         preparationToDelete.scheduleId);
+     137              :   }
+     138              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/preparation_schedule_dao.g.dart.gcov.html b/coverage/html/data/daos/preparation_schedule_dao.g.dart.gcov.html new file mode 100644 index 00000000..0736798e --- /dev/null +++ b/coverage/html/data/daos/preparation_schedule_dao.g.dart.gcov.html @@ -0,0 +1,88 @@ + + + + + + + LCOV - lcov.info - data/daos/preparation_schedule_dao.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daos - preparation_schedule_dao.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %50
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'preparation_schedule_dao.dart';
+       4              : 
+       5              : // ignore_for_file: type=lint
+       6              : mixin _$PreparationScheduleDaoMixin on DatabaseAccessor<AppDatabase> {
+       7            0 :   $PlacesTable get places => attachedDatabase.places;
+       8            0 :   $SchedulesTable get schedules => attachedDatabase.schedules;
+       9            0 :   $PreparationSchedulesTable get preparationSchedules =>
+      10            0 :       attachedDatabase.preparationSchedules;
+      11            0 :   $UsersTable get users => attachedDatabase.users;
+      12              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/preparation_user_dao.dart.gcov.html b/coverage/html/data/daos/preparation_user_dao.dart.gcov.html new file mode 100644 index 00000000..d1352401 --- /dev/null +++ b/coverage/html/data/daos/preparation_user_dao.dart.gcov.html @@ -0,0 +1,206 @@ + + + + + + + LCOV - lcov.info - data/daos/preparation_user_dao.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daos - preparation_user_dao.dartCoverageTotalHit
Test:lcov.infoLines:79.7 %5947
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:collection/collection.dart';
+       2              : import 'package:drift/drift.dart';
+       3              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       4              : import '/core/database/database.dart';
+       5              : import 'package:on_time_front/data/tables/preparation_user_table.dart';
+       6              : import 'package:on_time_front/data/tables/user_table.dart';
+       7              : 
+       8              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       9              : 
+      10              : part 'preparation_user_dao.g.dart';
+      11              : 
+      12              : @DriftAccessor(tables: [PreparationUsers, Users])
+      13              : class PreparationUserDao extends DatabaseAccessor<AppDatabase>
+      14              :     with _$PreparationUserDaoMixin {
+      15              :   final AppDatabase db;
+      16              : 
+      17            4 :   PreparationUserDao(this.db) : super(db);
+      18              : 
+      19            2 :   Future<void> createPreparationUser(
+      20              :       PreparationEntity preparationEntity, String userId) async {
+      21              :     String? previousStepId;
+      22              : 
+      23            4 :     for (var step in preparationEntity.preparationStepList) {
+      24            8 :       final insertedStep = await into(db.preparationUsers).insertReturning(
+      25            4 :         step.toPreparationUserModel(userId).toCompanion(false),
+      26              :       );
+      27              : 
+      28              :       if (previousStepId != null) {
+      29            6 :         await (update(db.preparationUsers)
+      30            8 :               ..where((tbl) => tbl.id.equals(previousStepId!)))
+      31            2 :             .write(
+      32            6 :           PreparationUsersCompanion(nextPreparationId: Value(insertedStep.id)),
+      33              :         );
+      34              :       }
+      35              : 
+      36            2 :       previousStepId = insertedStep.id;
+      37              :     }
+      38              :   }
+      39              : 
+      40            2 :   Future<PreparationEntity> getPreparationUsersByUserId(String userId) async {
+      41            6 :     final allSteps = await (select(db.preparationUsers)
+      42            8 :           ..where((tbl) => tbl.userId.equals(userId)))
+      43            2 :         .get();
+      44              : 
+      45            2 :     if (allSteps.isEmpty) {
+      46            0 :       return PreparationEntity(preparationStepList: []);
+      47              :     }
+      48              : 
+      49            2 :     final firstStep = allSteps.firstWhere(
+      50           12 :       (step) => allSteps.every((other) => other.nextPreparationId != step.id),
+      51            0 :       orElse: () => allSteps.first,
+      52              :     );
+      53              : 
+      54            2 :     final List<PreparationStepEntity> orderedSteps = [];
+      55              :     PreparationUser? currentStep = firstStep;
+      56              : 
+      57              :     while (currentStep != null) {
+      58            2 :       orderedSteps.add(
+      59            2 :         PreparationStepEntity(
+      60            2 :           id: currentStep.id,
+      61            2 :           preparationName: currentStep.preparationName,
+      62            4 :           preparationTime: Duration(minutes: currentStep.preparationTime),
+      63            2 :           nextPreparationId: currentStep.nextPreparationId,
+      64              :         ),
+      65              :       );
+      66            2 :       currentStep = allSteps.firstWhereOrNull(
+      67            8 :         (step) => step.id == currentStep!.nextPreparationId,
+      68              :       );
+      69              :     }
+      70              : 
+      71            2 :     return PreparationEntity(preparationStepList: orderedSteps);
+      72              :   }
+      73              : 
+      74            0 :   Future<PreparationStepEntity> getPreparationStepById(
+      75              :       String preparationStepId) async {
+      76            0 :     final result = await (select(db.preparationUsers)
+      77            0 :           ..where((tbl) => tbl.id.equals(preparationStepId)))
+      78            0 :         .getSingleOrNull();
+      79              : 
+      80              :     if (result == null) {
+      81            0 :       throw Exception("Preparation step not found");
+      82              :     }
+      83              : 
+      84            0 :     return PreparationStepEntity(
+      85            0 :       id: result.id,
+      86            0 :       preparationName: result.preparationName,
+      87            0 :       preparationTime: Duration(minutes: result.preparationTime),
+      88            0 :       nextPreparationId: result.nextPreparationId,
+      89              :     );
+      90              :   }
+      91              : 
+      92            2 :   Future<void> updatePreparationUser(
+      93              :       PreparationStepEntity stepEntity, String userId) async {
+      94            6 :     await (update(db.preparationUsers)
+      95           10 :           ..where((tbl) => tbl.id.equals(stepEntity.id)))
+      96            2 :         .write(
+      97            2 :       PreparationUsersCompanion(
+      98            4 :         preparationName: Value(stepEntity.preparationName),
+      99            6 :         preparationTime: Value(stepEntity.preparationTime.inMinutes),
+     100              :       ),
+     101              :     );
+     102              :   }
+     103              : 
+     104            2 :   Future<PreparationEntity> deletePreparationUser(String preparationId) async {
+     105            6 :     final preparationToDelete = await (select(db.preparationUsers)
+     106            8 :           ..where((tbl) => tbl.id.equals(preparationId)))
+     107            2 :         .getSingle();
+     108              : 
+     109            6 :     await (update(db.preparationUsers)
+     110            8 :           ..where((tbl) => tbl.nextPreparationId.equals(preparationId)))
+     111            2 :         .write(
+     112            2 :       PreparationUsersCompanion(
+     113            4 :         nextPreparationId: Value(preparationToDelete.nextPreparationId),
+     114              :       ),
+     115              :     );
+     116              : 
+     117            6 :     await (delete(db.preparationUsers)
+     118            8 :           ..where((tbl) => tbl.id.equals(preparationId)))
+     119            2 :         .go();
+     120              : 
+     121            4 :     return await getPreparationUsersByUserId(preparationToDelete.userId);
+     122              :   }
+     123              : 
+     124              :   // Future<PreparationEntity> getPreparationUsersByUserIdAfterDeletion(
+     125              :   //     String userId, String deletedId) async {
+     126              :   //   final steps = await getPreparationUsersByUserId(userId);
+     127              :   //   steps.preparationStepList.updateLinksAfterDeletion(deletedId);
+     128              :   //   return steps;
+     129              :   // }
+     130              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/preparation_user_dao.g.dart.gcov.html b/coverage/html/data/daos/preparation_user_dao.g.dart.gcov.html new file mode 100644 index 00000000..9d552bfe --- /dev/null +++ b/coverage/html/data/daos/preparation_user_dao.g.dart.gcov.html @@ -0,0 +1,86 @@ + + + + + + + LCOV - lcov.info - data/daos/preparation_user_dao.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daos - preparation_user_dao.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'preparation_user_dao.dart';
+       4              : 
+       5              : // ignore_for_file: type=lint
+       6              : mixin _$PreparationUserDaoMixin on DatabaseAccessor<AppDatabase> {
+       7            0 :   $UsersTable get users => attachedDatabase.users;
+       8            0 :   $PreparationUsersTable get preparationUsers =>
+       9            0 :       attachedDatabase.preparationUsers;
+      10              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/schedule_dao.dart.gcov.html b/coverage/html/data/daos/schedule_dao.dart.gcov.html new file mode 100644 index 00000000..00ff31e2 --- /dev/null +++ b/coverage/html/data/daos/schedule_dao.dart.gcov.html @@ -0,0 +1,171 @@ + + + + + + + LCOV - lcov.info - data/daos/schedule_dao.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daos - schedule_dao.dartCoverageTotalHit
Test:lcov.infoLines:80.0 %4536
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:drift/drift.dart';
+       2              : import 'package:on_time_front/data/tables/places_table.dart';
+       3              : import 'package:on_time_front/data/tables/schedule_with_place_model.dart';
+       4              : import '/core/database/database.dart';
+       5              : import 'package:on_time_front/data/tables/schedules_table.dart';
+       6              : 
+       7              : part 'schedule_dao.g.dart';
+       8              : 
+       9              : @DriftAccessor(tables: [Schedules, Places])
+      10              : class ScheduleDao extends DatabaseAccessor<AppDatabase>
+      11              :     with _$ScheduleDaoMixin {
+      12              :   final AppDatabase db;
+      13              : 
+      14            2 :   ScheduleDao(this.db) : super(db);
+      15              : 
+      16            1 :   Future<ScheduleWithPlace> createSchedule(
+      17              :       ScheduleWithPlace scheduleWithPlace) async {
+      18            4 :     final placeModel = await db.placeDao.createPlace(scheduleWithPlace.place);
+      19            4 :     final scheduleModel = await into(db.schedules).insertReturning(
+      20            2 :       scheduleWithPlace.schedule.toCompanion(false),
+      21              :     );
+      22              : 
+      23            1 :     return ScheduleWithPlace(
+      24              :       schedule: scheduleModel,
+      25              :       place: placeModel,
+      26              :     );
+      27              :   }
+      28              : 
+      29            1 :   Future<void> deleteSchedule(Schedule scheduleModel) async {
+      30            3 :     await (delete(db.schedules)
+      31            5 :           ..where((tbl) => tbl.id.equals(scheduleModel.id)))
+      32            1 :         .go();
+      33              :   }
+      34              : 
+      35            1 :   Future<ScheduleWithPlace> getScheduleById(String id) async {
+      36              :     try {
+      37            5 :       final query = await (select(db.schedules).join([
+      38           10 :         leftOuterJoin(db.places, db.places.id.equalsExp(db.schedules.placeId)),
+      39              :       ])
+      40            5 :             ..where(db.schedules.id.equals(id)))
+      41            1 :           .getSingle();
+      42            1 :       return ScheduleWithPlace(
+      43            3 :         schedule: query.readTable(db.schedules),
+      44            3 :         place: query.readTable(db.places),
+      45              :       );
+      46              :     } catch (e) {
+      47              :       rethrow;
+      48              :     }
+      49              :   }
+      50              : 
+      51            1 :   Future<Schedule> updateSchedule(Schedule scheduleModel) async {
+      52            3 :     final scheduleList = await (update(db.schedules)
+      53            5 :           ..where((tbl) => tbl.id.equals(scheduleModel.id)))
+      54            2 :         .writeReturning(scheduleModel.toCompanion(true));
+      55            3 :     assert(scheduleList.length == 1);
+      56            1 :     return scheduleList.first;
+      57              :   }
+      58              : 
+      59            1 :   Future<List<ScheduleWithPlace>> getSchedulesByDate(
+      60              :       DateTime startDate, DateTime? endDate) async {
+      61            5 :     final query = select(db.schedules).join([
+      62           10 :       leftOuterJoin(db.places, db.places.id.equalsExp(db.schedules.placeId)),
+      63              :     ])
+      64            6 :       ..where(db.schedules.scheduleTime.isBiggerOrEqualValue(startDate) &
+      65              :           (endDate == null
+      66            1 :               ? Constant<bool>(true)
+      67            4 :               : db.schedules.scheduleTime.isSmallerOrEqualValue(endDate)));
+      68            1 :     final result = await query.get();
+      69            1 :     final List<ScheduleWithPlace> scheduleList = [];
+      70              : 
+      71            2 :     await Future.forEach(result, (schedule) async {
+      72            2 :       scheduleList.add(ScheduleWithPlace(
+      73            3 :         schedule: schedule.readTable(db.schedules),
+      74            3 :         place: schedule.readTable(db.places),
+      75              :       ));
+      76              :     });
+      77              :     return scheduleList;
+      78              :   }
+      79              : 
+      80            0 :   Future<List<ScheduleWithPlace>> getScheduleList() async {
+      81            0 :     final query = select(db.schedules).join([
+      82            0 :       leftOuterJoin(db.places, db.places.id.equalsExp(db.schedules.placeId)),
+      83              :     ]);
+      84            0 :     final result = await query.get();
+      85            0 :     final List<ScheduleWithPlace> scheduleList = [];
+      86              : 
+      87            0 :     await Future.forEach(result, (schedule) async {
+      88            0 :       scheduleList.add(ScheduleWithPlace(
+      89            0 :         schedule: schedule.readTable(db.schedules),
+      90            0 :         place: schedule.readTable(db.places),
+      91              :       ));
+      92              :     });
+      93              :     return scheduleList;
+      94              :   }
+      95              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/schedule_dao.g.dart.gcov.html b/coverage/html/data/daos/schedule_dao.g.dart.gcov.html new file mode 100644 index 00000000..809f8f68 --- /dev/null +++ b/coverage/html/data/daos/schedule_dao.g.dart.gcov.html @@ -0,0 +1,85 @@ + + + + + + + LCOV - lcov.info - data/daos/schedule_dao.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daos - schedule_dao.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %20
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'schedule_dao.dart';
+       4              : 
+       5              : // ignore_for_file: type=lint
+       6              : mixin _$ScheduleDaoMixin on DatabaseAccessor<AppDatabase> {
+       7            0 :   $PlacesTable get places => attachedDatabase.places;
+       8            0 :   $SchedulesTable get schedules => attachedDatabase.schedules;
+       9              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/user_dao.dart.gcov.html b/coverage/html/data/daos/user_dao.dart.gcov.html new file mode 100644 index 00000000..7c3beaca --- /dev/null +++ b/coverage/html/data/daos/user_dao.dart.gcov.html @@ -0,0 +1,109 @@ + + + + + + + LCOV - lcov.info - data/daos/user_dao.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daos - user_dao.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %110
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:drift/drift.dart';
+       2              : import '/core/database/database.dart';
+       3              : import 'package:on_time_front/data/tables/user_table.dart';
+       4              : import 'package:on_time_front/domain/entities/user_entity.dart';
+       5              : 
+       6              : part 'user_dao.g.dart';
+       7              : 
+       8              : @DriftAccessor(tables: [Users])
+       9              : class UserDao extends DatabaseAccessor<AppDatabase> with _$UserDaoMixin {
+      10              :   final AppDatabase db;
+      11              : 
+      12            0 :   UserDao(this.db) : super(db);
+      13              : 
+      14            0 :   Future<void> createUser(UserEntity userEntity) async {
+      15            0 :     await into(db.users).insert(
+      16            0 :       userEntity.toModel().toCompanion(false),
+      17              :     );
+      18              :   }
+      19              : 
+      20            0 :   Future<UserEntity?> getUserById(String userId) async {
+      21            0 :     final user = await (select(db.users)..where((tbl) => tbl.id.equals(userId)))
+      22            0 :         .getSingleOrNull();
+      23              :     if (user != null) {
+      24            0 :       return UserEntity.fromModel(user);
+      25              :     }
+      26              :     return null;
+      27              :   }
+      28              : 
+      29            0 :   Future<List<UserEntity>> getAllUsers() async {
+      30            0 :     final query = await select(db.users).get();
+      31            0 :     return query.map((user) => UserEntity.fromModel(user)).toList();
+      32              :   }
+      33              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/daos/user_dao.g.dart.gcov.html b/coverage/html/data/daos/user_dao.g.dart.gcov.html new file mode 100644 index 00000000..dfa7eefe --- /dev/null +++ b/coverage/html/data/daos/user_dao.g.dart.gcov.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - lcov.info - data/daos/user_dao.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/daos - user_dao.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %10
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'user_dao.dart';
+       4              : 
+       5              : // ignore_for_file: type=lint
+       6              : mixin _$UserDaoMixin on DatabaseAccessor<AppDatabase> {
+       7            0 :   $UsersTable get users => attachedDatabase.users;
+       8              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/authentication_remote_data_source.dart.gcov.html b/coverage/html/data/data_sources/authentication_remote_data_source.dart.gcov.html new file mode 100644 index 00000000..10009520 --- /dev/null +++ b/coverage/html/data/data_sources/authentication_remote_data_source.dart.gcov.html @@ -0,0 +1,209 @@ + + + + + + + LCOV - lcov.info - data/data_sources/authentication_remote_data_source.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sources - authentication_remote_data_source.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %430
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:dio/dio.dart';
+       2              : import 'package:injectable/injectable.dart';
+       3              : import 'package:on_time_front/core/constants/endpoint.dart';
+       4              : import 'package:on_time_front/data/models/get_user_response_model.dart';
+       5              : import 'package:on_time_front/data/models/sign_in_user_response_model.dart';
+       6              : import 'package:on_time_front/data/models/sign_in_with_google_request_model.dart';
+       7              : import 'package:on_time_front/data/models/sign_in_with_apple_request_model.dart';
+       8              : import 'package:on_time_front/domain/entities/token_entity.dart';
+       9              : import 'package:on_time_front/domain/entities/user_entity.dart';
+      10              : 
+      11              : abstract interface class AuthenticationRemoteDataSource {
+      12              :   Future<(UserEntity, TokenEntity)> signIn(String email, String password);
+      13              : 
+      14              :   Future<(UserEntity, TokenEntity)> signUp(
+      15              :       String email, String password, String name);
+      16              : 
+      17              :   Future<(UserEntity, TokenEntity)> signInWithGoogle(
+      18              :       SignInWithGoogleRequestModel signInWithGoogleRequestModel);
+      19              : 
+      20              :   Future<(UserEntity, TokenEntity)> signInWithApple(
+      21              :       SignInWithAppleRequestModel signInWithAppleRequestModel);
+      22              : 
+      23              :   Future<UserEntity> getUser();
+      24              : }
+      25              : 
+      26              : @Injectable(as: AuthenticationRemoteDataSource)
+      27              : class AuthenticationRemoteDataSourceImpl
+      28              :     implements AuthenticationRemoteDataSource {
+      29              :   final Dio dio;
+      30            0 :   AuthenticationRemoteDataSourceImpl(this.dio);
+      31              : 
+      32            0 :   @override
+      33              :   Future<(UserEntity, TokenEntity)> signIn(
+      34              :       String email, String password) async {
+      35              :     try {
+      36            0 :       final result = await dio.post(
+      37            0 :         Endpoint.signIn,
+      38            0 :         data: {
+      39              :           'email': email,
+      40              :           'password': password,
+      41              :         },
+      42              :       );
+      43            0 :       if (result.statusCode == 200) {
+      44            0 :         final user = SignInUserResponseModel.fromJson(result.data['data']);
+      45            0 :         final token = TokenEntity.fromHeaders(result.headers);
+      46            0 :         return (user.toEntity(), token);
+      47              :       } else {
+      48            0 :         throw Exception('Error signing in');
+      49              :       }
+      50              :     } catch (e) {
+      51              :       rethrow;
+      52              :     }
+      53              :   }
+      54              : 
+      55            0 :   @override
+      56              :   Future<(UserEntity, TokenEntity)> signUp(
+      57              :       String email, String password, String name) async {
+      58              :     try {
+      59            0 :       final result = await dio.post(
+      60            0 :         Endpoint.signUp,
+      61            0 :         data: {
+      62              :           'email': email,
+      63              :           'password': password,
+      64              :           'name': name,
+      65              :         },
+      66              :       );
+      67            0 :       if (result.statusCode == 200) {
+      68            0 :         final user = SignInUserResponseModel.fromJson(result.data['data']);
+      69            0 :         final token = TokenEntity.fromHeaders(result.headers);
+      70            0 :         return (user.toEntity(), token);
+      71              :       } else {
+      72            0 :         throw Exception('Error signing up');
+      73              :       }
+      74              :     } catch (e) {
+      75              :       rethrow;
+      76              :     }
+      77              :   }
+      78              : 
+      79            0 :   @override
+      80              :   Future<(UserEntity, TokenEntity)> signInWithGoogle(
+      81              :       SignInWithGoogleRequestModel signInWithGoogleRequestModel) async {
+      82              :     try {
+      83            0 :       final result = await dio.post(
+      84            0 :         Endpoint.signInWithGoogle,
+      85            0 :         data: signInWithGoogleRequestModel.toJson(),
+      86              :       );
+      87            0 :       if (result.statusCode == 200) {
+      88            0 :         final user = SignInUserResponseModel.fromJson(result.data['data']);
+      89            0 :         final token = TokenEntity.fromHeaders(result.headers);
+      90            0 :         return (user.toEntity(), token);
+      91              :       } else {
+      92            0 :         throw Exception('Error signing in with Google');
+      93              :       }
+      94              :     } catch (e) {
+      95              :       rethrow;
+      96              :     }
+      97              :   }
+      98              : 
+      99            0 :   @override
+     100              :   Future<(UserEntity, TokenEntity)> signInWithApple(
+     101              :       SignInWithAppleRequestModel signInWithAppleRequestModel) async {
+     102              :     try {
+     103            0 :       final result = await dio.post(
+     104            0 :         Endpoint.signInWithApple,
+     105            0 :         data: signInWithAppleRequestModel.toJson(),
+     106              :       );
+     107            0 :       if (result.statusCode == 200) {
+     108            0 :         final user = SignInUserResponseModel.fromJson(result.data['data']);
+     109            0 :         final token = TokenEntity.fromHeaders(result.headers);
+     110            0 :         return (user.toEntity(), token);
+     111              :       } else {
+     112            0 :         throw Exception('Error signing in with Apple');
+     113              :       }
+     114              :     } catch (e) {
+     115              :       rethrow;
+     116              :     }
+     117              :   }
+     118              : 
+     119            0 :   @override
+     120              :   Future<UserEntity> getUser() async {
+     121              :     try {
+     122            0 :       final result = await dio.get(Endpoint.getUser);
+     123            0 :       if (result.statusCode == 200) {
+     124            0 :         final user = GetUserResponseModel.fromJson(result.data['data']);
+     125            0 :         return user.toEntity();
+     126              :       } else {
+     127            0 :         throw Exception('Error getting user');
+     128              :       }
+     129              :     } catch (e) {
+     130              :       rethrow;
+     131              :     }
+     132              :   }
+     133              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/index-sort-f.html b/coverage/html/data/data_sources/index-sort-f.html new file mode 100644 index 00000000..3d1eef4a --- /dev/null +++ b/coverage/html/data/data_sources/index-sort-f.html @@ -0,0 +1,161 @@ + + + + + + + LCOV - lcov.info - data/data_sources + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sourcesCoverageTotalHit
Test:lcov.infoLines:13.5 %22931
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
authentication_remote_data_source.dart +
0.0%
+
0.0 %43
notification_remote_data_source.dart +
0.0%
+
0.0 %7
preparation_local_data_source.dart +
0.0%
+
0.0 %28
preparation_remote_data_source.dart +
41.7%41.7%
+
41.7 %4820
preparation_with_time_local_data_source.dart +
0.0%
+
0.0 %34
schedule_local_data_source.dart +
0.0%
+
0.0 %17
schedule_remote_data_source.dart +
28.2%28.2%
+
28.2 %3911
token_local_data_source.dart +
0.0%
+
0.0 %13
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/index-sort-l.html b/coverage/html/data/data_sources/index-sort-l.html new file mode 100644 index 00000000..a950daa9 --- /dev/null +++ b/coverage/html/data/data_sources/index-sort-l.html @@ -0,0 +1,161 @@ + + + + + + + LCOV - lcov.info - data/data_sources + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sourcesCoverageTotalHit
Test:lcov.infoLines:13.5 %22931
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
notification_remote_data_source.dart +
0.0%
+
0.0 %7
token_local_data_source.dart +
0.0%
+
0.0 %13
schedule_local_data_source.dart +
0.0%
+
0.0 %17
preparation_local_data_source.dart +
0.0%
+
0.0 %28
preparation_with_time_local_data_source.dart +
0.0%
+
0.0 %34
authentication_remote_data_source.dart +
0.0%
+
0.0 %43
schedule_remote_data_source.dart +
28.2%28.2%
+
28.2 %3911
preparation_remote_data_source.dart +
41.7%41.7%
+
41.7 %4820
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/index.html b/coverage/html/data/data_sources/index.html new file mode 100644 index 00000000..8c15e2f4 --- /dev/null +++ b/coverage/html/data/data_sources/index.html @@ -0,0 +1,161 @@ + + + + + + + LCOV - lcov.info - data/data_sources + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sourcesCoverageTotalHit
Test:lcov.infoLines:13.5 %22931
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
authentication_remote_data_source.dart +
0.0%
+
0.0 %43
notification_remote_data_source.dart +
0.0%
+
0.0 %7
preparation_local_data_source.dart +
0.0%
+
0.0 %28
preparation_remote_data_source.dart +
41.7%41.7%
+
41.7 %4820
preparation_with_time_local_data_source.dart +
0.0%
+
0.0 %34
schedule_local_data_source.dart +
0.0%
+
0.0 %17
schedule_remote_data_source.dart +
28.2%28.2%
+
28.2 %3911
token_local_data_source.dart +
0.0%
+
0.0 %13
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/notification_remote_data_source.dart.gcov.html b/coverage/html/data/data_sources/notification_remote_data_source.dart.gcov.html new file mode 100644 index 00000000..628adcd2 --- /dev/null +++ b/coverage/html/data/data_sources/notification_remote_data_source.dart.gcov.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - data/data_sources/notification_remote_data_source.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sources - notification_remote_data_source.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %70
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:dio/dio.dart';
+       2              : import 'package:injectable/injectable.dart';
+       3              : import 'package:on_time_front/core/constants/endpoint.dart';
+       4              : import 'package:on_time_front/data/models/fcm_token_register_request_model.dart';
+       5              : 
+       6              : abstract interface class NotificationRemoteDataSource {
+       7              :   Future<void> fcmTokenRegister(FcmTokenRegisterRequestModel model);
+       8              : }
+       9              : 
+      10              : @Injectable(as: NotificationRemoteDataSource)
+      11              : class NotificationRemoteDataSourceImpl implements NotificationRemoteDataSource {
+      12              :   final Dio dio;
+      13              : 
+      14            0 :   NotificationRemoteDataSourceImpl(this.dio);
+      15              : 
+      16            0 :   @override
+      17              :   Future<void> fcmTokenRegister(FcmTokenRegisterRequestModel model) async {
+      18              :     try {
+      19            0 :       final result = await dio.post(
+      20            0 :         Endpoint.fcmTokenRegister,
+      21            0 :         data: model.toJson(),
+      22              :       );
+      23              : 
+      24            0 :       if (result.statusCode != 200) {
+      25            0 :         throw Exception('Error registering FCM token');
+      26              :       }
+      27              :     } catch (e) {
+      28              :       rethrow;
+      29              :     }
+      30              :   }
+      31              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/preparation_local_data_source.dart.gcov.html b/coverage/html/data/data_sources/preparation_local_data_source.dart.gcov.html new file mode 100644 index 00000000..3b084b8b --- /dev/null +++ b/coverage/html/data/data_sources/preparation_local_data_source.dart.gcov.html @@ -0,0 +1,166 @@ + + + + + + + LCOV - lcov.info - data/data_sources/preparation_local_data_source.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sources - preparation_local_data_source.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %280
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/core/database/database.dart';
+       3              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       4              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       5              : 
+       6              : abstract interface class PreparationLocalDataSource {
+       7              :   Future<void> createDefaultPreparation(PreparationEntity preparationEntity);
+       8              : 
+       9              :   Future<void> createCustomPreparation(
+      10              :       PreparationEntity preparationEntity, String scheduleId);
+      11              : 
+      12              :   Future<void> updatePreparation(PreparationStepEntity preparationStepEntity);
+      13              : 
+      14              :   Future<PreparationEntity> deletePreparation(
+      15              :       PreparationEntity preparationEntity);
+      16              : 
+      17              :   Future<PreparationEntity> getPreparationByScheduleId(String scheduleId);
+      18              : 
+      19              :   Future<PreparationStepEntity> getPreparationStepById(
+      20              :       String preparationStepId);
+      21              : }
+      22              : 
+      23              : @Injectable(as: PreparationLocalDataSource)
+      24              : class PreparationLocalDataSourceImpl implements PreparationLocalDataSource {
+      25              :   final AppDatabase appDatabase;
+      26              : 
+      27            0 :   PreparationLocalDataSourceImpl({required this.appDatabase});
+      28              : 
+      29            0 :   @override
+      30              :   Future<void> createDefaultPreparation(
+      31              :       PreparationEntity preparationEntity) async {
+      32            0 :     await appDatabase.preparationUserDao
+      33            0 :         .createPreparationUser(preparationEntity, 'userId');
+      34              :   }
+      35              : 
+      36            0 :   @override
+      37              :   Future<void> createCustomPreparation(
+      38              :       PreparationEntity preparationEntity, String scheduleId) async {
+      39            0 :     await appDatabase.preparationScheduleDao
+      40            0 :         .createPreparationSchedule(preparationEntity, scheduleId);
+      41              :   }
+      42              : 
+      43            0 :   @override
+      44              :   Future<PreparationEntity> getPreparationByScheduleId(
+      45              :       String scheduleId) async {
+      46            0 :     return await appDatabase.preparationScheduleDao
+      47            0 :         .getPreparationSchedulesByScheduleId(scheduleId);
+      48              :   }
+      49              : 
+      50            0 :   @override
+      51              :   Future<PreparationStepEntity> getPreparationStepById(
+      52              :       String preparationStepId) async {
+      53            0 :     return await appDatabase.preparationScheduleDao
+      54            0 :         .getPreparationStepById(preparationStepId);
+      55              :   }
+      56              : 
+      57            0 :   @override
+      58              :   Future<PreparationEntity> deletePreparation(
+      59              :       PreparationEntity preparationEntity) async {
+      60            0 :     if (preparationEntity.preparationStepList.isEmpty) {
+      61            0 :       throw Exception("No preparation steps to delete.");
+      62              :     }
+      63              : 
+      64            0 :     final firstStep = preparationEntity.preparationStepList.first;
+      65              : 
+      66            0 :     if (firstStep.nextPreparationId != null) {
+      67              :       // 스케줄 기반 삭제
+      68            0 :       return await appDatabase.preparationScheduleDao
+      69            0 :           .deletePreparationSchedule(firstStep.id);
+      70              :     } else {
+      71              :       // 사용자 기반 삭제
+      72            0 :       return await appDatabase.preparationUserDao
+      73            0 :           .deletePreparationUser(firstStep.id);
+      74              :     }
+      75              :   }
+      76              : 
+      77            0 :   @override
+      78              :   Future<void> updatePreparation(
+      79              :       PreparationStepEntity preparationStepEntity) async {
+      80            0 :     if (preparationStepEntity.nextPreparationId != null) {
+      81              :       // 스케줄 기반 업데이트
+      82            0 :       await appDatabase.preparationScheduleDao
+      83            0 :           .updatePreparationSchedule(preparationStepEntity, 'scheduleId');
+      84              :     } else {
+      85              :       // 사용자 기반 업데이트
+      86            0 :       await appDatabase.preparationUserDao
+      87            0 :           .updatePreparationUser(preparationStepEntity, 'userId');
+      88              :     }
+      89              :   }
+      90              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/preparation_remote_data_source.dart.gcov.html b/coverage/html/data/data_sources/preparation_remote_data_source.dart.gcov.html new file mode 100644 index 00000000..9cdb6862 --- /dev/null +++ b/coverage/html/data/data_sources/preparation_remote_data_source.dart.gcov.html @@ -0,0 +1,233 @@ + + + + + + + LCOV - lcov.info - data/data_sources/preparation_remote_data_source.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sources - preparation_remote_data_source.dartCoverageTotalHit
Test:lcov.infoLines:41.7 %4820
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:dio/dio.dart';
+       2              : import 'package:injectable/injectable.dart';
+       3              : 
+       4              : import 'package:on_time_front/core/constants/endpoint.dart';
+       5              : import 'package:on_time_front/data/models/update_preparation_schedule_request_model.dart';
+       6              : import 'package:on_time_front/data/models/update_preparation_user_request_model.dart';
+       7              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       8              : import 'package:on_time_front/data/models/create_preparation_schedule_request_model.dart';
+       9              : import 'package:on_time_front/data/models/create_defualt_preparation_request_model.dart';
+      10              : import 'package:on_time_front/data/models/get_preparation_step_response_model.dart';
+      11              : 
+      12              : abstract interface class PreparationRemoteDataSource {
+      13              :   Future<void> createDefaultPreparation(
+      14              :       CreateDefaultPreparationRequestModel model);
+      15              : 
+      16              :   Future<void> createCustomPreparation(
+      17              :       PreparationEntity preparationEntity, String scheduleId);
+      18              : 
+      19              :   Future<void> updateDefaultPreparation(PreparationEntity preparationEntity);
+      20              : 
+      21              :   Future<void> updatePreparationByScheduleId(
+      22              :       PreparationEntity preparationEntity, String scheduleId);
+      23              : 
+      24              :   Future<PreparationEntity> getPreparationByScheduleId(String scheduleId);
+      25              : 
+      26              :   Future<PreparationEntity> getDefualtPreparation();
+      27              : }
+      28              : 
+      29              : @Injectable(as: PreparationRemoteDataSource)
+      30              : class PreparationRemoteDataSourceImpl implements PreparationRemoteDataSource {
+      31              :   final Dio dio;
+      32              : 
+      33            1 :   PreparationRemoteDataSourceImpl(this.dio);
+      34              : 
+      35            1 :   @override
+      36              :   Future<void> createCustomPreparation(
+      37              :       PreparationEntity preparationEntity, String scheduleId) async {
+      38              :     try {
+      39              :       final requestModels =
+      40            1 :           PreparationScheduleCreateRequestModelListExtension.fromEntityList(
+      41            1 :               preparationEntity.preparationStepList);
+      42              : 
+      43            2 :       final result = await dio.post(
+      44            1 :         Endpoint.getCreateCustomPreparation(scheduleId),
+      45            4 :         data: requestModels.map((model) => model.toJson()).toList(),
+      46              :       );
+      47              : 
+      48            2 :       if (result.statusCode != 200) {
+      49            1 :         throw Exception('Error creating custom preparation');
+      50              :       }
+      51              :     } catch (e) {
+      52              :       rethrow;
+      53              :     }
+      54              :   }
+      55              : 
+      56            1 :   @override
+      57              :   Future<void> createDefaultPreparation(
+      58              :       CreateDefaultPreparationRequestModel model) async {
+      59              :     try {
+      60            2 :       final result = await dio.put(
+      61            1 :         Endpoint.createDefaultPreparation,
+      62            1 :         data: model.toJson(),
+      63              :       );
+      64              : 
+      65            2 :       if (result.statusCode != 200) {
+      66            1 :         throw Exception('Error creating default preparation');
+      67              :       }
+      68              :     } catch (e) {
+      69              :       rethrow;
+      70              :     }
+      71              :   }
+      72              : 
+      73            1 :   @override
+      74              :   Future<PreparationEntity> getPreparationByScheduleId(
+      75              :       String scheduleId) async {
+      76              :     try {
+      77            2 :       final result = await dio.get(
+      78            1 :         Endpoint.getPreparationByScheduleId(scheduleId),
+      79              :       );
+      80              : 
+      81            2 :       if (result.statusCode == 200) {
+      82            0 :         final responseModels = (result.data['data'] as List<dynamic>)
+      83            0 :             .map((json) => GetPreparationStepResponseModel.fromJson(
+      84              :                 json as Map<String, dynamic>))
+      85            0 :             .toList();
+      86              : 
+      87            0 :         return responseModels.toPreparationEntity();
+      88              :       } else {
+      89            1 :         throw Exception('Error fetching preparation by schedule ID');
+      90              :       }
+      91              :     } catch (e) {
+      92              :       rethrow;
+      93              :     }
+      94              :   }
+      95              : 
+      96            0 :   @override
+      97              :   Future<PreparationEntity> getDefualtPreparation() async {
+      98              :     try {
+      99            0 :       final result = await dio.get(Endpoint.getDefaultPreparation);
+     100              : 
+     101            0 :       if (result.statusCode == 200) {
+     102            0 :         final responseModels = (result.data['data'] as List<dynamic>)
+     103            0 :             .map((json) => GetPreparationStepResponseModel.fromJson(
+     104              :                 json as Map<String, dynamic>))
+     105            0 :             .toList();
+     106              : 
+     107            0 :         return responseModels.toPreparationEntity();
+     108              :       } else {
+     109            0 :         throw Exception('Error fetching default preparation');
+     110              :       }
+     111              :     } catch (e) {
+     112              :       rethrow;
+     113              :     }
+     114              :   }
+     115              : 
+     116            0 :   @override
+     117              :   Future<void> updateDefaultPreparation(
+     118              :       PreparationEntity preparationEntity) async {
+     119              :     try {
+     120              :       final updateModel =
+     121            0 :           PreparationUserModifyRequestModelListExtension.fromEntityList(
+     122            0 :               preparationEntity.preparationStepList);
+     123              : 
+     124            0 :       final result = await dio.post(
+     125            0 :         Endpoint.updateDefaultPreparation,
+     126            0 :         data: updateModel.map((model) => model.toJson()).toList(),
+     127              :       );
+     128              : 
+     129            0 :       if (result.statusCode != 200) {
+     130            0 :         throw Exception('Error updating preparation');
+     131              :       }
+     132              :     } catch (e) {
+     133              :       rethrow;
+     134              :     }
+     135              :   }
+     136              : 
+     137            0 :   @override
+     138              :   Future<void> updatePreparationByScheduleId(
+     139              :       PreparationEntity preparationEntity, String scheduleId) async {
+     140              :     try {
+     141              :       final updateModel =
+     142            0 :           PreparationScheduleModifyRequestModelListExtension.fromEntityList(
+     143            0 :               preparationEntity.preparationStepList);
+     144              : 
+     145            0 :       final result = await dio.post(
+     146            0 :         Endpoint.updatePreparationByScheduleId(scheduleId),
+     147            0 :         data: updateModel.map((model) => model.toJson()).toList(),
+     148              :       );
+     149              : 
+     150            0 :       if (result.statusCode != 200) {
+     151            0 :         throw Exception('Error updating preparation');
+     152              :       }
+     153              :     } catch (e) {
+     154              :       rethrow;
+     155              :     }
+     156              :   }
+     157              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/preparation_with_time_local_data_source.dart.gcov.html b/coverage/html/data/data_sources/preparation_with_time_local_data_source.dart.gcov.html new file mode 100644 index 00000000..c56607a2 --- /dev/null +++ b/coverage/html/data/data_sources/preparation_with_time_local_data_source.dart.gcov.html @@ -0,0 +1,149 @@ + + + + + + + LCOV - lcov.info - data/data_sources/preparation_with_time_local_data_source.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sources - preparation_with_time_local_data_source.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %340
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:convert';
+       2              : 
+       3              : import 'package:injectable/injectable.dart';
+       4              : import 'package:shared_preferences/shared_preferences.dart';
+       5              : import 'package:on_time_front/domain/entities/preparation_with_time_entity.dart';
+       6              : import 'package:on_time_front/domain/entities/preparation_step_with_time_entity.dart';
+       7              : 
+       8              : abstract interface class PreparationWithTimeLocalDataSource {
+       9              :   Future<void> savePreparation(
+      10              :       String scheduleId, PreparationWithTimeEntity preparation);
+      11              :   Future<PreparationWithTimeEntity?> loadPreparation(String scheduleId);
+      12              :   Future<void> clearPreparation(String scheduleId);
+      13              : }
+      14              : 
+      15              : @Injectable(as: PreparationWithTimeLocalDataSource)
+      16              : class PreparationWithTimeLocalDataSourceImpl
+      17              :     implements PreparationWithTimeLocalDataSource {
+      18              :   static const String _prefsKeyPrefix = 'preparation_with_time_';
+      19              : 
+      20            0 :   @override
+      21              :   Future<void> savePreparation(
+      22              :       String scheduleId, PreparationWithTimeEntity preparation) async {
+      23            0 :     final prefs = await SharedPreferences.getInstance();
+      24            0 :     final key = '$_prefsKeyPrefix$scheduleId';
+      25              : 
+      26            0 :     final jsonMap = {
+      27            0 :       'steps': preparation.preparationStepList
+      28            0 :           .map((s) => {
+      29            0 :                 'id': s.id,
+      30            0 :                 'name': s.preparationName,
+      31            0 :                 'time': s.preparationTime.inMilliseconds,
+      32            0 :                 'nextId': s.nextPreparationId,
+      33            0 :                 'elapsed': s.elapsedTime.inMilliseconds,
+      34            0 :                 'isDone': s.isDone,
+      35              :               })
+      36            0 :           .toList()
+      37              :     };
+      38              : 
+      39            0 :     await prefs.setString(key, jsonEncode(jsonMap));
+      40              :   }
+      41              : 
+      42            0 :   @override
+      43              :   Future<PreparationWithTimeEntity?> loadPreparation(String scheduleId) async {
+      44            0 :     final prefs = await SharedPreferences.getInstance();
+      45            0 :     final key = '$_prefsKeyPrefix$scheduleId';
+      46            0 :     final jsonString = prefs.getString(key);
+      47              :     if (jsonString == null) return null;
+      48              : 
+      49            0 :     final Map<String, dynamic> map = jsonDecode(jsonString);
+      50            0 :     final List<dynamic> steps = map['steps'] as List<dynamic>;
+      51              : 
+      52            0 :     final stepEntities = steps.map((raw) {
+      53              :       final m = raw as Map<String, dynamic>;
+      54            0 :       return PreparationStepWithTimeEntity(
+      55            0 :         id: m['id'] as String,
+      56            0 :         preparationName: m['name'] as String,
+      57            0 :         preparationTime: Duration(milliseconds: (m['time'] as num).toInt()),
+      58            0 :         nextPreparationId: m['nextId'] as String?,
+      59            0 :         elapsedTime: Duration(milliseconds: (m['elapsed'] as num).toInt()),
+      60            0 :         isDone: m['isDone'] as bool? ?? false,
+      61              :       );
+      62            0 :     }).toList();
+      63              : 
+      64            0 :     return PreparationWithTimeEntity(preparationStepList: stepEntities);
+      65              :   }
+      66              : 
+      67            0 :   @override
+      68              :   Future<void> clearPreparation(String scheduleId) async {
+      69            0 :     final prefs = await SharedPreferences.getInstance();
+      70            0 :     final key = '$_prefsKeyPrefix$scheduleId';
+      71            0 :     await prefs.remove(key);
+      72              :   }
+      73              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/schedule_local_data_source.dart.gcov.html b/coverage/html/data/data_sources/schedule_local_data_source.dart.gcov.html new file mode 100644 index 00000000..872d187d --- /dev/null +++ b/coverage/html/data/data_sources/schedule_local_data_source.dart.gcov.html @@ -0,0 +1,136 @@ + + + + + + + LCOV - lcov.info - data/data_sources/schedule_local_data_source.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sources - schedule_local_data_source.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %170
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/core/database/database.dart';
+       3              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       4              : 
+       5              : abstract interface class ScheduleLocalDataSource {
+       6              :   Future<void> createSchedule(ScheduleEntity scheduleEntity);
+       7              : 
+       8              :   Future<List<ScheduleEntity>> getSchedulesByDate(
+       9              :       DateTime startDate, DateTime? endDate);
+      10              : 
+      11              :   Future<ScheduleEntity> getScheduleById(String id);
+      12              : 
+      13              :   Future<void> updateSchedule(ScheduleEntity scheduleEntity);
+      14              : 
+      15              :   Future<void> deleteSchedule(ScheduleEntity scheduleEntity);
+      16              : }
+      17              : 
+      18              : @Injectable(as: ScheduleLocalDataSource)
+      19              : class ScheduleLocalDataSourceImpl implements ScheduleLocalDataSource {
+      20              :   final AppDatabase appDatabase;
+      21              : 
+      22            0 :   ScheduleLocalDataSourceImpl({
+      23              :     required this.appDatabase,
+      24              :   });
+      25              : 
+      26            0 :   @override
+      27              :   Future<void> createSchedule(ScheduleEntity scheduleEntity) async {
+      28            0 :     await appDatabase.scheduleDao
+      29            0 :         .createSchedule(scheduleEntity.toScheduleWithPlaceModel());
+      30              :   }
+      31              : 
+      32            0 :   @override
+      33              :   Future<void> deleteSchedule(ScheduleEntity schedulEntity) async {
+      34            0 :     await appDatabase.scheduleDao
+      35            0 :         .deleteSchedule(schedulEntity.toScheduleModel());
+      36              :   }
+      37              : 
+      38            0 :   @override
+      39              :   Future<ScheduleEntity> getScheduleById(String id) async {
+      40              :     final scheduleWithPlaceModel =
+      41            0 :         await appDatabase.scheduleDao.getScheduleById(id);
+      42            0 :     return ScheduleEntity.fromScheduleWithPlaceModel(scheduleWithPlaceModel);
+      43              :   }
+      44              : 
+      45            0 :   @override
+      46              :   Future<List<ScheduleEntity>> getSchedulesByDate(
+      47              :       DateTime startDate, DateTime? endDate) async {
+      48              :     final scheduleWithPlaceModel =
+      49            0 :         await appDatabase.scheduleDao.getSchedulesByDate(startDate, endDate);
+      50              :     return scheduleWithPlaceModel
+      51            0 :         .map((e) => ScheduleEntity.fromScheduleWithPlaceModel(e))
+      52            0 :         .toList();
+      53              :   }
+      54              : 
+      55            0 :   @override
+      56              :   Future<void> updateSchedule(ScheduleEntity scheduleEntity) async {
+      57            0 :     await appDatabase.scheduleDao
+      58            0 :         .updateSchedule(scheduleEntity.toScheduleModel());
+      59              :   }
+      60              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/schedule_remote_data_source.dart.gcov.html b/coverage/html/data/data_sources/schedule_remote_data_source.dart.gcov.html new file mode 100644 index 00000000..c3a221f6 --- /dev/null +++ b/coverage/html/data/data_sources/schedule_remote_data_source.dart.gcov.html @@ -0,0 +1,213 @@ + + + + + + + LCOV - lcov.info - data/data_sources/schedule_remote_data_source.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sources - schedule_remote_data_source.dartCoverageTotalHit
Test:lcov.infoLines:28.2 %3911
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:dio/dio.dart';
+       2              : import 'package:injectable/injectable.dart';
+       3              : import 'package:on_time_front/core/constants/endpoint.dart';
+       4              : 
+       5              : import 'package:on_time_front/data/models/create_schedule_request_model.dart';
+       6              : import 'package:on_time_front/data/models/get_schedule_response_model.dart';
+       7              : import 'package:on_time_front/data/models/update_schedule_request_model.dart';
+       8              : 
+       9              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+      10              : 
+      11              : abstract interface class ScheduleRemoteDataSource {
+      12              :   Future<void> createSchedule(ScheduleEntity schedule);
+      13              : 
+      14              :   Future<List<ScheduleEntity>> getSchedulesByDate(
+      15              :       DateTime startDate, DateTime? endDate);
+      16              : 
+      17              :   Future<ScheduleEntity> getScheduleById(String id);
+      18              : 
+      19              :   Future<void> updateSchedule(ScheduleEntity schedule);
+      20              : 
+      21              :   Future<void> deleteSchedule(ScheduleEntity schedule);
+      22              : 
+      23              :   Future<void> finishSchedule(String scheduleId, int latenessTime);
+      24              : }
+      25              : 
+      26              : @Injectable(as: ScheduleRemoteDataSource)
+      27              : class ScheduleRemoteDataSourceImpl implements ScheduleRemoteDataSource {
+      28              :   final Dio dio;
+      29            1 :   ScheduleRemoteDataSourceImpl(this.dio);
+      30              : 
+      31            1 :   @override
+      32              :   Future<void> createSchedule(ScheduleEntity schedule) async {
+      33              :     try {
+      34              :       CreateScheduleRequestModel createScheduleModel =
+      35            1 :           CreateScheduleRequestModel.fromEntity(schedule);
+      36            3 :       final result = await dio.post(Endpoint.createSchedule,
+      37            1 :           data: createScheduleModel.toJson());
+      38            2 :       if (result.statusCode == 200) {
+      39              :         return;
+      40              :       } else {
+      41            1 :         throw Exception('Error creating schedule worng status code');
+      42              :       }
+      43              :     } catch (e) {
+      44              :       rethrow;
+      45              :     }
+      46              :   }
+      47              : 
+      48            0 :   @override
+      49              :   Future<void> updateSchedule(ScheduleEntity schedule) async {
+      50              :     try {
+      51              :       UpdateScheduleRequestModel updateScheduleModel =
+      52            0 :           UpdateScheduleRequestModel.fromEntity(schedule);
+      53            0 :       final result = await dio.put(Endpoint.updateSchedule(schedule.id),
+      54            0 :           data: updateScheduleModel.toJson());
+      55            0 :       if (result.statusCode == 200) {
+      56              :         return;
+      57              :       } else {
+      58            0 :         throw Exception('Error updating schedule');
+      59              :       }
+      60              :     } catch (e) {
+      61              :       rethrow;
+      62              :     }
+      63              :   }
+      64              : 
+      65            1 :   @override
+      66              :   Future<void> deleteSchedule(ScheduleEntity schedule) async {
+      67              :     try {
+      68            4 :       final result = await dio.delete(Endpoint.deleteScheduleById(schedule.id));
+      69            2 :       if (result.statusCode == 200) {
+      70              :         return;
+      71              :       } else {
+      72            1 :         throw Exception('Error deleting schedule');
+      73              :       }
+      74              :     } catch (e) {
+      75              :       rethrow;
+      76              :     }
+      77              :   }
+      78              : 
+      79            0 :   @override
+      80              :   Future<void> finishSchedule(String scheduleId, int latenessTime) async {
+      81              :     try {
+      82            0 :       final result = await dio.put(
+      83            0 :         Endpoint.finishSchedule(scheduleId),
+      84            0 :         data: {
+      85              :           'scheduleId': scheduleId,
+      86              :           'latenessTime': latenessTime,
+      87              :         },
+      88              :       );
+      89            0 :       if (result.statusCode == 200) {
+      90              :         return;
+      91              :       } else {
+      92            0 :         throw Exception('Error finishing schedule');
+      93              :       }
+      94              :     } catch (e) {
+      95              :       rethrow;
+      96              :     }
+      97              :   }
+      98              : 
+      99            0 :   @override
+     100              :   Future<ScheduleEntity> getScheduleById(String id) async {
+     101              :     try {
+     102            0 :       final result = await dio.get(Endpoint.getScheduleById(id));
+     103            0 :       if (result.statusCode == 200) {
+     104              :         final GetScheduleResponseModel schedule =
+     105            0 :             GetScheduleResponseModel.fromJson(result.data["data"]);
+     106            0 :         return schedule.toEntity();
+     107              :       } else {
+     108            0 :         throw Exception('Error getting schedules');
+     109              :       }
+     110              :     } catch (e) {
+     111              :       rethrow;
+     112              :     }
+     113              :   }
+     114              : 
+     115            0 :   @override
+     116              :   Future<List<ScheduleEntity>> getSchedulesByDate(
+     117              :       DateTime startDate, DateTime? endDate) async {
+     118              :     try {
+     119              :       final result =
+     120            0 :           await dio.get(Endpoint.getSchedulesByDate, queryParameters: {
+     121            0 :         'startDate': startDate.toIso8601String(),
+     122            0 :         'endDate': endDate?.toIso8601String() ?? '',
+     123              :       });
+     124            0 :       if (result.statusCode == 200) {
+     125            0 :         final List<ScheduleEntity> schedules = result.data["data"]
+     126            0 :             .map<ScheduleEntity>(
+     127            0 :                 (e) => GetScheduleResponseModel.fromJson(e).toEntity())
+     128            0 :             .toList();
+     129              :         return schedules;
+     130              :       } else {
+     131            0 :         throw Exception('Error getting schedules');
+     132              :       }
+     133              :     } catch (e) {
+     134              :       rethrow;
+     135              :     }
+     136              :   }
+     137              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/data_sources/token_local_data_source.dart.gcov.html b/coverage/html/data/data_sources/token_local_data_source.dart.gcov.html new file mode 100644 index 00000000..29835967 --- /dev/null +++ b/coverage/html/data/data_sources/token_local_data_source.dart.gcov.html @@ -0,0 +1,126 @@ + + + + + + + LCOV - lcov.info - data/data_sources/token_local_data_source.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/data_sources - token_local_data_source.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %130
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+       2              : import 'package:injectable/injectable.dart';
+       3              : import 'package:on_time_front/domain/entities/token_entity.dart';
+       4              : 
+       5              : abstract class TokenLocalDataSource {
+       6              :   Future<void> storeTokens(TokenEntity token);
+       7              : 
+       8              :   Future<void> storeAuthToken(String token);
+       9              : 
+      10              :   Future<TokenEntity> getToken();
+      11              : 
+      12              :   Future<void> deleteToken();
+      13              : }
+      14              : 
+      15              : @Injectable(as: TokenLocalDataSource)
+      16              : class TokenLocalDataSourceImpl implements TokenLocalDataSource {
+      17              :   final storage = FlutterSecureStorage();
+      18              : 
+      19              :   final accessTokenKey = 'accessToken';
+      20              :   final refreshTokenKey = 'refreshToken';
+      21              : 
+      22            0 :   @override
+      23              :   Future<void> storeTokens(TokenEntity token) async {
+      24            0 :     await storage.write(key: accessTokenKey, value: token.accessToken);
+      25            0 :     await storage.write(key: refreshTokenKey, value: token.refreshToken);
+      26              :   }
+      27              : 
+      28            0 :   @override
+      29              :   Future<TokenEntity> getToken() async {
+      30              :     try {
+      31            0 :       final accessToken = await storage.read(key: accessTokenKey);
+      32            0 :       final refreshToken = await storage.read(key: refreshTokenKey);
+      33            0 :       return TokenEntity(
+      34              :           accessToken: accessToken!, refreshToken: refreshToken!);
+      35              :     } catch (e) {
+      36            0 :       throw Exception('Token not found');
+      37              :     }
+      38              :   }
+      39              : 
+      40            0 :   @override
+      41              :   Future<void> deleteToken() async {
+      42            0 :     await storage.delete(key: accessTokenKey);
+      43            0 :     await storage.delete(key: refreshTokenKey);
+      44              :   }
+      45              : 
+      46            0 :   @override
+      47              :   Future<void> storeAuthToken(String token) async {
+      48            0 :     await storage.write(key: accessTokenKey, value: token);
+      49              :   }
+      50              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/create_defualt_preparation_request_model.dart.gcov.html b/coverage/html/data/models/create_defualt_preparation_request_model.dart.gcov.html new file mode 100644 index 00000000..89205271 --- /dev/null +++ b/coverage/html/data/models/create_defualt_preparation_request_model.dart.gcov.html @@ -0,0 +1,114 @@ + + + + + + + LCOV - lcov.info - data/models/create_defualt_preparation_request_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - create_defualt_preparation_request_model.dartCoverageTotalHit
Test:lcov.infoLines:81.8 %119
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/data/models/create_preparation_step_request_model.dart';
+       3              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       4              : 
+       5              : part 'create_defualt_preparation_request_model.g.dart';
+       6              : 
+       7              : @JsonSerializable()
+       8              : class CreateDefaultPreparationRequestModel {
+       9              :   final String spareTime;
+      10              :   final String note;
+      11              :   final List<CreatePreparationStepRequestModel> preparationList;
+      12              : 
+      13            2 :   CreateDefaultPreparationRequestModel({
+      14              :     required this.spareTime,
+      15              :     required this.note,
+      16              :     required this.preparationList,
+      17              :   });
+      18              : 
+      19            0 :   factory CreateDefaultPreparationRequestModel.fromJson(
+      20              :           Map<String, dynamic> json) =>
+      21            0 :       _$CreateDefaultPreparationRequestModelFromJson(json);
+      22              : 
+      23            1 :   Map<String, dynamic> toJson() =>
+      24            1 :       _$CreateDefaultPreparationRequestModelToJson(this);
+      25              : 
+      26            2 :   static CreateDefaultPreparationRequestModel fromEntity(
+      27              :       {required PreparationEntity preparationEntity,
+      28              :       required Duration spareTime,
+      29              :       required String note}) {
+      30            2 :     return CreateDefaultPreparationRequestModel(
+      31            4 :       spareTime: spareTime.inMinutes.toString(),
+      32              :       note: note,
+      33            2 :       preparationList: preparationEntity.preparationStepList
+      34            6 :           .map((e) => CreatePreparationStepRequestModel.fromEntity(e))
+      35            2 :           .toList(),
+      36              :     );
+      37              :   }
+      38              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/create_defualt_preparation_request_model.g.dart.gcov.html b/coverage/html/data/models/create_defualt_preparation_request_model.g.dart.gcov.html new file mode 100644 index 00000000..60a076a9 --- /dev/null +++ b/coverage/html/data/models/create_defualt_preparation_request_model.g.dart.gcov.html @@ -0,0 +1,102 @@ + + + + + + + LCOV - lcov.info - data/models/create_defualt_preparation_request_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - create_defualt_preparation_request_model.g.dartCoverageTotalHit
Test:lcov.infoLines:41.7 %125
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'create_defualt_preparation_request_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : CreateDefaultPreparationRequestModel
+      10              :     _$CreateDefaultPreparationRequestModelFromJson(Map<String, dynamic> json) =>
+      11            0 :         CreateDefaultPreparationRequestModel(
+      12            0 :           spareTime: json['spareTime'] as String,
+      13            0 :           note: json['note'] as String,
+      14            0 :           preparationList: (json['preparationList'] as List<dynamic>)
+      15            0 :               .map((e) => CreatePreparationStepRequestModel.fromJson(
+      16              :                   e as Map<String, dynamic>))
+      17            0 :               .toList(),
+      18              :         );
+      19              : 
+      20            1 : Map<String, dynamic> _$CreateDefaultPreparationRequestModelToJson(
+      21              :         CreateDefaultPreparationRequestModel instance) =>
+      22            1 :     <String, dynamic>{
+      23            1 :       'spareTime': instance.spareTime,
+      24            1 :       'note': instance.note,
+      25            1 :       'preparationList': instance.preparationList,
+      26              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/create_preparation_schedule_request_model.dart.gcov.html b/coverage/html/data/models/create_preparation_schedule_request_model.dart.gcov.html new file mode 100644 index 00000000..71e8c04c --- /dev/null +++ b/coverage/html/data/models/create_preparation_schedule_request_model.dart.gcov.html @@ -0,0 +1,137 @@ + + + + + + + LCOV - lcov.info - data/models/create_preparation_schedule_request_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - create_preparation_schedule_request_model.dartCoverageTotalHit
Test:lcov.infoLines:56.5 %2313
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       3              : 
+       4              : part 'create_preparation_schedule_request_model.g.dart';
+       5              : 
+       6              : @JsonSerializable()
+       7              : class PreparationScheduleCreateRequestModel {
+       8              :   @JsonKey(name: 'preparationId')
+       9              :   final String id;
+      10              :   final String preparationName;
+      11              :   final int preparationTime;
+      12              :   final String? nextPreparationId;
+      13              : 
+      14            1 :   PreparationScheduleCreateRequestModel({
+      15              :     required this.id,
+      16              :     required this.preparationName,
+      17              :     required this.preparationTime,
+      18              :     required this.nextPreparationId,
+      19              :   });
+      20              : 
+      21            0 :   factory PreparationScheduleCreateRequestModel.fromJson(
+      22              :           Map<String, dynamic> json) =>
+      23            0 :       _$PreparationScheduleCreateRequestModelFromJson(json);
+      24              : 
+      25            1 :   Map<String, dynamic> toJson() =>
+      26            1 :       _$PreparationScheduleCreateRequestModelToJson(this);
+      27              : 
+      28            1 :   static PreparationScheduleCreateRequestModel fromEntity(
+      29              :       PreparationStepEntity entity) {
+      30            1 :     return PreparationScheduleCreateRequestModel(
+      31            1 :       id: entity.id,
+      32            1 :       preparationName: entity.preparationName,
+      33            2 :       preparationTime: entity.preparationTime.inMinutes,
+      34            1 :       nextPreparationId: entity.nextPreparationId,
+      35              :     );
+      36              :   }
+      37              : 
+      38            0 :   PreparationStepEntity toEntity() {
+      39            0 :     return PreparationStepEntity(
+      40            0 :       id: id,
+      41            0 :       preparationName: preparationName,
+      42            0 :       preparationTime: Duration(minutes: preparationTime),
+      43            0 :       nextPreparationId: nextPreparationId,
+      44              :     );
+      45              :   }
+      46              : }
+      47              : 
+      48              : extension PreparationScheduleCreateRequestModelListExtension
+      49              :     on List<PreparationScheduleCreateRequestModel> {
+      50            0 :   List<PreparationStepEntity> toEntityList() {
+      51            0 :     return map((model) => model.toEntity()).toList();
+      52              :   }
+      53              : 
+      54            1 :   static List<PreparationScheduleCreateRequestModel> fromEntityList(
+      55              :       List<PreparationStepEntity> entities) {
+      56              :     return entities
+      57            2 :         .map((entity) =>
+      58            1 :             PreparationScheduleCreateRequestModel.fromEntity(entity))
+      59            1 :         .toList();
+      60              :   }
+      61              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/create_preparation_schedule_request_model.g.dart.gcov.html b/coverage/html/data/models/create_preparation_schedule_request_model.g.dart.gcov.html new file mode 100644 index 00000000..80eed2a9 --- /dev/null +++ b/coverage/html/data/models/create_preparation_schedule_request_model.g.dart.gcov.html @@ -0,0 +1,102 @@ + + + + + + + LCOV - lcov.info - data/models/create_preparation_schedule_request_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - create_preparation_schedule_request_model.g.dartCoverageTotalHit
Test:lcov.infoLines:50.0 %126
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'create_preparation_schedule_request_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : PreparationScheduleCreateRequestModel
+      10              :     _$PreparationScheduleCreateRequestModelFromJson(
+      11              :             Map<String, dynamic> json) =>
+      12            0 :         PreparationScheduleCreateRequestModel(
+      13            0 :           id: json['preparationId'] as String,
+      14            0 :           preparationName: json['preparationName'] as String,
+      15            0 :           preparationTime: (json['preparationTime'] as num).toInt(),
+      16            0 :           nextPreparationId: json['nextPreparationId'] as String?,
+      17              :         );
+      18              : 
+      19            1 : Map<String, dynamic> _$PreparationScheduleCreateRequestModelToJson(
+      20              :         PreparationScheduleCreateRequestModel instance) =>
+      21            1 :     <String, dynamic>{
+      22            1 :       'preparationId': instance.id,
+      23            1 :       'preparationName': instance.preparationName,
+      24            1 :       'preparationTime': instance.preparationTime,
+      25            1 :       'nextPreparationId': instance.nextPreparationId,
+      26              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/create_preparation_step_request_model.dart.gcov.html b/coverage/html/data/models/create_preparation_step_request_model.dart.gcov.html new file mode 100644 index 00000000..eebade7d --- /dev/null +++ b/coverage/html/data/models/create_preparation_step_request_model.dart.gcov.html @@ -0,0 +1,122 @@ + + + + + + + LCOV - lcov.info - data/models/create_preparation_step_request_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - create_preparation_step_request_model.dartCoverageTotalHit
Test:lcov.infoLines:41.2 %177
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       3              : 
+       4              : part 'create_preparation_step_request_model.g.dart';
+       5              : 
+       6              : @JsonSerializable()
+       7              : class CreatePreparationStepRequestModel {
+       8              :   @JsonKey(name: 'preparationId')
+       9              :   final String id;
+      10              :   final String preparationName;
+      11              :   final int preparationTime;
+      12              :   final String? nextPreparationId;
+      13              : 
+      14            2 :   CreatePreparationStepRequestModel({
+      15              :     required this.id,
+      16              :     required this.preparationName,
+      17              :     required this.preparationTime,
+      18              :     required this.nextPreparationId,
+      19              :   });
+      20              : 
+      21            0 :   factory CreatePreparationStepRequestModel.fromJson(
+      22              :           Map<String, dynamic> json) =>
+      23            0 :       _$CreatePreparationStepRequestModelFromJson(json);
+      24              : 
+      25            0 :   Map<String, dynamic> toJson() =>
+      26            0 :       _$CreatePreparationStepRequestModelToJson(this);
+      27              : 
+      28            2 :   static CreatePreparationStepRequestModel fromEntity(
+      29              :       PreparationStepEntity entity) {
+      30            2 :     return CreatePreparationStepRequestModel(
+      31            2 :       id: entity.id,
+      32            2 :       preparationName: entity.preparationName,
+      33            4 :       preparationTime: entity.preparationTime.inMinutes,
+      34            2 :       nextPreparationId: entity.nextPreparationId,
+      35              :     );
+      36              :   }
+      37              : 
+      38            0 :   PreparationStepEntity toEntity() {
+      39            0 :     return PreparationStepEntity(
+      40            0 :       id: id,
+      41            0 :       preparationName: preparationName,
+      42            0 :       preparationTime: Duration(minutes: preparationTime),
+      43            0 :       nextPreparationId: nextPreparationId,
+      44              :     );
+      45              :   }
+      46              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/create_preparation_step_request_model.g.dart.gcov.html b/coverage/html/data/models/create_preparation_step_request_model.g.dart.gcov.html new file mode 100644 index 00000000..7e9a3129 --- /dev/null +++ b/coverage/html/data/models/create_preparation_step_request_model.g.dart.gcov.html @@ -0,0 +1,101 @@ + + + + + + + LCOV - lcov.info - data/models/create_preparation_step_request_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - create_preparation_step_request_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %120
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'create_preparation_step_request_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : CreatePreparationStepRequestModel _$CreatePreparationStepRequestModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     CreatePreparationStepRequestModel(
+      12            0 :       id: json['preparationId'] as String,
+      13            0 :       preparationName: json['preparationName'] as String,
+      14            0 :       preparationTime: (json['preparationTime'] as num).toInt(),
+      15            0 :       nextPreparationId: json['nextPreparationId'] as String?,
+      16              :     );
+      17              : 
+      18            0 : Map<String, dynamic> _$CreatePreparationStepRequestModelToJson(
+      19              :         CreatePreparationStepRequestModel instance) =>
+      20            0 :     <String, dynamic>{
+      21            0 :       'preparationId': instance.id,
+      22            0 :       'preparationName': instance.preparationName,
+      23            0 :       'preparationTime': instance.preparationTime,
+      24            0 :       'nextPreparationId': instance.nextPreparationId,
+      25              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/create_schedule_request_model.dart.gcov.html b/coverage/html/data/models/create_schedule_request_model.dart.gcov.html new file mode 100644 index 00000000..243909f1 --- /dev/null +++ b/coverage/html/data/models/create_schedule_request_model.dart.gcov.html @@ -0,0 +1,127 @@ + + + + + + + LCOV - lcov.info - data/models/create_schedule_request_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - create_schedule_request_model.dartCoverageTotalHit
Test:lcov.infoLines:87.5 %1614
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       3              : 
+       4              : part 'create_schedule_request_model.g.dart';
+       5              : 
+       6              : @JsonSerializable()
+       7              : class CreateScheduleRequestModel {
+       8              :   final String scheduleId;
+       9              :   final String placeId;
+      10              :   final String placeName;
+      11              :   final String scheduleName;
+      12              :   final DateTime scheduleTime;
+      13              :   final int moveTime;
+      14              :   final bool isChange;
+      15              :   final bool isStarted;
+      16              :   final int? scheduleSpareTime;
+      17              :   final String scheduleNote;
+      18              : 
+      19            1 :   const CreateScheduleRequestModel({
+      20              :     required this.scheduleId,
+      21              :     required this.placeId,
+      22              :     required this.placeName,
+      23              :     required this.scheduleName,
+      24              :     required this.scheduleTime,
+      25              :     required this.moveTime,
+      26              :     required this.isChange,
+      27              :     required this.isStarted,
+      28              :     required this.scheduleSpareTime,
+      29              :     required this.scheduleNote,
+      30              :   });
+      31              : 
+      32            0 :   factory CreateScheduleRequestModel.fromJson(Map<String, dynamic> json) =>
+      33            0 :       _$CreateScheduleRequestModelFromJson(json);
+      34              : 
+      35            2 :   Map<String, dynamic> toJson() => _$CreateScheduleRequestModelToJson(this);
+      36              : 
+      37            1 :   static CreateScheduleRequestModel fromEntity(ScheduleEntity entity) {
+      38            1 :     return CreateScheduleRequestModel(
+      39            1 :       scheduleId: entity.id,
+      40            2 :       placeId: entity.place.id,
+      41            2 :       placeName: entity.place.placeName,
+      42            1 :       scheduleName: entity.scheduleName,
+      43            1 :       scheduleTime: entity.scheduleTime,
+      44            2 :       moveTime: entity.moveTime.inMinutes,
+      45            1 :       isChange: entity.isChanged,
+      46            1 :       isStarted: entity.isStarted,
+      47            2 :       scheduleSpareTime: entity.scheduleSpareTime?.inMinutes,
+      48            1 :       scheduleNote: entity.scheduleNote,
+      49              :     );
+      50              :   }
+      51              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/create_schedule_request_model.g.dart.gcov.html b/coverage/html/data/models/create_schedule_request_model.g.dart.gcov.html new file mode 100644 index 00000000..38b8f30f --- /dev/null +++ b/coverage/html/data/models/create_schedule_request_model.g.dart.gcov.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - lcov.info - data/models/create_schedule_request_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - create_schedule_request_model.g.dartCoverageTotalHit
Test:lcov.infoLines:50.0 %2412
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'create_schedule_request_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : CreateScheduleRequestModel _$CreateScheduleRequestModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     CreateScheduleRequestModel(
+      12            0 :       scheduleId: json['scheduleId'] as String,
+      13            0 :       placeId: json['placeId'] as String,
+      14            0 :       placeName: json['placeName'] as String,
+      15            0 :       scheduleName: json['scheduleName'] as String,
+      16            0 :       scheduleTime: DateTime.parse(json['scheduleTime'] as String),
+      17            0 :       moveTime: (json['moveTime'] as num).toInt(),
+      18            0 :       isChange: json['isChange'] as bool,
+      19            0 :       isStarted: json['isStarted'] as bool,
+      20            0 :       scheduleSpareTime: (json['scheduleSpareTime'] as num?)?.toInt(),
+      21            0 :       scheduleNote: json['scheduleNote'] as String,
+      22              :     );
+      23              : 
+      24            1 : Map<String, dynamic> _$CreateScheduleRequestModelToJson(
+      25              :         CreateScheduleRequestModel instance) =>
+      26            1 :     <String, dynamic>{
+      27            1 :       'scheduleId': instance.scheduleId,
+      28            1 :       'placeId': instance.placeId,
+      29            1 :       'placeName': instance.placeName,
+      30            1 :       'scheduleName': instance.scheduleName,
+      31            2 :       'scheduleTime': instance.scheduleTime.toIso8601String(),
+      32            1 :       'moveTime': instance.moveTime,
+      33            1 :       'isChange': instance.isChange,
+      34            1 :       'isStarted': instance.isStarted,
+      35            1 :       'scheduleSpareTime': instance.scheduleSpareTime,
+      36            1 :       'scheduleNote': instance.scheduleNote,
+      37              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/fcm_token_register_request_model.dart.gcov.html b/coverage/html/data/models/fcm_token_register_request_model.dart.gcov.html new file mode 100644 index 00000000..1adc18fc --- /dev/null +++ b/coverage/html/data/models/fcm_token_register_request_model.dart.gcov.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - lcov.info - data/models/fcm_token_register_request_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - fcm_token_register_request_model.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %40
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : 
+       3              : part 'fcm_token_register_request_model.g.dart';
+       4              : 
+       5              : @JsonSerializable()
+       6              : class FcmTokenRegisterRequestModel {
+       7              :   final String firebaseToken;
+       8              : 
+       9            0 :   FcmTokenRegisterRequestModel({
+      10              :     required this.firebaseToken,
+      11              :   });
+      12              : 
+      13            0 :   factory FcmTokenRegisterRequestModel.fromJson(Map<String, dynamic> json) =>
+      14            0 :       _$FcmTokenRegisterRequestModelFromJson(json);
+      15            0 :   Map<String, dynamic> toJson() => _$FcmTokenRegisterRequestModelToJson(this);
+      16              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/fcm_token_register_request_model.g.dart.gcov.html b/coverage/html/data/models/fcm_token_register_request_model.g.dart.gcov.html new file mode 100644 index 00000000..9d09c37a --- /dev/null +++ b/coverage/html/data/models/fcm_token_register_request_model.g.dart.gcov.html @@ -0,0 +1,95 @@ + + + + + + + LCOV - lcov.info - data/models/fcm_token_register_request_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - fcm_token_register_request_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %60
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'fcm_token_register_request_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : FcmTokenRegisterRequestModel _$FcmTokenRegisterRequestModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     FcmTokenRegisterRequestModel(
+      12            0 :       firebaseToken: json['firebaseToken'] as String,
+      13              :     );
+      14              : 
+      15            0 : Map<String, dynamic> _$FcmTokenRegisterRequestModelToJson(
+      16              :         FcmTokenRegisterRequestModel instance) =>
+      17            0 :     <String, dynamic>{
+      18            0 :       'firebaseToken': instance.firebaseToken,
+      19              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/get_place_response_model.dart.gcov.html b/coverage/html/data/models/get_place_response_model.dart.gcov.html new file mode 100644 index 00000000..9e56fa64 --- /dev/null +++ b/coverage/html/data/models/get_place_response_model.dart.gcov.html @@ -0,0 +1,110 @@ + + + + + + + LCOV - lcov.info - data/models/get_place_response_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - get_place_response_model.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %120
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/domain/entities/place_entity.dart';
+       3              : 
+       4              : part 'get_place_response_model.g.dart';
+       5              : 
+       6              : @JsonSerializable()
+       7              : class GetPlaceResponseModel {
+       8              :   final String placeId;
+       9              :   final String placeName;
+      10              : 
+      11            0 :   const GetPlaceResponseModel({
+      12              :     required this.placeId,
+      13              :     required this.placeName,
+      14              :   });
+      15              : 
+      16            0 :   factory GetPlaceResponseModel.fromJson(Map<String, dynamic> json) =>
+      17            0 :       _$GetPlaceResponseModelFromJson(json);
+      18              : 
+      19            0 :   Map<String, dynamic> toJson() => _$GetPlaceResponseModelToJson(this);
+      20              : 
+      21            0 :   static GetPlaceResponseModel fromEntity(PlaceEntity entity) {
+      22            0 :     return GetPlaceResponseModel(
+      23            0 :       placeId: entity.id,
+      24            0 :       placeName: entity.placeName,
+      25              :     );
+      26              :   }
+      27              : 
+      28            0 :   PlaceEntity toEntity() {
+      29            0 :     return PlaceEntity(
+      30            0 :       id: placeId,
+      31            0 :       placeName: placeName,
+      32              :     );
+      33              :   }
+      34              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/get_place_response_model.g.dart.gcov.html b/coverage/html/data/models/get_place_response_model.g.dart.gcov.html new file mode 100644 index 00000000..33ef8a2c --- /dev/null +++ b/coverage/html/data/models/get_place_response_model.g.dart.gcov.html @@ -0,0 +1,97 @@ + + + + + + + LCOV - lcov.info - data/models/get_place_response_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - get_place_response_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %80
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'get_place_response_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : GetPlaceResponseModel _$GetPlaceResponseModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     GetPlaceResponseModel(
+      12            0 :       placeId: json['placeId'] as String,
+      13            0 :       placeName: json['placeName'] as String,
+      14              :     );
+      15              : 
+      16            0 : Map<String, dynamic> _$GetPlaceResponseModelToJson(
+      17              :         GetPlaceResponseModel instance) =>
+      18            0 :     <String, dynamic>{
+      19            0 :       'placeId': instance.placeId,
+      20            0 :       'placeName': instance.placeName,
+      21              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/get_preparation_step_response_model.dart.gcov.html b/coverage/html/data/models/get_preparation_step_response_model.dart.gcov.html new file mode 100644 index 00000000..5fbc8fb6 --- /dev/null +++ b/coverage/html/data/models/get_preparation_step_response_model.dart.gcov.html @@ -0,0 +1,130 @@ + + + + + + + LCOV - lcov.info - data/models/get_preparation_step_response_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - get_preparation_step_response_model.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %200
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       3              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       4              : 
+       5              : part 'get_preparation_step_response_model.g.dart';
+       6              : 
+       7              : @JsonSerializable()
+       8              : class GetPreparationStepResponseModel {
+       9              :   @JsonKey(name: 'preparationId')
+      10              :   final String id;
+      11              :   final String preparationName;
+      12              :   final int preparationTime;
+      13              :   final String? nextPreparationId;
+      14              : 
+      15            0 :   GetPreparationStepResponseModel({
+      16              :     required this.id,
+      17              :     required this.preparationName,
+      18              :     required this.preparationTime,
+      19              :     required this.nextPreparationId,
+      20              :   });
+      21              : 
+      22            0 :   factory GetPreparationStepResponseModel.fromJson(Map<String, dynamic> json) =>
+      23            0 :       _$GetPreparationStepResponseModelFromJson(json);
+      24              : 
+      25            0 :   Map<String, dynamic> toJson() =>
+      26            0 :       _$GetPreparationStepResponseModelToJson(this);
+      27              : 
+      28            0 :   PreparationStepEntity toEntity() {
+      29            0 :     return PreparationStepEntity(
+      30            0 :       id: id,
+      31            0 :       preparationName: preparationName,
+      32            0 :       preparationTime: Duration(minutes: preparationTime),
+      33            0 :       nextPreparationId: nextPreparationId,
+      34              :     );
+      35              :   }
+      36              : 
+      37            0 :   static GetPreparationStepResponseModel fromEntity(
+      38              :       PreparationStepEntity entity) {
+      39            0 :     return GetPreparationStepResponseModel(
+      40            0 :       id: entity.id,
+      41            0 :       preparationName: entity.preparationName,
+      42            0 :       preparationTime: entity.preparationTime.inMinutes,
+      43            0 :       nextPreparationId: entity.nextPreparationId,
+      44              :     );
+      45              :   }
+      46              : }
+      47              : 
+      48              : extension PreparationResponseModelListExtension
+      49              :     on List<GetPreparationStepResponseModel> {
+      50            0 :   PreparationEntity toPreparationEntity() {
+      51            0 :     final steps = map((model) => model.toEntity()).toList();
+      52            0 :     return PreparationEntity(preparationStepList: steps);
+      53              :   }
+      54              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/get_preparation_step_response_model.g.dart.gcov.html b/coverage/html/data/models/get_preparation_step_response_model.g.dart.gcov.html new file mode 100644 index 00000000..ec5ceec4 --- /dev/null +++ b/coverage/html/data/models/get_preparation_step_response_model.g.dart.gcov.html @@ -0,0 +1,101 @@ + + + + + + + LCOV - lcov.info - data/models/get_preparation_step_response_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - get_preparation_step_response_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %120
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'get_preparation_step_response_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : GetPreparationStepResponseModel _$GetPreparationStepResponseModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     GetPreparationStepResponseModel(
+      12            0 :       id: json['preparationId'] as String,
+      13            0 :       preparationName: json['preparationName'] as String,
+      14            0 :       preparationTime: (json['preparationTime'] as num).toInt(),
+      15            0 :       nextPreparationId: json['nextPreparationId'] as String?,
+      16              :     );
+      17              : 
+      18            0 : Map<String, dynamic> _$GetPreparationStepResponseModelToJson(
+      19              :         GetPreparationStepResponseModel instance) =>
+      20            0 :     <String, dynamic>{
+      21            0 :       'preparationId': instance.id,
+      22            0 :       'preparationName': instance.preparationName,
+      23            0 :       'preparationTime': instance.preparationTime,
+      24            0 :       'nextPreparationId': instance.nextPreparationId,
+      25              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/get_schedule_response_model.dart.gcov.html b/coverage/html/data/models/get_schedule_response_model.dart.gcov.html new file mode 100644 index 00000000..c1245b63 --- /dev/null +++ b/coverage/html/data/models/get_schedule_response_model.dart.gcov.html @@ -0,0 +1,141 @@ + + + + + + + LCOV - lcov.info - data/models/get_schedule_response_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - get_schedule_response_model.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %190
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/data/models/get_place_response_model.dart';
+       3              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       4              : 
+       5              : part 'get_schedule_response_model.g.dart';
+       6              : 
+       7              : @JsonSerializable()
+       8              : class GetScheduleResponseModel {
+       9              :   final String scheduleId;
+      10              :   final GetPlaceResponseModel place;
+      11              :   final String scheduleName;
+      12              :   final DateTime scheduleTime;
+      13              :   final int moveTime;
+      14              :   final int scheduleSpareTime;
+      15              :   final String scheduleNote;
+      16              :   final int? latenessTime;
+      17              :   final String? doneStatus;
+      18              : 
+      19            0 :   const GetScheduleResponseModel({
+      20              :     required this.scheduleId,
+      21              :     required this.place,
+      22              :     required this.scheduleName,
+      23              :     required this.scheduleTime,
+      24              :     required this.moveTime,
+      25              :     required this.scheduleSpareTime,
+      26              :     required this.scheduleNote,
+      27              :     this.latenessTime = 0,
+      28              :     this.doneStatus = 'NOT_ENDED',
+      29              :   });
+      30              : 
+      31            0 :   ScheduleEntity toEntity() {
+      32            0 :     return ScheduleEntity(
+      33            0 :       id: scheduleId,
+      34            0 :       place: place.toEntity(),
+      35            0 :       scheduleName: scheduleName,
+      36            0 :       scheduleTime: scheduleTime,
+      37            0 :       moveTime: Duration(minutes: moveTime),
+      38              :       isChanged: false,
+      39              :       isStarted: false,
+      40            0 :       scheduleSpareTime: Duration(minutes: scheduleSpareTime),
+      41            0 :       scheduleNote: scheduleNote,
+      42            0 :       latenessTime: latenessTime ?? -1,
+      43            0 :       doneStatus: _mapDoneStatus(doneStatus),
+      44              :     );
+      45              :   }
+      46              : 
+      47            0 :   factory GetScheduleResponseModel.fromJson(Map<String, dynamic> json) =>
+      48            0 :       _$GetScheduleResponseModelFromJson(json);
+      49              : 
+      50            0 :   Map<String, dynamic> toJson() => _$GetScheduleResponseModelToJson(this);
+      51              : }
+      52              : 
+      53            0 : ScheduleDoneStatus _mapDoneStatus(String? serverValue) {
+      54              :   switch (serverValue) {
+      55            0 :     case 'LATE':
+      56              :       return ScheduleDoneStatus.lateEnd;
+      57            0 :     case 'NORMAL':
+      58              :       return ScheduleDoneStatus.normalEnd;
+      59            0 :     case 'ABNORMAL':
+      60              :       return ScheduleDoneStatus.abnormalEnd;
+      61              :     case 'NOT_ENDED':
+      62              :     default:
+      63              :       return ScheduleDoneStatus.notEnded;
+      64              :   }
+      65              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/get_schedule_response_model.g.dart.gcov.html b/coverage/html/data/models/get_schedule_response_model.g.dart.gcov.html new file mode 100644 index 00000000..782bbd94 --- /dev/null +++ b/coverage/html/data/models/get_schedule_response_model.g.dart.gcov.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - lcov.info - data/models/get_schedule_response_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - get_schedule_response_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %220
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'get_schedule_response_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : GetScheduleResponseModel _$GetScheduleResponseModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     GetScheduleResponseModel(
+      12            0 :       scheduleId: json['scheduleId'] as String,
+      13              :       place:
+      14            0 :           GetPlaceResponseModel.fromJson(json['place'] as Map<String, dynamic>),
+      15            0 :       scheduleName: json['scheduleName'] as String,
+      16            0 :       scheduleTime: DateTime.parse(json['scheduleTime'] as String),
+      17            0 :       moveTime: (json['moveTime'] as num).toInt(),
+      18            0 :       scheduleSpareTime: (json['scheduleSpareTime'] as num).toInt(),
+      19            0 :       scheduleNote: json['scheduleNote'] as String,
+      20            0 :       latenessTime: (json['latenessTime'] as num?)?.toInt() ?? 0,
+      21            0 :       doneStatus: json['doneStatus'] as String? ?? 'NOT_ENDED',
+      22              :     );
+      23              : 
+      24            0 : Map<String, dynamic> _$GetScheduleResponseModelToJson(
+      25              :         GetScheduleResponseModel instance) =>
+      26            0 :     <String, dynamic>{
+      27            0 :       'scheduleId': instance.scheduleId,
+      28            0 :       'place': instance.place,
+      29            0 :       'scheduleName': instance.scheduleName,
+      30            0 :       'scheduleTime': instance.scheduleTime.toIso8601String(),
+      31            0 :       'moveTime': instance.moveTime,
+      32            0 :       'scheduleSpareTime': instance.scheduleSpareTime,
+      33            0 :       'scheduleNote': instance.scheduleNote,
+      34            0 :       'latenessTime': instance.latenessTime,
+      35            0 :       'doneStatus': instance.doneStatus,
+      36              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/get_user_response_model.dart.gcov.html b/coverage/html/data/models/get_user_response_model.dart.gcov.html new file mode 100644 index 00000000..e0d96c99 --- /dev/null +++ b/coverage/html/data/models/get_user_response_model.dart.gcov.html @@ -0,0 +1,118 @@ + + + + + + + LCOV - lcov.info - data/models/get_user_response_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - get_user_response_model.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %130
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:freezed_annotation/freezed_annotation.dart';
+       2              : import 'package:on_time_front/domain/entities/user_entity.dart';
+       3              : 
+       4              : part 'get_user_response_model.g.dart';
+       5              : 
+       6              : @JsonSerializable()
+       7              : class GetUserResponseModel {
+       8              :   final int userId;
+       9              :   final String email;
+      10              :   final String name;
+      11              :   final int? spareTime;
+      12              :   final String? note;
+      13              :   final double? punctualityScore;
+      14              :   final String? role;
+      15              : 
+      16            0 :   const GetUserResponseModel({
+      17              :     required this.userId,
+      18              :     required this.email,
+      19              :     required this.name,
+      20              :     required this.spareTime,
+      21              :     required this.punctualityScore,
+      22              :     this.role,
+      23              :     this.note,
+      24              :   });
+      25              : 
+      26            0 :   UserEntity toEntity() {
+      27            0 :     return UserEntity(
+      28            0 :       id: userId.toString(),
+      29            0 :       email: email,
+      30            0 :       name: name,
+      31            0 :       spareTime: Duration(minutes: spareTime ?? 0),
+      32            0 :       score: punctualityScore ?? -1,
+      33            0 :       isOnboardingCompleted: role == 'GUEST' ? false : true,
+      34            0 :       note: note ?? '',
+      35              :     );
+      36              :   }
+      37              : 
+      38            0 :   factory GetUserResponseModel.fromJson(Map<String, dynamic> json) =>
+      39            0 :       _$GetUserResponseModelFromJson(json);
+      40              : 
+      41            0 :   Map<String, dynamic> toJson() => _$GetUserResponseModelToJson(this);
+      42              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/get_user_response_model.g.dart.gcov.html b/coverage/html/data/models/get_user_response_model.g.dart.gcov.html new file mode 100644 index 00000000..61920251 --- /dev/null +++ b/coverage/html/data/models/get_user_response_model.g.dart.gcov.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - data/models/get_user_response_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - get_user_response_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %180
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'get_user_response_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : GetUserResponseModel _$GetUserResponseModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     GetUserResponseModel(
+      12            0 :       userId: (json['userId'] as num).toInt(),
+      13            0 :       email: json['email'] as String,
+      14            0 :       name: json['name'] as String,
+      15            0 :       spareTime: (json['spareTime'] as num?)?.toInt(),
+      16            0 :       punctualityScore: (json['punctualityScore'] as num?)?.toDouble(),
+      17            0 :       role: json['role'] as String?,
+      18            0 :       note: json['note'] as String?,
+      19              :     );
+      20              : 
+      21            0 : Map<String, dynamic> _$GetUserResponseModelToJson(
+      22              :         GetUserResponseModel instance) =>
+      23            0 :     <String, dynamic>{
+      24            0 :       'userId': instance.userId,
+      25            0 :       'email': instance.email,
+      26            0 :       'name': instance.name,
+      27            0 :       'spareTime': instance.spareTime,
+      28            0 :       'note': instance.note,
+      29            0 :       'punctualityScore': instance.punctualityScore,
+      30            0 :       'role': instance.role,
+      31              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/index-sort-f.html b/coverage/html/data/models/index-sort-f.html new file mode 100644 index 00000000..8227a7a5 --- /dev/null +++ b/coverage/html/data/models/index-sort-f.html @@ -0,0 +1,359 @@ + + + + + + + LCOV - lcov.info - data/models + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/modelsCoverageTotalHit
Test:lcov.infoLines:18.2 %42878
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
create_defualt_preparation_request_model.dart +
81.8%81.8%
+
81.8 %119
create_defualt_preparation_request_model.g.dart +
41.7%41.7%
+
41.7 %125
create_preparation_schedule_request_model.dart +
56.5%56.5%
+
56.5 %2313
create_preparation_schedule_request_model.g.dart +
50.0%50.0%
+
50.0 %126
create_preparation_step_request_model.dart +
41.2%41.2%
+
41.2 %177
create_preparation_step_request_model.g.dart +
0.0%
+
0.0 %12
create_schedule_request_model.dart +
87.5%87.5%
+
87.5 %1614
create_schedule_request_model.g.dart +
50.0%50.0%
+
50.0 %2412
fcm_token_register_request_model.dart +
0.0%
+
0.0 %4
fcm_token_register_request_model.g.dart +
0.0%
+
0.0 %6
get_place_response_model.dart +
0.0%
+
0.0 %12
get_place_response_model.g.dart +
0.0%
+
0.0 %8
get_preparation_step_response_model.dart +
0.0%
+
0.0 %20
get_preparation_step_response_model.g.dart +
0.0%
+
0.0 %12
get_schedule_response_model.dart +
0.0%
+
0.0 %19
get_schedule_response_model.g.dart +
0.0%
+
0.0 %22
get_user_response_model.dart +
0.0%
+
0.0 %13
get_user_response_model.g.dart +
0.0%
+
0.0 %18
sign_in_user_response_model.dart +
0.0%
+
0.0 %13
sign_in_user_response_model.g.dart +
0.0%
+
0.0 %18
sign_in_with_apple_request_model.dart +
0.0%
+
0.0 %8
sign_in_with_apple_request_model.g.dart +
0.0%
+
0.0 %12
sign_in_with_google_request_model.dart +
0.0%
+
0.0 %4
sign_in_with_google_request_model.g.dart +
0.0%
+
0.0 %6
update_preparation_schedule_request_model.dart +
0.0%
+
0.0 %23
update_preparation_schedule_request_model.g.dart +
0.0%
+
0.0 %12
update_preparation_user_request_model.dart +
0.0%
+
0.0 %22
update_preparation_user_request_model.g.dart +
0.0%
+
0.0 %12
update_schedule_request_model.dart +
80.0%80.0%
+
80.0 %1512
update_schedule_request_model.g.dart +
0.0%
+
0.0 %22
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/index-sort-l.html b/coverage/html/data/models/index-sort-l.html new file mode 100644 index 00000000..abcb1a1f --- /dev/null +++ b/coverage/html/data/models/index-sort-l.html @@ -0,0 +1,359 @@ + + + + + + + LCOV - lcov.info - data/models + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/modelsCoverageTotalHit
Test:lcov.infoLines:18.2 %42878
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
fcm_token_register_request_model.dart +
0.0%
+
0.0 %4
sign_in_with_google_request_model.dart +
0.0%
+
0.0 %4
fcm_token_register_request_model.g.dart +
0.0%
+
0.0 %6
sign_in_with_google_request_model.g.dart +
0.0%
+
0.0 %6
get_place_response_model.g.dart +
0.0%
+
0.0 %8
sign_in_with_apple_request_model.dart +
0.0%
+
0.0 %8
create_preparation_step_request_model.g.dart +
0.0%
+
0.0 %12
get_place_response_model.dart +
0.0%
+
0.0 %12
get_preparation_step_response_model.g.dart +
0.0%
+
0.0 %12
sign_in_with_apple_request_model.g.dart +
0.0%
+
0.0 %12
update_preparation_schedule_request_model.g.dart +
0.0%
+
0.0 %12
update_preparation_user_request_model.g.dart +
0.0%
+
0.0 %12
get_user_response_model.dart +
0.0%
+
0.0 %13
sign_in_user_response_model.dart +
0.0%
+
0.0 %13
get_user_response_model.g.dart +
0.0%
+
0.0 %18
sign_in_user_response_model.g.dart +
0.0%
+
0.0 %18
get_schedule_response_model.dart +
0.0%
+
0.0 %19
get_preparation_step_response_model.dart +
0.0%
+
0.0 %20
get_schedule_response_model.g.dart +
0.0%
+
0.0 %22
update_preparation_user_request_model.dart +
0.0%
+
0.0 %22
update_schedule_request_model.g.dart +
0.0%
+
0.0 %22
update_preparation_schedule_request_model.dart +
0.0%
+
0.0 %23
create_preparation_step_request_model.dart +
41.2%41.2%
+
41.2 %177
create_defualt_preparation_request_model.g.dart +
41.7%41.7%
+
41.7 %125
create_preparation_schedule_request_model.g.dart +
50.0%50.0%
+
50.0 %126
create_schedule_request_model.g.dart +
50.0%50.0%
+
50.0 %2412
create_preparation_schedule_request_model.dart +
56.5%56.5%
+
56.5 %2313
update_schedule_request_model.dart +
80.0%80.0%
+
80.0 %1512
create_defualt_preparation_request_model.dart +
81.8%81.8%
+
81.8 %119
create_schedule_request_model.dart +
87.5%87.5%
+
87.5 %1614
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/index.html b/coverage/html/data/models/index.html new file mode 100644 index 00000000..fd20a67a --- /dev/null +++ b/coverage/html/data/models/index.html @@ -0,0 +1,359 @@ + + + + + + + LCOV - lcov.info - data/models + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/modelsCoverageTotalHit
Test:lcov.infoLines:18.2 %42878
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
create_defualt_preparation_request_model.dart +
81.8%81.8%
+
81.8 %119
create_defualt_preparation_request_model.g.dart +
41.7%41.7%
+
41.7 %125
create_preparation_schedule_request_model.dart +
56.5%56.5%
+
56.5 %2313
create_preparation_schedule_request_model.g.dart +
50.0%50.0%
+
50.0 %126
create_preparation_step_request_model.dart +
41.2%41.2%
+
41.2 %177
create_preparation_step_request_model.g.dart +
0.0%
+
0.0 %12
create_schedule_request_model.dart +
87.5%87.5%
+
87.5 %1614
create_schedule_request_model.g.dart +
50.0%50.0%
+
50.0 %2412
fcm_token_register_request_model.dart +
0.0%
+
0.0 %4
fcm_token_register_request_model.g.dart +
0.0%
+
0.0 %6
get_place_response_model.dart +
0.0%
+
0.0 %12
get_place_response_model.g.dart +
0.0%
+
0.0 %8
get_preparation_step_response_model.dart +
0.0%
+
0.0 %20
get_preparation_step_response_model.g.dart +
0.0%
+
0.0 %12
get_schedule_response_model.dart +
0.0%
+
0.0 %19
get_schedule_response_model.g.dart +
0.0%
+
0.0 %22
get_user_response_model.dart +
0.0%
+
0.0 %13
get_user_response_model.g.dart +
0.0%
+
0.0 %18
sign_in_user_response_model.dart +
0.0%
+
0.0 %13
sign_in_user_response_model.g.dart +
0.0%
+
0.0 %18
sign_in_with_apple_request_model.dart +
0.0%
+
0.0 %8
sign_in_with_apple_request_model.g.dart +
0.0%
+
0.0 %12
sign_in_with_google_request_model.dart +
0.0%
+
0.0 %4
sign_in_with_google_request_model.g.dart +
0.0%
+
0.0 %6
update_preparation_schedule_request_model.dart +
0.0%
+
0.0 %23
update_preparation_schedule_request_model.g.dart +
0.0%
+
0.0 %12
update_preparation_user_request_model.dart +
0.0%
+
0.0 %22
update_preparation_user_request_model.g.dart +
0.0%
+
0.0 %12
update_schedule_request_model.dart +
80.0%80.0%
+
80.0 %1512
update_schedule_request_model.g.dart +
0.0%
+
0.0 %22
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/sign_in_user_response_model.dart.gcov.html b/coverage/html/data/models/sign_in_user_response_model.dart.gcov.html new file mode 100644 index 00000000..89499fa4 --- /dev/null +++ b/coverage/html/data/models/sign_in_user_response_model.dart.gcov.html @@ -0,0 +1,118 @@ + + + + + + + LCOV - lcov.info - data/models/sign_in_user_response_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - sign_in_user_response_model.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %130
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/domain/entities/user_entity.dart';
+       3              : 
+       4              : part 'sign_in_user_response_model.g.dart';
+       5              : 
+       6              : @JsonSerializable()
+       7              : class SignInUserResponseModel {
+       8              :   final int userId;
+       9              :   final String email;
+      10              :   final String name;
+      11              :   final int? spareTime;
+      12              :   final String? note;
+      13              :   final double? punctualityScore;
+      14              :   final String? role;
+      15              : 
+      16            0 :   const SignInUserResponseModel({
+      17              :     required this.userId,
+      18              :     required this.email,
+      19              :     required this.name,
+      20              :     required this.spareTime,
+      21              :     required this.punctualityScore,
+      22              :     this.role,
+      23              :     this.note,
+      24              :   });
+      25              : 
+      26            0 :   UserEntity toEntity() {
+      27            0 :     return UserEntity(
+      28            0 :       id: userId.toString(),
+      29            0 :       email: email,
+      30            0 :       name: name,
+      31            0 :       spareTime: Duration(minutes: spareTime ?? 0),
+      32            0 :       score: punctualityScore ?? -1,
+      33            0 :       isOnboardingCompleted: role == 'GUEST' ? false : true,
+      34            0 :       note: note ?? '',
+      35              :     );
+      36              :   }
+      37              : 
+      38            0 :   factory SignInUserResponseModel.fromJson(Map<String, dynamic> json) =>
+      39            0 :       _$SignInUserResponseModelFromJson(json);
+      40              : 
+      41            0 :   Map<String, dynamic> toJson() => _$SignInUserResponseModelToJson(this);
+      42              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/sign_in_user_response_model.g.dart.gcov.html b/coverage/html/data/models/sign_in_user_response_model.g.dart.gcov.html new file mode 100644 index 00000000..d8cba18c --- /dev/null +++ b/coverage/html/data/models/sign_in_user_response_model.g.dart.gcov.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - data/models/sign_in_user_response_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - sign_in_user_response_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %180
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'sign_in_user_response_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : SignInUserResponseModel _$SignInUserResponseModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     SignInUserResponseModel(
+      12            0 :       userId: (json['userId'] as num).toInt(),
+      13            0 :       email: json['email'] as String,
+      14            0 :       name: json['name'] as String,
+      15            0 :       spareTime: (json['spareTime'] as num?)?.toInt(),
+      16            0 :       punctualityScore: (json['punctualityScore'] as num?)?.toDouble(),
+      17            0 :       role: json['role'] as String?,
+      18            0 :       note: json['note'] as String?,
+      19              :     );
+      20              : 
+      21            0 : Map<String, dynamic> _$SignInUserResponseModelToJson(
+      22              :         SignInUserResponseModel instance) =>
+      23            0 :     <String, dynamic>{
+      24            0 :       'userId': instance.userId,
+      25            0 :       'email': instance.email,
+      26            0 :       'name': instance.name,
+      27            0 :       'spareTime': instance.spareTime,
+      28            0 :       'note': instance.note,
+      29            0 :       'punctualityScore': instance.punctualityScore,
+      30            0 :       'role': instance.role,
+      31              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/sign_in_with_apple_request_model.dart.gcov.html b/coverage/html/data/models/sign_in_with_apple_request_model.dart.gcov.html new file mode 100644 index 00000000..c1eb52c8 --- /dev/null +++ b/coverage/html/data/models/sign_in_with_apple_request_model.dart.gcov.html @@ -0,0 +1,106 @@ + + + + + + + LCOV - lcov.info - data/models/sign_in_with_apple_request_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - sign_in_with_apple_request_model.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %80
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:freezed_annotation/freezed_annotation.dart';
+       2              : 
+       3              : part 'sign_in_with_apple_request_model.g.dart';
+       4              : 
+       5              : @JsonSerializable()
+       6              : class SignInWithAppleRequestModel {
+       7              :   final String idToken;
+       8              :   final String authCode;
+       9              :   final String fullName;
+      10              :   final String? email;
+      11              : 
+      12            0 :   SignInWithAppleRequestModel({
+      13              :     required this.idToken,
+      14              :     required this.authCode,
+      15              :     required this.fullName,
+      16              :     this.email,
+      17              :   });
+      18              : 
+      19            0 :   Map<String, dynamic> toJson() {
+      20            0 :     final Map<String, dynamic> map = {
+      21            0 :       'idToken': idToken,
+      22            0 :       'authCode': authCode,
+      23            0 :       'fullName': fullName,
+      24              :     };
+      25            0 :     if (email != null) {
+      26            0 :       map['email'] = email;
+      27              :     }
+      28              :     return map;
+      29              :   }
+      30              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/sign_in_with_apple_request_model.g.dart.gcov.html b/coverage/html/data/models/sign_in_with_apple_request_model.g.dart.gcov.html new file mode 100644 index 00000000..1b78c4cc --- /dev/null +++ b/coverage/html/data/models/sign_in_with_apple_request_model.g.dart.gcov.html @@ -0,0 +1,101 @@ + + + + + + + LCOV - lcov.info - data/models/sign_in_with_apple_request_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - sign_in_with_apple_request_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %120
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'sign_in_with_apple_request_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : SignInWithAppleRequestModel _$SignInWithAppleRequestModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     SignInWithAppleRequestModel(
+      12            0 :       idToken: json['idToken'] as String,
+      13            0 :       authCode: json['authCode'] as String,
+      14            0 :       fullName: json['fullName'] as String,
+      15            0 :       email: json['email'] as String?,
+      16              :     );
+      17              : 
+      18            0 : Map<String, dynamic> _$SignInWithAppleRequestModelToJson(
+      19              :         SignInWithAppleRequestModel instance) =>
+      20            0 :     <String, dynamic>{
+      21            0 :       'idToken': instance.idToken,
+      22            0 :       'authCode': instance.authCode,
+      23            0 :       'fullName': instance.fullName,
+      24            0 :       'email': instance.email,
+      25              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/sign_in_with_google_request_model.dart.gcov.html b/coverage/html/data/models/sign_in_with_google_request_model.dart.gcov.html new file mode 100644 index 00000000..6131e559 --- /dev/null +++ b/coverage/html/data/models/sign_in_with_google_request_model.dart.gcov.html @@ -0,0 +1,95 @@ + + + + + + + LCOV - lcov.info - data/models/sign_in_with_google_request_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - sign_in_with_google_request_model.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %40
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:freezed_annotation/freezed_annotation.dart';
+       2              : 
+       3              : part 'sign_in_with_google_request_model.g.dart';
+       4              : 
+       5              : @JsonSerializable()
+       6              : class SignInWithGoogleRequestModel {
+       7              :   final String idToken;
+       8              : 
+       9            0 :   SignInWithGoogleRequestModel({
+      10              :     required this.idToken,
+      11              :   });
+      12              : 
+      13            0 :   Map<String, dynamic> toJson() {
+      14            0 :     return {
+      15            0 :       'idToken': idToken,
+      16              :       'refreshToken': '',
+      17              :     };
+      18              :   }
+      19              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/sign_in_with_google_request_model.g.dart.gcov.html b/coverage/html/data/models/sign_in_with_google_request_model.g.dart.gcov.html new file mode 100644 index 00000000..47613d33 --- /dev/null +++ b/coverage/html/data/models/sign_in_with_google_request_model.g.dart.gcov.html @@ -0,0 +1,95 @@ + + + + + + + LCOV - lcov.info - data/models/sign_in_with_google_request_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - sign_in_with_google_request_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %60
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'sign_in_with_google_request_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : SignInWithGoogleRequestModel _$SignInWithGoogleRequestModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     SignInWithGoogleRequestModel(
+      12            0 :       idToken: json['idToken'] as String,
+      13              :     );
+      14              : 
+      15            0 : Map<String, dynamic> _$SignInWithGoogleRequestModelToJson(
+      16              :         SignInWithGoogleRequestModel instance) =>
+      17            0 :     <String, dynamic>{
+      18            0 :       'idToken': instance.idToken,
+      19              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/update_preparation_schedule_request_model.dart.gcov.html b/coverage/html/data/models/update_preparation_schedule_request_model.dart.gcov.html new file mode 100644 index 00000000..49618ce8 --- /dev/null +++ b/coverage/html/data/models/update_preparation_schedule_request_model.dart.gcov.html @@ -0,0 +1,137 @@ + + + + + + + LCOV - lcov.info - data/models/update_preparation_schedule_request_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - update_preparation_schedule_request_model.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %230
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       3              : 
+       4              : part 'update_preparation_schedule_request_model.g.dart';
+       5              : 
+       6              : @JsonSerializable()
+       7              : class PreparationScheduleModifyRequestModel {
+       8              :   @JsonKey(name: 'preparationId')
+       9              :   final String id;
+      10              :   final String preparationName;
+      11              :   final int preparationTime;
+      12              :   final String? nextPreparationId;
+      13              : 
+      14            0 :   PreparationScheduleModifyRequestModel({
+      15              :     required this.id,
+      16              :     required this.preparationName,
+      17              :     required this.preparationTime,
+      18              :     required this.nextPreparationId,
+      19              :   });
+      20              : 
+      21            0 :   factory PreparationScheduleModifyRequestModel.fromJson(
+      22              :           Map<String, dynamic> json) =>
+      23            0 :       _$PreparationScheduleModifyRequestModelFromJson(json);
+      24              : 
+      25            0 :   Map<String, dynamic> toJson() =>
+      26            0 :       _$PreparationScheduleModifyRequestModelToJson(this);
+      27              : 
+      28            0 :   static PreparationScheduleModifyRequestModel fromEntity(
+      29              :       PreparationStepEntity entity) {
+      30            0 :     return PreparationScheduleModifyRequestModel(
+      31            0 :       id: entity.id,
+      32            0 :       preparationName: entity.preparationName,
+      33            0 :       preparationTime: entity.preparationTime.inMinutes,
+      34            0 :       nextPreparationId: entity.nextPreparationId,
+      35              :     );
+      36              :   }
+      37              : 
+      38            0 :   PreparationStepEntity toEntity() {
+      39            0 :     return PreparationStepEntity(
+      40            0 :       id: id,
+      41            0 :       preparationName: preparationName,
+      42            0 :       preparationTime: Duration(minutes: preparationTime),
+      43            0 :       nextPreparationId: nextPreparationId,
+      44              :     );
+      45              :   }
+      46              : }
+      47              : 
+      48              : extension PreparationScheduleModifyRequestModelListExtension
+      49              :     on List<PreparationScheduleModifyRequestModel> {
+      50            0 :   List<PreparationStepEntity> toEntityList() {
+      51            0 :     return map((model) => model.toEntity()).toList();
+      52              :   }
+      53              : 
+      54            0 :   static List<PreparationScheduleModifyRequestModel> fromEntityList(
+      55              :       List<PreparationStepEntity> entities) {
+      56              :     return entities
+      57            0 :         .map((entity) =>
+      58            0 :             PreparationScheduleModifyRequestModel.fromEntity(entity))
+      59            0 :         .toList();
+      60              :   }
+      61              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/update_preparation_schedule_request_model.g.dart.gcov.html b/coverage/html/data/models/update_preparation_schedule_request_model.g.dart.gcov.html new file mode 100644 index 00000000..41e5ea86 --- /dev/null +++ b/coverage/html/data/models/update_preparation_schedule_request_model.g.dart.gcov.html @@ -0,0 +1,102 @@ + + + + + + + LCOV - lcov.info - data/models/update_preparation_schedule_request_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - update_preparation_schedule_request_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %120
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'update_preparation_schedule_request_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : PreparationScheduleModifyRequestModel
+      10              :     _$PreparationScheduleModifyRequestModelFromJson(
+      11              :             Map<String, dynamic> json) =>
+      12            0 :         PreparationScheduleModifyRequestModel(
+      13            0 :           id: json['preparationId'] as String,
+      14            0 :           preparationName: json['preparationName'] as String,
+      15            0 :           preparationTime: (json['preparationTime'] as num).toInt(),
+      16            0 :           nextPreparationId: json['nextPreparationId'] as String?,
+      17              :         );
+      18              : 
+      19            0 : Map<String, dynamic> _$PreparationScheduleModifyRequestModelToJson(
+      20              :         PreparationScheduleModifyRequestModel instance) =>
+      21            0 :     <String, dynamic>{
+      22            0 :       'preparationId': instance.id,
+      23            0 :       'preparationName': instance.preparationName,
+      24            0 :       'preparationTime': instance.preparationTime,
+      25            0 :       'nextPreparationId': instance.nextPreparationId,
+      26              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/update_preparation_user_request_model.dart.gcov.html b/coverage/html/data/models/update_preparation_user_request_model.dart.gcov.html new file mode 100644 index 00000000..870b5464 --- /dev/null +++ b/coverage/html/data/models/update_preparation_user_request_model.dart.gcov.html @@ -0,0 +1,136 @@ + + + + + + + LCOV - lcov.info - data/models/update_preparation_user_request_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - update_preparation_user_request_model.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %220
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       3              : 
+       4              : part 'update_preparation_user_request_model.g.dart';
+       5              : 
+       6              : @JsonSerializable()
+       7              : class PreparationUserModifyRequestModel {
+       8              :   @JsonKey(name: 'preparationId')
+       9              :   final String id;
+      10              :   final String preparationName;
+      11              :   final int preparationTime;
+      12              :   final String? nextPreparationId;
+      13              : 
+      14            0 :   PreparationUserModifyRequestModel({
+      15              :     required this.id,
+      16              :     required this.preparationName,
+      17              :     required this.preparationTime,
+      18              :     required this.nextPreparationId,
+      19              :   });
+      20              : 
+      21            0 :   factory PreparationUserModifyRequestModel.fromJson(
+      22              :           Map<String, dynamic> json) =>
+      23            0 :       _$PreparationUserModifyRequestModelFromJson(json);
+      24              : 
+      25            0 :   Map<String, dynamic> toJson() =>
+      26            0 :       _$PreparationUserModifyRequestModelToJson(this);
+      27              : 
+      28            0 :   static PreparationUserModifyRequestModel fromEntity(
+      29              :       PreparationStepEntity entity) {
+      30            0 :     return PreparationUserModifyRequestModel(
+      31            0 :       id: entity.id,
+      32            0 :       preparationName: entity.preparationName,
+      33            0 :       preparationTime: entity.preparationTime.inMinutes,
+      34            0 :       nextPreparationId: entity.nextPreparationId,
+      35              :     );
+      36              :   }
+      37              : 
+      38            0 :   PreparationStepEntity toEntity() {
+      39            0 :     return PreparationStepEntity(
+      40            0 :       id: id,
+      41            0 :       preparationName: preparationName,
+      42            0 :       preparationTime: Duration(minutes: preparationTime),
+      43            0 :       nextPreparationId: nextPreparationId,
+      44              :     );
+      45              :   }
+      46              : }
+      47              : 
+      48              : extension PreparationUserModifyRequestModelListExtension
+      49              :     on List<PreparationUserModifyRequestModel> {
+      50            0 :   List<PreparationStepEntity> toEntityList() {
+      51            0 :     return map((model) => model.toEntity()).toList();
+      52              :   }
+      53              : 
+      54            0 :   static List<PreparationUserModifyRequestModel> fromEntityList(
+      55              :       List<PreparationStepEntity> entities) {
+      56              :     return entities
+      57            0 :         .map((entity) => PreparationUserModifyRequestModel.fromEntity(entity))
+      58            0 :         .toList();
+      59              :   }
+      60              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/update_preparation_user_request_model.g.dart.gcov.html b/coverage/html/data/models/update_preparation_user_request_model.g.dart.gcov.html new file mode 100644 index 00000000..19804fab --- /dev/null +++ b/coverage/html/data/models/update_preparation_user_request_model.g.dart.gcov.html @@ -0,0 +1,101 @@ + + + + + + + LCOV - lcov.info - data/models/update_preparation_user_request_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - update_preparation_user_request_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %120
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'update_preparation_user_request_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : PreparationUserModifyRequestModel _$PreparationUserModifyRequestModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     PreparationUserModifyRequestModel(
+      12            0 :       id: json['preparationId'] as String,
+      13            0 :       preparationName: json['preparationName'] as String,
+      14            0 :       preparationTime: (json['preparationTime'] as num).toInt(),
+      15            0 :       nextPreparationId: json['nextPreparationId'] as String?,
+      16              :     );
+      17              : 
+      18            0 : Map<String, dynamic> _$PreparationUserModifyRequestModelToJson(
+      19              :         PreparationUserModifyRequestModel instance) =>
+      20            0 :     <String, dynamic>{
+      21            0 :       'preparationId': instance.id,
+      22            0 :       'preparationName': instance.preparationName,
+      23            0 :       'preparationTime': instance.preparationTime,
+      24            0 :       'nextPreparationId': instance.nextPreparationId,
+      25              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/update_schedule_request_model.dart.gcov.html b/coverage/html/data/models/update_schedule_request_model.dart.gcov.html new file mode 100644 index 00000000..744a0385 --- /dev/null +++ b/coverage/html/data/models/update_schedule_request_model.dart.gcov.html @@ -0,0 +1,124 @@ + + + + + + + LCOV - lcov.info - data/models/update_schedule_request_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - update_schedule_request_model.dartCoverageTotalHit
Test:lcov.infoLines:80.0 %1512
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:json_annotation/json_annotation.dart';
+       2              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       3              : 
+       4              : part 'update_schedule_request_model.g.dart';
+       5              : 
+       6              : @JsonSerializable()
+       7              : class UpdateScheduleRequestModel {
+       8              :   final String scheduleId;
+       9              :   final String placeId;
+      10              :   final String placeName;
+      11              :   final String scheduleName;
+      12              :   final DateTime scheduleTime;
+      13              :   final int moveTime;
+      14              :   final int? scheduleSpareTime;
+      15              :   final String scheduleNote;
+      16              :   final int latenessTime;
+      17              : 
+      18            1 :   const UpdateScheduleRequestModel({
+      19              :     required this.scheduleId,
+      20              :     required this.placeId,
+      21              :     required this.placeName,
+      22              :     required this.scheduleName,
+      23              :     required this.scheduleTime,
+      24              :     required this.moveTime,
+      25              :     this.scheduleSpareTime,
+      26              :     required this.scheduleNote,
+      27              :     this.latenessTime = 0,
+      28              :   });
+      29              : 
+      30            0 :   factory UpdateScheduleRequestModel.fromJson(Map<String, dynamic> json) =>
+      31            0 :       _$UpdateScheduleRequestModelFromJson(json);
+      32              : 
+      33            0 :   Map<String, dynamic> toJson() => _$UpdateScheduleRequestModelToJson(this);
+      34              : 
+      35            1 :   static UpdateScheduleRequestModel fromEntity(ScheduleEntity entity) {
+      36            1 :     return UpdateScheduleRequestModel(
+      37            1 :       scheduleId: entity.id,
+      38            2 :       placeId: entity.place.id,
+      39            2 :       placeName: entity.place.placeName,
+      40            1 :       scheduleName: entity.scheduleName,
+      41            1 :       scheduleTime: entity.scheduleTime,
+      42            2 :       moveTime: entity.moveTime.inMinutes,
+      43            2 :       scheduleSpareTime: entity.scheduleSpareTime?.inMinutes,
+      44            1 :       scheduleNote: entity.scheduleNote,
+      45            1 :       latenessTime: entity.latenessTime,
+      46              :     );
+      47              :   }
+      48              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/models/update_schedule_request_model.g.dart.gcov.html b/coverage/html/data/models/update_schedule_request_model.g.dart.gcov.html new file mode 100644 index 00000000..0ac6c369 --- /dev/null +++ b/coverage/html/data/models/update_schedule_request_model.g.dart.gcov.html @@ -0,0 +1,111 @@ + + + + + + + LCOV - lcov.info - data/models/update_schedule_request_model.g.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/models - update_schedule_request_model.g.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %220
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : // GENERATED CODE - DO NOT MODIFY BY HAND
+       2              : 
+       3              : part of 'update_schedule_request_model.dart';
+       4              : 
+       5              : // **************************************************************************
+       6              : // JsonSerializableGenerator
+       7              : // **************************************************************************
+       8              : 
+       9            0 : UpdateScheduleRequestModel _$UpdateScheduleRequestModelFromJson(
+      10              :         Map<String, dynamic> json) =>
+      11            0 :     UpdateScheduleRequestModel(
+      12            0 :       scheduleId: json['scheduleId'] as String,
+      13            0 :       placeId: json['placeId'] as String,
+      14            0 :       placeName: json['placeName'] as String,
+      15            0 :       scheduleName: json['scheduleName'] as String,
+      16            0 :       scheduleTime: DateTime.parse(json['scheduleTime'] as String),
+      17            0 :       moveTime: (json['moveTime'] as num).toInt(),
+      18            0 :       scheduleSpareTime: (json['scheduleSpareTime'] as num?)?.toInt(),
+      19            0 :       scheduleNote: json['scheduleNote'] as String,
+      20            0 :       latenessTime: (json['latenessTime'] as num?)?.toInt() ?? 0,
+      21              :     );
+      22              : 
+      23            0 : Map<String, dynamic> _$UpdateScheduleRequestModelToJson(
+      24              :         UpdateScheduleRequestModel instance) =>
+      25            0 :     <String, dynamic>{
+      26            0 :       'scheduleId': instance.scheduleId,
+      27            0 :       'placeId': instance.placeId,
+      28            0 :       'placeName': instance.placeName,
+      29            0 :       'scheduleName': instance.scheduleName,
+      30            0 :       'scheduleTime': instance.scheduleTime.toIso8601String(),
+      31            0 :       'moveTime': instance.moveTime,
+      32            0 :       'scheduleSpareTime': instance.scheduleSpareTime,
+      33            0 :       'scheduleNote': instance.scheduleNote,
+      34            0 :       'latenessTime': instance.latenessTime,
+      35              :     };
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/repositories/index-sort-f.html b/coverage/html/data/repositories/index-sort-f.html new file mode 100644 index 00000000..643c6b24 --- /dev/null +++ b/coverage/html/data/repositories/index-sort-f.html @@ -0,0 +1,125 @@ + + + + + + + LCOV - lcov.info - data/repositories + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/repositoriesCoverageTotalHit
Test:lcov.infoLines:31.5 %8928
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
preparation_repository_impl.dart +
25.0%25.0%
+
25.0 %164
schedule_repository_impl.dart +
85.7%85.7%
+
85.7 %2824
timed_preparation_repository_impl.dart +
0.0%
+
0.0 %7
user_repository_impl.dart +
0.0%
+
0.0 %38
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/repositories/index-sort-l.html b/coverage/html/data/repositories/index-sort-l.html new file mode 100644 index 00000000..4c676fc3 --- /dev/null +++ b/coverage/html/data/repositories/index-sort-l.html @@ -0,0 +1,125 @@ + + + + + + + LCOV - lcov.info - data/repositories + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/repositoriesCoverageTotalHit
Test:lcov.infoLines:31.5 %8928
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
timed_preparation_repository_impl.dart +
0.0%
+
0.0 %7
user_repository_impl.dart +
0.0%
+
0.0 %38
preparation_repository_impl.dart +
25.0%25.0%
+
25.0 %164
schedule_repository_impl.dart +
85.7%85.7%
+
85.7 %2824
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/repositories/index.html b/coverage/html/data/repositories/index.html new file mode 100644 index 00000000..fb2b7a76 --- /dev/null +++ b/coverage/html/data/repositories/index.html @@ -0,0 +1,125 @@ + + + + + + + LCOV - lcov.info - data/repositories + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/repositoriesCoverageTotalHit
Test:lcov.infoLines:31.5 %8928
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
preparation_repository_impl.dart +
25.0%25.0%
+
25.0 %164
schedule_repository_impl.dart +
85.7%85.7%
+
85.7 %2824
timed_preparation_repository_impl.dart +
0.0%
+
0.0 %7
user_repository_impl.dart +
0.0%
+
0.0 %38
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/repositories/preparation_repository_impl.dart.gcov.html b/coverage/html/data/repositories/preparation_repository_impl.dart.gcov.html new file mode 100644 index 00000000..9fe49d57 --- /dev/null +++ b/coverage/html/data/repositories/preparation_repository_impl.dart.gcov.html @@ -0,0 +1,170 @@ + + + + + + + LCOV - lcov.info - data/repositories/preparation_repository_impl.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/repositories - preparation_repository_impl.dartCoverageTotalHit
Test:lcov.infoLines:25.0 %164
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:async';
+       2              : 
+       3              : import 'package:injectable/injectable.dart';
+       4              : import 'package:on_time_front/data/data_sources/preparation_local_data_source.dart';
+       5              : import 'package:on_time_front/data/data_sources/preparation_remote_data_source.dart';
+       6              : import 'package:on_time_front/data/models/create_defualt_preparation_request_model.dart';
+       7              : 
+       8              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       9              : 
+      10              : import 'package:on_time_front/domain/repositories/preparation_repository.dart';
+      11              : 
+      12              : @Singleton(as: PreparationRepository)
+      13              : class PreparationRepositoryImpl implements PreparationRepository {
+      14              :   final PreparationRemoteDataSource preparationRemoteDataSource;
+      15              :   final PreparationLocalDataSource preparationLocalDataSource;
+      16              : 
+      17            1 :   PreparationRepositoryImpl({
+      18              :     required this.preparationRemoteDataSource,
+      19              :     required this.preparationLocalDataSource,
+      20              :   });
+      21              : 
+      22            0 :   @override
+      23              :   Future<void> createDefaultPreparation(
+      24              :       {required PreparationEntity preparationEntity,
+      25              :       required Duration spareTime,
+      26              :       required String note}) async {
+      27              :     try {
+      28            0 :       await preparationRemoteDataSource.createDefaultPreparation(
+      29            0 :           CreateDefaultPreparationRequestModel.fromEntity(
+      30              :               preparationEntity: preparationEntity,
+      31              :               spareTime: spareTime,
+      32              :               note: note));
+      33              :     } catch (e) {
+      34              :       rethrow;
+      35              :     }
+      36              :   }
+      37              : 
+      38            0 :   @override
+      39              :   Future<void> createCustomPreparation(
+      40              :       PreparationEntity preparationEntity, String scheduleId) async {
+      41              :     try {
+      42            0 :       await preparationRemoteDataSource.createCustomPreparation(
+      43              :           preparationEntity, scheduleId);
+      44              :     } catch (e) {
+      45              :       rethrow;
+      46              :     }
+      47              :   }
+      48              : 
+      49            0 :   @override
+      50              :   Future<PreparationEntity> getPreparationByScheduleId(
+      51              :       String scheduleId) async {
+      52              :     try {
+      53            0 :       final remotePreparation = await preparationRemoteDataSource
+      54            0 :           .getPreparationByScheduleId(scheduleId);
+      55              :       return remotePreparation;
+      56              :     } catch (e) {
+      57              :       rethrow;
+      58              :     }
+      59              :   }
+      60              : 
+      61            0 :   @override
+      62              :   Future<PreparationEntity> getDefualtPreparation() async {
+      63              :     try {
+      64              :       final remotePreparation =
+      65            0 :           await preparationRemoteDataSource.getDefualtPreparation();
+      66              :       return remotePreparation;
+      67              :     } catch (e) {
+      68              :       rethrow;
+      69              :     }
+      70              :   }
+      71              : 
+      72            1 :   @override
+      73              :   Future<void> updateDefaultPreparation(
+      74              :       PreparationEntity preparationEntity) async {
+      75              :     try {
+      76            1 :       await preparationRemoteDataSource
+      77            1 :           .updateDefaultPreparation(preparationEntity);
+      78              :       // await preparationLocalDataSource.updatePreparation(preparationEntity);
+      79              :     } catch (e) {
+      80              :       rethrow;
+      81              :     }
+      82              :   }
+      83              : 
+      84            0 :   @override
+      85              :   Future<void> updatePreparationByScheduleId(
+      86              :       PreparationEntity preparationEntity, String scheduleId) async {
+      87              :     try {
+      88            0 :       await preparationRemoteDataSource.updatePreparationByScheduleId(
+      89              :           preparationEntity, scheduleId);
+      90              :     } catch (e) {
+      91              :       rethrow;
+      92              :     }
+      93              :   }
+      94              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/repositories/schedule_repository_impl.dart.gcov.html b/coverage/html/data/repositories/schedule_repository_impl.dart.gcov.html new file mode 100644 index 00000000..f0faab6c --- /dev/null +++ b/coverage/html/data/repositories/schedule_repository_impl.dart.gcov.html @@ -0,0 +1,177 @@ + + + + + + + LCOV - lcov.info - data/repositories/schedule_repository_impl.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/repositories - schedule_repository_impl.dartCoverageTotalHit
Test:lcov.infoLines:85.7 %2824
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:async';
+       2              : 
+       3              : import 'package:injectable/injectable.dart';
+       4              : import 'package:on_time_front/data/data_sources/schedule_local_data_source.dart';
+       5              : import 'package:on_time_front/data/data_sources/schedule_remote_data_source.dart';
+       6              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       7              : 
+       8              : import 'package:on_time_front/domain/repositories/schedule_repository.dart';
+       9              : import 'package:rxdart/subjects.dart';
+      10              : 
+      11              : @Singleton(as: ScheduleRepository)
+      12              : class ScheduleRepositoryImpl implements ScheduleRepository {
+      13              :   final ScheduleLocalDataSource scheduleLocalDataSource;
+      14              :   final ScheduleRemoteDataSource scheduleRemoteDataSource;
+      15              : 
+      16            1 :   late final _scheduleStreamController =
+      17            1 :       BehaviorSubject<Set<ScheduleEntity>>.seeded(
+      18              :     const <ScheduleEntity>{},
+      19              :   );
+      20              : 
+      21            1 :   ScheduleRepositoryImpl({
+      22              :     required this.scheduleLocalDataSource,
+      23              :     required this.scheduleRemoteDataSource,
+      24              :   });
+      25              : 
+      26            0 :   @override
+      27              :   Stream<Set<ScheduleEntity>> get scheduleStream =>
+      28            0 :       _scheduleStreamController.asBroadcastStream();
+      29              : 
+      30            1 :   @override
+      31              :   Future<void> createSchedule(ScheduleEntity schedule) async {
+      32              :     try {
+      33            2 :       await scheduleRemoteDataSource.createSchedule(schedule);
+      34              :       //await scheduleLocalDataSource.createSchedule(schedule);
+      35            1 :       _scheduleStreamController
+      36            5 :           .add(Set.from(_scheduleStreamController.value)..add(schedule));
+      37              :     } catch (e) {
+      38              :       rethrow;
+      39              :     }
+      40              :   }
+      41              : 
+      42            1 :   @override
+      43              :   Future<void> deleteSchedule(ScheduleEntity schedule) async {
+      44              :     try {
+      45            2 :       await scheduleRemoteDataSource.deleteSchedule(schedule);
+      46              :       //await scheduleLocalDataSource.deleteSchedule(schedule);
+      47            1 :       _scheduleStreamController
+      48            5 :           .add(Set.from(_scheduleStreamController.value)..remove(schedule));
+      49              :     } catch (e) {
+      50              :       rethrow;
+      51              :     }
+      52              :   }
+      53              : 
+      54            1 :   @override
+      55              :   Future<ScheduleEntity> getScheduleById(String id) async {
+      56              :     try {
+      57            2 :       final schedule = await scheduleRemoteDataSource.getScheduleById(id);
+      58            1 :       _scheduleStreamController
+      59            5 :           .add(Set.from(_scheduleStreamController.value)..add(schedule));
+      60              :       return schedule;
+      61              :     } catch (e) {
+      62              :       rethrow;
+      63              :     }
+      64              :   }
+      65              : 
+      66            1 :   @override
+      67              :   Future<List<ScheduleEntity>> getSchedulesByDate(
+      68              :       DateTime startDate, DateTime? endDate) async {
+      69              :     try {
+      70              :       final schedules =
+      71            2 :           await scheduleRemoteDataSource.getSchedulesByDate(startDate, endDate);
+      72            1 :       _scheduleStreamController
+      73            5 :           .add(Set.from(_scheduleStreamController.value)..addAll(schedules));
+      74              :       return schedules;
+      75              :     } catch (e) {
+      76              :       rethrow;
+      77              :     }
+      78              :   }
+      79              : 
+      80            1 :   @override
+      81              :   Future<void> updateSchedule(ScheduleEntity schedule) async {
+      82              :     try {
+      83            2 :       await scheduleRemoteDataSource.updateSchedule(schedule);
+      84            5 :       _scheduleStreamController.add(Set.from(_scheduleStreamController.value)
+      85            1 :         ..remove(schedule)
+      86            1 :         ..add(schedule));
+      87              :       //await scheduleLocalDataSource.updateSchedule(schedule);
+      88              :     } catch (e) {
+      89              :       rethrow;
+      90              :     }
+      91              :   }
+      92              : 
+      93            0 :   @override
+      94              :   Future<void> finishSchedule(String scheduleId, int latenessTime) async {
+      95              :     try {
+      96            0 :       await scheduleRemoteDataSource.finishSchedule(scheduleId, latenessTime);
+      97              :     } catch (e) {
+      98              :       rethrow;
+      99              :     }
+     100              :   }
+     101              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/repositories/timed_preparation_repository_impl.dart.gcov.html b/coverage/html/data/repositories/timed_preparation_repository_impl.dart.gcov.html new file mode 100644 index 00000000..baec9f67 --- /dev/null +++ b/coverage/html/data/repositories/timed_preparation_repository_impl.dart.gcov.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - lcov.info - data/repositories/timed_preparation_repository_impl.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/repositories - timed_preparation_repository_impl.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %70
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/data/data_sources/preparation_with_time_local_data_source.dart';
+       3              : import 'package:on_time_front/domain/entities/preparation_with_time_entity.dart';
+       4              : import 'package:on_time_front/domain/repositories/timed_preparation_repository.dart';
+       5              : 
+       6              : @Singleton(as: TimedPreparationRepository)
+       7              : class TimedPreparationRepositoryImpl implements TimedPreparationRepository {
+       8              :   final PreparationWithTimeLocalDataSource localDataSource;
+       9              : 
+      10            0 :   TimedPreparationRepositoryImpl({required this.localDataSource});
+      11              : 
+      12            0 :   @override
+      13              :   Future<void> clearTimedPreparation(String scheduleId) {
+      14            0 :     return localDataSource.clearPreparation(scheduleId);
+      15              :   }
+      16              : 
+      17            0 :   @override
+      18              :   Future<PreparationWithTimeEntity?> getTimedPreparation(String scheduleId) {
+      19            0 :     return localDataSource.loadPreparation(scheduleId);
+      20              :   }
+      21              : 
+      22            0 :   @override
+      23              :   Future<void> saveTimedPreparation(
+      24              :       String scheduleId, PreparationWithTimeEntity preparation) {
+      25            0 :     return localDataSource.savePreparation(scheduleId, preparation);
+      26              :   }
+      27              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/repositories/user_repository_impl.dart.gcov.html b/coverage/html/data/repositories/user_repository_impl.dart.gcov.html new file mode 100644 index 00000000..32381138 --- /dev/null +++ b/coverage/html/data/repositories/user_repository_impl.dart.gcov.html @@ -0,0 +1,203 @@ + + + + + + + LCOV - lcov.info - data/repositories/user_repository_impl.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/repositories - user_repository_impl.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %380
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:flutter/material.dart';
+       2              : import 'package:google_sign_in/google_sign_in.dart';
+       3              : import 'package:injectable/injectable.dart';
+       4              : import 'package:on_time_front/data/data_sources/authentication_remote_data_source.dart';
+       5              : import 'package:on_time_front/data/data_sources/token_local_data_source.dart';
+       6              : import 'package:on_time_front/data/models/sign_in_with_google_request_model.dart';
+       7              : import 'package:on_time_front/data/models/sign_in_with_apple_request_model.dart';
+       8              : import 'package:on_time_front/domain/entities/user_entity.dart';
+       9              : import 'package:on_time_front/domain/repositories/user_repository.dart';
+      10              : import 'package:rxdart/subjects.dart';
+      11              : 
+      12              : @Singleton(as: UserRepository)
+      13              : class UserRepositoryImpl implements UserRepository {
+      14              :   final AuthenticationRemoteDataSource _authenticationRemoteDataSource;
+      15              :   final TokenLocalDataSource _tokenLocalDataSource;
+      16              :   final GoogleSignIn _googleSignIn = GoogleSignIn(
+      17              :     scopes: ['email', 'profile'],
+      18              :     signInOption: SignInOption.standard,
+      19              :     forceCodeForRefreshToken: true,
+      20              :   );
+      21              :   late final _userStreamController = BehaviorSubject<UserEntity>.seeded(
+      22              :     const UserEntity.empty(),
+      23              :   );
+      24              : 
+      25            0 :   @override
+      26            0 :   GoogleSignIn get googleSignIn => _googleSignIn;
+      27              : 
+      28            0 :   UserRepositoryImpl(this._authenticationRemoteDataSource, this._tokenLocalDataSource);
+      29              : 
+      30              : 
+      31            0 :   @override
+      32              :   Future<UserEntity> getUser() async {
+      33              :     try {
+      34            0 :       final user = await _authenticationRemoteDataSource.getUser();
+      35            0 :       _userStreamController.add(user);
+      36              :       return user;
+      37              :     } catch (e) {
+      38              :       rethrow;
+      39              :     }
+      40              :   }
+      41              : 
+      42            0 :   @override
+      43              :   Future<void> signIn({required String email, required String password}) async {
+      44              :     try {
+      45              :       final result =
+      46            0 :           await _authenticationRemoteDataSource.signIn(email, password);
+      47            0 :       await _tokenLocalDataSource.storeTokens(result.$2);
+      48            0 :       _userStreamController.add(result.$1);
+      49              :     } catch (e) {
+      50              :       rethrow;
+      51              :     }
+      52              :   }
+      53              : 
+      54            0 :   @override
+      55              :   Future<void> signUp(
+      56              :       {required String email,
+      57              :       required String password,
+      58              :       required String name}) async {
+      59              :     try {
+      60              :       final result =
+      61            0 :           await _authenticationRemoteDataSource.signUp(email, password, name);
+      62            0 :       await _tokenLocalDataSource.storeTokens(result.$2);
+      63            0 :       _userStreamController.add(result.$1);
+      64              :     } catch (e) {
+      65              :       rethrow;
+      66              :     }
+      67              :   }
+      68              : 
+      69            0 :   @override
+      70              :   Future<void> signOut() async {
+      71            0 :     await _tokenLocalDataSource.deleteToken();
+      72            0 :     _userStreamController.add(const UserEntity.empty());
+      73              :   }
+      74              : 
+      75            0 :   @override
+      76              :   Future<void> signInWithGoogle(GoogleSignInAccount googleUser) async {
+      77              :     try {
+      78              :       final GoogleSignInAuthentication googleAuth =
+      79            0 :           await googleUser.authentication;
+      80            0 :       final String? idToken = googleAuth.idToken;
+      81              :       if (idToken != null) {
+      82            0 :         final signInWithGoogleRequestModel = SignInWithGoogleRequestModel(
+      83              :           idToken: idToken,
+      84              :         );
+      85            0 :         await _tokenLocalDataSource.deleteToken();
+      86            0 :         final result = await _authenticationRemoteDataSource
+      87            0 :             .signInWithGoogle(signInWithGoogleRequestModel);
+      88            0 :         await _tokenLocalDataSource.storeTokens(result.$2);
+      89            0 :         _userStreamController.add(result.$1);
+      90              :       } else {
+      91            0 :         throw Exception('Access Token is null');
+      92              :       }
+      93              :     } catch (e) {
+      94            0 :       debugPrint(e.toString());
+      95              :       rethrow;
+      96              :     }
+      97              :   }
+      98              : 
+      99            0 :   @override
+     100              :   Future<void> signInWithApple({
+     101              :     required String idToken,
+     102              :     required String authCode,
+     103              :     required String fullName,
+     104              :     String? email,
+     105              :   }) async {
+     106              :     try {
+     107            0 :       final signInWithAppleRequestModel = SignInWithAppleRequestModel(
+     108              :         idToken: idToken,
+     109              :         authCode: authCode,
+     110              :         fullName: fullName,
+     111              :         email: email,
+     112              :       );
+     113            0 :       await _tokenLocalDataSource.deleteToken();
+     114            0 :       final result = await _authenticationRemoteDataSource
+     115            0 :           .signInWithApple(signInWithAppleRequestModel);
+     116            0 :       await _tokenLocalDataSource.storeTokens(result.$2);
+     117            0 :       _userStreamController.add(result.$1);
+     118              :     } catch (e) {
+     119            0 :       debugPrint(e.toString());
+     120              :       rethrow;
+     121              :     }
+     122              :   }
+     123              : 
+     124            0 :   @override
+     125              :   Stream<UserEntity> get userStream =>
+     126            0 :       _userStreamController.asBroadcastStream();
+     127              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/tables/index-sort-f.html b/coverage/html/data/tables/index-sort-f.html new file mode 100644 index 00000000..7152b6d0 --- /dev/null +++ b/coverage/html/data/tables/index-sort-f.html @@ -0,0 +1,143 @@ + + + + + + + LCOV - lcov.info - data/tables + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/tablesCoverageTotalHit
Test:lcov.infoLines:6.5 %463
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
places_table.dart +
0.0%
+
0.0 %4
preparation_schedule_table.dart +
0.0%
+
0.0 %8
preparation_user_table.dart +
0.0%
+
0.0 %8
schedule_with_place_model.dart +
60.0%60.0%
+
60.0 %53
schedules_table.dart +
0.0%
+
0.0 %13
user_table.dart +
0.0%
+
0.0 %8
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/tables/index-sort-l.html b/coverage/html/data/tables/index-sort-l.html new file mode 100644 index 00000000..e6b1fe7a --- /dev/null +++ b/coverage/html/data/tables/index-sort-l.html @@ -0,0 +1,143 @@ + + + + + + + LCOV - lcov.info - data/tables + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/tablesCoverageTotalHit
Test:lcov.infoLines:6.5 %463
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
places_table.dart +
0.0%
+
0.0 %4
preparation_schedule_table.dart +
0.0%
+
0.0 %8
preparation_user_table.dart +
0.0%
+
0.0 %8
user_table.dart +
0.0%
+
0.0 %8
schedules_table.dart +
0.0%
+
0.0 %13
schedule_with_place_model.dart +
60.0%60.0%
+
60.0 %53
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/tables/index.html b/coverage/html/data/tables/index.html new file mode 100644 index 00000000..fef21b4c --- /dev/null +++ b/coverage/html/data/tables/index.html @@ -0,0 +1,143 @@ + + + + + + + LCOV - lcov.info - data/tables + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/tablesCoverageTotalHit
Test:lcov.infoLines:6.5 %463
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
places_table.dart +
0.0%
+
0.0 %4
preparation_schedule_table.dart +
0.0%
+
0.0 %8
preparation_user_table.dart +
0.0%
+
0.0 %8
schedule_with_place_model.dart +
60.0%60.0%
+
60.0 %53
schedules_table.dart +
0.0%
+
0.0 %13
user_table.dart +
0.0%
+
0.0 %8
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/tables/places_table.dart.gcov.html b/coverage/html/data/tables/places_table.dart.gcov.html new file mode 100644 index 00000000..84de2cee --- /dev/null +++ b/coverage/html/data/tables/places_table.dart.gcov.html @@ -0,0 +1,86 @@ + + + + + + + LCOV - lcov.info - data/tables/places_table.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/tables - places_table.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %40
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:drift/drift.dart';
+       2              : import 'package:uuid/uuid.dart';
+       3              : 
+       4              : class Places extends Table {
+       5            0 :   TextColumn get id => text().clientDefault(() => Uuid().v7())();
+       6            0 :   TextColumn get placeName => text().withLength(min: 1, max: 30)();
+       7              : 
+       8            0 :   @override
+       9            0 :   Set<Column> get primaryKey => {id};
+      10              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/tables/preparation_schedule_table.dart.gcov.html b/coverage/html/data/tables/preparation_schedule_table.dart.gcov.html new file mode 100644 index 00000000..89b34e5c --- /dev/null +++ b/coverage/html/data/tables/preparation_schedule_table.dart.gcov.html @@ -0,0 +1,91 @@ + + + + + + + LCOV - lcov.info - data/tables/preparation_schedule_table.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/tables - preparation_schedule_table.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %80
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:drift/drift.dart';
+       2              : import 'package:on_time_front/data/tables/schedules_table.dart';
+       3              : import 'package:uuid/uuid.dart';
+       4              : 
+       5              : class PreparationSchedules extends Table {
+       6            0 :   TextColumn get id => text().clientDefault(() => Uuid().v7())();
+       7            0 :   TextColumn get scheduleId => text().references(Schedules, #id)();
+       8            0 :   TextColumn get preparationName => text().withLength(min: 1, max: 30)();
+       9            0 :   IntColumn get preparationTime => integer()();
+      10            0 :   TextColumn get nextPreparationId =>
+      11            0 :       text().nullable().references(PreparationSchedules, #id)();
+      12              : 
+      13            0 :   @override
+      14            0 :   Set<Column> get primaryKey => {id};
+      15              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/tables/preparation_user_table.dart.gcov.html b/coverage/html/data/tables/preparation_user_table.dart.gcov.html new file mode 100644 index 00000000..5888e535 --- /dev/null +++ b/coverage/html/data/tables/preparation_user_table.dart.gcov.html @@ -0,0 +1,91 @@ + + + + + + + LCOV - lcov.info - data/tables/preparation_user_table.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/tables - preparation_user_table.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %80
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:drift/drift.dart';
+       2              : import 'package:on_time_front/data/tables/user_table.dart';
+       3              : import 'package:uuid/uuid.dart';
+       4              : 
+       5              : class PreparationUsers extends Table {
+       6            0 :   TextColumn get id => text().clientDefault(() => Uuid().v7())();
+       7            0 :   TextColumn get userId => text().references(Users, #id)();
+       8            0 :   TextColumn get preparationName => text().withLength(min: 1, max: 30)();
+       9            0 :   IntColumn get preparationTime => integer()();
+      10            0 :   TextColumn get nextPreparationId =>
+      11            0 :       text().nullable().references(PreparationUsers, #id)();
+      12              : 
+      13            0 :   @override
+      14            0 :   Set<Column> get primaryKey => {id};
+      15              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/tables/schedule_with_place_model.dart.gcov.html b/coverage/html/data/tables/schedule_with_place_model.dart.gcov.html new file mode 100644 index 00000000..b92fa90b --- /dev/null +++ b/coverage/html/data/tables/schedule_with_place_model.dart.gcov.html @@ -0,0 +1,95 @@ + + + + + + + LCOV - lcov.info - data/tables/schedule_with_place_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/tables - schedule_with_place_model.dartCoverageTotalHit
Test:lcov.infoLines:60.0 %53
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:equatable/equatable.dart';
+       2              : import 'package:on_time_front/core/database/database.dart';
+       3              : 
+       4              : class ScheduleWithPlace extends Equatable {
+       5            1 :   const ScheduleWithPlace({required this.schedule, required this.place});
+       6              : 
+       7              :   // The classes are generated by drift for each of the tables involved in the
+       8              :   // join.
+       9              :   final Schedule schedule;
+      10              :   final Place place;
+      11              : 
+      12            1 :   @override
+      13            3 :   List<Object?> get props => [schedule, place];
+      14              : 
+      15            0 :   @override
+      16              :   String toString() {
+      17            0 :     return 'ScheduleWithPlace{schedule: $schedule, place: $place}';
+      18              :   }
+      19              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/tables/schedules_table.dart.gcov.html b/coverage/html/data/tables/schedules_table.dart.gcov.html new file mode 100644 index 00000000..2d3727a0 --- /dev/null +++ b/coverage/html/data/tables/schedules_table.dart.gcov.html @@ -0,0 +1,97 @@ + + + + + + + LCOV - lcov.info - data/tables/schedules_table.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/tables - schedules_table.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %130
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:drift/drift.dart';
+       2              : import 'package:on_time_front/core/utils/json_converters/duration_json_converters.dart';
+       3              : import 'package:on_time_front/data/tables/places_table.dart';
+       4              : import 'package:uuid/uuid.dart';
+       5              : 
+       6              : class Schedules extends Table {
+       7            0 :   TextColumn get id => text().clientDefault(() => Uuid().v7())();
+       8            0 :   TextColumn get placeId => text().references(Places, #id)();
+       9            0 :   TextColumn get scheduleName => text()();
+      10            0 :   DateTimeColumn get scheduleTime => dateTime()();
+      11            0 :   IntColumn get moveTime => integer().map(DurationSqlConverter())();
+      12            0 :   BoolColumn get isChanged => boolean().withDefault(const Constant(false))();
+      13            0 :   BoolColumn get isStarted => boolean().withDefault(const Constant(false))();
+      14            0 :   IntColumn get scheduleSpareTime =>
+      15            0 :       integer().nullable().map(DurationSqlConverter())();
+      16            0 :   TextColumn get scheduleNote => text().nullable()();
+      17            0 :   IntColumn get latenessTime => integer().withDefault(const Constant(-1))();
+      18              : 
+      19            0 :   @override
+      20            0 :   Set<Column> get primaryKey => {id};
+      21              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/data/tables/user_table.dart.gcov.html b/coverage/html/data/tables/user_table.dart.gcov.html new file mode 100644 index 00000000..134e2af3 --- /dev/null +++ b/coverage/html/data/tables/user_table.dart.gcov.html @@ -0,0 +1,90 @@ + + + + + + + LCOV - lcov.info - data/tables/user_table.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - data/tables - user_table.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %80
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:drift/drift.dart';
+       2              : import 'package:uuid/uuid.dart';
+       3              : 
+       4              : class Users extends Table {
+       5            0 :   TextColumn get id => text().clientDefault(() => Uuid().v7())();
+       6            0 :   TextColumn get email => text().withLength(min: 1, max: 320)();
+       7            0 :   TextColumn get name => text().withLength(min: 1, max: 30)();
+       8            0 :   IntColumn get spareTime => integer()();
+       9            0 :   TextColumn get note => text()();
+      10            0 :   RealColumn get score => real()();
+      11              : 
+      12            0 :   @override
+      13            0 :   Set<Column> get primaryKey => {id};
+      14              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/index-sort-f.html b/coverage/html/domain/entities/index-sort-f.html new file mode 100644 index 00000000..438d8f07 --- /dev/null +++ b/coverage/html/domain/entities/index-sort-f.html @@ -0,0 +1,170 @@ + + + + + + + LCOV - lcov.info - domain/entities + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entitiesCoverageTotalHit
Test:lcov.infoLines:6.9 %26218
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
place_entity.dart +
11.1%11.1%
+
11.1 %91
preparation_entity.dart +
12.5%12.5%
+
12.5 %81
preparation_step_entity.dart +
47.8%47.8%
+
47.8 %2311
preparation_step_with_time_entity.dart +
0.0%
+
0.0 %23
preparation_with_time_entity.dart +
0.0%
+
0.0 %87
schedule_entity.dart +
8.0%8.0%
+
8.0 %504
schedule_with_preparation_entity.dart +
0.0%
+
0.0 %35
token_entity.dart +
0.0%
+
0.0 %7
user_entity.dart +
5.0%5.0%
+
5.0 %201
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/index-sort-l.html b/coverage/html/domain/entities/index-sort-l.html new file mode 100644 index 00000000..8ad0b9a4 --- /dev/null +++ b/coverage/html/domain/entities/index-sort-l.html @@ -0,0 +1,170 @@ + + + + + + + LCOV - lcov.info - domain/entities + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entitiesCoverageTotalHit
Test:lcov.infoLines:6.9 %26218
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
token_entity.dart +
0.0%
+
0.0 %7
preparation_step_with_time_entity.dart +
0.0%
+
0.0 %23
schedule_with_preparation_entity.dart +
0.0%
+
0.0 %35
preparation_with_time_entity.dart +
0.0%
+
0.0 %87
user_entity.dart +
5.0%5.0%
+
5.0 %201
schedule_entity.dart +
8.0%8.0%
+
8.0 %504
place_entity.dart +
11.1%11.1%
+
11.1 %91
preparation_entity.dart +
12.5%12.5%
+
12.5 %81
preparation_step_entity.dart +
47.8%47.8%
+
47.8 %2311
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/index.html b/coverage/html/domain/entities/index.html new file mode 100644 index 00000000..513d2b82 --- /dev/null +++ b/coverage/html/domain/entities/index.html @@ -0,0 +1,170 @@ + + + + + + + LCOV - lcov.info - domain/entities + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entitiesCoverageTotalHit
Test:lcov.infoLines:6.9 %26218
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
place_entity.dart +
11.1%11.1%
+
11.1 %91
preparation_entity.dart +
12.5%12.5%
+
12.5 %81
preparation_step_entity.dart +
47.8%47.8%
+
47.8 %2311
preparation_step_with_time_entity.dart +
0.0%
+
0.0 %23
preparation_with_time_entity.dart +
0.0%
+
0.0 %87
schedule_entity.dart +
8.0%8.0%
+
8.0 %504
schedule_with_preparation_entity.dart +
0.0%
+
0.0 %35
token_entity.dart +
0.0%
+
0.0 %7
user_entity.dart +
5.0%5.0%
+
5.0 %201
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/place_entity.dart.gcov.html b/coverage/html/domain/entities/place_entity.dart.gcov.html new file mode 100644 index 00000000..983d85c8 --- /dev/null +++ b/coverage/html/domain/entities/place_entity.dart.gcov.html @@ -0,0 +1,101 @@ + + + + + + + LCOV - lcov.info - domain/entities/place_entity.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entities - place_entity.dartCoverageTotalHit
Test:lcov.infoLines:11.1 %91
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import '/core/database/database.dart';
+       2              : 
+       3              : class PlaceEntity {
+       4              :   final String id;
+       5              :   final String placeName;
+       6              : 
+       7            2 :   PlaceEntity({
+       8              :     required this.id,
+       9              :     required this.placeName,
+      10              :   });
+      11              : 
+      12            0 :   static fromModel(Place place) {
+      13            0 :     return PlaceEntity(
+      14            0 :       id: place.id,
+      15            0 :       placeName: place.placeName,
+      16              :     );
+      17              :   }
+      18              : 
+      19            0 :   Place toModel() {
+      20            0 :     return Place(
+      21            0 :       id: id,
+      22            0 :       placeName: placeName,
+      23              :     );
+      24              :   }
+      25              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/preparation_entity.dart.gcov.html b/coverage/html/domain/entities/preparation_entity.dart.gcov.html new file mode 100644 index 00000000..6a4f2265 --- /dev/null +++ b/coverage/html/domain/entities/preparation_entity.dart.gcov.html @@ -0,0 +1,101 @@ + + + + + + + LCOV - lcov.info - domain/entities/preparation_entity.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entities - preparation_entity.dartCoverageTotalHit
Test:lcov.infoLines:12.5 %81
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:equatable/equatable.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       3              : 
+       4              : class PreparationEntity extends Equatable {
+       5              :   final List<PreparationStepEntity> preparationStepList;
+       6              : 
+       7            4 :   const PreparationEntity({
+       8              :     required this.preparationStepList,
+       9              :   });
+      10              : 
+      11            0 :   Duration get totalDuration {
+      12            0 :     return preparationStepList.fold(
+      13              :       Duration.zero,
+      14            0 :       (previousValue, element) => previousValue + element.preparationTime,
+      15              :     );
+      16              :   }
+      17              : 
+      18            0 :   @override
+      19              :   String toString() {
+      20            0 :     return 'PreparationEntity(preparationStepList: ${preparationStepList.toString()})';
+      21              :   }
+      22              : 
+      23            0 :   @override
+      24            0 :   List<Object?> get props => [preparationStepList];
+      25              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/preparation_step_entity.dart.gcov.html b/coverage/html/domain/entities/preparation_step_entity.dart.gcov.html new file mode 100644 index 00000000..4a40f42c --- /dev/null +++ b/coverage/html/domain/entities/preparation_step_entity.dart.gcov.html @@ -0,0 +1,135 @@ + + + + + + + LCOV - lcov.info - domain/entities/preparation_step_entity.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entities - preparation_step_entity.dartCoverageTotalHit
Test:lcov.infoLines:47.8 %2311
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:equatable/equatable.dart';
+       2              : import 'package:on_time_front/core/database/database.dart';
+       3              : 
+       4              : class PreparationStepEntity extends Equatable {
+       5              :   final String id;
+       6              :   final String preparationName;
+       7              :   final Duration preparationTime;
+       8              :   final String? nextPreparationId;
+       9              : 
+      10            4 :   const PreparationStepEntity({
+      11              :     required this.id,
+      12              :     required this.preparationName,
+      13              :     required this.preparationTime,
+      14              :     this.nextPreparationId,
+      15              :   });
+      16              : 
+      17            2 :   PreparationUser toPreparationUserModel(String userId) {
+      18            2 :     return PreparationUser(
+      19            2 :       id: id,
+      20              :       userId: userId,
+      21            2 :       preparationName: preparationName,
+      22            4 :       preparationTime: preparationTime.inMinutes,
+      23            2 :       nextPreparationId: nextPreparationId,
+      24              :     );
+      25              :   }
+      26              : 
+      27            0 :   PreparationSchedule toPreparationScheduleModel(String scheduleId) {
+      28            0 :     return PreparationSchedule(
+      29            0 :       id: id,
+      30              :       scheduleId: scheduleId,
+      31            0 :       preparationName: preparationName,
+      32            0 :       preparationTime: preparationTime.inMinutes,
+      33            0 :       nextPreparationId: nextPreparationId,
+      34              :     );
+      35              :   }
+      36              : 
+      37            0 :   @override
+      38              :   String toString() {
+      39            0 :     return 'PreparationStepEntity(id: $id, preparationName: $preparationName, preparationTime: $preparationTime, nextPreparationId: $nextPreparationId)';
+      40              :   }
+      41              : 
+      42            2 :   PreparationStepEntity copyWith({
+      43              :     String? id,
+      44              :     String? preparationName,
+      45              :     Duration? preparationTime,
+      46              :     String? nextPreparationId,
+      47              :   }) {
+      48            2 :     return PreparationStepEntity(
+      49            2 :       id: id ?? this.id,
+      50            0 :       preparationName: preparationName ?? this.preparationName,
+      51            0 :       preparationTime: preparationTime ?? this.preparationTime,
+      52            2 :       nextPreparationId: nextPreparationId ?? this.nextPreparationId,
+      53              :     );
+      54              :   }
+      55              : 
+      56            0 :   @override
+      57              :   List<Object?> get props =>
+      58            0 :       [id, preparationName, preparationTime, nextPreparationId];
+      59              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/preparation_step_with_time_entity.dart.gcov.html b/coverage/html/domain/entities/preparation_step_with_time_entity.dart.gcov.html new file mode 100644 index 00000000..a2834743 --- /dev/null +++ b/coverage/html/domain/entities/preparation_step_with_time_entity.dart.gcov.html @@ -0,0 +1,134 @@ + + + + + + + LCOV - lcov.info - domain/entities/preparation_step_with_time_entity.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entities - preparation_step_with_time_entity.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %230
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       2              : 
+       3              : class PreparationStepWithTimeEntity extends PreparationStepEntity {
+       4              :   final Duration elapsedTime;
+       5              :   final bool isDone;
+       6              : 
+       7            0 :   const PreparationStepWithTimeEntity({
+       8              :     required super.id,
+       9              :     required super.preparationName,
+      10              :     required super.preparationTime,
+      11              :     required super.nextPreparationId,
+      12              :     this.elapsedTime = Duration.zero,
+      13              :     this.isDone = false,
+      14              :   });
+      15              : 
+      16            0 :   @override
+      17              :   PreparationStepWithTimeEntity copyWith({
+      18              :     String? id,
+      19              :     String? preparationName,
+      20              :     Duration? preparationTime,
+      21              :     String? nextPreparationId,
+      22              :     Duration? elapsedTime,
+      23              :     bool? isDone,
+      24              :   }) {
+      25            0 :     return PreparationStepWithTimeEntity(
+      26            0 :       id: id ?? this.id,
+      27            0 :       preparationName: preparationName ?? this.preparationName,
+      28            0 :       preparationTime: preparationTime ?? this.preparationTime,
+      29            0 :       nextPreparationId: nextPreparationId ?? this.nextPreparationId,
+      30            0 :       elapsedTime: elapsedTime ?? this.elapsedTime,
+      31            0 :       isDone: isDone ?? this.isDone,
+      32              :     );
+      33              :   }
+      34              : 
+      35            0 :   PreparationStepWithTimeEntity timeElapsed(Duration elapsed) {
+      36            0 :     final updatedElapsed = elapsedTime + elapsed;
+      37            0 :     final updatedIsDone = updatedElapsed >= preparationTime;
+      38            0 :     return copyWith(
+      39              :       elapsedTime: updatedElapsed,
+      40              :       isDone: updatedIsDone,
+      41              :     );
+      42              :   }
+      43              : 
+      44            0 :   @override
+      45              :   String toString() {
+      46            0 :     return 'PreparationStepWithTimeEntity(id: $id, preparationName: $preparationName, preparationTime: $preparationTime, nextPreparationId: $nextPreparationId, elapsedTime: $elapsedTime, isDone: $isDone)';
+      47              :   }
+      48              : 
+      49            0 :   @override
+      50            0 :   List<Object?> get props => [
+      51            0 :         id,
+      52            0 :         preparationName,
+      53            0 :         preparationTime,
+      54            0 :         nextPreparationId,
+      55            0 :         elapsedTime,
+      56            0 :         isDone
+      57              :       ];
+      58              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/preparation_with_time_entity.dart.gcov.html b/coverage/html/domain/entities/preparation_with_time_entity.dart.gcov.html new file mode 100644 index 00000000..6e830d7e --- /dev/null +++ b/coverage/html/domain/entities/preparation_with_time_entity.dart.gcov.html @@ -0,0 +1,267 @@ + + + + + + + LCOV - lcov.info - domain/entities/preparation_with_time_entity.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entities - preparation_with_time_entity.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %870
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:equatable/equatable.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       3              : import 'package:on_time_front/domain/entities/preparation_step_with_time_entity.dart';
+       4              : import 'package:on_time_front/presentation/shared/constants/constants.dart';
+       5              : 
+       6              : class PreparationWithTimeEntity extends PreparationEntity implements Equatable {
+       7            0 :   const PreparationWithTimeEntity({
+       8              :     required List<PreparationStepWithTimeEntity> preparationStepList,
+       9            0 :   }) : super(preparationStepList: preparationStepList);
+      10              : 
+      11            0 :   factory PreparationWithTimeEntity.fromPreparation(
+      12              :       PreparationEntity preparation) {
+      13            0 :     return PreparationWithTimeEntity(
+      14            0 :       preparationStepList: preparation.preparationStepList
+      15            0 :           .map(
+      16            0 :             (step) => PreparationStepWithTimeEntity(
+      17            0 :               id: step.id,
+      18            0 :               preparationName: step.preparationName,
+      19            0 :               preparationTime: step.preparationTime,
+      20            0 :               nextPreparationId: step.nextPreparationId,
+      21              :             ),
+      22              :           )
+      23            0 :           .toList(),
+      24              :     );
+      25              :   }
+      26              : 
+      27            0 :   PreparationWithTimeEntity copyWith({
+      28              :     List<PreparationStepWithTimeEntity>? preparationStepList,
+      29              :   }) {
+      30            0 :     return PreparationWithTimeEntity(
+      31            0 :       preparationStepList: preparationStepList ?? this.preparationStepList,
+      32              :     );
+      33              :   }
+      34              : 
+      35            0 :   @override
+      36              :   List<PreparationStepWithTimeEntity> get preparationStepList =>
+      37            0 :       super.preparationStepList.cast<PreparationStepWithTimeEntity>();
+      38              : 
+      39            0 :   PreparationStepWithTimeEntity? get currentStep {
+      40            0 :     for (final step in preparationStepList) {
+      41            0 :       if (!step.isDone) {
+      42              :         return step;
+      43              :       }
+      44              :     }
+      45              :     return null; // All steps are done
+      46              :   }
+      47              : 
+      48              :   /// Returns true if all preparation steps are completed
+      49            0 :   bool get isAllStepsDone {
+      50            0 :     return currentStep == null;
+      51              :   }
+      52              : 
+      53            0 :   Duration get elapsedTime => preparationStepList.fold<Duration>(
+      54            0 :       Duration.zero, (sum, s) => sum + s.elapsedTime);
+      55              : 
+      56              :   /// Returns the progress as a value between 0.0 and 1.0
+      57            0 :   double get progress {
+      58            0 :     final totalSeconds = totalDuration.inSeconds;
+      59            0 :     final elapsed = elapsedTime.inSeconds;
+      60            0 :     return totalSeconds == 0 ? 0.0 : (elapsed / totalSeconds).clamp(0.0, 1.0);
+      61              :   }
+      62              : 
+      63              :   /// Returns the current step index, or -1 if all steps are done
+      64            0 :   int get currentStepIndex {
+      65            0 :     final current = currentStep;
+      66            0 :     if (current == null) return -1;
+      67            0 :     return preparationStepList.indexWhere((step) => step.id == current.id);
+      68              :   }
+      69              : 
+      70              :   /// Returns the resolved current step index for display purposes
+      71            0 :   int get resolvedCurrentStepIndex {
+      72            0 :     final index = currentStepIndex;
+      73            0 :     return index == -1 ? preparationStepList.length - 1 : index;
+      74              :   }
+      75              : 
+      76              :   /// Returns the current step's remaining time
+      77            0 :   Duration get currentStepRemainingTime {
+      78            0 :     final current = currentStep;
+      79              :     if (current == null) return Duration.zero;
+      80            0 :     final remaining = current.preparationTime - current.elapsedTime;
+      81            0 :     return remaining.isNegative ? Duration.zero : remaining;
+      82              :   }
+      83              : 
+      84              :   /// Returns the current step's name for display
+      85            0 :   String get currentStepName {
+      86            0 :     final current = currentStep;
+      87            0 :     if (current != null) return current.preparationName;
+      88            0 :     return preparationStepList.isNotEmpty
+      89            0 :         ? preparationStepList.last.preparationName
+      90              :         : '';
+      91              :   }
+      92              : 
+      93              :   /// Returns elapsed times for each step in seconds
+      94            0 :   List<int> get stepElapsedTimesInSeconds {
+      95            0 :     return preparationStepList
+      96            0 :         .map<int>((step) => step.elapsedTime.inSeconds)
+      97            0 :         .toList();
+      98              :   }
+      99              : 
+     100              :   /// Returns the preparation state for each step
+     101            0 :   List<PreparationStateEnum> get preparationStepStates {
+     102            0 :     final resolvedIndex = resolvedCurrentStepIndex;
+     103              : 
+     104            0 :     return List<PreparationStateEnum>.generate(
+     105            0 :       preparationStepList.length,
+     106            0 :       (index) {
+     107            0 :         if (isAllStepsDone) {
+     108              :           // All steps are done
+     109              :           return PreparationStateEnum.done;
+     110              :         }
+     111            0 :         if (index < resolvedIndex) {
+     112              :           return PreparationStateEnum.done;
+     113              :         }
+     114            0 :         if (index == resolvedIndex && !isAllStepsDone) {
+     115              :           return PreparationStateEnum.now;
+     116              :         }
+     117              :         return PreparationStateEnum.yet;
+     118              :       },
+     119              :     );
+     120              :   }
+     121              : 
+     122            0 :   PreparationWithTimeEntity timeElapsed(Duration elapsed) {
+     123            0 :     final current = currentStep;
+     124              :     if (current == null) {
+     125              :       return this; // All steps are done, no changes needed
+     126              :     }
+     127              : 
+     128              :     Duration remainingElapsed = elapsed;
+     129              :     List<PreparationStepWithTimeEntity> updatedSteps =
+     130            0 :         List.from(preparationStepList);
+     131              : 
+     132              :     // Find the current step index
+     133            0 :     int currentIndex = updatedSteps.indexWhere((step) => step.id == current.id);
+     134              : 
+     135              :     // Apply elapsed time to current and subsequent steps if needed
+     136            0 :     while (remainingElapsed > Duration.zero &&
+     137            0 :         currentIndex < updatedSteps.length) {
+     138            0 :       final step = updatedSteps[currentIndex];
+     139            0 :       if (step.isDone) {
+     140            0 :         currentIndex++;
+     141              :         continue;
+     142              :       }
+     143              : 
+     144            0 :       final stepRemainingTime = step.preparationTime - step.elapsedTime;
+     145              : 
+     146            0 :       if (remainingElapsed >= stepRemainingTime) {
+     147              :         // Complete this step and move to next
+     148            0 :         updatedSteps[currentIndex] = step.copyWith(
+     149            0 :           elapsedTime: step.preparationTime,
+     150              :           isDone: true,
+     151              :         );
+     152            0 :         remainingElapsed -= stepRemainingTime;
+     153            0 :         currentIndex++;
+     154              :       } else {
+     155              :         // Partially complete this step
+     156            0 :         updatedSteps[currentIndex] = step.copyWith(
+     157            0 :           elapsedTime: step.elapsedTime + remainingElapsed,
+     158            0 :           isDone: step.elapsedTime + remainingElapsed >= step.preparationTime,
+     159              :         );
+     160              :         remainingElapsed = Duration.zero;
+     161              :       }
+     162              :     }
+     163              : 
+     164            0 :     return copyWith(preparationStepList: updatedSteps);
+     165              :   }
+     166              : 
+     167            0 :   PreparationWithTimeEntity skipCurrentStep() {
+     168            0 :     final current = currentStep;
+     169              :     if (current == null) {
+     170              :       return this; // All steps are done, no changes needed
+     171              :     }
+     172              : 
+     173            0 :     final updatedCurrentStep = current.copyWith(
+     174              :       isDone: true,
+     175              :     );
+     176            0 :     return copyWith(
+     177            0 :       preparationStepList: preparationStepList
+     178            0 :           .map((step) =>
+     179            0 :               step.id == updatedCurrentStep.id ? updatedCurrentStep : step)
+     180            0 :           .toList(),
+     181              :     );
+     182              :   }
+     183              : 
+     184            0 :   @override
+     185              :   String toString() {
+     186            0 :     return 'PreparationWithTimeEntity(preparationStepList: ${preparationStepList.toString()})';
+     187              :   }
+     188              : 
+     189            0 :   @override
+     190            0 :   List<Object?> get props => [preparationStepList];
+     191              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/schedule_entity.dart.gcov.html b/coverage/html/domain/entities/schedule_entity.dart.gcov.html new file mode 100644 index 00000000..1587e385 --- /dev/null +++ b/coverage/html/domain/entities/schedule_entity.dart.gcov.html @@ -0,0 +1,189 @@ + + + + + + + LCOV - lcov.info - domain/entities/schedule_entity.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entities - schedule_entity.dartCoverageTotalHit
Test:lcov.infoLines:8.0 %504
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:equatable/equatable.dart';
+       2              : import 'package:on_time_front/data/tables/schedule_with_place_model.dart';
+       3              : 
+       4              : import '/core/database/database.dart';
+       5              : import 'package:on_time_front/domain/entities/place_entity.dart';
+       6              : 
+       7              : class ScheduleEntity extends Equatable {
+       8              :   final String id;
+       9              :   final PlaceEntity place;
+      10              :   final String scheduleName;
+      11              :   final DateTime scheduleTime;
+      12              :   final Duration moveTime;
+      13              :   final bool isChanged;
+      14              :   final bool isStarted;
+      15              :   final Duration? scheduleSpareTime;
+      16              :   final String scheduleNote;
+      17              :   final int latenessTime;
+      18              :   final ScheduleDoneStatus doneStatus;
+      19              : 
+      20            2 :   const ScheduleEntity({
+      21              :     required this.id,
+      22              :     required this.place,
+      23              :     required this.scheduleName,
+      24              :     required this.scheduleTime,
+      25              :     required this.moveTime,
+      26              :     required this.isChanged,
+      27              :     required this.isStarted,
+      28              :     required this.scheduleSpareTime,
+      29              :     required this.scheduleNote,
+      30              :     this.latenessTime = 0,
+      31              :     this.doneStatus = ScheduleDoneStatus.notEnded,
+      32              :   });
+      33              : 
+      34            0 :   static ScheduleEntity fromScheduleWithPlaceModel(
+      35              :       ScheduleWithPlace scheduleWithPlace) {
+      36            0 :     final schedule = scheduleWithPlace.schedule;
+      37            0 :     final place = scheduleWithPlace.place;
+      38            0 :     return ScheduleEntity(
+      39            0 :       id: schedule.id,
+      40            0 :       place: PlaceEntity.fromModel(place),
+      41            0 :       scheduleName: schedule.scheduleName,
+      42            0 :       scheduleTime: schedule.scheduleTime,
+      43            0 :       moveTime: schedule.moveTime,
+      44            0 :       isChanged: schedule.isChanged,
+      45            0 :       isStarted: schedule.isStarted,
+      46            0 :       scheduleSpareTime: schedule.scheduleSpareTime,
+      47            0 :       scheduleNote: schedule.scheduleNote ?? '',
+      48            0 :       latenessTime: schedule.latenessTime,
+      49              :       doneStatus: ScheduleDoneStatus.notEnded,
+      50              :     );
+      51              :   }
+      52              : 
+      53            0 :   Schedule toScheduleModel() {
+      54            0 :     return Schedule(
+      55            0 :       id: id,
+      56            0 :       placeId: place.id,
+      57            0 :       scheduleName: scheduleName,
+      58            0 :       scheduleTime: scheduleTime,
+      59            0 :       moveTime: moveTime,
+      60            0 :       isChanged: isChanged,
+      61            0 :       isStarted: isStarted,
+      62            0 :       scheduleSpareTime: scheduleSpareTime,
+      63            0 :       scheduleNote: scheduleNote,
+      64            0 :       latenessTime: latenessTime,
+      65              :     );
+      66              :   }
+      67              : 
+      68            0 :   ScheduleWithPlace toScheduleWithPlaceModel() {
+      69            0 :     return ScheduleWithPlace(
+      70            0 :       schedule: toScheduleModel(),
+      71            0 :       place: place.toModel(),
+      72              :     );
+      73              :   }
+      74              : 
+      75            0 :   @override
+      76              :   String toString() {
+      77            0 :     return 'ScheduleEntity(id: $id, place: $place, scheduleName: $scheduleName, scheduleTime: $scheduleTime, moveTime: $moveTime, isChanged: $isChanged, isStarted: $isStarted, scheduleSpareTime: $scheduleSpareTime, scheduleNote: $scheduleNote, latenessTime: $latenessTime)';
+      78              :   }
+      79              : 
+      80            1 :   @override
+      81              :   bool operator ==(Object other) {
+      82              :     if (identical(this, other)) return true;
+      83              : 
+      84            0 :     return other is ScheduleEntity && other.id == id;
+      85              :   }
+      86              : 
+      87            1 :   @override
+      88              :   int get hashCode {
+      89            2 :     return id.hashCode;
+      90              :   }
+      91              : 
+      92            0 :   @override
+      93            0 :   List<Object?> get props => [
+      94            0 :         id,
+      95            0 :         place,
+      96            0 :         scheduleName,
+      97            0 :         scheduleTime,
+      98            0 :         moveTime,
+      99            0 :         isChanged,
+     100            0 :         isStarted,
+     101            0 :         scheduleSpareTime,
+     102            0 :         scheduleNote,
+     103            0 :         latenessTime,
+     104            0 :         doneStatus,
+     105              :       ];
+     106              : }
+     107              : 
+     108              : enum ScheduleDoneStatus {
+     109              :   lateEnd, // LATE        // 지각종료
+     110              :   normalEnd, // NORMAL      // 지각 안 한 종료
+     111              :   abnormalEnd, // ABNORMAL    // 비정상종료
+     112              :   notEnded, // NOT_ENDED
+     113              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/schedule_with_preparation_entity.dart.gcov.html b/coverage/html/domain/entities/schedule_with_preparation_entity.dart.gcov.html new file mode 100644 index 00000000..6d6da769 --- /dev/null +++ b/coverage/html/domain/entities/schedule_with_preparation_entity.dart.gcov.html @@ -0,0 +1,147 @@ + + + + + + + LCOV - lcov.info - domain/entities/schedule_with_preparation_entity.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entities - schedule_with_preparation_entity.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %350
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:on_time_front/domain/entities/preparation_with_time_entity.dart';
+       2              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       3              : 
+       4              : class ScheduleWithPreparationEntity extends ScheduleEntity {
+       5              :   final PreparationWithTimeEntity preparation;
+       6              : 
+       7            0 :   const ScheduleWithPreparationEntity({
+       8              :     required super.id,
+       9              :     required super.place,
+      10              :     required super.scheduleName,
+      11              :     required super.scheduleTime,
+      12              :     required super.moveTime,
+      13              :     required super.isChanged,
+      14              :     required super.isStarted,
+      15              :     required super.scheduleSpareTime,
+      16              :     required super.scheduleNote,
+      17              :     required this.preparation,
+      18              :   });
+      19              : 
+      20              :   ///Returns the total duration of the schedule including the moving time and the preparation time.
+      21            0 :   Duration get totalDuration =>
+      22            0 :       moveTime +
+      23            0 :       preparation.totalDuration +
+      24            0 :       (scheduleSpareTime ?? Duration.zero);
+      25              : 
+      26              :   ///Returns the time when the preparation starts.
+      27            0 :   DateTime get preparationStartTime => scheduleTime.subtract(totalDuration);
+      28              : 
+      29              :   /// Returns the time remaining before needing to leave
+      30            0 :   Duration get timeRemainingBeforeLeaving {
+      31            0 :     final now = DateTime.now();
+      32            0 :     final spareTime = scheduleSpareTime ?? Duration.zero;
+      33            0 :     final remaining = scheduleTime.difference(now) - moveTime - spareTime;
+      34              :     return remaining;
+      35              :   }
+      36              : 
+      37              :   /// Returns whether the schedule is running late
+      38            0 :   bool get isLate {
+      39            0 :     return timeRemainingBeforeLeaving.isNegative;
+      40              :   }
+      41              : 
+      42            0 :   static ScheduleWithPreparationEntity fromScheduleAndPreparationEntity(
+      43              :       ScheduleEntity schedule, PreparationWithTimeEntity preparation) {
+      44            0 :     return ScheduleWithPreparationEntity(
+      45            0 :       id: schedule.id,
+      46            0 :       place: schedule.place,
+      47            0 :       scheduleName: schedule.scheduleName,
+      48            0 :       scheduleTime: schedule.scheduleTime,
+      49            0 :       moveTime: schedule.moveTime,
+      50            0 :       isChanged: schedule.isChanged,
+      51            0 :       isStarted: schedule.isStarted,
+      52            0 :       scheduleSpareTime: schedule.scheduleSpareTime,
+      53            0 :       scheduleNote: schedule.scheduleNote,
+      54              :       preparation: preparation,
+      55              :     );
+      56              :   }
+      57              : 
+      58            0 :   @override
+      59            0 :   List<Object?> get props => [
+      60            0 :         id,
+      61            0 :         place,
+      62            0 :         scheduleName,
+      63            0 :         scheduleTime,
+      64            0 :         moveTime,
+      65            0 :         isChanged,
+      66            0 :         isStarted,
+      67            0 :         scheduleSpareTime,
+      68            0 :         scheduleNote,
+      69            0 :         preparation
+      70              :       ];
+      71              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/token_entity.dart.gcov.html b/coverage/html/domain/entities/token_entity.dart.gcov.html new file mode 100644 index 00000000..bf3603c1 --- /dev/null +++ b/coverage/html/domain/entities/token_entity.dart.gcov.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - domain/entities/token_entity.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entities - token_entity.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %70
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:dio/dio.dart';
+       2              : import 'package:equatable/equatable.dart';
+       3              : 
+       4              : class TokenEntity extends Equatable {
+       5              :   final String accessToken;
+       6              :   final String refreshToken;
+       7              : 
+       8            0 :   const TokenEntity({
+       9              :     required this.accessToken,
+      10              :     required this.refreshToken,
+      11              :   });
+      12              : 
+      13            0 :   static TokenEntity fromHeaders(Headers headers) {
+      14            0 :     return TokenEntity(
+      15            0 :       accessToken: headers.value('authorization')!,
+      16            0 :       refreshToken: headers.value('authorization-refresh')!,
+      17              :     );
+      18              :   }
+      19              : 
+      20            0 :   @override
+      21            0 :   List<Object?> get props => [accessToken, refreshToken];
+      22              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/entities/user_entity.dart.gcov.html b/coverage/html/domain/entities/user_entity.dart.gcov.html new file mode 100644 index 00000000..71c37083 --- /dev/null +++ b/coverage/html/domain/entities/user_entity.dart.gcov.html @@ -0,0 +1,121 @@ + + + + + + + LCOV - lcov.info - domain/entities/user_entity.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/entities - user_entity.dartCoverageTotalHit
Test:lcov.infoLines:5.0 %201
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import '/core/database/database.dart';
+       2              : import 'package:freezed_annotation/freezed_annotation.dart';
+       3              : 
+       4              : part 'user_entity.freezed.dart';
+       5              : 
+       6              : @freezed
+       7              : class UserEntity with _$UserEntity {
+       8           12 :   const UserEntity._();
+       9              : 
+      10              :   const factory UserEntity(
+      11              :       {required String id,
+      12              :       required String email,
+      13              :       required String name,
+      14              :       required Duration spareTime,
+      15              :       required String note,
+      16              :       required double score,
+      17              :       @Default(false) bool isOnboardingCompleted}) = _UserEntity;
+      18              : 
+      19              :   const factory UserEntity.empty() = _UserEntityEmpty;
+      20              : 
+      21            0 :   static UserEntity fromModel(User user) {
+      22            0 :     return UserEntity(
+      23            0 :       id: user.id,
+      24            0 :       email: user.email,
+      25            0 :       name: user.name,
+      26            0 :       spareTime: Duration(minutes: user.spareTime),
+      27            0 :       note: user.note,
+      28            0 :       score: user.score,
+      29              :     );
+      30              :   }
+      31              : 
+      32            0 :   User toModel() {
+      33            0 :     return map(
+      34            0 :         (userEntity) => User(
+      35            0 :               id: userEntity.id,
+      36            0 :               email: userEntity.email,
+      37            0 :               name: userEntity.name,
+      38            0 :               spareTime: userEntity.spareTime.inMinutes,
+      39            0 :               note: userEntity.note,
+      40            0 :               score: userEntity.score,
+      41              :             ),
+      42            0 :         empty: (_) =>
+      43            0 :             throw Exception('Cannot convert empty UserEntity to User'));
+      44              :   }
+      45              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/create_custom_preparation_use_case.dart.gcov.html b/coverage/html/domain/use-cases/create_custom_preparation_use_case.dart.gcov.html new file mode 100644 index 00000000..a0b819f5 --- /dev/null +++ b/coverage/html/domain/use-cases/create_custom_preparation_use_case.dart.gcov.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/create_custom_preparation_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - create_custom_preparation_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/preparation_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class CreateCustomPreparationUseCase {
+       7              :   final PreparationRepository _preparationRepository;
+       8              : 
+       9            0 :   CreateCustomPreparationUseCase(this._preparationRepository);
+      10              : 
+      11            0 :   Future<void> call(
+      12              :       PreparationEntity preparationEntity, String scheduleId) async {
+      13            0 :     await _preparationRepository.createCustomPreparation(
+      14              :         preparationEntity, scheduleId);
+      15              :   }
+      16              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/create_schedule_with_place_use_case.dart.gcov.html b/coverage/html/domain/use-cases/create_schedule_with_place_use_case.dart.gcov.html new file mode 100644 index 00000000..31105595 --- /dev/null +++ b/coverage/html/domain/use-cases/create_schedule_with_place_use_case.dart.gcov.html @@ -0,0 +1,90 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/create_schedule_with_place_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - create_schedule_with_place_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/schedule_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class CreateScheduleWithPlaceUseCase {
+       7              :   final ScheduleRepository _scheduleRepository;
+       8              : 
+       9            0 :   CreateScheduleWithPlaceUseCase(this._scheduleRepository);
+      10              : 
+      11            0 :   Future<void> call(ScheduleEntity schedule) async {
+      12            0 :     await _scheduleRepository.createSchedule(schedule);
+      13              :   }
+      14              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/delete_schedule_use_case.dart.gcov.html b/coverage/html/domain/use-cases/delete_schedule_use_case.dart.gcov.html new file mode 100644 index 00000000..9f6a0ba3 --- /dev/null +++ b/coverage/html/domain/use-cases/delete_schedule_use_case.dart.gcov.html @@ -0,0 +1,90 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/delete_schedule_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - delete_schedule_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/schedule_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class DeleteScheduleUseCase {
+       7              :   final ScheduleRepository _scheduleRepository;
+       8              : 
+       9            0 :   DeleteScheduleUseCase(this._scheduleRepository);
+      10              : 
+      11            0 :   Future<void> call(ScheduleEntity schedule) async {
+      12            0 :     return _scheduleRepository.deleteSchedule(schedule);
+      13              :   }
+      14              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/finish_schedule_use_case.dart.gcov.html b/coverage/html/domain/use-cases/finish_schedule_use_case.dart.gcov.html new file mode 100644 index 00000000..ecba475e --- /dev/null +++ b/coverage/html/domain/use-cases/finish_schedule_use_case.dart.gcov.html @@ -0,0 +1,89 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/finish_schedule_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - finish_schedule_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/repositories/schedule_repository.dart';
+       3              : 
+       4              : @Injectable()
+       5              : class FinishScheduleUseCase {
+       6              :   final ScheduleRepository _scheduleRepository;
+       7              : 
+       8            0 :   FinishScheduleUseCase(this._scheduleRepository);
+       9              : 
+      10            0 :   Future<void> call(String scheduleId, int latenessTime) async {
+      11            0 :     await _scheduleRepository.finishSchedule(scheduleId, latenessTime);
+      12              :   }
+      13              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/get_default_preparation_use_case.dart.gcov.html b/coverage/html/domain/use-cases/get_default_preparation_use_case.dart.gcov.html new file mode 100644 index 00000000..c4df0848 --- /dev/null +++ b/coverage/html/domain/use-cases/get_default_preparation_use_case.dart.gcov.html @@ -0,0 +1,90 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/get_default_preparation_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - get_default_preparation_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/preparation_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class GetDefaultPreparationUseCase {
+       7              :   final PreparationRepository _preparationRepository;
+       8              : 
+       9            0 :   GetDefaultPreparationUseCase(this._preparationRepository);
+      10              : 
+      11            0 :   Future<PreparationEntity> call() async {
+      12            0 :     return await _preparationRepository.getDefualtPreparation();
+      13              :   }
+      14              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart.gcov.html b/coverage/html/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart.gcov.html new file mode 100644 index 00000000..a458c6a4 --- /dev/null +++ b/coverage/html/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart.gcov.html @@ -0,0 +1,133 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/get_nearest_upcoming_schedule_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - get_nearest_upcoming_schedule_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %130
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:async';
+       2              : 
+       3              : import 'package:injectable/injectable.dart';
+       4              : import 'package:on_time_front/domain/entities/schedule_with_preparation_entity.dart';
+       5              : import 'package:on_time_front/domain/entities/preparation_with_time_entity.dart';
+       6              : import 'package:on_time_front/domain/repositories/timed_preparation_repository.dart';
+       7              : import 'package:on_time_front/domain/use-cases/get_preparation_by_schedule_id_use_case.dart';
+       8              : import 'package:on_time_front/domain/use-cases/get_schedules_by_date_use_case.dart';
+       9              : import 'package:on_time_front/domain/use-cases/load_schedules_for_week_use_case.dart';
+      10              : 
+      11              : @Injectable()
+      12              : class GetNearestUpcomingScheduleUseCase {
+      13              :   final GetSchedulesByDateUseCase _getScheduleByDateUseCase;
+      14              :   final GetPreparationByScheduleIdUseCase _getPreparationByScheduleIdUseCase;
+      15              :   final LoadSchedulesForWeekUseCase _loadSchedulesForWeekUseCase;
+      16              :   final TimedPreparationRepository _timedPreparationRepository;
+      17              : 
+      18            0 :   GetNearestUpcomingScheduleUseCase(
+      19              :       this._getScheduleByDateUseCase,
+      20              :       this._getPreparationByScheduleIdUseCase,
+      21              :       this._loadSchedulesForWeekUseCase,
+      22              :       this._timedPreparationRepository);
+      23              : 
+      24            0 :   Stream<ScheduleWithPreparationEntity?> call() async* {
+      25            0 :     final DateTime now = DateTime.now();
+      26              : 
+      27            0 :     _loadSchedulesForWeekUseCase(now);
+      28              : 
+      29              :     final upcomingScheduleStream =
+      30            0 :         _getScheduleByDateUseCase(now, now.add(const Duration(days: 2)));
+      31            0 :     await for (final upcomingSchedule in upcomingScheduleStream) {
+      32            0 :       if (upcomingSchedule.isNotEmpty) {
+      33            0 :         final schedule = upcomingSchedule.first;
+      34              : 
+      35              :         // First try to load locally stored timed preparation
+      36              :         final localTimed =
+      37            0 :             await _timedPreparationRepository.getTimedPreparation(schedule.id);
+      38              :         if (localTimed != null) {
+      39            0 :           yield ScheduleWithPreparationEntity.fromScheduleAndPreparationEntity(
+      40              :               schedule, localTimed);
+      41              :           continue;
+      42              :         }
+      43              : 
+      44              :         // Fallback to fetching canonical preparation from source
+      45              :         final preparation =
+      46            0 :             await _getPreparationByScheduleIdUseCase(schedule.id);
+      47              :         final scheduleWithPreparation =
+      48            0 :             ScheduleWithPreparationEntity.fromScheduleAndPreparationEntity(
+      49              :                 schedule,
+      50            0 :                 PreparationWithTimeEntity.fromPreparation(preparation));
+      51              :         yield scheduleWithPreparation;
+      52              :       } else {
+      53              :         yield null;
+      54              :       }
+      55              :     }
+      56              :   }
+      57              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/get_preparation_by_schedule_id_use_case.dart.gcov.html b/coverage/html/domain/use-cases/get_preparation_by_schedule_id_use_case.dart.gcov.html new file mode 100644 index 00000000..ab40cd82 --- /dev/null +++ b/coverage/html/domain/use-cases/get_preparation_by_schedule_id_use_case.dart.gcov.html @@ -0,0 +1,90 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/get_preparation_by_schedule_id_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - get_preparation_by_schedule_id_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/preparation_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class GetPreparationByScheduleIdUseCase {
+       7              :   final PreparationRepository _preparationRepository;
+       8              : 
+       9            0 :   GetPreparationByScheduleIdUseCase(this._preparationRepository);
+      10              : 
+      11            0 :   Future<PreparationEntity> call(String scheduleId) async {
+      12            0 :     return await _preparationRepository.getPreparationByScheduleId(scheduleId);
+      13              :   }
+      14              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/get_schedule_by_id_use_case.dart.gcov.html b/coverage/html/domain/use-cases/get_schedule_by_id_use_case.dart.gcov.html new file mode 100644 index 00000000..6e82cb00 --- /dev/null +++ b/coverage/html/domain/use-cases/get_schedule_by_id_use_case.dart.gcov.html @@ -0,0 +1,90 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/get_schedule_by_id_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - get_schedule_by_id_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/schedule_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class GetScheduleByIdUseCase {
+       7              :   final ScheduleRepository _scheduleRepository;
+       8              : 
+       9            0 :   GetScheduleByIdUseCase(this._scheduleRepository);
+      10              : 
+      11            0 :   Future<ScheduleEntity> call(String id) {
+      12            0 :     return _scheduleRepository.getScheduleById(id);
+      13              :   }
+      14              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/get_schedules_by_date_use_case.dart.gcov.html b/coverage/html/domain/use-cases/get_schedules_by_date_use_case.dart.gcov.html new file mode 100644 index 00000000..085cbabe --- /dev/null +++ b/coverage/html/domain/use-cases/get_schedules_by_date_use_case.dart.gcov.html @@ -0,0 +1,101 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/get_schedules_by_date_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - get_schedules_by_date_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %90
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/schedule_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class GetSchedulesByDateUseCase {
+       7              :   final ScheduleRepository _scheduleRepository;
+       8              : 
+       9            0 :   GetSchedulesByDateUseCase(this._scheduleRepository);
+      10              : 
+      11            0 :   Stream<List<ScheduleEntity>> call(
+      12              :       DateTime startDate, DateTime endDate) async* {
+      13            0 :     final schedulesStream = _scheduleRepository.scheduleStream;
+      14            0 :     await for (final schedules in schedulesStream) {
+      15              :       final filteredSchedules = schedules
+      16            0 :           .where((schedule) =>
+      17            0 :               schedule.scheduleTime.compareTo(startDate) >= 0 &&
+      18            0 :               schedule.scheduleTime.isBefore(endDate))
+      19            0 :           .toList();
+      20              :       filteredSchedules
+      21            0 :           .sort((a, b) => a.scheduleTime.compareTo(b.scheduleTime));
+      22              :       yield filteredSchedules;
+      23              :     }
+      24              :   }
+      25              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/index-sort-f.html b/coverage/html/domain/use-cases/index-sort-f.html new file mode 100644 index 00000000..a051a99a --- /dev/null +++ b/coverage/html/domain/use-cases/index-sort-f.html @@ -0,0 +1,260 @@ + + + + + + + LCOV - lcov.info - domain/use-cases + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-casesCoverageTotalHit
Test:lcov.infoLines:0.0 %780
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
create_custom_preparation_use_case.dart +
0.0%
+
0.0 %3
create_schedule_with_place_use_case.dart +
0.0%
+
0.0 %3
delete_schedule_use_case.dart +
0.0%
+
0.0 %3
finish_schedule_use_case.dart +
0.0%
+
0.0 %3
get_default_preparation_use_case.dart +
0.0%
+
0.0 %3
get_nearest_upcoming_schedule_use_case.dart +
0.0%
+
0.0 %13
get_preparation_by_schedule_id_use_case.dart +
0.0%
+
0.0 %3
get_schedule_by_id_use_case.dart +
0.0%
+
0.0 %3
get_schedules_by_date_use_case.dart +
0.0%
+
0.0 %9
load_schedules_for_month_use_case.dart +
0.0%
+
0.0 %5
load_schedules_for_week_use_case.dart +
0.0%
+
0.0 %5
load_user_use_case.dart +
0.0%
+
0.0 %3
onboard_use_case.dart +
0.0%
+
0.0 %4
save_timed_preparation_use_case.dart +
0.0%
+
0.0 %3
sign_out_use_case.dart +
0.0%
+
0.0 %3
stream_user_use_case.dart +
0.0%
+
0.0 %3
update_default_preparation_use_case.dart +
0.0%
+
0.0 %3
update_preparation_by_schedule_id_use_case.dart +
0.0%
+
0.0 %3
update_schedule_use_case.dart +
0.0%
+
0.0 %3
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/index-sort-l.html b/coverage/html/domain/use-cases/index-sort-l.html new file mode 100644 index 00000000..24e8aaba --- /dev/null +++ b/coverage/html/domain/use-cases/index-sort-l.html @@ -0,0 +1,260 @@ + + + + + + + LCOV - lcov.info - domain/use-cases + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-casesCoverageTotalHit
Test:lcov.infoLines:0.0 %780
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
create_custom_preparation_use_case.dart +
0.0%
+
0.0 %3
create_schedule_with_place_use_case.dart +
0.0%
+
0.0 %3
delete_schedule_use_case.dart +
0.0%
+
0.0 %3
finish_schedule_use_case.dart +
0.0%
+
0.0 %3
get_default_preparation_use_case.dart +
0.0%
+
0.0 %3
get_preparation_by_schedule_id_use_case.dart +
0.0%
+
0.0 %3
get_schedule_by_id_use_case.dart +
0.0%
+
0.0 %3
load_user_use_case.dart +
0.0%
+
0.0 %3
save_timed_preparation_use_case.dart +
0.0%
+
0.0 %3
sign_out_use_case.dart +
0.0%
+
0.0 %3
stream_user_use_case.dart +
0.0%
+
0.0 %3
update_default_preparation_use_case.dart +
0.0%
+
0.0 %3
update_preparation_by_schedule_id_use_case.dart +
0.0%
+
0.0 %3
update_schedule_use_case.dart +
0.0%
+
0.0 %3
onboard_use_case.dart +
0.0%
+
0.0 %4
load_schedules_for_month_use_case.dart +
0.0%
+
0.0 %5
load_schedules_for_week_use_case.dart +
0.0%
+
0.0 %5
get_schedules_by_date_use_case.dart +
0.0%
+
0.0 %9
get_nearest_upcoming_schedule_use_case.dart +
0.0%
+
0.0 %13
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/index.html b/coverage/html/domain/use-cases/index.html new file mode 100644 index 00000000..138278be --- /dev/null +++ b/coverage/html/domain/use-cases/index.html @@ -0,0 +1,260 @@ + + + + + + + LCOV - lcov.info - domain/use-cases + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-casesCoverageTotalHit
Test:lcov.infoLines:0.0 %780
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
create_custom_preparation_use_case.dart +
0.0%
+
0.0 %3
create_schedule_with_place_use_case.dart +
0.0%
+
0.0 %3
delete_schedule_use_case.dart +
0.0%
+
0.0 %3
finish_schedule_use_case.dart +
0.0%
+
0.0 %3
get_default_preparation_use_case.dart +
0.0%
+
0.0 %3
get_nearest_upcoming_schedule_use_case.dart +
0.0%
+
0.0 %13
get_preparation_by_schedule_id_use_case.dart +
0.0%
+
0.0 %3
get_schedule_by_id_use_case.dart +
0.0%
+
0.0 %3
get_schedules_by_date_use_case.dart +
0.0%
+
0.0 %9
load_schedules_for_month_use_case.dart +
0.0%
+
0.0 %5
load_schedules_for_week_use_case.dart +
0.0%
+
0.0 %5
load_user_use_case.dart +
0.0%
+
0.0 %3
onboard_use_case.dart +
0.0%
+
0.0 %4
save_timed_preparation_use_case.dart +
0.0%
+
0.0 %3
sign_out_use_case.dart +
0.0%
+
0.0 %3
stream_user_use_case.dart +
0.0%
+
0.0 %3
update_default_preparation_use_case.dart +
0.0%
+
0.0 %3
update_preparation_by_schedule_id_use_case.dart +
0.0%
+
0.0 %3
update_schedule_use_case.dart +
0.0%
+
0.0 %3
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/load_schedules_for_month_use_case.dart.gcov.html b/coverage/html/domain/use-cases/load_schedules_for_month_use_case.dart.gcov.html new file mode 100644 index 00000000..65dd8d83 --- /dev/null +++ b/coverage/html/domain/use-cases/load_schedules_for_month_use_case.dart.gcov.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/load_schedules_for_month_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - load_schedules_for_month_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %50
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/repositories/schedule_repository.dart';
+       3              : 
+       4              : @Injectable()
+       5              : class LoadSchedulesForMonthUseCase {
+       6              :   final ScheduleRepository _scheduleRepository;
+       7              : 
+       8            0 :   LoadSchedulesForMonthUseCase(this._scheduleRepository);
+       9              : 
+      10            0 :   Future<void> call(DateTime date) async {
+      11            0 :     final startOfMonth = DateTime(date.year, date.month, 1);
+      12            0 :     final endOfMonth = DateTime(date.year, date.month + 1, 0);
+      13              : 
+      14            0 :     await _scheduleRepository.getSchedulesByDate(startOfMonth, endOfMonth);
+      15              :   }
+      16              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/load_schedules_for_week_use_case.dart.gcov.html b/coverage/html/domain/use-cases/load_schedules_for_week_use_case.dart.gcov.html new file mode 100644 index 00000000..dc52afed --- /dev/null +++ b/coverage/html/domain/use-cases/load_schedules_for_week_use_case.dart.gcov.html @@ -0,0 +1,91 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/load_schedules_for_week_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - load_schedules_for_week_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %50
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/repositories/schedule_repository.dart';
+       3              : 
+       4              : @Injectable()
+       5              : class LoadSchedulesForWeekUseCase {
+       6              :   final ScheduleRepository _scheduleRepository;
+       7            0 :   LoadSchedulesForWeekUseCase(this._scheduleRepository);
+       8              : 
+       9            0 :   Future<void> call(DateTime date) async {
+      10            0 :     final startOfWeek = date.subtract(Duration(days: date.weekday - 1));
+      11            0 :     final endOfWeek = startOfWeek.add(Duration(days: 7));
+      12              : 
+      13            0 :     await _scheduleRepository.getSchedulesByDate(startOfWeek, endOfWeek);
+      14              :   }
+      15              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/load_user_use_case.dart.gcov.html b/coverage/html/domain/use-cases/load_user_use_case.dart.gcov.html new file mode 100644 index 00000000..74533a5b --- /dev/null +++ b/coverage/html/domain/use-cases/load_user_use_case.dart.gcov.html @@ -0,0 +1,89 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/load_user_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - load_user_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/repositories/user_repository.dart';
+       3              : 
+       4              : @Injectable()
+       5              : class LoadUserUseCase {
+       6              :   final UserRepository _userRepository;
+       7              : 
+       8            0 :   LoadUserUseCase(this._userRepository);
+       9              : 
+      10            0 :   Future<void> call() async {
+      11            0 :     await _userRepository.getUser();
+      12              :   }
+      13              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/onboard_use_case.dart.gcov.html b/coverage/html/domain/use-cases/onboard_use_case.dart.gcov.html new file mode 100644 index 00000000..e9d68dbc --- /dev/null +++ b/coverage/html/domain/use-cases/onboard_use_case.dart.gcov.html @@ -0,0 +1,97 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/onboard_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - onboard_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %40
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/user_repository.dart';
+       4              : import 'package:on_time_front/domain/repositories/preparation_repository.dart';
+       5              : 
+       6              : @Injectable()
+       7              : class OnboardUseCase {
+       8              :   final PreparationRepository _preparationRepository;
+       9              :   final UserRepository _userRepository;
+      10              : 
+      11            0 :   OnboardUseCase(this._preparationRepository, this._userRepository);
+      12              : 
+      13            0 :   Future<void> call(
+      14              :       {required PreparationEntity preparationEntity,
+      15              :       required Duration spareTime,
+      16              :       required String note}) async {
+      17            0 :     await _preparationRepository.createDefaultPreparation(
+      18              :         preparationEntity: preparationEntity, spareTime: spareTime, note: note);
+      19            0 :     await _userRepository.getUser();
+      20              :   }
+      21              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/save_timed_preparation_use_case.dart.gcov.html b/coverage/html/domain/use-cases/save_timed_preparation_use_case.dart.gcov.html new file mode 100644 index 00000000..cf332c37 --- /dev/null +++ b/coverage/html/domain/use-cases/save_timed_preparation_use_case.dart.gcov.html @@ -0,0 +1,91 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/save_timed_preparation_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - save_timed_preparation_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_with_time_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/timed_preparation_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class SaveTimedPreparationUseCase {
+       7              :   final TimedPreparationRepository _timedPreparationRepository;
+       8              : 
+       9            0 :   SaveTimedPreparationUseCase(this._timedPreparationRepository);
+      10              : 
+      11            0 :   Future<void> call(String scheduleId, PreparationWithTimeEntity preparation) {
+      12            0 :     return _timedPreparationRepository.saveTimedPreparation(
+      13              :         scheduleId, preparation);
+      14              :   }
+      15              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/sign_out_use_case.dart.gcov.html b/coverage/html/domain/use-cases/sign_out_use_case.dart.gcov.html new file mode 100644 index 00000000..cc07435e --- /dev/null +++ b/coverage/html/domain/use-cases/sign_out_use_case.dart.gcov.html @@ -0,0 +1,89 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/sign_out_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - sign_out_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/repositories/user_repository.dart';
+       3              : 
+       4              : @Injectable()
+       5              : class SignOutUseCase {
+       6              :   final UserRepository _userRepository;
+       7              : 
+       8            0 :   SignOutUseCase(this._userRepository);
+       9              : 
+      10            0 :   Future<void> call() async {
+      11            0 :     return _userRepository.signOut();
+      12              :   }
+      13              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/stream_user_use_case.dart.gcov.html b/coverage/html/domain/use-cases/stream_user_use_case.dart.gcov.html new file mode 100644 index 00000000..b3d05db7 --- /dev/null +++ b/coverage/html/domain/use-cases/stream_user_use_case.dart.gcov.html @@ -0,0 +1,90 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/stream_user_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - stream_user_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/user_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/user_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class StreamUserUseCase {
+       7              :   final UserRepository _userRepository;
+       8              : 
+       9            0 :   StreamUserUseCase(this._userRepository);
+      10              : 
+      11            0 :   Stream<UserEntity> call() {
+      12            0 :     return _userRepository.userStream;
+      13              :   }
+      14              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/update_default_preparation_use_case.dart.gcov.html b/coverage/html/domain/use-cases/update_default_preparation_use_case.dart.gcov.html new file mode 100644 index 00000000..233b239a --- /dev/null +++ b/coverage/html/domain/use-cases/update_default_preparation_use_case.dart.gcov.html @@ -0,0 +1,90 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/update_default_preparation_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - update_default_preparation_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/preparation_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class UpdateDefaultPreparationUseCase {
+       7              :   final PreparationRepository _preparationRepository;
+       8              : 
+       9            0 :   UpdateDefaultPreparationUseCase(this._preparationRepository);
+      10              : 
+      11            0 :   Future<void> call(PreparationEntity preparationEntity) async {
+      12            0 :     await _preparationRepository.updateDefaultPreparation(preparationEntity);
+      13              :   }
+      14              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/update_preparation_by_schedule_id_use_case.dart.gcov.html b/coverage/html/domain/use-cases/update_preparation_by_schedule_id_use_case.dart.gcov.html new file mode 100644 index 00000000..2c05f876 --- /dev/null +++ b/coverage/html/domain/use-cases/update_preparation_by_schedule_id_use_case.dart.gcov.html @@ -0,0 +1,92 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/update_preparation_by_schedule_id_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - update_preparation_by_schedule_id_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/preparation_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class UpdatePreparationByScheduleIdUseCase {
+       7              :   final PreparationRepository _preparationRepository;
+       8              : 
+       9            0 :   UpdatePreparationByScheduleIdUseCase(this._preparationRepository);
+      10              : 
+      11            0 :   Future<void> call(
+      12              :       PreparationEntity preparationEntity, String scheduleId) async {
+      13            0 :     await _preparationRepository.updatePreparationByScheduleId(
+      14              :         preparationEntity, scheduleId);
+      15              :   }
+      16              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/domain/use-cases/update_schedule_use_case.dart.gcov.html b/coverage/html/domain/use-cases/update_schedule_use_case.dart.gcov.html new file mode 100644 index 00000000..3757e835 --- /dev/null +++ b/coverage/html/domain/use-cases/update_schedule_use_case.dart.gcov.html @@ -0,0 +1,90 @@ + + + + + + + LCOV - lcov.info - domain/use-cases/update_schedule_use_case.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - domain/use-cases - update_schedule_use_case.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:injectable/injectable.dart';
+       2              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       3              : import 'package:on_time_front/domain/repositories/schedule_repository.dart';
+       4              : 
+       5              : @Injectable()
+       6              : class UpdateScheduleUseCase {
+       7              :   final ScheduleRepository _scheduleRepository;
+       8              : 
+       9            0 :   UpdateScheduleUseCase(this._scheduleRepository);
+      10              : 
+      11            0 :   Future<void> call(ScheduleEntity schedule) async {
+      12            0 :     await _scheduleRepository.updateSchedule(schedule);
+      13              :   }
+      14              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/emerald.png b/coverage/html/emerald.png new file mode 100644 index 0000000000000000000000000000000000000000..38ad4f4068b935643d2486f323005fb294a9bd7e GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^Jb!lvI6;R0X`wF(yt=9xVZRt1vCRixIA4P dLn>}1Cji+@42)0J?}79&c)I$ztaD0e0sy@GAL0N2 literal 0 HcmV?d00001 diff --git a/coverage/html/gcov.css b/coverage/html/gcov.css new file mode 100644 index 00000000..1cacc835 --- /dev/null +++ b/coverage/html/gcov.css @@ -0,0 +1,1125 @@ +/* All views: initial background and text color */ +body +{ + color: #000000; + background-color: #ffffff; +} + +/* All views: standard link format*/ +a:link +{ + color: #284fa8; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #00cb40; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #ff0040; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding-bottom: 10px; + font-family: sans-serif; + font-size: 20pt; + font-style: italic; + font-weight: bold; +} +/* table footnote */ +td.footnote +{ + text-align: left; + padding-left: 100px; + padding-right: 10px; + background-color: #dae7fe; /* light blue table background color */ + /* dark blue table header color + background-color: #6688d4; */ + white-space: nowrap; + font-family: sans-serif; + font-style: italic; + font-size:70%; +} +/* "Line coverage date bins" leader */ +td.subTableHeader +{ + text-align: center; + padding-bottom: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: center; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: top; + white-space: nowrap; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; +} + +/* All views: header item coverage table heading */ +td.headerCovTableHead +{ + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; +} + +/* All views: header item coverage table entry */ +td.headerCovTableEntry +{ + text-align: right; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #dae7fe; +} + +/* All views: header item coverage table entry for high coverage rate */ +td.headerCovTableEntryHi +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #a7fc9d; +} + +/* All views: header item coverage table entry for medium coverage rate */ +td.headerCovTableEntryMed +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ffea20; +} + +/* All views: header item coverage table entry for ow coverage rate */ +td.headerCovTableEntryLo +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ff0000; +} + +/* All views: header legend value for legend entry */ +td.headerValueLeg +{ + text-align: left; + color: #000000; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; + padding-top: 4px; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #6688d4; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: + table headline format */ +td.tableHead +{ + text-align: center; + color: #ffffff; + background-color: #6688d4; + font-family: sans-serif; + font-size: 120%; + font-weight: bold; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; +} + +span.tableHeadSort +{ + padding-right: 4px; +} + +/* Directory view/File view (all): filename entry format */ +td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Directory view/File view (all): directory name entry format */ +td.coverDirectory +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #b8d0ff; + font-family: monospace; +} + +/* Directory view/File view (all): filename entry format */ +td.overallOwner +{ + text-align: center; + font-weight: bold; + font-family: sans-serif; + background-color: #dae7fe; + padding-right: 10px; + padding-left: 10px; +} + +/* Directory view/File view (all): filename entry format */ +td.ownerName +{ + text-align: right; + font-style: italic; + font-family: sans-serif; + background-color: #E5DBDB; + padding-right: 10px; + padding-left: 20px; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.owner_coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #E5DBDB; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #000000; +} + +/* Directory view/File view (all): percentage entry for files with + high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + font-weight: bold; + font-family: sans-serif; +} + +/* 'owner' entry: slightly lighter color than 'coverPerHi' */ +td.owner_coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #82E0AA; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry */ +td.coverNumDflt +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + white-space: nowrap; + font-family: sans-serif; +} + +/* td background color and font for the 'owner' section of the table */ +td.ownerTla +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #E5DBDB; + white-space: nowrap; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all): line count entry for files with + high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + white-space: nowrap; + font-family: sans-serif; +} + +td.owner_coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #82E0AA; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + font-weight: bold; + font-family: sans-serif; +} + +td.owner_coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #F9E79F; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + white-space: nowrap; + font-family: sans-serif; +} + +td.owner_coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #F9E79F; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +td.owner_coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #EC7063; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + white-space: nowrap; + font-family: sans-serif; +} + +td.owner_coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #EC7063; + white-space: nowrap; + font-family: sans-serif; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #b8d0ff; + font-size:80%; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #b8d0ff; + font-size:80%; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #ffffff; + font-size:80%; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: right; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #dae7fe; +} + +/* Source code view: function entry */ +td.coverFn +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-weight: bold; + font-family: sans-serif; +} + +td.coverFnAlias +{ + text-align: right; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + /* make this a slightly different color than the leader - otherwise, + otherwise the alias is hard to distinguish in the table */ + background-color: #E5DBDB; /* very light pale grey/blue */ + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnAliasLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #EC7063; /* lighter red */ + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnAliasHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; + margin-top: 2px; +} + +/* elided/removed code */ +span.elidedSource +{ + font-family: sans-serif; + /*font-size: 8pt; */ + font-style: italic; + background-color: lightgrey; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #efe383; +} + +/* Source code view: line number format when there are deleted + lines in the corresponding location */ +span.lineNumWithDelete +{ + foreground-color: #efe383; + background-color: lightgrey; +} + +/* Source code view: format for Cov legend */ +span.coverLegendCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #cad7fe; +} + +/* Source code view: format for NoCov legend */ +span.coverLegendNoCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #ff6230; +} + +/* Source code view: format for the source code heading line */ +pre.sourceHeading +{ + white-space: pre; + font-family: monospace; + font-weight: bold; + margin: 0px; +} + +/* All views: header legend value for low rate */ +td.headerValueLegL +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 4px; + padding-right: 2px; + background-color: #ff0000; + font-size: 80%; +} + +/* All views: header legend value for med rate */ +td.headerValueLegM +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 2px; + background-color: #ffea20; + font-size: 80%; +} + +/* All views: header legend value for hi rate */ +td.headerValueLegH +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 4px; + background-color: #a7fc9d; + font-size: 80%; +} + +/* All views except source code view: legend format for low coverage */ +span.coverLegendCovLo +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ff0000; +} + +/* All views except source code view: legend format for med coverage */ +span.coverLegendCovMed +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ffea20; +} + +/* All views except source code view: legend format for hi coverage */ +span.coverLegendCovHi +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #a7fc9d; +} + +a.branchTla:link +{ + color: #000000; +} + +a.branchTla:visited +{ + color: #000000; +} + +a.mcdcTla:link +{ + color: #000000; +} + +a.mcdcTla:visited +{ + color: #000000; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered New Code (+ => 0): +Newly added code is not tested" */ +td.tlaUNC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgUNC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered New Code (+ => 0): +Newly added code is not tested" */ +span.tlaUNC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgUNC { + background-color: #FF6230; +} +a.tlaBgUNC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadUNC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Lost Baseline Coverage (1 => 0): +Unchanged code is no longer tested" */ +td.tlaLBC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgLBC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Lost Baseline Coverage (1 => 0): +Unchanged code is no longer tested" */ +span.tlaLBC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgLBC { + background-color: #FF6230; +} +a.tlaBgLBC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadLBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Included Code (# => 0): +Previously unused code is untested" */ +td.tlaUIC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgUIC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Included Code (# => 0): +Previously unused code is untested" */ +span.tlaUIC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgUIC { + background-color: #FF6230; +} +a.tlaBgUIC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadUIC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Baseline Code (0 => 0): +Unchanged code was untested before, is untested now" */ +td.tlaUBC +{ + text-align: right; + background-color: #FF6230; +} +td.tlaBgUBC { + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Uncovered Baseline Code (0 => 0): +Unchanged code was untested before, is untested now" */ +span.tlaUBC +{ + text-align: left; + background-color: #FF6230; +} +span.tlaBgUBC { + background-color: #FF6230; +} +a.tlaBgUBC { + background-color: #FF6230; + color: #000000; +} + +td.headerCovTableHeadUBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FF6230; +} + +/* Source code view/table entry background: format for lines classified as "Gained Baseline Coverage (0 => 1): +Unchanged code is tested now" */ +td.tlaGBC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgGBC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained Baseline Coverage (0 => 1): +Unchanged code is tested now" */ +span.tlaGBC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgGBC { + background-color: #CAD7FE; +} +a.tlaBgGBC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadGBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained Included Coverage (# => 1): +Previously unused code is tested now" */ +td.tlaGIC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgGIC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained Included Coverage (# => 1): +Previously unused code is tested now" */ +span.tlaGIC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgGIC { + background-color: #CAD7FE; +} +a.tlaBgGIC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadGIC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained New Coverage (+ => 1): +Newly added code is tested" */ +td.tlaGNC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgGNC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Gained New Coverage (+ => 1): +Newly added code is tested" */ +span.tlaGNC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgGNC { + background-color: #CAD7FE; +} +a.tlaBgGNC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadGNC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Covered Baseline Code (1 => 1): +Unchanged code was tested before and is still tested" */ +td.tlaCBC +{ + text-align: right; + background-color: #CAD7FE; +} +td.tlaBgCBC { + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Covered Baseline Code (1 => 1): +Unchanged code was tested before and is still tested" */ +span.tlaCBC +{ + text-align: left; + background-color: #CAD7FE; +} +span.tlaBgCBC { + background-color: #CAD7FE; +} +a.tlaBgCBC { + background-color: #CAD7FE; + color: #000000; +} + +td.headerCovTableHeadCBC { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #CAD7FE; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Uncovered Baseline (0 => #): +Previously untested code is unused now" */ +td.tlaEUB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgEUB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Uncovered Baseline (0 => #): +Previously untested code is unused now" */ +span.tlaEUB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgEUB { + background-color: #FFFFFF; +} +a.tlaBgEUB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadEUB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Covered Baseline (1 => #): +Previously tested code is unused now" */ +td.tlaECB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgECB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Excluded Covered Baseline (1 => #): +Previously tested code is unused now" */ +span.tlaECB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgECB { + background-color: #FFFFFF; +} +a.tlaBgECB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadECB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Uncovered Baseline (0 => -): +Previously untested code has been deleted" */ +td.tlaDUB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgDUB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Uncovered Baseline (0 => -): +Previously untested code has been deleted" */ +span.tlaDUB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgDUB { + background-color: #FFFFFF; +} +a.tlaBgDUB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadDUB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Covered Baseline (1 => -): +Previously tested code has been deleted" */ +td.tlaDCB +{ + text-align: right; + background-color: #FFFFFF; +} +td.tlaBgDCB { + background-color: #FFFFFF; +} + +/* Source code view/table entry background: format for lines classified as "Deleted Covered Baseline (1 => -): +Previously tested code has been deleted" */ +span.tlaDCB +{ + text-align: left; + background-color: #FFFFFF; +} +span.tlaBgDCB { + background-color: #FFFFFF; +} +a.tlaBgDCB { + background-color: #FFFFFF; + color: #000000; +} + +td.headerCovTableHeadDCB { + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + white-space: nowrap; + background-color: #FFFFFF; +} + +/* Source code view: format for date/owner bin that is not hit */ +span.missBins +{ + background-color: #ff0000 /* red */ +} diff --git a/coverage/html/glass.png b/coverage/html/glass.png new file mode 100644 index 0000000000000000000000000000000000000000..e1abc00680a3093c49fdb775ae6bdb6764c95af2 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)gaEa{HEjtmSN`?>!lvI6;R0X`wF z|Ns97GD8ntt^-nxB|(0{3=Yq3q=7g|-tI089jvk*Kn`btM`SSr1Gf+eGhVt|_XjA* zUgGKN%6^Gmn4d%Ph(nkFP>9RZ#WAE}PI3Z}&BVayv3^M*kj3EX>gTe~DWM4f=_Dpv literal 0 HcmV?d00001 diff --git a/coverage/html/index-sort-f.html b/coverage/html/index-sort-f.html new file mode 100644 index 00000000..1055698f --- /dev/null +++ b/coverage/html/index-sort-f.html @@ -0,0 +1,350 @@ + + + + + + + LCOV - lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelCoverageTotalHit
Test:lcov.infoLines:17.4 %3848670
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
core/constants/ +
39.1%39.1%
+
39.1 %239
core/database/ +
24.8%24.8%
+
24.8 %1623403
core/di/ +
0.0%
+
0.0 %3
core/dio/ +
0.0%
+
0.0 %6
core/dio/adapters/ +
0.0%
+
0.0 %2
core/dio/interceptors/ +
0.0%
+
0.0 %66
core/dio/transformers/ +
0.0%
+
0.0 %7
core/services/ +
0.0%
+
0.0 %2
core/utils/json_converters/ +
100.0%
+
100.0 %55
data/daos/ +
44.4%44.4%
+
44.4 %19687
data/data_sources/ +
13.5%13.5%
+
13.5 %22931
data/models/ +
18.2%18.2%
+
18.2 %42878
data/repositories/ +
31.5%31.5%
+
31.5 %8928
data/tables/ +
6.5%6.5%
+
6.5 %463
domain/entities/ +
6.9%6.9%
+
6.9 %26218
domain/use-cases/ +
0.0%
+
0.0 %78
presentation/app/bloc/auth/ +
0.0%
+
0.0 %38
presentation/app/bloc/schedule/ +
4.8%4.8%
+
4.8 %1246
presentation/calendar/bloc/ +
0.0%
+
0.0 %101
presentation/early_late/bloc/ +
0.0%
+
0.0 %53
presentation/home/bloc/ +
0.0%
+
0.0 %40
presentation/my_page/preparation_spare_time_edit/bloc/ +
0.0%
+
0.0 %53
presentation/onboarding/cubit/ +
0.0%
+
0.0 %39
presentation/onboarding/preparation_name_select/input_models/ +
25.0%25.0%
+
25.0 %41
presentation/onboarding/preparation_time/input_models/ +
16.7%16.7%
+
16.7 %61
presentation/schedule_create/bloc/ +
0.0%
+
0.0 %136
presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/ +
0.0%
+
0.0 %122
presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/ +
0.0%
+
0.0 %22
presentation/shared/constants/ +
0.0%
+
0.0 %45
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/index-sort-l.html b/coverage/html/index-sort-l.html new file mode 100644 index 00000000..2861e17f --- /dev/null +++ b/coverage/html/index-sort-l.html @@ -0,0 +1,350 @@ + + + + + + + LCOV - lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelCoverageTotalHit
Test:lcov.infoLines:17.4 %3848670
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
core/dio/adapters/ +
0.0%
+
0.0 %2
core/services/ +
0.0%
+
0.0 %2
core/di/ +
0.0%
+
0.0 %3
core/dio/ +
0.0%
+
0.0 %6
core/dio/transformers/ +
0.0%
+
0.0 %7
presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/ +
0.0%
+
0.0 %22
presentation/app/bloc/auth/ +
0.0%
+
0.0 %38
presentation/onboarding/cubit/ +
0.0%
+
0.0 %39
presentation/home/bloc/ +
0.0%
+
0.0 %40
presentation/shared/constants/ +
0.0%
+
0.0 %45
presentation/early_late/bloc/ +
0.0%
+
0.0 %53
presentation/my_page/preparation_spare_time_edit/bloc/ +
0.0%
+
0.0 %53
core/dio/interceptors/ +
0.0%
+
0.0 %66
domain/use-cases/ +
0.0%
+
0.0 %78
presentation/calendar/bloc/ +
0.0%
+
0.0 %101
presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/ +
0.0%
+
0.0 %122
presentation/schedule_create/bloc/ +
0.0%
+
0.0 %136
presentation/app/bloc/schedule/ +
4.8%4.8%
+
4.8 %1246
data/tables/ +
6.5%6.5%
+
6.5 %463
domain/entities/ +
6.9%6.9%
+
6.9 %26218
data/data_sources/ +
13.5%13.5%
+
13.5 %22931
presentation/onboarding/preparation_time/input_models/ +
16.7%16.7%
+
16.7 %61
data/models/ +
18.2%18.2%
+
18.2 %42878
core/database/ +
24.8%24.8%
+
24.8 %1623403
presentation/onboarding/preparation_name_select/input_models/ +
25.0%25.0%
+
25.0 %41
data/repositories/ +
31.5%31.5%
+
31.5 %8928
core/constants/ +
39.1%39.1%
+
39.1 %239
data/daos/ +
44.4%44.4%
+
44.4 %19687
core/utils/json_converters/ +
100.0%
+
100.0 %55
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/index.html b/coverage/html/index.html new file mode 100644 index 00000000..52b78908 --- /dev/null +++ b/coverage/html/index.html @@ -0,0 +1,350 @@ + + + + + + + LCOV - lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelCoverageTotalHit
Test:lcov.infoLines:17.4 %3848670
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
core/constants/ +
39.1%39.1%
+
39.1 %239
core/database/ +
24.8%24.8%
+
24.8 %1623403
core/di/ +
0.0%
+
0.0 %3
core/dio/ +
0.0%
+
0.0 %6
core/dio/adapters/ +
0.0%
+
0.0 %2
core/dio/interceptors/ +
0.0%
+
0.0 %66
core/dio/transformers/ +
0.0%
+
0.0 %7
core/services/ +
0.0%
+
0.0 %2
core/utils/json_converters/ +
100.0%
+
100.0 %55
data/daos/ +
44.4%44.4%
+
44.4 %19687
data/data_sources/ +
13.5%13.5%
+
13.5 %22931
data/models/ +
18.2%18.2%
+
18.2 %42878
data/repositories/ +
31.5%31.5%
+
31.5 %8928
data/tables/ +
6.5%6.5%
+
6.5 %463
domain/entities/ +
6.9%6.9%
+
6.9 %26218
domain/use-cases/ +
0.0%
+
0.0 %78
presentation/app/bloc/auth/ +
0.0%
+
0.0 %38
presentation/app/bloc/schedule/ +
4.8%4.8%
+
4.8 %1246
presentation/calendar/bloc/ +
0.0%
+
0.0 %101
presentation/early_late/bloc/ +
0.0%
+
0.0 %53
presentation/home/bloc/ +
0.0%
+
0.0 %40
presentation/my_page/preparation_spare_time_edit/bloc/ +
0.0%
+
0.0 %53
presentation/onboarding/cubit/ +
0.0%
+
0.0 %39
presentation/onboarding/preparation_name_select/input_models/ +
25.0%25.0%
+
25.0 %41
presentation/onboarding/preparation_time/input_models/ +
16.7%16.7%
+
16.7 %61
presentation/schedule_create/bloc/ +
0.0%
+
0.0 %136
presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/ +
0.0%
+
0.0 %122
presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/ +
0.0%
+
0.0 %22
presentation/shared/constants/ +
0.0%
+
0.0 %45
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/auth/auth_bloc.dart.gcov.html b/coverage/html/presentation/app/bloc/auth/auth_bloc.dart.gcov.html new file mode 100644 index 00000000..a99691cd --- /dev/null +++ b/coverage/html/presentation/app/bloc/auth/auth_bloc.dart.gcov.html @@ -0,0 +1,146 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/auth/auth_bloc.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/auth - auth_bloc.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %230
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:async';
+       2              : 
+       3              : import 'package:equatable/equatable.dart';
+       4              : import 'package:flutter_bloc/flutter_bloc.dart';
+       5              : import 'package:injectable/injectable.dart';
+       6              : import 'package:on_time_front/domain/entities/user_entity.dart';
+       7              : import 'package:on_time_front/domain/use-cases/load_user_use_case.dart';
+       8              : import 'package:on_time_front/domain/use-cases/sign_out_use_case.dart';
+       9              : import 'package:on_time_front/domain/use-cases/stream_user_use_case.dart';
+      10              : import 'package:on_time_front/presentation/app/bloc/schedule/schedule_bloc.dart';
+      11              : 
+      12              : part 'auth_event.dart';
+      13              : part 'auth_state.dart';
+      14              : 
+      15              : @Injectable()
+      16              : class AuthBloc extends Bloc<AuthEvent, AuthState> {
+      17            0 :   AuthBloc(this._streamUserUseCase, this._signOutUseCase, this._loadUserUseCase,
+      18              :       this._scheduleBloc)
+      19            0 :       : super(AuthState(user: const UserEntity.empty())) {
+      20            0 :     on<AuthUserSubscriptionRequested>(_appUserSubscriptionRequested);
+      21            0 :     on<AuthSignOutPressed>(_appLogoutPressed);
+      22              :   }
+      23              : 
+      24              :   final StreamUserUseCase _streamUserUseCase;
+      25              :   final LoadUserUseCase _loadUserUseCase;
+      26              :   final SignOutUseCase _signOutUseCase;
+      27              :   final ScheduleBloc _scheduleBloc;
+      28              :   Timer? _timer;
+      29              : 
+      30            0 :   Future<void> _appUserSubscriptionRequested(
+      31              :     AuthUserSubscriptionRequested event,
+      32              :     Emitter<AuthState> emit,
+      33              :   ) {
+      34            0 :     _loadUserUseCase();
+      35            0 :     return emit.onEach(
+      36            0 :       _streamUserUseCase.call(),
+      37            0 :       onData: (user) async {
+      38            0 :         emit(
+      39            0 :           state.copyWith(
+      40              :             user: user,
+      41            0 :             status: user.map<AuthStatus>(
+      42            0 :               (entity) => entity.isOnboardingCompleted
+      43              :                   ? AuthStatus.authenticated
+      44              :                   : AuthStatus.onboardingNotCompleted,
+      45            0 :               empty: (_) => AuthStatus.unauthenticated,
+      46              :             ),
+      47              :           ),
+      48              :         );
+      49            0 :         await Future.delayed(const Duration(milliseconds: 0));
+      50            0 :         if (state.status == AuthStatus.authenticated) {
+      51            0 :           _scheduleBloc.add(const ScheduleSubscriptionRequested());
+      52              :         }
+      53              :       },
+      54            0 :       onError: addError,
+      55              :     );
+      56              :   }
+      57              : 
+      58            0 :   void _appLogoutPressed(
+      59              :     AuthSignOutPressed event,
+      60              :     Emitter<AuthState> emit,
+      61              :   ) {
+      62            0 :     _signOutUseCase();
+      63              :   }
+      64              : 
+      65            0 :   @override
+      66              :   Future<void> close() {
+      67            0 :     _timer?.cancel();
+      68            0 :     return super.close();
+      69              :   }
+      70              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/auth/auth_event.dart.gcov.html b/coverage/html/presentation/app/bloc/auth/auth_event.dart.gcov.html new file mode 100644 index 00000000..5d8802d3 --- /dev/null +++ b/coverage/html/presentation/app/bloc/auth/auth_event.dart.gcov.html @@ -0,0 +1,89 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/auth/auth_event.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/auth - auth_event.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %30
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'auth_bloc.dart';
+       2              : 
+       3              : abstract class AuthEvent {
+       4            0 :   const AuthEvent();
+       5              : }
+       6              : 
+       7              : final class AuthUserSubscriptionRequested extends AuthEvent {
+       8            0 :   const AuthUserSubscriptionRequested();
+       9              : }
+      10              : 
+      11              : final class AuthSignOutPressed extends AuthEvent {
+      12            0 :   const AuthSignOutPressed();
+      13              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/auth/auth_state.dart.gcov.html b/coverage/html/presentation/app/bloc/auth/auth_state.dart.gcov.html new file mode 100644 index 00000000..8c40c540 --- /dev/null +++ b/coverage/html/presentation/app/bloc/auth/auth_state.dart.gcov.html @@ -0,0 +1,117 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/auth/auth_state.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/auth - auth_state.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %120
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'auth_bloc.dart';
+       2              : 
+       3              : enum AuthStatus {
+       4              :   authenticated,
+       5              :   unauthenticated,
+       6              :   onboardingNotCompleted,
+       7              : }
+       8              : 
+       9              : class AuthState extends Equatable {
+      10            0 :   AuthState({UserEntity user = const UserEntity.empty()})
+      11            0 :       : this._(
+      12            0 :           status: user.map<AuthStatus>(
+      13            0 :             (entity) => entity.isOnboardingCompleted
+      14              :                 ? AuthStatus.unauthenticated
+      15              :                 : AuthStatus.onboardingNotCompleted,
+      16            0 :             empty: (_) => AuthStatus.unauthenticated,
+      17              :           ),
+      18              :           user: user,
+      19              :         );
+      20              : 
+      21            0 :   const AuthState._({
+      22              :     required this.status,
+      23              :     this.user = const UserEntity.empty(),
+      24              :   });
+      25              : 
+      26              :   final AuthStatus status;
+      27              :   final UserEntity user;
+      28              : 
+      29            0 :   AuthState copyWith({
+      30              :     AuthStatus? status,
+      31              :     UserEntity? user,
+      32              :   }) {
+      33            0 :     return AuthState._(
+      34            0 :       status: status ?? this.status,
+      35            0 :       user: user ?? this.user,
+      36              :     );
+      37              :   }
+      38              : 
+      39            0 :   @override
+      40            0 :   List<Object> get props => [status, user];
+      41              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/auth/index-sort-f.html b/coverage/html/presentation/app/bloc/auth/index-sort-f.html new file mode 100644 index 00000000..40b88f34 --- /dev/null +++ b/coverage/html/presentation/app/bloc/auth/index-sort-f.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/auth + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/authCoverageTotalHit
Test:lcov.infoLines:0.0 %380
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
auth_bloc.dart +
0.0%
+
0.0 %23
auth_event.dart +
0.0%
+
0.0 %3
auth_state.dart +
0.0%
+
0.0 %12
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/auth/index-sort-l.html b/coverage/html/presentation/app/bloc/auth/index-sort-l.html new file mode 100644 index 00000000..4c2a0cb0 --- /dev/null +++ b/coverage/html/presentation/app/bloc/auth/index-sort-l.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/auth + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/authCoverageTotalHit
Test:lcov.infoLines:0.0 %380
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
auth_event.dart +
0.0%
+
0.0 %3
auth_state.dart +
0.0%
+
0.0 %12
auth_bloc.dart +
0.0%
+
0.0 %23
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/auth/index.html b/coverage/html/presentation/app/bloc/auth/index.html new file mode 100644 index 00000000..3a0f6eaa --- /dev/null +++ b/coverage/html/presentation/app/bloc/auth/index.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/auth + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/authCoverageTotalHit
Test:lcov.infoLines:0.0 %380
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
auth_bloc.dart +
0.0%
+
0.0 %23
auth_event.dart +
0.0%
+
0.0 %3
auth_state.dart +
0.0%
+
0.0 %12
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/schedule/index-sort-f.html b/coverage/html/presentation/app/bloc/schedule/index-sort-f.html new file mode 100644 index 00000000..0881e6d4 --- /dev/null +++ b/coverage/html/presentation/app/bloc/schedule/index-sort-f.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/schedule + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/scheduleCoverageTotalHit
Test:lcov.infoLines:4.8 %1246
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
schedule_bloc.dart +
0.0%
+
0.0 %81
schedule_event.dart +
13.6%13.6%
+
13.6 %223
schedule_state.dart +
14.3%14.3%
+
14.3 %213
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/schedule/index-sort-l.html b/coverage/html/presentation/app/bloc/schedule/index-sort-l.html new file mode 100644 index 00000000..81ad8404 --- /dev/null +++ b/coverage/html/presentation/app/bloc/schedule/index-sort-l.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/schedule + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/scheduleCoverageTotalHit
Test:lcov.infoLines:4.8 %1246
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
schedule_bloc.dart +
0.0%
+
0.0 %81
schedule_event.dart +
13.6%13.6%
+
13.6 %223
schedule_state.dart +
14.3%14.3%
+
14.3 %213
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/schedule/index.html b/coverage/html/presentation/app/bloc/schedule/index.html new file mode 100644 index 00000000..1739485f --- /dev/null +++ b/coverage/html/presentation/app/bloc/schedule/index.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/schedule + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/scheduleCoverageTotalHit
Test:lcov.infoLines:4.8 %1246
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
schedule_bloc.dart +
0.0%
+
0.0 %81
schedule_event.dart +
13.6%13.6%
+
13.6 %223
schedule_state.dart +
14.3%14.3%
+
14.3 %213
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/schedule/schedule_bloc.dart.gcov.html b/coverage/html/presentation/app/bloc/schedule/schedule_bloc.dart.gcov.html new file mode 100644 index 00000000..bdbb009a --- /dev/null +++ b/coverage/html/presentation/app/bloc/schedule/schedule_bloc.dart.gcov.html @@ -0,0 +1,242 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/schedule/schedule_bloc.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/schedule - schedule_bloc.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %810
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:async';
+       2              : 
+       3              : import 'package:equatable/equatable.dart';
+       4              : import 'package:flutter/foundation.dart';
+       5              : import 'package:flutter_bloc/flutter_bloc.dart';
+       6              : import 'package:injectable/injectable.dart';
+       7              : import 'package:on_time_front/core/services/navigation_service.dart';
+       8              : import 'package:on_time_front/domain/entities/schedule_with_preparation_entity.dart';
+       9              : import 'package:on_time_front/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart';
+      10              : import 'package:on_time_front/domain/use-cases/save_timed_preparation_use_case.dart';
+      11              : import 'package:on_time_front/domain/use-cases/finish_schedule_use_case.dart';
+      12              : 
+      13              : part 'schedule_event.dart';
+      14              : part 'schedule_state.dart';
+      15              : 
+      16              : @Singleton()
+      17              : class ScheduleBloc extends Bloc<ScheduleEvent, ScheduleState> {
+      18            0 :   ScheduleBloc(this._getNearestUpcomingScheduleUseCase, this._navigationService,
+      19              :       this._saveTimedPreparationUseCase, this._finishScheduleUseCase)
+      20            0 :       : super(const ScheduleState.initial()) {
+      21            0 :     on<ScheduleSubscriptionRequested>(_onSubscriptionRequested);
+      22            0 :     on<ScheduleUpcomingReceived>(_onUpcomingReceived);
+      23            0 :     on<ScheduleStarted>(_onScheduleStarted);
+      24            0 :     on<ScheduleTick>(_onTick);
+      25            0 :     on<ScheduleStepSkipped>(_onStepSkipped);
+      26            0 :     on<ScheduleFinished>(_onFinished);
+      27              :   }
+      28              : 
+      29              :   final GetNearestUpcomingScheduleUseCase _getNearestUpcomingScheduleUseCase;
+      30              :   final NavigationService _navigationService;
+      31              :   final SaveTimedPreparationUseCase _saveTimedPreparationUseCase;
+      32              :   final FinishScheduleUseCase _finishScheduleUseCase;
+      33              :   StreamSubscription<ScheduleWithPreparationEntity?>?
+      34              :       _upcomingScheduleSubscription;
+      35              :   Timer? _scheduleStartTimer;
+      36              :   String? _currentScheduleId;
+      37              :   Timer? _preparationTimer;
+      38              : 
+      39            0 :   Future<void> _onSubscriptionRequested(
+      40              :       ScheduleSubscriptionRequested event, Emitter<ScheduleState> emit) async {
+      41            0 :     await _upcomingScheduleSubscription?.cancel();
+      42              : 
+      43            0 :     _upcomingScheduleSubscription =
+      44            0 :         _getNearestUpcomingScheduleUseCase().listen((upcomingSchedule) {
+      45              :       // ✅ Safety check: Only add events if bloc is still active
+      46            0 :       if (!isClosed) {
+      47            0 :         add(ScheduleUpcomingReceived(upcomingSchedule));
+      48              :       }
+      49              :     });
+      50              :   }
+      51              : 
+      52            0 :   Future<void> _onUpcomingReceived(
+      53              :       ScheduleUpcomingReceived event, Emitter<ScheduleState> emit) async {
+      54              :     // Cancel any existing timer
+      55            0 :     _scheduleStartTimer?.cancel();
+      56            0 :     _scheduleStartTimer = null;
+      57              : 
+      58            0 :     if (event.upcomingSchedule == null ||
+      59            0 :         event.upcomingSchedule!.scheduleTime.isBefore(DateTime.now())) {
+      60            0 :       emit(const ScheduleState.notExists());
+      61            0 :       _currentScheduleId = null;
+      62            0 :     } else if (_isPreparationOnGoing(event.upcomingSchedule!)) {
+      63            0 :       emit(ScheduleState.ongoing(event.upcomingSchedule!));
+      64            0 :       debugPrint(
+      65            0 :           'ongoingSchedule: ${event.upcomingSchedule}, currentStep: ${event.upcomingSchedule!.preparation.currentStep}');
+      66            0 :       _startPreparationTimer();
+      67              :     } else {
+      68            0 :       emit(ScheduleState.upcoming(event.upcomingSchedule!));
+      69            0 :       debugPrint('upcomingSchedule: ${event.upcomingSchedule}');
+      70            0 :       _currentScheduleId = event.upcomingSchedule!.id;
+      71            0 :       _startScheduleTimer(event.upcomingSchedule!);
+      72              :     }
+      73              :   }
+      74              : 
+      75            0 :   Future<void> _onScheduleStarted(
+      76              :       ScheduleStarted event, Emitter<ScheduleState> emit) async {
+      77              :     // Only process if this event is for the current schedule
+      78            0 :     if (state.schedule != null && state.schedule!.id == _currentScheduleId) {
+      79              :       // Mark the schedule as started by updating the state
+      80            0 :       debugPrint('scheddle started: ${state.schedule}');
+      81            0 :       emit(ScheduleState.started(state.schedule!));
+      82            0 :       _navigationService.push('/scheduleStart');
+      83            0 :       _startPreparationTimer();
+      84              :     }
+      85              :   }
+      86              : 
+      87            0 :   Future<void> _onTick(ScheduleTick event, Emitter<ScheduleState> emit) async {
+      88            0 :     if (state.schedule == null) return;
+      89              :     final updatedPreparation =
+      90            0 :         state.schedule!.preparation.timeElapsed(event.elapsed);
+      91            0 :     debugPrint('elapsedTime: ${updatedPreparation.elapsedTime}');
+      92              : 
+      93              :     final newSchedule =
+      94            0 :         ScheduleWithPreparationEntity.fromScheduleAndPreparationEntity(
+      95            0 :             state.schedule!, updatedPreparation);
+      96              : 
+      97            0 :     emit(state.copyWith(schedule: newSchedule));
+      98              :   }
+      99              : 
+     100            0 :   Future<void> _onStepSkipped(
+     101              :       ScheduleStepSkipped event, Emitter<ScheduleState> emit) async {
+     102            0 :     if (state.schedule == null) return;
+     103            0 :     final updated = state.schedule!.preparation.skipCurrentStep();
+     104            0 :     emit(state.copyWith(
+     105              :         schedule:
+     106            0 :             ScheduleWithPreparationEntity.fromScheduleAndPreparationEntity(
+     107            0 :                 state.schedule!, updated)));
+     108            0 :     await _saveTimedPreparationUseCase(state.schedule!.id, updated);
+     109              :   }
+     110              : 
+     111            0 :   Future<void> _onFinished(
+     112              :       ScheduleFinished event, Emitter<ScheduleState> emit) async {
+     113            0 :     if (state.schedule == null) return;
+     114            0 :     final scheduleId = state.schedule!.id;
+     115              :     try {
+     116            0 :       await _finishScheduleUseCase(scheduleId, event.latenessTime);
+     117              :       // After finishing, clear timers and set state to notExists
+     118            0 :       _preparationTimer?.cancel();
+     119            0 :       _scheduleStartTimer?.cancel();
+     120            0 :       emit(const ScheduleState.notExists());
+     121              :     } catch (_) {
+     122            0 :       debugPrint('error finishing schedule: $_');
+     123              :     }
+     124              :   }
+     125              : 
+     126            0 :   void _startScheduleTimer(ScheduleWithPreparationEntity schedule) {
+     127            0 :     final duration = state.durationUntilPreparationStart;
+     128              :     if (duration == null) return;
+     129            0 :     _scheduleStartTimer = Timer(duration, () {
+     130              :       // Only add event if bloc is still active and schedule ID matches
+     131            0 :       if (!isClosed && _currentScheduleId == schedule.id) {
+     132            0 :         add(const ScheduleStarted());
+     133              :       }
+     134              :     });
+     135              :   }
+     136              : 
+     137            0 :   void _startPreparationTimer() {
+     138            0 :     if (state.schedule == null) return;
+     139            0 :     _preparationTimer?.cancel();
+     140              :     final elapsedTimeAfterLastTick =
+     141            0 :         DateTime.now().difference(state.schedule!.preparationStartTime) -
+     142            0 :             state.schedule!.preparation.elapsedTime;
+     143            0 :     debugPrint('elapsedTimeAfterLastTick: $elapsedTimeAfterLastTick');
+     144            0 :     add(ScheduleTick(elapsedTimeAfterLastTick));
+     145            0 :     _preparationTimer = Timer.periodic(Duration(seconds: 1), (_) {
+     146            0 :       if (!isClosed) add(ScheduleTick(Duration(seconds: 1)));
+     147              :     });
+     148              :   }
+     149              : 
+     150            0 :   @override
+     151              :   Future<void> close() {
+     152              :     // ✅ Proper cleanup: Cancel subscription and timer before closing
+     153            0 :     _upcomingScheduleSubscription?.cancel();
+     154            0 :     _scheduleStartTimer?.cancel();
+     155            0 :     _preparationTimer?.cancel();
+     156            0 :     return super.close();
+     157              :   }
+     158              : 
+     159            0 :   bool _isPreparationOnGoing(ScheduleWithPreparationEntity schedule) {
+     160            0 :     final start = schedule.preparationStartTime;
+     161            0 :     return start.isBefore(DateTime.now()) &&
+     162            0 :         schedule.scheduleTime.isAfter(DateTime.now());
+     163              :   }
+     164              : 
+     165              :   // Removed unused helper since we now split in the event
+     166              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/schedule/schedule_event.dart.gcov.html b/coverage/html/presentation/app/bloc/schedule/schedule_event.dart.gcov.html new file mode 100644 index 00000000..05a24a23 --- /dev/null +++ b/coverage/html/presentation/app/bloc/schedule/schedule_event.dart.gcov.html @@ -0,0 +1,138 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/schedule/schedule_event.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/schedule - schedule_event.dartCoverageTotalHit
Test:lcov.infoLines:13.6 %223
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'schedule_bloc.dart';
+       2              : 
+       3              : class ScheduleEvent extends Equatable {
+       4            8 :   const ScheduleEvent();
+       5              : 
+       6            0 :   @override
+       7            0 :   List<Object?> get props => [];
+       8              : }
+       9              : 
+      10              : final class ScheduleSubscriptionRequested extends ScheduleEvent {
+      11            4 :   const ScheduleSubscriptionRequested();
+      12              : 
+      13            0 :   @override
+      14            0 :   List<Object?> get props => [];
+      15              : }
+      16              : 
+      17              : final class ScheduleUpcomingReceived extends ScheduleEvent {
+      18              :   final ScheduleWithPreparationEntity? upcomingSchedule;
+      19              : 
+      20            0 :   const ScheduleUpcomingReceived(
+      21              :       ScheduleWithPreparationEntity? upcomingScheduleWithPreparation)
+      22              :       : upcomingSchedule = upcomingScheduleWithPreparation;
+      23              : 
+      24            0 :   @override
+      25            0 :   List<Object?> get props => [upcomingSchedule];
+      26              : }
+      27              : 
+      28              : final class ScheduleStarted extends ScheduleEvent {
+      29            4 :   const ScheduleStarted();
+      30              : 
+      31            0 :   @override
+      32            0 :   List<Object?> get props => [];
+      33              : }
+      34              : 
+      35              : final class SchedulePreparationStarted extends ScheduleEvent {
+      36            0 :   const SchedulePreparationStarted();
+      37              : 
+      38            0 :   @override
+      39            0 :   List<Object?> get props => [];
+      40              : }
+      41              : 
+      42              : final class ScheduleTick extends ScheduleEvent {
+      43              :   final Duration elapsed;
+      44              : 
+      45            0 :   const ScheduleTick(this.elapsed);
+      46              : 
+      47            0 :   @override
+      48            0 :   List<Object?> get props => [elapsed];
+      49              : }
+      50              : 
+      51              : final class ScheduleStepSkipped extends ScheduleEvent {
+      52            0 :   const ScheduleStepSkipped();
+      53              : }
+      54              : 
+      55              : final class ScheduleFinished extends ScheduleEvent {
+      56              :   final int latenessTime;
+      57              : 
+      58            0 :   const ScheduleFinished(this.latenessTime);
+      59              : 
+      60            0 :   @override
+      61            0 :   List<Object?> get props => [latenessTime];
+      62              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/app/bloc/schedule/schedule_state.dart.gcov.html b/coverage/html/presentation/app/bloc/schedule/schedule_state.dart.gcov.html new file mode 100644 index 00000000..933a6fd8 --- /dev/null +++ b/coverage/html/presentation/app/bloc/schedule/schedule_state.dart.gcov.html @@ -0,0 +1,129 @@ + + + + + + + LCOV - lcov.info - presentation/app/bloc/schedule/schedule_state.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/app/bloc/schedule - schedule_state.dartCoverageTotalHit
Test:lcov.infoLines:14.3 %213
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'schedule_bloc.dart';
+       2              : 
+       3              : enum ScheduleStatus {
+       4              :   initial,
+       5              :   notExists,
+       6              :   upcoming,
+       7              :   ongoing,
+       8              :   started,
+       9              : }
+      10              : 
+      11              : class ScheduleState extends Equatable {
+      12            4 :   const ScheduleState._({
+      13              :     required this.status,
+      14              :     this.schedule,
+      15              :   });
+      16              : 
+      17            4 :   const ScheduleState.initial() : this._(status: ScheduleStatus.initial);
+      18              : 
+      19            4 :   const ScheduleState.notExists() : this._(status: ScheduleStatus.notExists);
+      20              : 
+      21            0 :   const ScheduleState.upcoming(ScheduleWithPreparationEntity schedule)
+      22            0 :       : this._(status: ScheduleStatus.upcoming, schedule: schedule);
+      23              : 
+      24            0 :   const ScheduleState.ongoing(ScheduleWithPreparationEntity schedule)
+      25            0 :       : this._(status: ScheduleStatus.ongoing, schedule: schedule);
+      26              : 
+      27            0 :   const ScheduleState.started(ScheduleWithPreparationEntity schedule)
+      28            0 :       : this._(status: ScheduleStatus.started, schedule: schedule);
+      29              : 
+      30              :   final ScheduleStatus status;
+      31              :   final ScheduleWithPreparationEntity? schedule;
+      32              : 
+      33            0 :   ScheduleState copyWith({
+      34              :     ScheduleStatus? status,
+      35              :     ScheduleWithPreparationEntity? schedule,
+      36              :   }) {
+      37            0 :     return ScheduleState._(
+      38            0 :       status: status ?? this.status,
+      39            0 :       schedule: schedule ?? this.schedule,
+      40              :     );
+      41              :   }
+      42              : 
+      43            0 :   Duration? get durationUntilPreparationStart {
+      44            0 :     if (schedule == null) return null;
+      45            0 :     final now = DateTime.now();
+      46            0 :     final target = schedule!.preparationStartTime;
+      47            0 :     if (target.isBefore(now) || target.isAtSameMomentAs(now)) return null;
+      48            0 :     return target.difference(now);
+      49              :   }
+      50              : 
+      51            0 :   @override
+      52            0 :   List<Object?> get props => [status, schedule, schedule?.preparation];
+      53              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/calendar/bloc/index-sort-f.html b/coverage/html/presentation/calendar/bloc/index-sort-f.html new file mode 100644 index 00000000..3d4d665c --- /dev/null +++ b/coverage/html/presentation/calendar/bloc/index-sort-f.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/calendar/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/calendar/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %1010
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
monthly_schedules_bloc.dart +
0.0%
+
0.0 %74
monthly_schedules_event.dart +
0.0%
+
0.0 %16
monthly_schedules_state.dart +
0.0%
+
0.0 %11
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/calendar/bloc/index-sort-l.html b/coverage/html/presentation/calendar/bloc/index-sort-l.html new file mode 100644 index 00000000..fa9f758a --- /dev/null +++ b/coverage/html/presentation/calendar/bloc/index-sort-l.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/calendar/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/calendar/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %1010
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
monthly_schedules_state.dart +
0.0%
+
0.0 %11
monthly_schedules_event.dart +
0.0%
+
0.0 %16
monthly_schedules_bloc.dart +
0.0%
+
0.0 %74
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/calendar/bloc/index.html b/coverage/html/presentation/calendar/bloc/index.html new file mode 100644 index 00000000..c4874847 --- /dev/null +++ b/coverage/html/presentation/calendar/bloc/index.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/calendar/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/calendar/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %1010
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
monthly_schedules_bloc.dart +
0.0%
+
0.0 %74
monthly_schedules_event.dart +
0.0%
+
0.0 %16
monthly_schedules_state.dart +
0.0%
+
0.0 %11
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/calendar/bloc/monthly_schedules_bloc.dart.gcov.html b/coverage/html/presentation/calendar/bloc/monthly_schedules_bloc.dart.gcov.html new file mode 100644 index 00000000..1e2fcba0 --- /dev/null +++ b/coverage/html/presentation/calendar/bloc/monthly_schedules_bloc.dart.gcov.html @@ -0,0 +1,230 @@ + + + + + + + LCOV - lcov.info - presentation/calendar/bloc/monthly_schedules_bloc.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/calendar/bloc - monthly_schedules_bloc.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %740
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:equatable/equatable.dart';
+       2              : import 'package:flutter/material.dart';
+       3              : import 'package:flutter_bloc/flutter_bloc.dart';
+       4              : import 'package:injectable/injectable.dart';
+       5              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       6              : import 'package:on_time_front/domain/use-cases/delete_schedule_use_case.dart';
+       7              : import 'package:on_time_front/domain/use-cases/get_schedules_by_date_use_case.dart';
+       8              : import 'package:on_time_front/domain/use-cases/load_schedules_for_month_use_case.dart';
+       9              : 
+      10              : part 'monthly_schedules_event.dart';
+      11              : part 'monthly_schedules_state.dart';
+      12              : 
+      13              : @Injectable()
+      14              : class MonthlySchedulesBloc
+      15              :     extends Bloc<MonthlySchedulesEvent, MonthlySchedulesState> {
+      16            0 :   MonthlySchedulesBloc(
+      17              :     this._loadSchedulesForMonthUseCase,
+      18              :     this._getSchedulesByDateUseCase,
+      19              :     this._deleteScheduleUseCase,
+      20            0 :   ) : super(MonthlySchedulesState()) {
+      21            0 :     on<MonthlySchedulesSubscriptionRequested>(_onSubscriptionRequested);
+      22            0 :     on<MonthlySchedulesMonthAdded>(_onMonthAdded);
+      23            0 :     on<MonthlySchedulesScheduleDeleted>(_onScheduleDeleted);
+      24              :   }
+      25              : 
+      26              :   final LoadSchedulesForMonthUseCase _loadSchedulesForMonthUseCase;
+      27              :   final GetSchedulesByDateUseCase _getSchedulesByDateUseCase;
+      28              :   final DeleteScheduleUseCase _deleteScheduleUseCase;
+      29              : 
+      30            0 :   Future<void> _onSubscriptionRequested(
+      31              :     MonthlySchedulesSubscriptionRequested event,
+      32              :     Emitter<MonthlySchedulesState> emit,
+      33              :   ) async {
+      34            0 :     emit(state.copyWith(status: () => MonthlySchedulesStatus.loading));
+      35              : 
+      36            0 :     await _loadSchedulesForMonthUseCase(event.date);
+      37              : 
+      38            0 :     await emit.forEach(
+      39            0 :       _getSchedulesByDateUseCase(event.startDate, event.endDate),
+      40            0 :       onData: (schedules) => state.copyWith(
+      41            0 :         status: () => MonthlySchedulesStatus.success,
+      42            0 :         schedules: () => schedules.fold<Map<DateTime, List<ScheduleEntity>>>(
+      43            0 :           {},
+      44            0 :           (previousValue, element) {
+      45            0 :             final scheduleTime = DateTime(
+      46            0 :               element.scheduleTime.year,
+      47            0 :               element.scheduleTime.month,
+      48            0 :               element.scheduleTime.day,
+      49              :             );
+      50            0 :             if (previousValue.containsKey(scheduleTime)) {
+      51            0 :               previousValue[scheduleTime]!.add(element);
+      52              :             } else {
+      53            0 :               previousValue[scheduleTime] = [element];
+      54              :             }
+      55              :             return previousValue;
+      56              :           },
+      57              :         ),
+      58            0 :         startDate: () => event.startDate,
+      59            0 :         endDate: () => event.endDate,
+      60              :       ),
+      61            0 :       onError: (error, stackTrace) => state.copyWith(
+      62            0 :         status: () => MonthlySchedulesStatus.error,
+      63              :       ),
+      64              :     );
+      65              :   }
+      66              : 
+      67            0 :   Future<void> _onMonthAdded(
+      68              :     MonthlySchedulesMonthAdded event,
+      69              :     Emitter<MonthlySchedulesState> emit,
+      70              :   ) async {
+      71              :     late DateTime startDate;
+      72              :     late DateTime endDate;
+      73            0 :     if (!(state.startDate!.isAfter(event.startDate) ||
+      74            0 :         state.endDate!.isBefore(event.endDate))) {
+      75              :       // If the month is already loaded, we don't need to load the schedules again.
+      76            0 :       startDate = state.startDate!;
+      77            0 :       endDate = state.endDate!;
+      78            0 :     } else if (event.date.month !=
+      79            0 :             state.startDate!.subtract(Duration(days: 1)).month &&
+      80            0 :         (event.date.month != state.endDate!.month)) {
+      81              :       // If the month is not consecutive, we need to load the schedules for the
+      82            0 :       add(MonthlySchedulesSubscriptionRequested(date: event.date));
+      83              :       return;
+      84              :     } else {
+      85              :       // If the month is not consecutive, we need to load the schedules for the
+      86              :       // month and update the state with the new schedules.
+      87              : 
+      88            0 :       startDate = event.startDate.isBefore(state.startDate!)
+      89            0 :           ? event.startDate
+      90            0 :           : state.startDate!;
+      91            0 :       endDate = event.endDate.isAfter(state.endDate!)
+      92            0 :           ? event.endDate
+      93            0 :           : state.endDate!;
+      94              : 
+      95            0 :       emit(state.copyWith(
+      96            0 :         status: () => MonthlySchedulesStatus.loading,
+      97            0 :         schedules: () => state.schedules,
+      98            0 :         startDate: () => startDate,
+      99            0 :         endDate: () => endDate,
+     100              :       ));
+     101              : 
+     102            0 :       await _loadSchedulesForMonthUseCase(event.date);
+     103              :     }
+     104              : 
+     105            0 :     debugPrint('startDate: $startDate, endDate: $endDate');
+     106            0 :     await emit.forEach(
+     107            0 :       _getSchedulesByDateUseCase(startDate, endDate),
+     108            0 :       onData: (schedules) {
+     109            0 :         return state.copyWith(
+     110            0 :           status: () => MonthlySchedulesStatus.success,
+     111            0 :           schedules: () => schedules.fold<Map<DateTime, List<ScheduleEntity>>>(
+     112            0 :             {},
+     113            0 :             (previousValue, element) {
+     114            0 :               final scheduleTime = DateTime(
+     115            0 :                 element.scheduleTime.year,
+     116            0 :                 element.scheduleTime.month,
+     117            0 :                 element.scheduleTime.day,
+     118              :               );
+     119            0 :               if (previousValue.containsKey(scheduleTime)) {
+     120            0 :                 previousValue[scheduleTime]!.add(element);
+     121              :               } else {
+     122            0 :                 previousValue[scheduleTime] = [element];
+     123              :               }
+     124              :               return previousValue;
+     125              :             },
+     126              :           ),
+     127            0 :           startDate: () => startDate,
+     128            0 :           endDate: () => endDate,
+     129              :         );
+     130              :       },
+     131            0 :       onError: (error, stackTrace) {
+     132            0 :         return state.copyWith(
+     133            0 :           status: () => MonthlySchedulesStatus.error,
+     134              :         );
+     135              :       },
+     136              :     );
+     137              :   }
+     138              : 
+     139            0 :   Future<void> _onScheduleDeleted(
+     140              :     MonthlySchedulesScheduleDeleted event,
+     141              :     Emitter<MonthlySchedulesState> emit,
+     142              :   ) async {
+     143              :     try {
+     144            0 :       emit(state.copyWith(
+     145            0 :         lastDeletedSchedule: () => event.schedule,
+     146              :       ));
+     147            0 :       await _deleteScheduleUseCase(event.schedule);
+     148              :     } catch (e) {
+     149            0 :       emit(state.copyWith(
+     150            0 :         status: () => MonthlySchedulesStatus.error,
+     151              :       ));
+     152              :     }
+     153              :   }
+     154              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/calendar/bloc/monthly_schedules_event.dart.gcov.html b/coverage/html/presentation/calendar/bloc/monthly_schedules_event.dart.gcov.html new file mode 100644 index 00000000..03783fc7 --- /dev/null +++ b/coverage/html/presentation/calendar/bloc/monthly_schedules_event.dart.gcov.html @@ -0,0 +1,118 @@ + + + + + + + LCOV - lcov.info - presentation/calendar/bloc/monthly_schedules_event.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/calendar/bloc - monthly_schedules_event.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %160
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'monthly_schedules_bloc.dart';
+       2              : 
+       3              : sealed class MonthlySchedulesEvent extends Equatable {
+       4            0 :   const MonthlySchedulesEvent();
+       5              : 
+       6            0 :   @override
+       7            0 :   List<Object> get props => [];
+       8              : }
+       9              : 
+      10              : final class MonthlySchedulesSubscriptionRequested
+      11              :     extends MonthlySchedulesEvent {
+      12              :   final DateTime date;
+      13              : 
+      14            0 :   const MonthlySchedulesSubscriptionRequested({required this.date});
+      15              : 
+      16            0 :   DateTime get startDate => DateTime(date.year, date.month, 1);
+      17            0 :   DateTime get endDate => DateTime(date.year, date.month + 1, 1);
+      18              : 
+      19            0 :   @override
+      20            0 :   List<Object> get props => [startDate, endDate];
+      21              : }
+      22              : 
+      23              : final class MonthlySchedulesMonthAdded extends MonthlySchedulesEvent {
+      24              :   final DateTime date;
+      25              : 
+      26            0 :   const MonthlySchedulesMonthAdded({required this.date});
+      27              : 
+      28            0 :   DateTime get startDate => DateTime(date.year, date.month, 1);
+      29            0 :   DateTime get endDate => DateTime(date.year, date.month + 1, 1);
+      30              : 
+      31            0 :   @override
+      32            0 :   List<Object> get props => [date];
+      33              : }
+      34              : 
+      35              : final class MonthlySchedulesScheduleDeleted extends MonthlySchedulesEvent {
+      36              :   final ScheduleEntity schedule;
+      37              : 
+      38            0 :   const MonthlySchedulesScheduleDeleted({required this.schedule});
+      39              : 
+      40            0 :   @override
+      41            0 :   List<Object> get props => [schedule];
+      42              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/calendar/bloc/monthly_schedules_state.dart.gcov.html b/coverage/html/presentation/calendar/bloc/monthly_schedules_state.dart.gcov.html new file mode 100644 index 00000000..f6ea7efe --- /dev/null +++ b/coverage/html/presentation/calendar/bloc/monthly_schedules_state.dart.gcov.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/calendar/bloc/monthly_schedules_state.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/calendar/bloc - monthly_schedules_state.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %110
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'monthly_schedules_bloc.dart';
+       2              : 
+       3              : enum MonthlySchedulesStatus { initial, loading, success, error }
+       4              : 
+       5              : final class MonthlySchedulesState extends Equatable {
+       6            0 :   const MonthlySchedulesState(
+       7              :       {this.status = MonthlySchedulesStatus.initial,
+       8              :       this.schedules = const {},
+       9              :       this.lastDeletedSchedule,
+      10              :       this.startDate,
+      11              :       this.endDate});
+      12              : 
+      13              :   final MonthlySchedulesStatus status;
+      14              :   final Map<DateTime, List<ScheduleEntity>> schedules;
+      15              :   final ScheduleEntity? lastDeletedSchedule;
+      16              :   final DateTime? startDate;
+      17              :   final DateTime? endDate;
+      18              : 
+      19            0 :   MonthlySchedulesState copyWith({
+      20              :     MonthlySchedulesStatus Function()? status,
+      21              :     Map<DateTime, List<ScheduleEntity>> Function()? schedules,
+      22              :     ScheduleEntity? Function()? lastDeletedSchedule,
+      23              :     DateTime? Function()? startDate,
+      24              :     DateTime? Function()? endDate,
+      25              :   }) {
+      26            0 :     return MonthlySchedulesState(
+      27            0 :       status: status != null ? status() : this.status,
+      28            0 :       schedules: schedules != null ? schedules() : this.schedules,
+      29              :       lastDeletedSchedule: lastDeletedSchedule != null
+      30            0 :           ? lastDeletedSchedule()
+      31            0 :           : this.lastDeletedSchedule,
+      32            0 :       startDate: startDate != null ? startDate() : this.startDate,
+      33            0 :       endDate: endDate != null ? endDate() : this.endDate,
+      34              :     );
+      35              :   }
+      36              : 
+      37            0 :   @override
+      38              :   List<Object?> get props =>
+      39            0 :       [status, schedules, lastDeletedSchedule, startDate, endDate];
+      40              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/early_late/bloc/early_late_screen_bloc.dart.gcov.html b/coverage/html/presentation/early_late/bloc/early_late_screen_bloc.dart.gcov.html new file mode 100644 index 00000000..ae40da5b --- /dev/null +++ b/coverage/html/presentation/early_late/bloc/early_late_screen_bloc.dart.gcov.html @@ -0,0 +1,140 @@ + + + + + + + LCOV - lcov.info - presentation/early_late/bloc/early_late_screen_bloc.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/early_late/bloc - early_late_screen_bloc.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %310
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:flutter_bloc/flutter_bloc.dart';
+       2              : import 'package:equatable/equatable.dart';
+       3              : import 'package:injectable/injectable.dart';
+       4              : import 'package:on_time_front/presentation/shared/constants/early_late_text_images.dart';
+       5              : 
+       6              : part 'early_late_screen_event.dart';
+       7              : part 'early_late_screen_state.dart';
+       8              : 
+       9              : @injectable
+      10              : class EarlyLateScreenBloc
+      11              :     extends Bloc<EarlyLateScreenEvent, EarlyLateScreenState> {
+      12            0 :   EarlyLateScreenBloc() : super(EarlyLateScreenInitial()) {
+      13            0 :     on<LoadEarlyLateInfo>(_onLoadEarlyLateInfo);
+      14            0 :     on<ChecklistLoaded>(_onLoadChecklist);
+      15            0 :     on<ChecklistItemToggled>(_onToggleChecklistItem);
+      16              :   }
+      17              : 
+      18            0 :   void _onLoadEarlyLateInfo(
+      19              :       LoadEarlyLateInfo event, Emitter<EarlyLateScreenState> emit) {
+      20            0 :     bool isLate = event.earlyLateTime < 0;
+      21            0 :     int absSeconds = event.earlyLateTime.abs();
+      22            0 :     int minuteValue = (absSeconds / 60).ceil();
+      23              : 
+      24              :     Map<String, String> messageData = isLate
+      25            0 :         ? getLateMessage() // { "message": "문구", "image": "파일명" }
+      26            0 :         : getEarlyMessage(minuteValue); // { "message": "문구", "image": "파일명" }
+      27              : 
+      28            0 :     emit(EarlyLateScreenLoadSuccess(
+      29            0 :       checklist: List.generate(3, (index) => false),
+      30              :       isLate: isLate,
+      31            0 :       earlylateMessage: messageData['message']!,
+      32            0 :       earlylateImage: messageData['image']!,
+      33              :     ));
+      34              :   }
+      35              : 
+      36            0 :   void _onLoadChecklist(
+      37              :       ChecklistLoaded event, Emitter<EarlyLateScreenState> emit) {
+      38            0 :     if (state is EarlyLateScreenLoadSuccess) {
+      39            0 :       final currentState = state as EarlyLateScreenLoadSuccess;
+      40            0 :       emit(EarlyLateScreenLoadSuccess(
+      41            0 :         checklist: event.checklist,
+      42            0 :         isLate: currentState.isLate,
+      43            0 :         earlylateMessage: currentState.earlylateMessage,
+      44            0 :         earlylateImage: currentState.earlylateImage,
+      45              :       ));
+      46              :     }
+      47              :   }
+      48              : 
+      49            0 :   void _onToggleChecklistItem(
+      50              :       ChecklistItemToggled event, Emitter<EarlyLateScreenState> emit) {
+      51            0 :     if (state is EarlyLateScreenLoadSuccess) {
+      52            0 :       final currentState = state as EarlyLateScreenLoadSuccess;
+      53            0 :       final updatedChecklist = List<bool>.from(currentState.checklist);
+      54            0 :       updatedChecklist[event.index] = !updatedChecklist[event.index];
+      55              : 
+      56            0 :       emit(EarlyLateScreenLoadSuccess(
+      57              :         checklist: updatedChecklist,
+      58            0 :         isLate: currentState.isLate,
+      59            0 :         earlylateMessage: currentState.earlylateMessage,
+      60            0 :         earlylateImage: currentState.earlylateImage,
+      61              :       ));
+      62              :     }
+      63              :   }
+      64              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/early_late/bloc/early_late_screen_event.dart.gcov.html b/coverage/html/presentation/early_late/bloc/early_late_screen_event.dart.gcov.html new file mode 100644 index 00000000..ffa1be86 --- /dev/null +++ b/coverage/html/presentation/early_late/bloc/early_late_screen_event.dart.gcov.html @@ -0,0 +1,111 @@ + + + + + + + LCOV - lcov.info - presentation/early_late/bloc/early_late_screen_event.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/early_late/bloc - early_late_screen_event.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %120
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'early_late_screen_bloc.dart';
+       2              : 
+       3              : abstract class EarlyLateScreenEvent extends Equatable {
+       4            0 :   const EarlyLateScreenEvent();
+       5              : 
+       6            0 :   @override
+       7            0 :   List<Object> get props => [];
+       8              : }
+       9              : 
+      10              : class LoadEarlyLateInfo extends EarlyLateScreenEvent {
+      11              :   final int earlyLateTime;
+      12              : 
+      13            0 :   const LoadEarlyLateInfo({required this.earlyLateTime});
+      14              : 
+      15            0 :   @override
+      16            0 :   List<Object> get props => [earlyLateTime];
+      17              : }
+      18              : 
+      19              : class ChecklistLoaded extends EarlyLateScreenEvent {
+      20              :   final List<bool> checklist;
+      21              : 
+      22            0 :   const ChecklistLoaded({required this.checklist});
+      23              : 
+      24            0 :   @override
+      25            0 :   List<Object> get props => [checklist];
+      26              : }
+      27              : 
+      28              : class ChecklistItemToggled extends EarlyLateScreenEvent {
+      29              :   final int index;
+      30              : 
+      31            0 :   const ChecklistItemToggled(this.index);
+      32              : 
+      33            0 :   @override
+      34            0 :   List<Object> get props => [index];
+      35              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/early_late/bloc/early_late_screen_state.dart.gcov.html b/coverage/html/presentation/early_late/bloc/early_late_screen_state.dart.gcov.html new file mode 100644 index 00000000..cb91c3c3 --- /dev/null +++ b/coverage/html/presentation/early_late/bloc/early_late_screen_state.dart.gcov.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - lcov.info - presentation/early_late/bloc/early_late_screen_state.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/early_late/bloc - early_late_screen_state.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %100
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'early_late_screen_bloc.dart';
+       2              : 
+       3              : sealed class EarlyLateScreenState extends Equatable {
+       4            0 :   const EarlyLateScreenState();
+       5              : 
+       6            0 :   @override
+       7            0 :   List<Object> get props => [];
+       8              : }
+       9              : 
+      10              : class EarlyLateScreenInitial extends EarlyLateScreenState {}
+      11              : 
+      12              : class EarlyLateScreenLoadSuccess extends EarlyLateScreenState {
+      13              :   final List<bool> checklist;
+      14              :   final bool isLate;
+      15              :   final String earlylateMessage;
+      16              :   final String earlylateImage;
+      17              : 
+      18            0 :   const EarlyLateScreenLoadSuccess({
+      19              :     required this.checklist,
+      20              :     required this.isLate,
+      21              :     required this.earlylateMessage,
+      22              :     required this.earlylateImage,
+      23              :   });
+      24              : 
+      25            0 :   @override
+      26            0 :   List<Object> get props => [
+      27            0 :         checklist,
+      28            0 :         isLate,
+      29            0 :         earlylateMessage,
+      30            0 :         earlylateImage,
+      31              :       ];
+      32              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/early_late/bloc/index-sort-f.html b/coverage/html/presentation/early_late/bloc/index-sort-f.html new file mode 100644 index 00000000..ce1e0202 --- /dev/null +++ b/coverage/html/presentation/early_late/bloc/index-sort-f.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/early_late/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/early_late/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %530
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
early_late_screen_bloc.dart +
0.0%
+
0.0 %31
early_late_screen_event.dart +
0.0%
+
0.0 %12
early_late_screen_state.dart +
0.0%
+
0.0 %10
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/early_late/bloc/index-sort-l.html b/coverage/html/presentation/early_late/bloc/index-sort-l.html new file mode 100644 index 00000000..6210202f --- /dev/null +++ b/coverage/html/presentation/early_late/bloc/index-sort-l.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/early_late/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/early_late/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %530
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
early_late_screen_state.dart +
0.0%
+
0.0 %10
early_late_screen_event.dart +
0.0%
+
0.0 %12
early_late_screen_bloc.dart +
0.0%
+
0.0 %31
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/early_late/bloc/index.html b/coverage/html/presentation/early_late/bloc/index.html new file mode 100644 index 00000000..65b9334e --- /dev/null +++ b/coverage/html/presentation/early_late/bloc/index.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/early_late/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/early_late/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %530
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
early_late_screen_bloc.dart +
0.0%
+
0.0 %31
early_late_screen_event.dart +
0.0%
+
0.0 %12
early_late_screen_state.dart +
0.0%
+
0.0 %10
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/home/bloc/index-sort-f.html b/coverage/html/presentation/home/bloc/index-sort-f.html new file mode 100644 index 00000000..7d27e7b6 --- /dev/null +++ b/coverage/html/presentation/home/bloc/index-sort-f.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/home/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/home/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %400
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
weekly_schedules_bloc.dart +
0.0%
+
0.0 %13
weekly_schedules_event.dart +
0.0%
+
0.0 %8
weekly_schedules_state.dart +
0.0%
+
0.0 %19
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/home/bloc/index-sort-l.html b/coverage/html/presentation/home/bloc/index-sort-l.html new file mode 100644 index 00000000..3e3f521a --- /dev/null +++ b/coverage/html/presentation/home/bloc/index-sort-l.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/home/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/home/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %400
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
weekly_schedules_event.dart +
0.0%
+
0.0 %8
weekly_schedules_bloc.dart +
0.0%
+
0.0 %13
weekly_schedules_state.dart +
0.0%
+
0.0 %19
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/home/bloc/index.html b/coverage/html/presentation/home/bloc/index.html new file mode 100644 index 00000000..4ba5e50d --- /dev/null +++ b/coverage/html/presentation/home/bloc/index.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/home/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/home/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %400
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
weekly_schedules_bloc.dart +
0.0%
+
0.0 %13
weekly_schedules_event.dart +
0.0%
+
0.0 %8
weekly_schedules_state.dart +
0.0%
+
0.0 %19
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/home/bloc/weekly_schedules_bloc.dart.gcov.html b/coverage/html/presentation/home/bloc/weekly_schedules_bloc.dart.gcov.html new file mode 100644 index 00000000..a709ed4f --- /dev/null +++ b/coverage/html/presentation/home/bloc/weekly_schedules_bloc.dart.gcov.html @@ -0,0 +1,117 @@ + + + + + + + LCOV - lcov.info - presentation/home/bloc/weekly_schedules_bloc.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/home/bloc - weekly_schedules_bloc.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %130
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:collection/collection.dart';
+       2              : import 'package:equatable/equatable.dart';
+       3              : import 'package:flutter_bloc/flutter_bloc.dart';
+       4              : import 'package:injectable/injectable.dart';
+       5              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       6              : import 'package:on_time_front/domain/use-cases/get_schedules_by_date_use_case.dart';
+       7              : import 'package:on_time_front/domain/use-cases/load_schedules_for_week_use_case.dart';
+       8              : 
+       9              : part 'weekly_schedules_event.dart';
+      10              : part 'weekly_schedules_state.dart';
+      11              : 
+      12              : @Injectable()
+      13              : class WeeklySchedulesBloc
+      14              :     extends Bloc<WeeklySchedulesEvent, WeeklySchedulesState> {
+      15            0 :   WeeklySchedulesBloc(
+      16              :     this._loadSchedulesForWeekUseCase,
+      17              :     this._getSchedulesByDateUseCase,
+      18            0 :   ) : super(WeeklySchedulesState()) {
+      19            0 :     on<WeeklySchedulesSubscriptionRequested>(
+      20            0 :       (event, emit) async {
+      21            0 :         emit(state.copyWith(status: () => WeeklySchedulesStatus.loading));
+      22              : 
+      23            0 :         await _loadSchedulesForWeekUseCase(event.date);
+      24              : 
+      25            0 :         await emit.forEach(
+      26            0 :           _getSchedulesByDateUseCase(event.startDate, event.endDate),
+      27            0 :           onData: (schedules) => state.copyWith(
+      28            0 :             status: () => WeeklySchedulesStatus.success,
+      29            0 :             schedules: () => schedules,
+      30              :           ),
+      31            0 :           onError: (error, stackTrace) => state.copyWith(
+      32            0 :             status: () => WeeklySchedulesStatus.error,
+      33              :           ),
+      34              :         );
+      35              :       },
+      36              :     );
+      37              :   }
+      38              : 
+      39              :   final LoadSchedulesForWeekUseCase _loadSchedulesForWeekUseCase;
+      40              :   final GetSchedulesByDateUseCase _getSchedulesByDateUseCase;
+      41              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/home/bloc/weekly_schedules_event.dart.gcov.html b/coverage/html/presentation/home/bloc/weekly_schedules_event.dart.gcov.html new file mode 100644 index 00000000..76a1931b --- /dev/null +++ b/coverage/html/presentation/home/bloc/weekly_schedules_event.dart.gcov.html @@ -0,0 +1,96 @@ + + + + + + + LCOV - lcov.info - presentation/home/bloc/weekly_schedules_event.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/home/bloc - weekly_schedules_event.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %80
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'weekly_schedules_bloc.dart';
+       2              : 
+       3              : sealed class WeeklySchedulesEvent extends Equatable {
+       4            0 :   const WeeklySchedulesEvent();
+       5              : 
+       6            0 :   @override
+       7            0 :   List<Object> get props => [];
+       8              : }
+       9              : 
+      10              : final class WeeklySchedulesSubscriptionRequested extends WeeklySchedulesEvent {
+      11              :   final DateTime date;
+      12              : 
+      13            0 :   const WeeklySchedulesSubscriptionRequested({required this.date});
+      14              : 
+      15            0 :   DateTime get startDate => date.subtract(Duration(days: date.weekday - 1));
+      16            0 :   DateTime get endDate => startDate.add(Duration(days: 7));
+      17              : 
+      18            0 :   @override
+      19            0 :   List<Object> get props => [startDate, endDate];
+      20              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/home/bloc/weekly_schedules_state.dart.gcov.html b/coverage/html/presentation/home/bloc/weekly_schedules_state.dart.gcov.html new file mode 100644 index 00000000..0936d5d9 --- /dev/null +++ b/coverage/html/presentation/home/bloc/weekly_schedules_state.dart.gcov.html @@ -0,0 +1,115 @@ + + + + + + + LCOV - lcov.info - presentation/home/bloc/weekly_schedules_state.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/home/bloc - weekly_schedules_state.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %190
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'weekly_schedules_bloc.dart';
+       2              : 
+       3              : enum WeeklySchedulesStatus { initial, loading, success, error }
+       4              : 
+       5              : final class WeeklySchedulesState extends Equatable {
+       6            0 :   const WeeklySchedulesState(
+       7              :       {this.status = WeeklySchedulesStatus.initial, this.schedules = const []});
+       8              : 
+       9              :   final WeeklySchedulesStatus status;
+      10              :   final List<ScheduleEntity> schedules;
+      11              : 
+      12            0 :   List<DateTime> get dates =>
+      13            0 :       schedules.map((schedule) => schedule.scheduleTime).toList();
+      14            0 :   ScheduleEntity? get todaySchedule => schedules
+      15            0 :       .where((schedule) {
+      16            0 :         final now = DateTime.now();
+      17            0 :         return schedule.scheduleTime.year == now.year &&
+      18            0 :             schedule.scheduleTime.month == now.month &&
+      19            0 :             schedule.scheduleTime.day == now.day;
+      20              :       })
+      21            0 :       .sortedBy((e) => e.scheduleTime)
+      22            0 :       .firstOrNull;
+      23              : 
+      24            0 :   WeeklySchedulesState copyWith({
+      25              :     WeeklySchedulesStatus Function()? status,
+      26              :     List<ScheduleEntity> Function()? schedules,
+      27              :   }) {
+      28            0 :     return WeeklySchedulesState(
+      29            0 :       status: status != null ? status() : this.status,
+      30            0 :       schedules: schedules != null ? schedules() : this.schedules,
+      31              :     );
+      32              :   }
+      33              : 
+      34            0 :   @override
+      35            0 :   List<Object> get props => [
+      36            0 :         status,
+      37            0 :         ...schedules,
+      38              :       ];
+      39              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_bloc.dart.gcov.html b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_bloc.dart.gcov.html new file mode 100644 index 00000000..80a36f2a --- /dev/null +++ b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_bloc.dart.gcov.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - lcov.info - presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_bloc.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/my_page/preparation_spare_time_edit/bloc - default_preparation_spare_time_form_bloc.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %300
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:flutter_bloc/flutter_bloc.dart';
+       2              : import 'package:equatable/equatable.dart';
+       3              : import 'package:injectable/injectable.dart';
+       4              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       5              : import 'package:on_time_front/domain/use-cases/get_default_preparation_use_case.dart';
+       6              : import 'package:on_time_front/domain/use-cases/onboard_use_case.dart';
+       7              : 
+       8              : part 'default_preparation_spare_time_form_event.dart';
+       9              : part 'default_preparation_spare_time_form_state.dart';
+      10              : 
+      11              : @injectable
+      12              : class DefaultPreparationSpareTimeFormBloc extends Bloc<
+      13              :     DefaultPreparationSpareTimeFormEvent,
+      14              :     DefaultPreparationSpareTimeFormState> {
+      15            0 :   DefaultPreparationSpareTimeFormBloc(
+      16              :     this._getDefaultPreparationUseCase,
+      17              :     this._onboardUseCase,
+      18            0 :   ) : super(DefaultPreparationSpareTimeFormState()) {
+      19            0 :     on<FormEditRequested>(_onFormEditRequested);
+      20            0 :     on<SpareTimeIncreased>(_onSpareTimeIncreased);
+      21            0 :     on<SpareTimeDecreased>(_onSpareTimeDecreased);
+      22            0 :     on<FormSubmitted>(_onFormSubmitted);
+      23              :   }
+      24              : 
+      25              :   final GetDefaultPreparationUseCase _getDefaultPreparationUseCase;
+      26              :   final OnboardUseCase _onboardUseCase;
+      27              :   final Duration lowerBound = Duration(minutes: 10);
+      28              :   final Duration stepSize = Duration(minutes: 5);
+      29              : 
+      30            0 :   Future<void> _onFormEditRequested(FormEditRequested event,
+      31              :       Emitter<DefaultPreparationSpareTimeFormState> emit) async {
+      32            0 :     emit(state.copyWith(
+      33              :       status: DefaultPreparationSpareTimeStatus.loading,
+      34              :     ));
+      35              : 
+      36            0 :     final preparation = await _getDefaultPreparationUseCase();
+      37              : 
+      38            0 :     emit(state.copyWith(
+      39              :       status: DefaultPreparationSpareTimeStatus.success,
+      40              :       preparation: preparation,
+      41            0 :       spareTime: event.spareTime,
+      42              :     ));
+      43              :   }
+      44              : 
+      45            0 :   void _onSpareTimeIncreased(SpareTimeIncreased event,
+      46              :       Emitter<DefaultPreparationSpareTimeFormState> emit) {
+      47            0 :     final currentSpareTime = state.spareTime ?? Duration.zero;
+      48            0 :     final newSpareTime = currentSpareTime + stepSize;
+      49              : 
+      50            0 :     emit(state.copyWith(
+      51              :       spareTime: newSpareTime,
+      52              :     ));
+      53              :   }
+      54              : 
+      55            0 :   void _onSpareTimeDecreased(SpareTimeDecreased event,
+      56              :       Emitter<DefaultPreparationSpareTimeFormState> emit) {
+      57            0 :     final currentSpareTime = state.spareTime ?? Duration.zero;
+      58            0 :     final newSpareTime = currentSpareTime - stepSize;
+      59              : 
+      60            0 :     if (newSpareTime >= lowerBound) {
+      61            0 :       emit(state.copyWith(
+      62              :         spareTime: newSpareTime,
+      63              :       ));
+      64              :     }
+      65              :   }
+      66              : 
+      67            0 :   Future<void> _onFormSubmitted(FormSubmitted event,
+      68              :       Emitter<DefaultPreparationSpareTimeFormState> emit) async {
+      69            0 :     if (state.spareTime == null) {
+      70            0 :       emit(state.copyWith(
+      71              :         status: DefaultPreparationSpareTimeStatus.error,
+      72              :       ));
+      73              :       return;
+      74              :     }
+      75              : 
+      76            0 :     emit(state.copyWith(
+      77              :       status: DefaultPreparationSpareTimeStatus.loading,
+      78              :     ));
+      79              : 
+      80              :     try {
+      81            0 :       await _onboardUseCase(
+      82            0 :         preparationEntity: event.preparation,
+      83            0 :         spareTime: state.spareTime!,
+      84            0 :         note: event.note,
+      85              :       );
+      86              : 
+      87            0 :       emit(state.copyWith(
+      88              :         status: DefaultPreparationSpareTimeStatus.success,
+      89              :       ));
+      90              :     } catch (e) {
+      91            0 :       emit(state.copyWith(
+      92              :         status: DefaultPreparationSpareTimeStatus.error,
+      93              :       ));
+      94              :     }
+      95              :   }
+      96              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_event.dart.gcov.html b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_event.dart.gcov.html new file mode 100644 index 00000000..7270d618 --- /dev/null +++ b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_event.dart.gcov.html @@ -0,0 +1,115 @@ + + + + + + + LCOV - lcov.info - presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_event.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/my_page/preparation_spare_time_edit/bloc - default_preparation_spare_time_form_event.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %150
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'default_preparation_spare_time_form_bloc.dart';
+       2              : 
+       3              : class DefaultPreparationSpareTimeFormEvent extends Equatable {
+       4            0 :   const DefaultPreparationSpareTimeFormEvent();
+       5              : 
+       6            0 :   @override
+       7            0 :   List<Object?> get props => [];
+       8              : }
+       9              : 
+      10              : class FormEditRequested extends DefaultPreparationSpareTimeFormEvent {
+      11            0 :   const FormEditRequested({required this.spareTime});
+      12              :   final Duration spareTime;
+      13              : 
+      14            0 :   @override
+      15            0 :   List<Object?> get props => [spareTime];
+      16              : }
+      17              : 
+      18              : class SpareTimeIncreased extends DefaultPreparationSpareTimeFormEvent {
+      19            0 :   const SpareTimeIncreased();
+      20              : 
+      21            0 :   @override
+      22            0 :   List<Object?> get props => [];
+      23              : }
+      24              : 
+      25              : class SpareTimeDecreased extends DefaultPreparationSpareTimeFormEvent {
+      26            0 :   const SpareTimeDecreased();
+      27              : 
+      28            0 :   @override
+      29            0 :   List<Object?> get props => [];
+      30              : }
+      31              : 
+      32              : class FormSubmitted extends DefaultPreparationSpareTimeFormEvent {
+      33            0 :   const FormSubmitted({required this.note, required this.preparation});
+      34              :   final String note;
+      35              :   final PreparationEntity preparation;
+      36              : 
+      37            0 :   @override
+      38            0 :   List<Object?> get props => [note];
+      39              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_state.dart.gcov.html b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_state.dart.gcov.html new file mode 100644 index 00000000..12606991 --- /dev/null +++ b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_state.dart.gcov.html @@ -0,0 +1,110 @@ + + + + + + + LCOV - lcov.info - presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_state.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/my_page/preparation_spare_time_edit/bloc - default_preparation_spare_time_form_state.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %80
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'default_preparation_spare_time_form_bloc.dart';
+       2              : 
+       3              : enum DefaultPreparationSpareTimeStatus {
+       4              :   initial,
+       5              :   loading,
+       6              :   success,
+       7              :   error,
+       8              : }
+       9              : 
+      10              : class DefaultPreparationSpareTimeFormState extends Equatable {
+      11            0 :   const DefaultPreparationSpareTimeFormState({
+      12              :     this.status = DefaultPreparationSpareTimeStatus.initial,
+      13              :     this.spareTime,
+      14              :     this.preparation,
+      15              :   });
+      16              :   final DefaultPreparationSpareTimeStatus status;
+      17              :   final Duration? spareTime;
+      18              :   final PreparationEntity? preparation;
+      19              : 
+      20            0 :   @override
+      21            0 :   List<Object?> get props => [status, spareTime, preparation];
+      22              : 
+      23            0 :   DefaultPreparationSpareTimeFormState copyWith({
+      24              :     DefaultPreparationSpareTimeStatus? status,
+      25              :     Duration? spareTime,
+      26              :     PreparationEntity? preparation,
+      27              :   }) {
+      28            0 :     return DefaultPreparationSpareTimeFormState(
+      29            0 :       status: status ?? this.status,
+      30            0 :       spareTime: spareTime ?? this.spareTime,
+      31            0 :       preparation: preparation ?? this.preparation,
+      32              :     );
+      33              :   }
+      34              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index-sort-f.html b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index-sort-f.html new file mode 100644 index 00000000..6e79947d --- /dev/null +++ b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index-sort-f.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/my_page/preparation_spare_time_edit/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/my_page/preparation_spare_time_edit/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %530
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
default_preparation_spare_time_form_bloc.dart +
0.0%
+
0.0 %30
default_preparation_spare_time_form_event.dart +
0.0%
+
0.0 %15
default_preparation_spare_time_form_state.dart +
0.0%
+
0.0 %8
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index-sort-l.html b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index-sort-l.html new file mode 100644 index 00000000..727e4f93 --- /dev/null +++ b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index-sort-l.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/my_page/preparation_spare_time_edit/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/my_page/preparation_spare_time_edit/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %530
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
default_preparation_spare_time_form_state.dart +
0.0%
+
0.0 %8
default_preparation_spare_time_form_event.dart +
0.0%
+
0.0 %15
default_preparation_spare_time_form_bloc.dart +
0.0%
+
0.0 %30
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index.html b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index.html new file mode 100644 index 00000000..86f53419 --- /dev/null +++ b/coverage/html/presentation/my_page/preparation_spare_time_edit/bloc/index.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/my_page/preparation_spare_time_edit/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/my_page/preparation_spare_time_edit/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %530
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
default_preparation_spare_time_form_bloc.dart +
0.0%
+
0.0 %30
default_preparation_spare_time_form_event.dart +
0.0%
+
0.0 %15
default_preparation_spare_time_form_state.dart +
0.0%
+
0.0 %8
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/onboarding/cubit/index-sort-f.html b/coverage/html/presentation/onboarding/cubit/index-sort-f.html new file mode 100644 index 00000000..feb34dcb --- /dev/null +++ b/coverage/html/presentation/onboarding/cubit/index-sort-f.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - presentation/onboarding/cubit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/onboarding/cubitCoverageTotalHit
Test:lcov.infoLines:0.0 %390
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
onboarding_cubit.dart +
0.0%
+
0.0 %11
onboarding_state.dart +
0.0%
+
0.0 %28
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/onboarding/cubit/index-sort-l.html b/coverage/html/presentation/onboarding/cubit/index-sort-l.html new file mode 100644 index 00000000..b6ccebc8 --- /dev/null +++ b/coverage/html/presentation/onboarding/cubit/index-sort-l.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - presentation/onboarding/cubit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/onboarding/cubitCoverageTotalHit
Test:lcov.infoLines:0.0 %390
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
onboarding_cubit.dart +
0.0%
+
0.0 %11
onboarding_state.dart +
0.0%
+
0.0 %28
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/onboarding/cubit/index.html b/coverage/html/presentation/onboarding/cubit/index.html new file mode 100644 index 00000000..0e6fff1a --- /dev/null +++ b/coverage/html/presentation/onboarding/cubit/index.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - presentation/onboarding/cubit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/onboarding/cubitCoverageTotalHit
Test:lcov.infoLines:0.0 %390
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
onboarding_cubit.dart +
0.0%
+
0.0 %11
onboarding_state.dart +
0.0%
+
0.0 %28
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/onboarding/cubit/onboarding_cubit.dart.gcov.html b/coverage/html/presentation/onboarding/cubit/onboarding_cubit.dart.gcov.html new file mode 100644 index 00000000..266f9381 --- /dev/null +++ b/coverage/html/presentation/onboarding/cubit/onboarding_cubit.dart.gcov.html @@ -0,0 +1,115 @@ + + + + + + + LCOV - lcov.info - presentation/onboarding/cubit/onboarding_cubit.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/onboarding/cubit - onboarding_cubit.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %110
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:equatable/equatable.dart';
+       2              : import 'package:flutter_bloc/flutter_bloc.dart';
+       3              : import 'package:injectable/injectable.dart';
+       4              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       5              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+       6              : import 'package:on_time_front/domain/use-cases/onboard_use_case.dart';
+       7              : 
+       8              : part 'onboarding_state.dart';
+       9              : 
+      10              : @Injectable()
+      11              : class OnboardingCubit extends Cubit<OnboardingState> {
+      12            0 :   OnboardingCubit(
+      13              :     this._createDefaultPreparationUseCase,
+      14            0 :   ) : super(OnboardingState());
+      15              : 
+      16              :   final OnboardUseCase _createDefaultPreparationUseCase;
+      17              : 
+      18            0 :   Future<void> onboardingFormSubmitted() async {
+      19            0 :     return await _createDefaultPreparationUseCase(
+      20            0 :       preparationEntity: state.toEntity(),
+      21            0 :       spareTime: state.spareTime!,
+      22            0 :       note: state.note ?? '',
+      23              :     );
+      24              :   }
+      25              : 
+      26            0 :   void onboardingFormChanged({
+      27              :     List<OnboardingPreparationStepState>? preparationStepList,
+      28              :     Duration? spareTime,
+      29              :   }) {
+      30            0 :     emit(state.copyWith(
+      31              :         preparationStepList: preparationStepList, spareTime: spareTime));
+      32              :   }
+      33              : 
+      34            0 :   void onboardingFormValidated({
+      35              :     required bool isValid,
+      36              :   }) {
+      37            0 :     emit(state.copyWith(isValid: isValid));
+      38              :   }
+      39              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/onboarding/cubit/onboarding_state.dart.gcov.html b/coverage/html/presentation/onboarding/cubit/onboarding_state.dart.gcov.html new file mode 100644 index 00000000..44d6deb5 --- /dev/null +++ b/coverage/html/presentation/onboarding/cubit/onboarding_state.dart.gcov.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - lcov.info - presentation/onboarding/cubit/onboarding_state.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/onboarding/cubit - onboarding_state.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %280
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'onboarding_cubit.dart';
+       2              : 
+       3              : class OnboardingState extends Equatable {
+       4            0 :   const OnboardingState(
+       5              :       {this.preparationStepList = const [],
+       6              :       this.spareTime,
+       7              :       this.note,
+       8              :       this.isValid = false});
+       9              :   final List<OnboardingPreparationStepState> preparationStepList;
+      10              :   final Duration? spareTime;
+      11              :   final String? note;
+      12              :   final bool isValid;
+      13              : 
+      14            0 :   OnboardingState copyWith({
+      15              :     List<OnboardingPreparationStepState>? preparationStepList,
+      16              :     Duration? spareTime,
+      17              :     String? note,
+      18              :     bool? isValid,
+      19              :   }) {
+      20            0 :     return OnboardingState(
+      21            0 :       preparationStepList: preparationStepList ?? this.preparationStepList,
+      22            0 :       spareTime: spareTime ?? this.spareTime,
+      23            0 :       note: note ?? this.note,
+      24            0 :       isValid: isValid ?? this.isValid,
+      25              :     );
+      26              :   }
+      27              : 
+      28            0 :   PreparationEntity toEntity() {
+      29            0 :     return PreparationEntity(
+      30            0 :       preparationStepList: preparationStepList
+      31            0 :           .map((step) => PreparationStepEntity(
+      32            0 :                 id: step.id,
+      33            0 :                 preparationName: step.preparationName,
+      34            0 :                 preparationTime: step.preparationTime,
+      35            0 :                 nextPreparationId: step.nextPreparationId,
+      36              :               ))
+      37            0 :           .toList(),
+      38              :     );
+      39              :   }
+      40              : 
+      41            0 :   @override
+      42            0 :   List<Object?> get props => [preparationStepList, spareTime, note, isValid];
+      43              : }
+      44              : 
+      45              : class OnboardingPreparationStepState extends Equatable {
+      46            0 :   const OnboardingPreparationStepState({
+      47              :     required this.id,
+      48              :     required this.preparationName,
+      49              :     this.preparationTime = const Duration(minutes: 0),
+      50              :     this.nextPreparationId,
+      51              :   });
+      52              : 
+      53              :   final String id;
+      54              :   final String preparationName;
+      55              :   final Duration preparationTime;
+      56              :   final String? nextPreparationId;
+      57              : 
+      58            0 :   OnboardingPreparationStepState copyWith({
+      59              :     String? id,
+      60              :     String? preparationName,
+      61              :     Duration? preparationTime,
+      62              :     String? nextPreparationId,
+      63              :   }) {
+      64            0 :     return OnboardingPreparationStepState(
+      65            0 :       id: id ?? this.id,
+      66            0 :       preparationName: preparationName ?? this.preparationName,
+      67            0 :       preparationTime: preparationTime ?? this.preparationTime,
+      68            0 :       nextPreparationId: nextPreparationId == ''
+      69              :           ? null
+      70            0 :           : (nextPreparationId ?? this.nextPreparationId),
+      71              :     );
+      72              :   }
+      73              : 
+      74            0 :   @override
+      75              :   List<Object?> get props =>
+      76            0 :       [id, preparationName, preparationTime, nextPreparationId];
+      77              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/onboarding/preparation_name_select/input_models/index.html b/coverage/html/presentation/onboarding/preparation_name_select/input_models/index.html new file mode 100644 index 00000000..ddbd5fb1 --- /dev/null +++ b/coverage/html/presentation/onboarding/preparation_name_select/input_models/index.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - presentation/onboarding/preparation_name_select/input_models + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/onboarding/preparation_name_select/input_modelsCoverageTotalHit
Test:lcov.infoLines:25.0 %41
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
preparation_name_input_model.dart +
25.0%25.0%
+
25.0 %41
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/onboarding/preparation_name_select/input_models/preparation_name_input_model.dart.gcov.html b/coverage/html/presentation/onboarding/preparation_name_select/input_models/preparation_name_input_model.dart.gcov.html new file mode 100644 index 00000000..cbb8ce3a --- /dev/null +++ b/coverage/html/presentation/onboarding/preparation_name_select/input_models/preparation_name_input_model.dart.gcov.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - lcov.info - presentation/onboarding/preparation_name_select/input_models/preparation_name_input_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/onboarding/preparation_name_select/input_models - preparation_name_input_model.dartCoverageTotalHit
Test:lcov.infoLines:25.0 %41
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:formz/formz.dart';
+       2              : 
+       3              : /// Validation errors for the [PreparationNameInputModel] [FormzInput].
+       4              : enum PreparationNameValidationError {
+       5              :   empty,
+       6              : }
+       7              : 
+       8              : class PreparationNameInputModel
+       9              :     extends FormzInput<String, PreparationNameValidationError> {
+      10            4 :   const PreparationNameInputModel.pure([super.value = '']) : super.pure();
+      11            0 :   const PreparationNameInputModel.dirty([super.value = '']) : super.dirty();
+      12              : 
+      13            0 :   @override
+      14              :   PreparationNameValidationError? validator(String value) {
+      15            0 :     return value.isEmpty ? PreparationNameValidationError.empty : null;
+      16              :   }
+      17              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/onboarding/preparation_time/input_models/index.html b/coverage/html/presentation/onboarding/preparation_time/input_models/index.html new file mode 100644 index 00000000..8e80009f --- /dev/null +++ b/coverage/html/presentation/onboarding/preparation_time/input_models/index.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - presentation/onboarding/preparation_time/input_models + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/onboarding/preparation_time/input_modelsCoverageTotalHit
Test:lcov.infoLines:16.7 %61
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
preparation_time_input_model.dart +
16.7%16.7%
+
16.7 %61
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/onboarding/preparation_time/input_models/preparation_time_input_model.dart.gcov.html b/coverage/html/presentation/onboarding/preparation_time/input_models/preparation_time_input_model.dart.gcov.html new file mode 100644 index 00000000..1ae8a11f --- /dev/null +++ b/coverage/html/presentation/onboarding/preparation_time/input_models/preparation_time_input_model.dart.gcov.html @@ -0,0 +1,95 @@ + + + + + + + LCOV - lcov.info - presentation/onboarding/preparation_time/input_models/preparation_time_input_model.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/onboarding/preparation_time/input_models - preparation_time_input_model.dartCoverageTotalHit
Test:lcov.infoLines:16.7 %61
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:formz/formz.dart';
+       2              : 
+       3              : /// Validation errors for the [PreparationTimeInputModel] [FormzInput].
+       4              : enum PreparationTimeValidationError {
+       5              :   zero,
+       6              : }
+       7              : 
+       8              : class PreparationTimeInputModel
+       9              :     extends FormzInput<Duration, PreparationTimeValidationError> {
+      10            4 :   const PreparationTimeInputModel.pure([super.value = Duration.zero])
+      11            0 :       : super.pure();
+      12            0 :   const PreparationTimeInputModel.dirty([super.value = Duration.zero])
+      13            0 :       : super.dirty();
+      14              : 
+      15            0 :   @override
+      16              :   PreparationTimeValidationError? validator(Duration value) {
+      17            0 :     return value.inMinutes == 0 ? PreparationTimeValidationError.zero : null;
+      18              :   }
+      19              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/bloc/index-sort-f.html b/coverage/html/presentation/schedule_create/bloc/index-sort-f.html new file mode 100644 index 00000000..3026b857 --- /dev/null +++ b/coverage/html/presentation/schedule_create/bloc/index-sort-f.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %1360
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
schedule_form_bloc.dart +
0.0%
+
0.0 %65
schedule_form_event.dart +
0.0%
+
0.0 %30
schedule_form_state.dart +
0.0%
+
0.0 %41
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/bloc/index-sort-l.html b/coverage/html/presentation/schedule_create/bloc/index-sort-l.html new file mode 100644 index 00000000..2f76489a --- /dev/null +++ b/coverage/html/presentation/schedule_create/bloc/index-sort-l.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %1360
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
schedule_form_event.dart +
0.0%
+
0.0 %30
schedule_form_state.dart +
0.0%
+
0.0 %41
schedule_form_bloc.dart +
0.0%
+
0.0 %65
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/bloc/index.html b/coverage/html/presentation/schedule_create/bloc/index.html new file mode 100644 index 00000000..10a6263c --- /dev/null +++ b/coverage/html/presentation/schedule_create/bloc/index.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %1360
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
schedule_form_bloc.dart +
0.0%
+
0.0 %65
schedule_form_event.dart +
0.0%
+
0.0 %30
schedule_form_state.dart +
0.0%
+
0.0 %41
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/bloc/schedule_form_bloc.dart.gcov.html b/coverage/html/presentation/schedule_create/bloc/schedule_form_bloc.dart.gcov.html new file mode 100644 index 00000000..1d46aa49 --- /dev/null +++ b/coverage/html/presentation/schedule_create/bloc/schedule_form_bloc.dart.gcov.html @@ -0,0 +1,272 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/bloc/schedule_form_bloc.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/bloc - schedule_form_bloc.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %650
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:equatable/equatable.dart';
+       2              : import 'package:flutter_bloc/flutter_bloc.dart';
+       3              : import 'package:injectable/injectable.dart';
+       4              : import 'package:on_time_front/domain/entities/place_entity.dart';
+       5              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       6              : import 'package:on_time_front/domain/entities/schedule_entity.dart';
+       7              : import 'package:on_time_front/domain/use-cases/create_custom_preparation_use_case.dart';
+       8              : import 'package:on_time_front/domain/use-cases/create_schedule_with_place_use_case.dart';
+       9              : import 'package:on_time_front/domain/use-cases/get_default_preparation_use_case.dart';
+      10              : import 'package:on_time_front/domain/use-cases/get_preparation_by_schedule_id_use_case.dart';
+      11              : import 'package:on_time_front/domain/use-cases/get_schedule_by_id_use_case.dart';
+      12              : import 'package:on_time_front/domain/use-cases/update_preparation_by_schedule_id_use_case.dart';
+      13              : import 'package:on_time_front/domain/use-cases/update_schedule_use_case.dart';
+      14              : import 'package:uuid/uuid.dart';
+      15              : 
+      16              : part 'schedule_form_event.dart';
+      17              : part 'schedule_form_state.dart';
+      18              : 
+      19              : @Injectable()
+      20              : class ScheduleFormBloc extends Bloc<ScheduleFormEvent, ScheduleFormState> {
+      21            0 :   ScheduleFormBloc(
+      22              :     this._getPreparationByScheduleIdUseCase,
+      23              :     this._getDefaultPreparationUseCase,
+      24              :     this._getScheduleByIdUseCase,
+      25              :     this._createScheduleWithPlaceUseCase,
+      26              :     this._createCustomPreparationUseCase,
+      27              :     this._updateScheduleUseCase,
+      28              :     this._updatePreparationByScheduleIdUseCase,
+      29            0 :   ) : super(ScheduleFormState()) {
+      30            0 :     on<ScheduleFormEditRequested>(_onEditRequested);
+      31            0 :     on<ScheduleFormCreateRequested>(_onCreateRequested);
+      32            0 :     on<ScheduleFormScheduleNameChanged>(_onScheduleNameChanged);
+      33            0 :     on<ScheduleFormScheduleDateTimeChanged>(_onScheduleDateChanged);
+      34            0 :     on<ScheduleFormPlaceNameChanged>(_onPlaceNameChanged);
+      35            0 :     on<ScheduleFormMoveTimeChanged>(_onMoveTimeChanged);
+      36            0 :     on<ScheduleFormScheduleSpareTimeChanged>(_onScheduleSpareTimeChanged);
+      37            0 :     on<ScheduleFormPreparationChanged>(_onPreparationChanged);
+      38            0 :     on<ScheduleFormUpdated>(_onUpdated);
+      39            0 :     on<ScheduleFormCreated>(_onCreated);
+      40            0 :     on<ScheduleFormValidated>(_onValidated);
+      41              :   }
+      42              : 
+      43              :   final GetPreparationByScheduleIdUseCase _getPreparationByScheduleIdUseCase;
+      44              :   final GetDefaultPreparationUseCase _getDefaultPreparationUseCase;
+      45              :   final GetScheduleByIdUseCase _getScheduleByIdUseCase;
+      46              :   final CreateScheduleWithPlaceUseCase _createScheduleWithPlaceUseCase;
+      47              :   final CreateCustomPreparationUseCase _createCustomPreparationUseCase;
+      48              :   final UpdateScheduleUseCase _updateScheduleUseCase;
+      49              :   final UpdatePreparationByScheduleIdUseCase
+      50              :       _updatePreparationByScheduleIdUseCase;
+      51              : 
+      52            0 :   Future<void> _onEditRequested(
+      53              :     ScheduleFormEditRequested event,
+      54              :     Emitter<ScheduleFormState> emit,
+      55              :   ) async {
+      56            0 :     emit(state.copyWith(
+      57              :       status: ScheduleFormStatus.loading,
+      58              :     ));
+      59              : 
+      60              :     final PreparationEntity preparationEntity =
+      61            0 :         await _getPreparationByScheduleIdUseCase(event.scheduleId);
+      62              : 
+      63              :     final ScheduleEntity scheduleEntity =
+      64            0 :         await _getScheduleByIdUseCase(event.scheduleId);
+      65              : 
+      66            0 :     emit(state.copyWith(
+      67              :       status: ScheduleFormStatus.success,
+      68            0 :       id: scheduleEntity.id,
+      69            0 :       placeName: scheduleEntity.place.placeName,
+      70            0 :       scheduleName: scheduleEntity.scheduleName,
+      71            0 :       scheduleTime: scheduleEntity.scheduleTime,
+      72            0 :       moveTime: scheduleEntity.moveTime,
+      73            0 :       isChanged: scheduleEntity.isChanged
+      74              :           ? IsPreparationChanged.changed
+      75              :           : IsPreparationChanged.unchanged,
+      76            0 :       scheduleSpareTime: scheduleEntity.scheduleSpareTime,
+      77            0 :       scheduleNote: scheduleEntity.scheduleNote,
+      78              :       preparation: preparationEntity,
+      79              :     ));
+      80              :   }
+      81              : 
+      82            0 :   void _onCreateRequested(
+      83              :     ScheduleFormCreateRequested event,
+      84              :     Emitter<ScheduleFormState> emit,
+      85              :   ) async {
+      86            0 :     emit(state.copyWith(
+      87              :       status: ScheduleFormStatus.loading,
+      88              :     ));
+      89              : 
+      90              :     final PreparationEntity defaultPreparationStepList =
+      91            0 :         await _getDefaultPreparationUseCase();
+      92              : 
+      93            0 :     emit(state.copyWith(
+      94              :       status: ScheduleFormStatus.success,
+      95            0 :       id: Uuid().v7(),
+      96              :       placeName: null,
+      97              :       scheduleName: null,
+      98              :       scheduleTime: null,
+      99              :       moveTime: null,
+     100              :       isChanged: null,
+     101              :       scheduleSpareTime: null,
+     102              :       scheduleNote: null,
+     103              :       preparation: defaultPreparationStepList,
+     104              :     ));
+     105              :   }
+     106              : 
+     107            0 :   void _onScheduleNameChanged(
+     108              :     ScheduleFormScheduleNameChanged event,
+     109              :     Emitter<ScheduleFormState> emit,
+     110              :   ) {
+     111            0 :     emit(state.copyWith(scheduleName: event.scheduleName));
+     112              :   }
+     113              : 
+     114            0 :   void _onScheduleDateChanged(
+     115              :     ScheduleFormScheduleDateTimeChanged event,
+     116              :     Emitter<ScheduleFormState> emit,
+     117              :   ) {
+     118            0 :     emit(state.copyWith(
+     119            0 :       scheduleTime: DateTime(
+     120            0 :         event.scheduleDate.year,
+     121            0 :         event.scheduleDate.month,
+     122            0 :         event.scheduleDate.day,
+     123            0 :         event.scheduleTime.hour,
+     124            0 :         event.scheduleTime.minute,
+     125              :       ),
+     126              :     ));
+     127              :   }
+     128              : 
+     129            0 :   void _onPlaceNameChanged(
+     130              :     ScheduleFormPlaceNameChanged event,
+     131              :     Emitter<ScheduleFormState> emit,
+     132              :   ) {
+     133            0 :     emit(state.copyWith(placeName: event.placeName));
+     134              :   }
+     135              : 
+     136            0 :   void _onMoveTimeChanged(
+     137              :     ScheduleFormMoveTimeChanged event,
+     138              :     Emitter<ScheduleFormState> emit,
+     139              :   ) {
+     140            0 :     emit(state.copyWith(moveTime: event.moveTime));
+     141              :   }
+     142              : 
+     143            0 :   void _onScheduleSpareTimeChanged(
+     144              :     ScheduleFormScheduleSpareTimeChanged event,
+     145              :     Emitter<ScheduleFormState> emit,
+     146              :   ) {
+     147            0 :     emit(state.copyWith(scheduleSpareTime: event.scheduleSpareTime));
+     148              :   }
+     149              : 
+     150            0 :   void _onPreparationChanged(
+     151              :     ScheduleFormPreparationChanged event,
+     152              :     Emitter<ScheduleFormState> emit,
+     153              :   ) {
+     154              :     final IsPreparationChanged isChagned;
+     155            0 :     if (state.preparation == event.preparation) {
+     156              :       // not changed
+     157              :       isChagned = IsPreparationChanged.unchanged;
+     158              :     } else {
+     159              :       isChagned = IsPreparationChanged.changed;
+     160              :     }
+     161              : 
+     162            0 :     emit(state.copyWith(
+     163            0 :       preparation: event.preparation,
+     164              :       isChanged: isChagned,
+     165              :     ));
+     166              :   }
+     167              : 
+     168            0 :   Future<void> _onUpdated(
+     169              :     ScheduleFormUpdated event,
+     170              :     Emitter<ScheduleFormState> emit,
+     171              :   ) async {
+     172            0 :     final ScheduleEntity scheduleEntity = state.createEntity(state);
+     173            0 :     await _updateScheduleUseCase(scheduleEntity);
+     174            0 :     if (state.isChanged != IsPreparationChanged.unchanged) {
+     175            0 :       _updatePreparationByScheduleIdUseCase(
+     176            0 :           state.preparation!, scheduleEntity.id);
+     177              :     }
+     178              :   }
+     179              : 
+     180            0 :   Future<void> _onCreated(
+     181              :     ScheduleFormCreated event,
+     182              :     Emitter<ScheduleFormState> emit,
+     183              :   ) async {
+     184            0 :     final ScheduleEntity scheduleEntity = state.createEntity(state);
+     185            0 :     await _createScheduleWithPlaceUseCase(scheduleEntity);
+     186            0 :     if (state.isChanged != IsPreparationChanged.unchanged) {
+     187            0 :       await _createCustomPreparationUseCase(
+     188            0 :           state.preparation!, scheduleEntity.id);
+     189              :     }
+     190              :   }
+     191              : 
+     192            0 :   void _onValidated(
+     193              :       ScheduleFormValidated event, Emitter<ScheduleFormState> emit) {
+     194            0 :     emit(state.copyWith(isValid: event.isValid));
+     195              :   }
+     196              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/bloc/schedule_form_event.dart.gcov.html b/coverage/html/presentation/schedule_create/bloc/schedule_form_event.dart.gcov.html new file mode 100644 index 00000000..f0031a3c --- /dev/null +++ b/coverage/html/presentation/schedule_create/bloc/schedule_form_event.dart.gcov.html @@ -0,0 +1,170 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/bloc/schedule_form_event.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/bloc - schedule_form_event.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %300
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'schedule_form_bloc.dart';
+       2              : 
+       3              : sealed class ScheduleFormEvent extends Equatable {
+       4            0 :   const ScheduleFormEvent();
+       5              : 
+       6            0 :   @override
+       7            0 :   List<Object> get props => [];
+       8              : }
+       9              : 
+      10              : final class ScheduleFormEditRequested extends ScheduleFormEvent {
+      11              :   final String scheduleId;
+      12              : 
+      13            0 :   const ScheduleFormEditRequested({required this.scheduleId});
+      14              : 
+      15            0 :   @override
+      16            0 :   List<Object> get props => [scheduleId];
+      17              : }
+      18              : 
+      19              : final class ScheduleFormCreateRequested extends ScheduleFormEvent {
+      20            0 :   const ScheduleFormCreateRequested();
+      21              : }
+      22              : 
+      23              : final class ScheduleFormScheduleNameChanged extends ScheduleFormEvent {
+      24              :   final String scheduleName;
+      25              : 
+      26            0 :   const ScheduleFormScheduleNameChanged({required this.scheduleName});
+      27              : 
+      28            0 :   @override
+      29            0 :   List<Object> get props => [scheduleName];
+      30              : }
+      31              : 
+      32              : final class ScheduleFormScheduleDateTimeChanged extends ScheduleFormEvent {
+      33              :   final DateTime scheduleDate;
+      34              :   final DateTime scheduleTime;
+      35              : 
+      36            0 :   const ScheduleFormScheduleDateTimeChanged(
+      37              :       {required this.scheduleDate, required this.scheduleTime});
+      38              : 
+      39            0 :   @override
+      40            0 :   List<Object> get props => [scheduleDate, scheduleTime];
+      41              : }
+      42              : 
+      43              : final class ScheduleFormPlaceNameChanged extends ScheduleFormEvent {
+      44              :   final String placeName;
+      45              : 
+      46            0 :   const ScheduleFormPlaceNameChanged({required this.placeName});
+      47              : 
+      48            0 :   @override
+      49            0 :   List<Object> get props => [placeName];
+      50              : }
+      51              : 
+      52              : final class ScheduleFormMoveTimeChanged extends ScheduleFormEvent {
+      53              :   final Duration moveTime;
+      54              : 
+      55            0 :   const ScheduleFormMoveTimeChanged({required this.moveTime});
+      56              : 
+      57            0 :   @override
+      58            0 :   List<Object> get props => [moveTime];
+      59              : }
+      60              : 
+      61              : final class ScheduleFormScheduleSpareTimeChanged extends ScheduleFormEvent {
+      62              :   final Duration scheduleSpareTime;
+      63              : 
+      64            0 :   const ScheduleFormScheduleSpareTimeChanged({required this.scheduleSpareTime});
+      65              : 
+      66            0 :   @override
+      67            0 :   List<Object> get props => [scheduleSpareTime];
+      68              : }
+      69              : 
+      70              : final class ScheduleFormPreparationChanged extends ScheduleFormEvent {
+      71              :   final PreparationEntity preparation;
+      72              : 
+      73            0 :   const ScheduleFormPreparationChanged({required this.preparation});
+      74              : 
+      75            0 :   @override
+      76            0 :   List<Object> get props => [preparation];
+      77              : }
+      78              : 
+      79              : final class ScheduleFormUpdated extends ScheduleFormEvent {
+      80            0 :   const ScheduleFormUpdated();
+      81              : }
+      82              : 
+      83              : final class ScheduleFormCreated extends ScheduleFormEvent {
+      84            0 :   const ScheduleFormCreated();
+      85              : }
+      86              : 
+      87              : final class ScheduleFormValidated extends ScheduleFormEvent {
+      88              :   final bool isValid;
+      89              : 
+      90            0 :   const ScheduleFormValidated({required this.isValid});
+      91              : 
+      92            0 :   @override
+      93            0 :   List<Object> get props => [isValid];
+      94              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/bloc/schedule_form_state.dart.gcov.html b/coverage/html/presentation/schedule_create/bloc/schedule_form_state.dart.gcov.html new file mode 100644 index 00000000..aa40beba --- /dev/null +++ b/coverage/html/presentation/schedule_create/bloc/schedule_form_state.dart.gcov.html @@ -0,0 +1,172 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/bloc/schedule_form_state.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/bloc - schedule_form_state.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %410
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'schedule_form_bloc.dart';
+       2              : 
+       3              : enum ScheduleFormStatus { initial, loading, success, error }
+       4              : 
+       5              : enum IsPreparationChanged { changed, unchanged }
+       6              : 
+       7              : final class ScheduleFormState extends Equatable {
+       8              :   final ScheduleFormStatus status;
+       9              :   final String id;
+      10              :   final String? placeName;
+      11              :   final String? scheduleName;
+      12              :   final DateTime? scheduleTime;
+      13              :   final Duration? moveTime;
+      14              :   final IsPreparationChanged isChanged;
+      15              :   final Duration? scheduleSpareTime;
+      16              :   final String? scheduleNote;
+      17              :   final PreparationEntity? preparation;
+      18              :   final bool isValid;
+      19              : 
+      20            0 :   ScheduleFormState({
+      21              :     this.status = ScheduleFormStatus.initial,
+      22              :     String? id,
+      23              :     this.placeName,
+      24              :     this.scheduleName,
+      25              :     this.scheduleTime,
+      26              :     this.moveTime,
+      27              :     this.isChanged = IsPreparationChanged.unchanged,
+      28              :     this.scheduleSpareTime,
+      29              :     this.scheduleNote,
+      30              :     this.preparation,
+      31              :     this.isValid = false,
+      32            0 :   }) : id = id ?? Uuid().v7();
+      33              : 
+      34            0 :   ScheduleFormState copyWith({
+      35              :     ScheduleFormStatus? status,
+      36              :     String? id,
+      37              :     String? placeName,
+      38              :     String? scheduleName,
+      39              :     DateTime? scheduleTime,
+      40              :     Duration? moveTime,
+      41              :     IsPreparationChanged? isChanged,
+      42              :     Duration? scheduleSpareTime,
+      43              :     String? scheduleNote,
+      44              :     PreparationEntity? preparation,
+      45              :     bool? isValid,
+      46              :   }) {
+      47            0 :     return ScheduleFormState(
+      48            0 :       status: status ?? this.status,
+      49            0 :       id: id ?? this.id,
+      50            0 :       placeName: placeName ?? this.placeName,
+      51            0 :       scheduleName: scheduleName ?? this.scheduleName,
+      52            0 :       scheduleTime: scheduleTime ?? this.scheduleTime,
+      53            0 :       moveTime: moveTime ?? this.moveTime,
+      54            0 :       isChanged: isChanged ?? this.isChanged,
+      55            0 :       scheduleSpareTime: scheduleSpareTime ?? this.scheduleSpareTime,
+      56            0 :       scheduleNote: scheduleNote ?? this.scheduleNote,
+      57            0 :       preparation: preparation ?? this.preparation,
+      58            0 :       isValid: isValid ?? this.isValid,
+      59              :     );
+      60              :   }
+      61              : 
+      62            0 :   Duration get totalPreparationTime {
+      63            0 :     return preparation?.preparationStepList
+      64            0 :             .map((e) => e.preparationTime)
+      65            0 :             .reduce((value, element) => value + element) ??
+      66              :         Duration.zero;
+      67              :   }
+      68              : 
+      69            0 :   ScheduleEntity createEntity(ScheduleFormState state) {
+      70            0 :     return ScheduleEntity(
+      71            0 :       id: state.id,
+      72            0 :       place: PlaceEntity(id: Uuid().v7(), placeName: state.placeName!),
+      73            0 :       scheduleName: state.scheduleName!,
+      74            0 :       scheduleTime: state.scheduleTime!,
+      75            0 :       moveTime: state.moveTime!,
+      76            0 :       isChanged: !(state.isChanged == IsPreparationChanged.unchanged),
+      77            0 :       scheduleSpareTime: state.scheduleSpareTime,
+      78            0 :       scheduleNote: state.scheduleNote ?? '',
+      79              :       isStarted: false,
+      80              :     );
+      81              :   }
+      82              : 
+      83            0 :   @override
+      84            0 :   List<Object?> get props => [
+      85            0 :         id,
+      86            0 :         placeName,
+      87            0 :         scheduleName,
+      88            0 :         scheduleTime,
+      89            0 :         moveTime,
+      90            0 :         isChanged,
+      91            0 :         scheduleSpareTime,
+      92            0 :         scheduleNote,
+      93            0 :         preparation,
+      94            0 :         isValid,
+      95              :       ];
+      96              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index-sort-f.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index-sort-f.html new file mode 100644 index 00000000..bddcdb53 --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index-sort-f.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %1220
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
preparation_form_bloc.dart +
0.0%
+
0.0 %62
preparation_form_event.dart +
0.0%
+
0.0 %22
preparation_form_state.dart +
0.0%
+
0.0 %38
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index-sort-l.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index-sort-l.html new file mode 100644 index 00000000..d9529998 --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index-sort-l.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %1220
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
preparation_form_event.dart +
0.0%
+
0.0 %22
preparation_form_state.dart +
0.0%
+
0.0 %38
preparation_form_bloc.dart +
0.0%
+
0.0 %62
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index.html new file mode 100644 index 00000000..58d90953 --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/index.html @@ -0,0 +1,116 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/blocCoverageTotalHit
Test:lcov.infoLines:0.0 %1220
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
preparation_form_bloc.dart +
0.0%
+
0.0 %62
preparation_form_event.dart +
0.0%
+
0.0 %22
preparation_form_state.dart +
0.0%
+
0.0 %38
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart.gcov.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart.gcov.html new file mode 100644 index 00000000..c5e00528 --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart.gcov.html @@ -0,0 +1,232 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc - preparation_form_bloc.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %620
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:async';
+       2              : 
+       3              : import 'package:collection/collection.dart';
+       4              : import 'package:equatable/equatable.dart';
+       5              : import 'package:flutter_bloc/flutter_bloc.dart';
+       6              : import 'package:formz/formz.dart';
+       7              : import 'package:injectable/injectable.dart';
+       8              : import 'package:on_time_front/domain/entities/preparation_entity.dart';
+       9              : import 'package:on_time_front/domain/entities/preparation_step_entity.dart';
+      10              : import 'package:on_time_front/presentation/onboarding/preparation_name_select/input_models/preparation_name_input_model.dart';
+      11              : import 'package:on_time_front/presentation/onboarding/preparation_time/input_models/preparation_time_input_model.dart';
+      12              : import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart';
+      13              : 
+      14              : part 'preparation_form_event.dart';
+      15              : part 'preparation_form_state.dart';
+      16              : 
+      17              : @Injectable()
+      18              : class PreparationFormBloc
+      19              :     extends Bloc<PreparationFormEvent, PreparationFormState> {
+      20            0 :   PreparationFormBloc() : super(PreparationFormState()) {
+      21            0 :     on<PreparationFormEditRequested>(_onPreparationFormEditRequested);
+      22            0 :     on<PreparationFormPreparationStepCreated>(
+      23            0 :         _onPreparationFormPreparationStepCreated);
+      24            0 :     on<PreparationFormPreparationStepRemoved>(
+      25            0 :         _onPreparationFormPreparationStepRemoved);
+      26            0 :     on<PreparationFormPreparationStepNameChanged>(
+      27            0 :         _onPreparationFormPreparationStepNameChanged);
+      28            0 :     on<PreparationFormPreparationStepTimeChanged>(
+      29            0 :         _onPreparationFormPreparationStepTimeChanged);
+      30            0 :     on<PreparationFormPreparationStepOrderChanged>(
+      31            0 :         _onPreparationFormPreparationStepOrderChanged);
+      32            0 :     on<PreparationFormPreparationStepCreationRequested>(
+      33            0 :         _onPreparationFormPreparationStepCreationRequested);
+      34              :   }
+      35              : 
+      36            0 :   void _onPreparationFormEditRequested(
+      37              :     PreparationFormEditRequested event,
+      38              :     Emitter<PreparationFormState> emit,
+      39              :   ) {
+      40              :     final PreparationFormState preparationFormState =
+      41            0 :         PreparationFormState.fromEntity(event.preparationEntity);
+      42            0 :     final isValid = _validate(preparationFormState.preparationStepList);
+      43            0 :     emit(state.copyWith(
+      44              :       status: PreparationFormStatus.initial,
+      45            0 :       preparationStepList: preparationFormState.preparationStepList,
+      46              :       isValid: isValid,
+      47              :     ));
+      48              :   }
+      49              : 
+      50            0 :   void _onPreparationFormPreparationStepCreated(
+      51              :     PreparationFormPreparationStepCreated event,
+      52              :     Emitter<PreparationFormState> emit,
+      53              :   ) {
+      54            0 :     if (state.status == PreparationFormStatus.adding) {
+      55              :       final List<PreparationStepFormState> preparationStepList;
+      56            0 :       if (event.preparationStep.preparationName.isValid) {
+      57            0 :         preparationStepList = [
+      58            0 :           ...state.preparationStepList,
+      59            0 :           event.preparationStep,
+      60              :         ];
+      61              :       } else {
+      62            0 :         preparationStepList = state.preparationStepList;
+      63              :       }
+      64            0 :       final isValid = _validate(preparationStepList);
+      65            0 :       emit(state.copyWith(
+      66              :         preparationStepList: preparationStepList,
+      67              :         status: PreparationFormStatus.initial,
+      68              :         isValid: isValid,
+      69              :       ));
+      70              :     }
+      71              :   }
+      72              : 
+      73            0 :   void _onPreparationFormPreparationStepRemoved(
+      74              :     PreparationFormPreparationStepRemoved event,
+      75              :     Emitter<PreparationFormState> emit,
+      76              :   ) {
+      77              :     final removedList =
+      78            0 :         List<PreparationStepFormState>.from(state.preparationStepList);
+      79            0 :     removedList.removeWhere((element) => element.id == event.preparationStepId);
+      80              : 
+      81            0 :     emit(state.copyWith(
+      82              :       preparationStepList: removedList,
+      83              :     ));
+      84              :   }
+      85              : 
+      86            0 :   void _onPreparationFormPreparationStepNameChanged(
+      87              :     PreparationFormPreparationStepNameChanged event,
+      88              :     Emitter<PreparationFormState> emit,
+      89              :   ) {
+      90              :     final changedList =
+      91            0 :         List<PreparationStepFormState>.from(state.preparationStepList);
+      92            0 :     changedList[event.index] = changedList[event.index].copyWith(
+      93              :       preparationName:
+      94            0 :           PreparationNameInputModel.dirty(event.preparationStepName),
+      95              :     );
+      96              : 
+      97            0 :     final isValid = _validate(changedList);
+      98            0 :     emit(state.copyWith(
+      99              :       preparationStepList: changedList,
+     100              :       isValid: isValid,
+     101              :     ));
+     102              :   }
+     103              : 
+     104            0 :   void _onPreparationFormPreparationStepTimeChanged(
+     105              :     PreparationFormPreparationStepTimeChanged event,
+     106              :     Emitter<PreparationFormState> emit,
+     107              :   ) {
+     108              :     final changedList =
+     109            0 :         List<PreparationStepFormState>.from(state.preparationStepList);
+     110            0 :     changedList[event.index] = changedList[event.index].copyWith(
+     111              :       preparationTime:
+     112            0 :           PreparationTimeInputModel.dirty(event.preparationStepTime),
+     113              :     );
+     114            0 :     final isValid = _validate(changedList);
+     115            0 :     emit(state.copyWith(
+     116              :       preparationStepList: changedList,
+     117              :       isValid: isValid,
+     118              :     ));
+     119              :   }
+     120              : 
+     121            0 :   void _onPreparationFormPreparationStepOrderChanged(
+     122              :     PreparationFormPreparationStepOrderChanged event,
+     123              :     Emitter<PreparationFormState> emit,
+     124              :   ) {
+     125              :     final changedList =
+     126            0 :         List<PreparationStepFormState>.from(state.preparationStepList);
+     127            0 :     int oldIndex = event.oldIndex;
+     128            0 :     int newIndex = event.newIndex;
+     129            0 :     if (oldIndex < newIndex) {
+     130            0 :       newIndex -= 1;
+     131              :     }
+     132              : 
+     133            0 :     final item = changedList.removeAt(oldIndex);
+     134            0 :     changedList.insert(newIndex, item);
+     135              : 
+     136            0 :     emit(state.copyWith(
+     137              :       preparationStepList: changedList,
+     138              :     ));
+     139              :   }
+     140              : 
+     141            0 :   bool _validate(List<PreparationStepFormState> preparationStepList) {
+     142            0 :     final isValid = preparationStepList.isNotEmpty &&
+     143            0 :         Formz.validate(preparationStepList
+     144            0 :             .map((e) => [e.preparationName, e.preparationTime])
+     145            0 :             .expand((element) => element)
+     146            0 :             .cast<FormzInput<dynamic, dynamic>>()
+     147            0 :             .toList());
+     148              :     return isValid;
+     149              :   }
+     150              : 
+     151            0 :   FutureOr<void> _onPreparationFormPreparationStepCreationRequested(
+     152              :       PreparationFormPreparationStepCreationRequested event,
+     153              :       Emitter<PreparationFormState> emit) {
+     154            0 :     emit(state.copyWith(status: PreparationFormStatus.adding));
+     155              :   }
+     156              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_event.dart.gcov.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_event.dart.gcov.html new file mode 100644 index 00000000..1abcd522 --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_event.dart.gcov.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_event.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc - preparation_form_event.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %220
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'preparation_form_bloc.dart';
+       2              : 
+       3              : sealed class PreparationFormEvent extends Equatable {
+       4            0 :   const PreparationFormEvent();
+       5              : 
+       6            0 :   @override
+       7            0 :   List<Object> get props => [];
+       8              : }
+       9              : 
+      10              : final class PreparationFormEditRequested extends PreparationFormEvent {
+      11              :   final PreparationEntity preparationEntity;
+      12              : 
+      13            0 :   const PreparationFormEditRequested({required this.preparationEntity});
+      14              : 
+      15            0 :   @override
+      16            0 :   List<Object> get props => [];
+      17              : }
+      18              : 
+      19              : final class PreparationFormPreparationStepCreated extends PreparationFormEvent {
+      20              :   final PreparationStepFormState preparationStep;
+      21              : 
+      22            0 :   const PreparationFormPreparationStepCreated({required this.preparationStep});
+      23              : 
+      24            0 :   @override
+      25            0 :   List<Object> get props => [preparationStep];
+      26              : }
+      27              : 
+      28              : final class PreparationFormPreparationStepRemoved extends PreparationFormEvent {
+      29              :   final String preparationStepId;
+      30              : 
+      31            0 :   const PreparationFormPreparationStepRemoved(
+      32              :       {required this.preparationStepId});
+      33              : 
+      34            0 :   @override
+      35            0 :   List<Object> get props => [preparationStepId];
+      36              : }
+      37              : 
+      38              : final class PreparationFormPreparationStepNameChanged
+      39              :     extends PreparationFormEvent {
+      40              :   final int index;
+      41              :   final String preparationStepName;
+      42              : 
+      43            0 :   const PreparationFormPreparationStepNameChanged(
+      44              :       {required this.index, required this.preparationStepName});
+      45              : 
+      46            0 :   @override
+      47            0 :   List<Object> get props => [index, preparationStepName];
+      48              : }
+      49              : 
+      50              : final class PreparationFormPreparationStepTimeChanged
+      51              :     extends PreparationFormEvent {
+      52              :   final int index;
+      53              :   final Duration preparationStepTime;
+      54              : 
+      55            0 :   const PreparationFormPreparationStepTimeChanged(
+      56              :       {required this.index, required this.preparationStepTime});
+      57              : 
+      58            0 :   @override
+      59            0 :   List<Object> get props => [index, preparationStepTime];
+      60              : }
+      61              : 
+      62              : final class PreparationFormPreparationStepOrderChanged
+      63              :     extends PreparationFormEvent {
+      64              :   final int oldIndex;
+      65              :   final int newIndex;
+      66              : 
+      67            0 :   const PreparationFormPreparationStepOrderChanged(
+      68              :       {required this.oldIndex, required this.newIndex});
+      69              : 
+      70            0 :   @override
+      71            0 :   List<Object> get props => [oldIndex, newIndex];
+      72              : }
+      73              : 
+      74              : final class PreparationFormPreparationStepCreationRequested
+      75              :     extends PreparationFormEvent {
+      76            0 :   const PreparationFormPreparationStepCreationRequested();
+      77              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_state.dart.gcov.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_state.dart.gcov.html new file mode 100644 index 00000000..6fff1e51 --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_state.dart.gcov.html @@ -0,0 +1,153 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_state.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc - preparation_form_state.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %380
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'preparation_form_bloc.dart';
+       2              : 
+       3              : enum PreparationFormStatus { initial, success, adding }
+       4              : 
+       5              : final class PreparationFormState extends Equatable {
+       6            0 :   const PreparationFormState({
+       7              :     this.status = PreparationFormStatus.initial,
+       8              :     this.preparationStepList = const [],
+       9              :     this.isValid = false,
+      10              :   });
+      11              : 
+      12            0 :   factory PreparationFormState.fromEntity(PreparationEntity preparationEntity) {
+      13            0 :     final List<PreparationStepFormState> preparationStepFormStateList = [];
+      14              :     String? nextPreparationStepId;
+      15              : 
+      16            0 :     final int length = preparationEntity.preparationStepList.length;
+      17            0 :     for (var i = 0; i < length; i++) {
+      18            0 :       for (var j = 0; j < length; j++) {
+      19            0 :         final currentPreparationStep = preparationEntity.preparationStepList[j];
+      20            0 :         if (currentPreparationStep.nextPreparationId == nextPreparationStepId) {
+      21            0 :           nextPreparationStepId = currentPreparationStep.id;
+      22            0 :           preparationStepFormStateList.add(
+      23            0 :             PreparationStepFormState(
+      24            0 :               id: currentPreparationStep.id,
+      25            0 :               preparationName: PreparationNameInputModel.pure(
+      26            0 :                   currentPreparationStep.preparationName),
+      27            0 :               preparationTime: PreparationTimeInputModel.pure(
+      28            0 :                   currentPreparationStep.preparationTime),
+      29              :             ),
+      30              :           );
+      31              :           break;
+      32              :         }
+      33              :       }
+      34              :     }
+      35            0 :     return PreparationFormState(
+      36              :       status: PreparationFormStatus.success,
+      37            0 :       preparationStepList: preparationStepFormStateList.reversed.toList(),
+      38              :     );
+      39              :   }
+      40              : 
+      41            0 :   PreparationEntity toPreparationEntity() {
+      42            0 :     final steps = preparationStepList
+      43            0 :         .mapIndexed((index, step) => PreparationStepEntity(
+      44            0 :               id: step.id,
+      45            0 :               preparationName: step.preparationName.value,
+      46            0 :               preparationTime: step.preparationTime.value,
+      47            0 :               nextPreparationId: index < preparationStepList.length - 1
+      48            0 :                   ? preparationStepList[index + 1].id
+      49              :                   : null, // if not last step, set next step id
+      50              :             ))
+      51            0 :         .toList();
+      52            0 :     return PreparationEntity(preparationStepList: steps);
+      53              :   }
+      54              : 
+      55              :   final PreparationFormStatus status;
+      56              :   final List<PreparationStepFormState> preparationStepList;
+      57              :   final bool isValid;
+      58              : 
+      59            0 :   PreparationFormState copyWith({
+      60              :     PreparationFormStatus? status,
+      61              :     List<PreparationStepFormState>? preparationStepList,
+      62              :     bool? isValid,
+      63              :   }) {
+      64            0 :     return PreparationFormState(
+      65            0 :       status: status ?? this.status,
+      66            0 :       preparationStepList: preparationStepList ?? this.preparationStepList,
+      67            0 :       isValid: isValid ?? this.isValid,
+      68              :     );
+      69              :   }
+      70              : 
+      71            0 :   @override
+      72            0 :   List<Object> get props => [
+      73            0 :         status,
+      74            0 :         preparationStepList,
+      75            0 :         isValid,
+      76              :       ];
+      77              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index-sort-f.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index-sort-f.html new file mode 100644 index 00000000..fed1c232 --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index-sort-f.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubitCoverageTotalHit
Test:lcov.infoLines:0.0 %220
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
preparation_step_form_cubit.dart +
0.0%
+
0.0 %12
preparation_step_form_state.dart +
0.0%
+
0.0 %10
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index-sort-l.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index-sort-l.html new file mode 100644 index 00000000..04b00acc --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index-sort-l.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubitCoverageTotalHit
Test:lcov.infoLines:0.0 %220
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
preparation_step_form_state.dart +
0.0%
+
0.0 %10
preparation_step_form_cubit.dart +
0.0%
+
0.0 %12
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index.html new file mode 100644 index 00000000..0583f0a7 --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/index.html @@ -0,0 +1,107 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubitCoverageTotalHit
Test:lcov.infoLines:0.0 %220
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
preparation_step_form_cubit.dart +
0.0%
+
0.0 %12
preparation_step_form_state.dart +
0.0%
+
0.0 %10
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart.gcov.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart.gcov.html new file mode 100644 index 00000000..c9b3954a --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart.gcov.html @@ -0,0 +1,111 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit - preparation_step_form_cubit.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %120
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'package:equatable/equatable.dart';
+       2              : import 'package:flutter_bloc/flutter_bloc.dart';
+       3              : import 'package:on_time_front/presentation/onboarding/preparation_name_select/input_models/preparation_name_input_model.dart';
+       4              : import 'package:on_time_front/presentation/onboarding/preparation_time/input_models/preparation_time_input_model.dart';
+       5              : import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart';
+       6              : import 'package:uuid/uuid.dart';
+       7              : 
+       8              : part 'preparation_step_form_state.dart';
+       9              : 
+      10              : class PreparationStepFormCubit extends Cubit<PreparationStepFormState> {
+      11            0 :   PreparationStepFormCubit(
+      12              :     super.initialState, {
+      13              :     required this.preparationFormBloc,
+      14              :   });
+      15              : 
+      16              :   final PreparationFormBloc preparationFormBloc;
+      17              : 
+      18            0 :   void nameChanged(String value) {
+      19            0 :     final preparationName = PreparationNameInputModel.dirty(value);
+      20            0 :     emit(state.copyWith(
+      21            0 :         preparationName: preparationName, isValid: preparationName.isValid));
+      22              :   }
+      23              : 
+      24            0 :   void timeChanged(Duration value) {
+      25            0 :     final preparationTime = PreparationTimeInputModel.dirty(value);
+      26            0 :     emit(state.copyWith(
+      27            0 :         preparationTime: preparationTime, isValid: preparationTime.isValid));
+      28              :   }
+      29              : 
+      30            0 :   void preparationStepSaved() {
+      31            0 :     preparationFormBloc.add(PreparationFormPreparationStepCreated(
+      32            0 :       preparationStep: state,
+      33              :     ));
+      34              :   }
+      35              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_state.dart.gcov.html b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_state.dart.gcov.html new file mode 100644 index 00000000..c38383d3 --- /dev/null +++ b/coverage/html/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_state.dart.gcov.html @@ -0,0 +1,108 @@ + + + + + + + LCOV - lcov.info - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_state.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit - preparation_step_form_state.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %100
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : part of 'preparation_step_form_cubit.dart';
+       2              : 
+       3              : class PreparationStepFormState extends Equatable {
+       4            0 :   PreparationStepFormState({
+       5              :     String? id,
+       6              :     this.preparationName = const PreparationNameInputModel.pure(),
+       7              :     this.preparationTime = const PreparationTimeInputModel.pure(),
+       8              :     this.isValid = false,
+       9            0 :   }) : id = id ?? Uuid().v7();
+      10              : 
+      11              :   final String id;
+      12              :   final PreparationNameInputModel preparationName;
+      13              :   final PreparationTimeInputModel preparationTime;
+      14              :   final bool isValid;
+      15              : 
+      16            0 :   PreparationStepFormState copyWith({
+      17              :     String? id,
+      18              :     PreparationNameInputModel? preparationName,
+      19              :     PreparationTimeInputModel? preparationTime,
+      20              :     bool? isValid,
+      21              :   }) {
+      22            0 :     return PreparationStepFormState(
+      23            0 :       id: id ?? this.id,
+      24            0 :       preparationName: preparationName ?? this.preparationName,
+      25            0 :       preparationTime: preparationTime ?? this.preparationTime,
+      26            0 :       isValid: isValid ?? this.isValid,
+      27              :     );
+      28              :   }
+      29              : 
+      30            0 :   @override
+      31            0 :   List<Object> get props => [id, preparationName, preparationTime, isValid];
+      32              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/shared/constants/early_late_text_images.dart.gcov.html b/coverage/html/presentation/shared/constants/early_late_text_images.dart.gcov.html new file mode 100644 index 00000000..1fd02459 --- /dev/null +++ b/coverage/html/presentation/shared/constants/early_late_text_images.dart.gcov.html @@ -0,0 +1,184 @@ + + + + + + + LCOV - lcov.info - presentation/shared/constants/early_late_text_images.dart + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/shared/constants - early_late_text_images.dartCoverageTotalHit
Test:lcov.infoLines:0.0 %450
Test Date:2025-11-11 18:45:19Functions:-00
+
+ + + + + + + + +

+
            Line data    Source code
+
+       1              : import 'dart:math';
+       2              : 
+       3              : /// 지각 시 표시될 문구들
+       4              : const Map<String, String> lateMessagesWithImages = {
+       5              :   "지구의 자전이 너무 빨랐나 봐요!\n조금 늦었지만 괜찮아요!": 'character_earth.svg',
+       6              :   "시간이 당신을 기다리지 않았지만,\n사람들은 기다려줄 거예요. 아마도요.": 'character.svg',
+       7              :   "‘시간은 금이다’고 했지만,\n오늘은 그 금을 잠시 빌려 쓴 것 같네요!": 'character.svg',
+       8              :   "지각의 달인이 되고 싶지 않다면,\n조금 더 일찍 출발해보아요!": 'character.svg',
+       9              :   "늦었다고 서두르다 넘어지면 더 늦어요.\n살짝 서둘러봐요!": 'character.svg',
+      10              :   "시공간을 뛰어넘는\n타임머신이 있었으면 좋겠어요…!": 'character.svg',
+      11              :   "조금 늦긴 했지만,\n오늘의 기분을 망칠 수는 없죠.\n어서 가보자구요!": 'character.svg',
+      12              :   "늦은 것 자체가 죄는 아니지만,\n더 나은 시간을 만드는 건 우리의 몫이죠.": 'character.svg',
+      13              :   "이미 마음은 현장에 도착해 있었는데,\n몸이 따라오질 않았네요.": 'character.svg',
+      14              :   "영화 주인공은 늦게 등장하는 법이라던가…?\n그 기분으로 출발!": 'character.svg',
+      15              :   "달력이 오늘을 운명의 날로 정해놨나 봐요.\n하지만 우린 이길 수 있어요!": 'character.svg',
+      16              :   "시간은 도망갔지만,\n당신의 열정은 따라잡을 수 있어요!": 'character.svg',
+      17              :   "오늘의 체크리스트는 완벽했지만,\n시간이 체크리스트에 없었던 건가요?": 'character.svg',
+      18              :   "오늘의 지각은 역사를 만들었군요!\n다음엔 새로운 기록을 세우지 않도록 해봐요!": 'character.svg',
+      19              :   "지각계의 마스터가 되어가고 있어요.\n하지만 이제 새로운 길을 찾아봐요!": 'character.svg',
+      20              : };
+      21              : 
+      22              : /// 일찍 준비 시, 분 단위 구간별 문구 맵
+      23            0 : final Map<Range, List<Map<String, String>>> earlyMessagesWithImages = {
+      24            0 :   Range(0, 5): [
+      25            0 :     {"message": "아슬아슬하게 지각을 피했어요!", "image": 'character.svg'},
+      26            0 :     {"message": "우산을 깜빡하지 않을 여유를 벌었어요.", "image": 'character.svg'},
+      27              :   ],
+      28            0 :   Range(6, 10): [
+      29            0 :     {"message": "택시비를 아꼈어요!", "image": 'character.svg'},
+      30            0 :     {"message": "심호흡 한 번 하고\n천천히 걸어갈 시간이 생겼어요.", "image": 'character.svg'},
+      31            0 :     {
+      32              :       "message": "여유롭게 갈 수 있겠어요\n좋아하는 노래와 함께 산뜻하게 출발해봐요",
+      33              :       "image": 'character_headphone.svg'
+      34              :     },
+      35              :   ],
+      36            0 :   Range(11, 15): [
+      37            0 :     {"message": "즐거운 커피 한 잔의\n여유를 얻었어요.", "image": 'character.svg'},
+      38            0 :     {"message": "횡단보도 신호를 기다릴\n스트레스에서 벗어났어요.", "image": 'character.svg'},
+      39              :   ],
+      40            0 :   Range(16, 20): [
+      41            0 :     {"message": "지하철 환승을 여유롭게 할 수 있어요.", "image": 'character.svg'},
+      42            0 :     {"message": "친구를 만나기 전에\n간단히 메시지를 보낼 시간이 생겼어요.", "image": 'character.svg'},
+      43              :   ],
+      44            0 :   Range(21, 30): [
+      45            0 :     {"message": "출발 전에 잊은 물건을\n챙길 기회가 생겼어요!", "image": "character.svg"},
+      46            0 :     {
+      47              :       "message": "예정 시간보다 빠르게 도착해서\n장소를 한 바퀴 둘러볼 수 있어요.",
+      48              :       "image": "character.svg"
+      49              :     },
+      50              :   ],
+      51            0 :   Range(31, 40): [
+      52            0 :     {"message": "부모님께 전화를 걸\n여유로운 시간을 벌었어요.", "image": "character.svg"},
+      53            0 :     {"message": "조금 더 준비된 모습으로\n상대를 만날 수 있어요.", "image": "character.svg"},
+      54              :   ],
+      55            0 :   Range(41, 59): [
+      56            0 :     {
+      57              :       "message": "영화 예고편을 보며\n시간을 보낼 수 있어요!",
+      58              :     },
+      59            0 :     {"message": "약속 장소에서\n조용히 책 몇 페이지를 읽을 수 있어요.", "image": "character.svg"},
+      60              :   ],
+      61            0 :   Range.openEnded(60): [
+      62            0 :     {"message": "삶의 소소한 여유를 얻었어요!", "image": "character.svg"},
+      63            0 :     {"message": "지각 걱정 없이 미리 가서\n주변을 살펴볼 수 있어요.", "image": "character.svg"},
+      64              :   ],
+      65              : };
+      66              : 
+      67              : class Range {
+      68              :   final int start;
+      69              :   final int? end;
+      70              : 
+      71            0 :   Range(this.start, [this.end]) {
+      72            0 :     if (end != null && end! < start) {
+      73            0 :       throw ArgumentError("end 값은 start 값보다 크거나 같아야 합니다.");
+      74              :     }
+      75              :   }
+      76              : 
+      77            0 :   Range.openEnded(this.start) : end = null;
+      78              : 
+      79            0 :   bool contains(int value) {
+      80            0 :     if (end == null) {
+      81            0 :       return value >= start;
+      82              :     }
+      83            0 :     return value >= start && value <= end!;
+      84              :   }
+      85              : }
+      86              : 
+      87            0 : Map<String, String> getEarlyMessage(int value) {
+      88            0 :   for (final range in earlyMessagesWithImages.keys) {
+      89            0 :     if (range.contains(value)) {
+      90            0 :       final list = earlyMessagesWithImages[range]!;
+      91            0 :       return list[Random().nextInt(list.length)];
+      92              :     }
+      93              :   }
+      94            0 :   return {
+      95              :     "message": "정확히 시간을 맞춰 준비했어요! 혹시 몸에 시계라도 있나요?",
+      96              :     "image": 'character.svg'
+      97              :   };
+      98              : }
+      99              : 
+     100              : /// 지각 시 랜덤 문구
+     101            0 : Map<String, String> getLateMessage() {
+     102            0 :   final messages = lateMessagesWithImages.keys.toList();
+     103            0 :   final selectedMessage = messages[Random().nextInt(messages.length)];
+     104            0 :   return {
+     105              :     "message": selectedMessage,
+     106            0 :     "image": lateMessagesWithImages[selectedMessage] ?? 'character.svg'
+     107              :   };
+     108              : }
+        
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/presentation/shared/constants/index.html b/coverage/html/presentation/shared/constants/index.html new file mode 100644 index 00000000..b64ad008 --- /dev/null +++ b/coverage/html/presentation/shared/constants/index.html @@ -0,0 +1,98 @@ + + + + + + + LCOV - lcov.info - presentation/shared/constants + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - presentation/shared/constantsCoverageTotalHit
Test:lcov.infoLines:0.0 %450
Test Date:2025-11-11 18:45:19Functions:-00
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

File Sort by file nameLine Coverage Sort by line coverage
Rate Total Hit
early_late_text_images.dart +
0.0%
+
0.0 %45
Note: 'Function Coverage' columns elided as function owner is not identified.
+
+
+ + + + +
Generated by: LCOV version 2.3.2-1
+
+ + + diff --git a/coverage/html/ruby.png b/coverage/html/ruby.png new file mode 100644 index 0000000000000000000000000000000000000000..991b6d4ec9e78be165e3ef757eed1aada287364d GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^FceV#7`HfI^%F z9+AZi4BSE>%y{W;-5;PJOS+@4BLl<6e(pbstUx|nfKQ0)e^Y%R^MdiLxj>4`)5S5Q b;#P73kj=!v_*DHKNFRfztDnm{r-UW|iOwIS literal 0 HcmV?d00001 diff --git a/coverage/html/snow.png b/coverage/html/snow.png new file mode 100644 index 0000000000000000000000000000000000000000..2cdae107fceec6e7f02ac7acb4a34a82a540caa5 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^MM!lvI6;R0X`wF|Ns97GD8ntt^-nBo-U3d c6}OTTfNUlP#;5A{K>8RwUHx3vIVCg!071?oo&W#< literal 0 HcmV?d00001 diff --git a/coverage/html/updown.png b/coverage/html/updown.png new file mode 100644 index 0000000000000000000000000000000000000000..aa56a238b3e6c435265250f9266cd1b8caba0f20 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^AT}Qd8;}%R+`Ae`*?77*hG?8mPH5^{)z4*}Q$iB}huR`+ literal 0 HcmV?d00001 diff --git a/coverage/lcov.info b/coverage/lcov.info new file mode 100644 index 00000000..8231eece --- /dev/null +++ b/coverage/lcov.info @@ -0,0 +1,4368 @@ +SF:lib/core/database/database.g.dart +DA:10,3 +DA:13,6 +DA:14,3 +DA:17,0 +DA:21,6 +DA:22,3 +DA:24,3 +DA:27,3 +DA:28,9 +DA:29,3 +DA:30,6 +DA:31,3 +DA:34,2 +DA:37,2 +DA:38,2 +DA:39,2 +DA:40,8 +DA:42,2 +DA:43,2 +DA:44,6 +DA:46,0 +DA:51,3 +DA:52,3 +DA:53,1 +DA:55,1 +DA:56,1 +DA:57,2 +DA:58,3 +DA:59,2 +DA:60,3 +DA:64,0 +DA:66,0 +DA:73,1 +DA:74,0 +DA:76,0 +DA:77,0 +DA:78,0 +DA:82,1 +DA:83,1 +DA:84,2 +DA:85,2 +DA:89,0 +DA:91,0 +DA:92,0 +DA:93,0 +DA:94,0 +DA:97,0 +DA:99,0 +DA:100,0 +DA:101,0 +DA:102,0 +DA:106,0 +DA:107,0 +DA:108,0 +DA:110,0 +DA:111,0 +DA:112,0 +DA:113,0 +DA:117,0 +DA:119,0 +DA:120,0 +DA:121,0 +DA:122,0 +DA:123,0 +DA:126,0 +DA:127,0 +DA:128,1 +DA:131,1 +DA:132,3 +DA:133,3 +DA:140,2 +DA:145,0 +DA:149,0 +DA:150,0 +DA:155,0 +DA:156,0 +DA:157,0 +DA:158,0 +DA:162,0 +DA:164,0 +DA:165,0 +DA:166,0 +DA:167,0 +DA:171,2 +DA:173,2 +DA:174,4 +DA:175,8 +DA:177,4 +DA:178,8 +DA:180,4 +DA:181,0 +DA:186,0 +DA:188,0 +DA:189,0 +DA:190,0 +DA:191,0 +DA:192,0 +DA:193,0 +DA:202,3 +DA:205,6 +DA:206,3 +DA:209,0 +DA:213,6 +DA:214,3 +DA:218,3 +DA:222,6 +DA:223,3 +DA:228,6 +DA:229,3 +DA:234,3 +DA:235,6 +DA:237,6 +DA:241,6 +DA:242,3 +DA:246,3 +DA:251,6 +DA:252,3 +DA:256,3 +DA:262,6 +DA:263,3 +DA:265,3 +DA:266,3 +DA:270,6 +DA:271,3 +DA:276,6 +DA:277,3 +DA:281,3 +DA:282,3 +DA:283,3 +DA:284,3 +DA:285,3 +DA:286,3 +DA:287,3 +DA:288,3 +DA:289,3 +DA:290,3 +DA:291,3 +DA:292,3 +DA:294,3 +DA:295,6 +DA:296,3 +DA:299,2 +DA:302,2 +DA:303,2 +DA:304,2 +DA:305,8 +DA:307,2 +DA:308,2 +DA:309,6 +DA:311,0 +DA:313,2 +DA:314,2 +DA:316,4 +DA:317,2 +DA:319,0 +DA:321,2 +DA:322,2 +DA:324,4 +DA:325,2 +DA:327,0 +DA:329,2 +DA:330,2 +DA:331,2 +DA:332,6 +DA:334,2 +DA:335,2 +DA:336,6 +DA:338,2 +DA:339,2 +DA:340,2 +DA:342,4 +DA:343,2 +DA:345,2 +DA:346,2 +DA:348,4 +DA:349,2 +DA:354,3 +DA:355,3 +DA:356,1 +DA:358,1 +DA:359,1 +DA:360,2 +DA:361,3 +DA:362,2 +DA:363,3 +DA:364,2 +DA:365,3 +DA:366,3 +DA:367,2 +DA:368,3 +DA:369,1 +DA:370,3 +DA:371,2 +DA:372,3 +DA:373,2 +DA:374,3 +DA:375,2 +DA:376,3 +DA:377,2 +DA:378,2 +DA:379,3 +DA:380,2 +DA:381,3 +DA:385,0 +DA:387,0 +DA:390,6 +DA:391,3 +DA:392,6 +DA:393,3 +DA:395,6 +DA:396,6 +DA:410,1 +DA:421,0 +DA:423,0 +DA:424,0 +DA:425,0 +DA:426,0 +DA:427,0 +DA:429,0 +DA:430,0 +DA:432,0 +DA:433,0 +DA:434,0 +DA:435,0 +DA:436,0 +DA:437,0 +DA:439,0 +DA:440,0 +DA:442,0 +DA:446,1 +DA:447,1 +DA:448,2 +DA:449,2 +DA:450,2 +DA:451,2 +DA:452,2 +DA:453,2 +DA:454,2 +DA:455,1 +DA:457,2 +DA:458,1 +DA:460,2 +DA:461,2 +DA:465,0 +DA:467,0 +DA:468,0 +DA:469,0 +DA:470,0 +DA:471,0 +DA:472,0 +DA:473,0 +DA:474,0 +DA:475,0 +DA:476,0 +DA:477,0 +DA:478,0 +DA:479,0 +DA:480,0 +DA:483,0 +DA:485,0 +DA:486,0 +DA:487,0 +DA:488,0 +DA:489,0 +DA:490,0 +DA:492,0 +DA:493,0 +DA:494,0 +DA:495,0 +DA:496,0 +DA:497,0 +DA:498,0 +DA:499,0 +DA:503,1 +DA:514,1 +DA:515,1 +DA:516,1 +DA:517,1 +DA:518,1 +DA:519,1 +DA:520,1 +DA:521,1 +DA:522,1 +DA:523,0 +DA:524,1 +DA:526,2 +DA:527,1 +DA:529,0 +DA:530,0 +DA:531,0 +DA:532,0 +DA:533,0 +DA:534,0 +DA:535,0 +DA:536,0 +DA:537,0 +DA:538,0 +DA:539,0 +DA:540,0 +DA:541,0 +DA:542,0 +DA:543,0 +DA:544,0 +DA:545,0 +DA:546,0 +DA:547,0 +DA:548,0 +DA:549,0 +DA:550,0 +DA:554,0 +DA:556,0 +DA:557,0 +DA:558,0 +DA:559,0 +DA:560,0 +DA:561,0 +DA:562,0 +DA:563,0 +DA:564,0 +DA:565,0 +DA:566,0 +DA:567,0 +DA:568,0 +DA:571,0 +DA:572,0 +DA:573,0 +DA:574,0 +DA:575,0 +DA:576,0 +DA:577,0 +DA:578,0 +DA:579,0 +DA:580,0 +DA:581,0 +DA:582,0 +DA:583,1 +DA:586,1 +DA:587,3 +DA:588,3 +DA:589,3 +DA:590,3 +DA:591,3 +DA:592,3 +DA:593,3 +DA:594,3 +DA:595,3 +DA:596,3 +DA:611,2 +DA:624,0 +DA:636,0 +DA:637,0 +DA:638,0 +DA:639,0 +DA:640,0 +DA:653,0 +DA:654,0 +DA:655,0 +DA:656,0 +DA:657,0 +DA:658,0 +DA:659,0 +DA:660,0 +DA:661,0 +DA:662,0 +DA:663,0 +DA:664,0 +DA:668,0 +DA:680,0 +DA:681,0 +DA:682,0 +DA:683,0 +DA:684,0 +DA:685,0 +DA:686,0 +DA:687,0 +DA:688,0 +DA:689,0 +DA:690,0 +DA:691,0 +DA:695,2 +DA:697,2 +DA:698,4 +DA:699,8 +DA:701,4 +DA:702,8 +DA:704,4 +DA:705,8 +DA:707,4 +DA:708,8 +DA:710,4 +DA:711,4 +DA:712,8 +DA:714,4 +DA:715,8 +DA:717,4 +DA:718,8 +DA:720,4 +DA:721,4 +DA:722,2 +DA:723,6 +DA:725,4 +DA:726,8 +DA:728,4 +DA:729,8 +DA:731,4 +DA:732,0 +DA:737,0 +DA:739,0 +DA:740,0 +DA:741,0 +DA:742,0 +DA:743,0 +DA:744,0 +DA:745,0 +DA:746,0 +DA:747,0 +DA:748,0 +DA:749,0 +DA:750,0 +DA:751,0 +DA:752,0 +DA:760,3 +DA:763,6 +DA:764,3 +DA:767,0 +DA:770,6 +DA:771,3 +DA:773,3 +DA:778,6 +DA:779,3 +DA:781,3 +DA:787,6 +DA:788,3 +DA:792,6 +DA:793,3 +DA:797,6 +DA:798,3 +DA:800,3 +DA:802,21 +DA:803,3 +DA:804,6 +DA:805,3 +DA:808,2 +DA:811,2 +DA:812,2 +DA:813,2 +DA:814,8 +DA:816,2 +DA:817,2 +DA:818,6 +DA:820,0 +DA:822,2 +DA:823,2 +DA:824,6 +DA:826,0 +DA:828,2 +DA:829,2 +DA:830,6 +DA:832,0 +DA:834,2 +DA:835,2 +DA:836,6 +DA:838,0 +DA:840,2 +DA:841,2 +DA:842,6 +DA:844,0 +DA:849,3 +DA:850,3 +DA:851,0 +DA:853,0 +DA:854,0 +DA:855,0 +DA:856,0 +DA:857,0 +DA:858,0 +DA:859,0 +DA:860,0 +DA:861,0 +DA:862,0 +DA:863,0 +DA:864,0 +DA:865,0 +DA:866,0 +DA:870,0 +DA:872,0 +DA:883,0 +DA:890,0 +DA:892,0 +DA:893,0 +DA:894,0 +DA:895,0 +DA:896,0 +DA:897,0 +DA:898,0 +DA:902,0 +DA:903,0 +DA:904,0 +DA:905,0 +DA:906,0 +DA:907,0 +DA:908,0 +DA:909,0 +DA:913,0 +DA:915,0 +DA:916,0 +DA:917,0 +DA:918,0 +DA:919,0 +DA:920,0 +DA:921,0 +DA:922,0 +DA:925,0 +DA:927,0 +DA:928,0 +DA:929,0 +DA:930,0 +DA:931,0 +DA:932,0 +DA:933,0 +DA:934,0 +DA:938,0 +DA:945,0 +DA:946,0 +DA:947,0 +DA:948,0 +DA:949,0 +DA:950,0 +DA:951,0 +DA:953,0 +DA:954,0 +DA:955,0 +DA:956,0 +DA:957,0 +DA:958,0 +DA:959,0 +DA:960,0 +DA:964,0 +DA:966,0 +DA:967,0 +DA:968,0 +DA:969,0 +DA:970,0 +DA:971,0 +DA:972,0 +DA:973,0 +DA:974,0 +DA:977,0 +DA:978,0 +DA:979,0 +DA:982,0 +DA:983,0 +DA:984,0 +DA:985,0 +DA:986,0 +DA:987,0 +DA:988,0 +DA:999,2 +DA:1008,0 +DA:1016,0 +DA:1017,0 +DA:1018,0 +DA:1019,0 +DA:1020,0 +DA:1021,0 +DA:1030,0 +DA:1031,0 +DA:1032,0 +DA:1033,0 +DA:1034,0 +DA:1035,0 +DA:1036,0 +DA:1037,0 +DA:1041,0 +DA:1049,0 +DA:1050,0 +DA:1051,0 +DA:1052,0 +DA:1053,0 +DA:1054,0 +DA:1055,0 +DA:1056,0 +DA:1060,2 +DA:1062,2 +DA:1063,4 +DA:1064,8 +DA:1066,4 +DA:1067,8 +DA:1069,4 +DA:1070,8 +DA:1072,4 +DA:1073,8 +DA:1075,4 +DA:1076,8 +DA:1078,4 +DA:1079,8 +DA:1081,4 +DA:1082,0 +DA:1087,0 +DA:1089,0 +DA:1090,0 +DA:1091,0 +DA:1092,0 +DA:1093,0 +DA:1094,0 +DA:1095,0 +DA:1096,0 +DA:1097,0 +DA:1098,0 +DA:1107,3 +DA:1110,6 +DA:1111,3 +DA:1114,0 +DA:1118,6 +DA:1119,3 +DA:1123,3 +DA:1127,6 +DA:1128,3 +DA:1130,3 +DA:1136,6 +DA:1137,3 +DA:1142,3 +DA:1143,6 +DA:1146,3 +DA:1148,3 +DA:1150,18 +DA:1151,3 +DA:1152,6 +DA:1153,3 +DA:1156,0 +DA:1160,0 +DA:1161,0 +DA:1162,0 +DA:1163,0 +DA:1165,0 +DA:1166,0 +DA:1168,0 +DA:1169,0 +DA:1171,0 +DA:1173,0 +DA:1174,0 +DA:1176,0 +DA:1177,0 +DA:1179,0 +DA:1181,0 +DA:1182,0 +DA:1184,0 +DA:1185,0 +DA:1187,0 +DA:1189,0 +DA:1190,0 +DA:1192,0 +DA:1193,0 +DA:1198,3 +DA:1199,3 +DA:1200,0 +DA:1202,0 +DA:1203,0 +DA:1204,0 +DA:1205,0 +DA:1206,0 +DA:1207,0 +DA:1208,0 +DA:1209,0 +DA:1210,0 +DA:1211,0 +DA:1212,0 +DA:1213,0 +DA:1217,0 +DA:1219,0 +DA:1230,0 +DA:1236,0 +DA:1238,0 +DA:1239,0 +DA:1240,0 +DA:1241,0 +DA:1242,0 +DA:1243,0 +DA:1244,0 +DA:1249,0 +DA:1250,0 +DA:1251,0 +DA:1252,0 +DA:1253,0 +DA:1254,0 +DA:1255,0 +DA:1257,0 +DA:1261,0 +DA:1263,0 +DA:1264,0 +DA:1265,0 +DA:1266,0 +DA:1267,0 +DA:1268,0 +DA:1270,0 +DA:1273,0 +DA:1275,0 +DA:1276,0 +DA:1277,0 +DA:1278,0 +DA:1279,0 +DA:1280,0 +DA:1281,0 +DA:1285,0 +DA:1291,0 +DA:1292,0 +DA:1293,0 +DA:1294,0 +DA:1295,0 +DA:1296,0 +DA:1297,0 +DA:1298,0 +DA:1300,0 +DA:1301,0 +DA:1302,0 +DA:1304,0 +DA:1305,0 +DA:1306,0 +DA:1307,0 +DA:1308,0 +DA:1309,0 +DA:1310,0 +DA:1311,0 +DA:1312,0 +DA:1313,0 +DA:1317,0 +DA:1319,0 +DA:1320,0 +DA:1321,0 +DA:1322,0 +DA:1323,0 +DA:1324,0 +DA:1325,0 +DA:1326,0 +DA:1329,0 +DA:1330,0 +DA:1331,0 +DA:1332,0 +DA:1335,0 +DA:1336,0 +DA:1337,0 +DA:1338,0 +DA:1339,0 +DA:1340,0 +DA:1351,0 +DA:1359,0 +DA:1366,0 +DA:1367,0 +DA:1368,0 +DA:1369,0 +DA:1377,0 +DA:1378,0 +DA:1379,0 +DA:1380,0 +DA:1381,0 +DA:1382,0 +DA:1383,0 +DA:1387,0 +DA:1394,0 +DA:1395,0 +DA:1396,0 +DA:1397,0 +DA:1398,0 +DA:1399,0 +DA:1400,0 +DA:1404,0 +DA:1406,0 +DA:1407,0 +DA:1408,0 +DA:1410,0 +DA:1411,0 +DA:1413,0 +DA:1414,0 +DA:1416,0 +DA:1417,0 +DA:1419,0 +DA:1420,0 +DA:1422,0 +DA:1423,0 +DA:1428,0 +DA:1430,0 +DA:1431,0 +DA:1432,0 +DA:1433,0 +DA:1434,0 +DA:1435,0 +DA:1436,0 +DA:1437,0 +DA:1438,0 +DA:1447,3 +DA:1450,6 +DA:1451,3 +DA:1454,0 +DA:1457,6 +DA:1458,3 +DA:1462,3 +DA:1466,6 +DA:1467,3 +DA:1469,3 +DA:1475,6 +DA:1476,3 +DA:1481,3 +DA:1482,6 +DA:1485,3 +DA:1487,3 +DA:1489,18 +DA:1490,3 +DA:1491,6 +DA:1492,3 +DA:1495,2 +DA:1498,2 +DA:1499,2 +DA:1500,2 +DA:1501,8 +DA:1503,2 +DA:1504,2 +DA:1505,6 +DA:1507,0 +DA:1509,2 +DA:1510,2 +DA:1512,4 +DA:1513,2 +DA:1515,0 +DA:1517,2 +DA:1518,2 +DA:1520,4 +DA:1521,2 +DA:1523,0 +DA:1525,2 +DA:1526,2 +DA:1528,4 +DA:1529,2 +DA:1534,3 +DA:1535,3 +DA:1536,2 +DA:1538,0 +DA:1539,2 +DA:1540,4 +DA:1541,6 +DA:1542,4 +DA:1543,6 +DA:1544,6 +DA:1545,4 +DA:1546,4 +DA:1547,6 +DA:1548,6 +DA:1549,4 +DA:1553,0 +DA:1555,0 +DA:1565,2 +DA:1571,0 +DA:1573,0 +DA:1574,0 +DA:1575,0 +DA:1576,0 +DA:1577,0 +DA:1578,0 +DA:1579,0 +DA:1584,2 +DA:1585,2 +DA:1586,4 +DA:1587,4 +DA:1588,4 +DA:1589,4 +DA:1590,2 +DA:1592,4 +DA:1596,0 +DA:1598,0 +DA:1599,0 +DA:1600,0 +DA:1601,0 +DA:1602,0 +DA:1603,0 +DA:1605,0 +DA:1608,0 +DA:1610,0 +DA:1611,0 +DA:1612,0 +DA:1613,0 +DA:1614,0 +DA:1615,0 +DA:1616,0 +DA:1620,0 +DA:1626,0 +DA:1627,0 +DA:1628,0 +DA:1629,0 +DA:1630,0 +DA:1631,0 +DA:1632,0 +DA:1633,0 +DA:1635,0 +DA:1636,0 +DA:1637,0 +DA:1638,0 +DA:1639,0 +DA:1640,0 +DA:1641,0 +DA:1642,0 +DA:1643,0 +DA:1644,0 +DA:1645,0 +DA:1646,0 +DA:1647,0 +DA:1651,0 +DA:1653,0 +DA:1654,0 +DA:1655,0 +DA:1656,0 +DA:1657,0 +DA:1658,0 +DA:1659,0 +DA:1660,0 +DA:1663,0 +DA:1664,0 +DA:1665,0 +DA:1666,0 +DA:1669,0 +DA:1670,0 +DA:1671,0 +DA:1672,0 +DA:1673,0 +DA:1674,0 +DA:1684,2 +DA:1692,0 +DA:1699,0 +DA:1700,0 +DA:1701,0 +DA:1702,0 +DA:1710,0 +DA:1711,0 +DA:1712,0 +DA:1713,0 +DA:1714,0 +DA:1715,0 +DA:1716,0 +DA:1720,0 +DA:1727,0 +DA:1728,0 +DA:1729,0 +DA:1730,0 +DA:1731,0 +DA:1732,0 +DA:1733,0 +DA:1737,2 +DA:1739,2 +DA:1740,4 +DA:1741,8 +DA:1743,4 +DA:1744,8 +DA:1746,4 +DA:1747,8 +DA:1749,4 +DA:1750,8 +DA:1752,4 +DA:1753,8 +DA:1755,4 +DA:1756,0 +DA:1761,0 +DA:1763,0 +DA:1764,0 +DA:1765,0 +DA:1766,0 +DA:1767,0 +DA:1768,0 +DA:1769,0 +DA:1770,0 +DA:1771,0 +DA:1776,8 +DA:1777,0 +DA:1778,6 +DA:1779,6 +DA:1780,6 +DA:1781,3 +DA:1782,3 +DA:1783,3 +DA:1784,3 +DA:1786,2 +DA:1792,0 +DA:1794,0 +DA:1795,3 +DA:1797,18 +DA:1813,0 +DA:1815,0 +DA:1816,0 +DA:1817,0 +DA:1818,0 +DA:1820,0 +DA:1821,0 +DA:1822,0 +DA:1824,0 +DA:1825,0 +DA:1826,0 +DA:1832,0 +DA:1839,0 +DA:1840,0 +DA:1842,0 +DA:1843,0 +DA:1845,0 +DA:1847,0 +DA:1849,0 +DA:1850,0 +DA:1851,0 +DA:1852,0 +DA:1855,0 +DA:1856,0 +DA:1857,0 +DA:1863,0 +DA:1869,0 +DA:1876,0 +DA:1877,0 +DA:1879,0 +DA:1880,0 +DA:1885,0 +DA:1892,0 +DA:1893,0 +DA:1895,0 +DA:1896,0 +DA:1898,0 +DA:1900,0 +DA:1902,0 +DA:1903,0 +DA:1904,0 +DA:1905,0 +DA:1908,0 +DA:1909,0 +DA:1910,0 +DA:1916,0 +DA:1932,0 +DA:1933,0 +DA:1936,0 +DA:1937,0 +DA:1938,0 +DA:1939,0 +DA:1940,0 +DA:1941,0 +DA:1942,0 +DA:1947,0 +DA:1952,0 +DA:1957,0 +DA:1962,0 +DA:1963,0 +DA:1964,0 +DA:1965,0 +DA:1966,0 +DA:1967,0 +DA:1969,0 +DA:1971,0 +DA:1972,0 +DA:1974,0 +DA:1977,0 +DA:1978,0 +DA:1979,0 +DA:1980,0 +DA:1981,0 +DA:1983,0 +DA:2033,0 +DA:2035,0 +DA:2036,0 +DA:2038,0 +DA:2039,0 +DA:2041,0 +DA:2042,0 +DA:2043,0 +DA:2045,0 +DA:2046,0 +DA:2049,0 +DA:2052,0 +DA:2053,0 +DA:2054,0 +DA:2056,0 +DA:2058,0 +DA:2059,0 +DA:2060,0 +DA:2063,0 +DA:2064,0 +DA:2065,0 +DA:2071,0 +DA:2078,0 +DA:2079,0 +DA:2081,0 +DA:2082,0 +DA:2084,0 +DA:2085,0 +DA:2087,0 +DA:2088,0 +DA:2089,0 +DA:2090,0 +DA:2092,0 +DA:2093,0 +DA:2095,0 +DA:2096,0 +DA:2098,0 +DA:2099,0 +DA:2100,0 +DA:2101,0 +DA:2103,0 +DA:2104,0 +DA:2106,0 +DA:2107,0 +DA:2109,0 +DA:2110,0 +DA:2112,0 +DA:2113,0 +DA:2114,0 +DA:2115,0 +DA:2118,0 +DA:2119,0 +DA:2120,0 +DA:2129,0 +DA:2132,0 +DA:2134,0 +DA:2135,0 +DA:2136,0 +DA:2137,0 +DA:2140,0 +DA:2141,0 +DA:2142,0 +DA:2148,0 +DA:2154,0 +DA:2161,0 +DA:2162,0 +DA:2164,0 +DA:2165,0 +DA:2166,0 +DA:2168,0 +DA:2169,0 +DA:2170,0 +DA:2172,0 +DA:2173,0 +DA:2175,0 +DA:2176,0 +DA:2178,0 +DA:2179,0 +DA:2181,0 +DA:2182,0 +DA:2183,0 +DA:2185,0 +DA:2186,0 +DA:2187,0 +DA:2189,0 +DA:2190,0 +DA:2191,0 +DA:2193,0 +DA:2194,0 +DA:2196,0 +DA:2197,0 +DA:2198,0 +DA:2199,0 +DA:2202,0 +DA:2203,0 +DA:2204,0 +DA:2216,0 +DA:2223,0 +DA:2224,0 +DA:2226,0 +DA:2227,0 +DA:2229,0 +DA:2230,0 +DA:2232,0 +DA:2233,0 +DA:2235,0 +DA:2236,0 +DA:2238,0 +DA:2239,0 +DA:2241,0 +DA:2242,0 +DA:2243,0 +DA:2245,0 +DA:2246,0 +DA:2248,0 +DA:2249,0 +DA:2251,0 +DA:2252,0 +DA:2254,0 +DA:2255,0 +DA:2256,0 +DA:2257,0 +DA:2260,0 +DA:2261,0 +DA:2262,0 +DA:2271,0 +DA:2275,0 +DA:2277,0 +DA:2278,0 +DA:2279,0 +DA:2280,0 +DA:2283,0 +DA:2284,0 +DA:2285,0 +DA:2291,0 +DA:2307,0 +DA:2308,0 +DA:2311,0 +DA:2312,0 +DA:2313,0 +DA:2314,0 +DA:2315,0 +DA:2316,0 +DA:2317,0 +DA:2330,0 +DA:2343,0 +DA:2356,0 +DA:2369,0 +DA:2370,0 +DA:2371,0 +DA:2372,0 +DA:2374,0 +DA:2375,0 +DA:2377,0 +DA:2379,0 +DA:2380,0 +DA:2394,0 +DA:2396,0 +DA:2398,0 +DA:2400,0 +DA:2402,0 +DA:2408,0 +DA:2409,0 +DA:2411,0 +DA:2415,0 +DA:2416,0 +DA:2417,0 +DA:2418,0 +DA:2420,0 +DA:2421,0 +DA:2463,0 +DA:2465,0 +DA:2467,0 +DA:2468,0 +DA:2469,0 +DA:2471,0 +DA:2473,0 +DA:2474,0 +DA:2477,0 +DA:2478,0 +DA:2479,0 +DA:2484,0 +DA:2491,0 +DA:2492,0 +DA:2494,0 +DA:2495,0 +DA:2497,0 +DA:2498,0 +DA:2500,0 +DA:2501,0 +DA:2503,0 +DA:2504,0 +DA:2506,0 +DA:2507,0 +DA:2509,0 +DA:2511,0 +DA:2513,0 +DA:2514,0 +DA:2515,0 +DA:2516,0 +DA:2519,0 +DA:2520,0 +DA:2521,0 +DA:2527,0 +DA:2533,0 +DA:2540,0 +DA:2541,0 +DA:2543,0 +DA:2544,0 +DA:2546,0 +DA:2547,0 +DA:2549,0 +DA:2550,0 +DA:2552,0 +DA:2553,0 +DA:2555,0 +DA:2556,0 +DA:2561,0 +DA:2568,0 +DA:2569,0 +DA:2571,0 +DA:2572,0 +DA:2574,0 +DA:2575,0 +DA:2577,0 +DA:2578,0 +DA:2580,0 +DA:2581,0 +DA:2583,0 +DA:2584,0 +DA:2586,0 +DA:2588,0 +DA:2590,0 +DA:2591,0 +DA:2592,0 +DA:2593,0 +DA:2596,0 +DA:2597,0 +DA:2598,0 +DA:2604,0 +DA:2620,0 +DA:2621,0 +DA:2624,0 +DA:2625,0 +DA:2626,0 +DA:2627,0 +DA:2628,0 +DA:2629,0 +DA:2630,0 +DA:2639,0 +DA:2648,0 +DA:2657,0 +DA:2666,0 +DA:2667,0 +DA:2668,0 +DA:2669,0 +DA:2670,0 +DA:2671,0 +DA:2673,0 +DA:2674,0 +DA:2677,0 +DA:2678,0 +DA:2680,0 +DA:2684,0 +DA:2685,0 +DA:2686,0 +DA:2687,0 +DA:2688,0 +DA:2690,0 +DA:2732,0 +DA:2735,0 +DA:2736,0 +DA:2737,0 +DA:2739,0 +DA:2740,0 +DA:2742,0 +DA:2743,0 +DA:2744,0 +DA:2746,0 +DA:2747,0 +DA:2750,0 +DA:2751,0 +DA:2752,0 +DA:2753,0 +DA:2755,0 +DA:2756,0 +DA:2759,0 +DA:2760,0 +DA:2761,0 +DA:2763,0 +DA:2764,0 +DA:2770,0 +DA:2777,0 +DA:2778,0 +DA:2780,0 +DA:2781,0 +DA:2782,0 +DA:2784,0 +DA:2785,0 +DA:2786,0 +DA:2788,0 +DA:2789,0 +DA:2791,0 +DA:2792,0 +DA:2793,0 +DA:2794,0 +DA:2797,0 +DA:2798,0 +DA:2799,0 +DA:2808,0 +DA:2809,0 +DA:2811,0 +DA:2812,0 +DA:2813,0 +DA:2814,0 +DA:2817,0 +DA:2818,0 +DA:2819,0 +DA:2831,0 +DA:2838,0 +DA:2839,0 +DA:2841,0 +DA:2842,0 +DA:2843,0 +DA:2845,0 +DA:2846,0 +DA:2847,0 +DA:2849,0 +DA:2850,0 +DA:2852,0 +DA:2853,0 +DA:2854,0 +DA:2855,0 +DA:2858,0 +DA:2859,0 +DA:2860,0 +DA:2869,0 +DA:2871,0 +DA:2873,0 +DA:2874,0 +DA:2875,0 +DA:2876,0 +DA:2879,0 +DA:2880,0 +DA:2881,0 +DA:2893,0 +DA:2900,0 +DA:2901,0 +DA:2903,0 +DA:2904,0 +DA:2906,0 +DA:2907,0 +DA:2909,0 +DA:2910,0 +DA:2912,0 +DA:2913,0 +DA:2914,0 +DA:2915,0 +DA:2918,0 +DA:2919,0 +DA:2920,0 +DA:2929,0 +DA:2931,0 +DA:2933,0 +DA:2934,0 +DA:2935,0 +DA:2936,0 +DA:2939,0 +DA:2940,0 +DA:2941,0 +DA:2963,0 +DA:2965,0 +DA:2968,0 +DA:2969,0 +DA:2970,0 +DA:2971,0 +DA:2973,0 +DA:2974,0 +DA:2976,0 +DA:2984,0 +DA:2992,0 +DA:3000,0 +DA:3008,0 +DA:3009,0 +DA:3010,0 +DA:3011,0 +DA:3013,0 +DA:3014,0 +DA:3016,0 +DA:3018,0 +DA:3031,0 +DA:3033,0 +DA:3035,0 +DA:3037,0 +DA:3039,0 +DA:3040,0 +DA:3044,0 +DA:3046,0 +DA:3048,0 +DA:3050,0 +DA:3051,0 +DA:3057,0 +DA:3058,0 +DA:3099,0 +DA:3102,0 +DA:3103,0 +DA:3105,0 +DA:3106,0 +DA:3108,0 +DA:3109,0 +DA:3110,0 +DA:3112,0 +DA:3113,0 +DA:3116,0 +DA:3117,0 +DA:3118,0 +DA:3120,0 +DA:3121,0 +DA:3124,0 +DA:3125,0 +DA:3126,0 +DA:3128,0 +DA:3129,0 +DA:3135,0 +DA:3142,0 +DA:3143,0 +DA:3145,0 +DA:3146,0 +DA:3147,0 +DA:3149,0 +DA:3150,0 +DA:3151,0 +DA:3153,0 +DA:3154,0 +DA:3156,0 +DA:3157,0 +DA:3158,0 +DA:3159,0 +DA:3162,0 +DA:3163,0 +DA:3164,0 +DA:3173,0 +DA:3174,0 +DA:3176,0 +DA:3177,0 +DA:3178,0 +DA:3179,0 +DA:3182,0 +DA:3183,0 +DA:3184,0 +DA:3196,0 +DA:3203,0 +DA:3204,0 +DA:3206,0 +DA:3207,0 +DA:3208,0 +DA:3210,0 +DA:3211,0 +DA:3212,0 +DA:3214,0 +DA:3215,0 +DA:3217,0 +DA:3218,0 +DA:3219,0 +DA:3220,0 +DA:3223,0 +DA:3224,0 +DA:3225,0 +DA:3234,0 +DA:3235,0 +DA:3237,0 +DA:3238,0 +DA:3239,0 +DA:3240,0 +DA:3243,0 +DA:3244,0 +DA:3245,0 +DA:3257,0 +DA:3264,0 +DA:3265,0 +DA:3267,0 +DA:3268,0 +DA:3270,0 +DA:3271,0 +DA:3273,0 +DA:3274,0 +DA:3276,0 +DA:3277,0 +DA:3278,0 +DA:3279,0 +DA:3282,0 +DA:3283,0 +DA:3284,0 +DA:3293,0 +DA:3294,0 +DA:3296,0 +DA:3297,0 +DA:3298,0 +DA:3299,0 +DA:3302,0 +DA:3303,0 +DA:3304,0 +DA:3326,0 +DA:3328,0 +DA:3331,0 +DA:3332,0 +DA:3333,0 +DA:3334,0 +DA:3335,0 +DA:3336,0 +DA:3337,0 +DA:3345,0 +DA:3353,0 +DA:3361,0 +DA:3369,0 +DA:3370,0 +DA:3371,0 +DA:3372,0 +DA:3374,0 +DA:3375,0 +DA:3376,0 +DA:3378,0 +DA:3391,0 +DA:3393,0 +DA:3395,0 +DA:3397,0 +DA:3399,0 +DA:3403,0 +DA:3405,0 +DA:3407,0 +DA:3409,0 +DA:3410,0 +DA:3416,0 +DA:3417,0 +DA:3439,0 +DA:3440,0 +DA:3441,0 +DA:3442,0 +DA:3443,0 +DA:3444,0 +DA:3445,0 +DA:3446,0 +DA:3447,0 +DA:3448,0 +DA:3449,0 +LF:1601 +LH:385 +end_of_record +SF:lib/core/database/database.dart +DA:35,3 +DA:37,3 +DA:39,3 +DA:42,3 +DA:43,3 +DA:44,3 +DA:45,3 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:53,3 +DA:54,3 +DA:58,1 +DA:59,1 +DA:61,1 +DA:62,1 +DA:63,1 +LF:18 +LH:14 +end_of_record +SF:lib/core/database/riverpod.g.dart +DA:9,1 +DA:13,3 +LF:2 +LH:2 +end_of_record +SF:lib/core/database/riverpod.dart +DA:7,1 +DA:9,1 +LF:2 +LH:2 +end_of_record +SF:lib/core/utils/json_converters/duration_json_converters.dart +DA:5,3 +DA:7,1 +DA:9,1 +DA:12,2 +DA:14,2 +LF:5 +LH:5 +end_of_record +SF:lib/data/daos/place_dao.g.dart +DA:7,0 +LF:1 +LH:0 +end_of_record +SF:lib/data/daos/place_dao.dart +DA:11,2 +DA:13,1 +DA:14,4 +DA:15,1 +DA:19,0 +DA:20,0 +DA:21,0 +LF:7 +LH:4 +end_of_record +SF:lib/data/daos/preparation_schedule_dao.g.dart +DA:7,0 +DA:8,0 +DA:9,0 +DA:10,0 +DA:11,0 +LF:5 +LH:0 +end_of_record +SF:lib/data/daos/preparation_schedule_dao.dart +DA:20,0 +DA:22,0 +DA:26,0 +DA:28,0 +DA:29,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:43,0 +DA:47,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:53,0 +DA:54,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:62,0 +DA:66,0 +DA:67,0 +DA:68,0 +DA:69,0 +DA:70,0 +DA:71,0 +DA:74,0 +DA:75,0 +DA:79,0 +DA:82,0 +DA:84,0 +DA:85,0 +DA:86,0 +DA:89,0 +DA:92,0 +DA:93,0 +DA:94,0 +DA:95,0 +DA:96,0 +DA:100,0 +DA:102,0 +DA:103,0 +DA:104,0 +DA:105,0 +DA:106,0 +DA:107,0 +DA:108,0 +DA:113,0 +DA:116,0 +DA:117,0 +DA:118,0 +DA:121,0 +DA:122,0 +DA:123,0 +DA:124,0 +DA:125,0 +DA:130,0 +DA:131,0 +DA:132,0 +DA:135,0 +DA:136,0 +LF:62 +LH:0 +end_of_record +SF:lib/data/daos/preparation_user_dao.g.dart +DA:7,0 +DA:8,0 +DA:9,0 +LF:3 +LH:0 +end_of_record +SF:lib/data/daos/preparation_user_dao.dart +DA:17,4 +DA:19,2 +DA:23,4 +DA:24,8 +DA:25,4 +DA:29,6 +DA:30,8 +DA:31,2 +DA:32,6 +DA:36,2 +DA:40,2 +DA:41,6 +DA:42,8 +DA:43,2 +DA:45,2 +DA:46,0 +DA:49,2 +DA:50,12 +DA:51,0 +DA:54,2 +DA:58,2 +DA:59,2 +DA:60,2 +DA:61,2 +DA:62,4 +DA:63,2 +DA:66,2 +DA:67,8 +DA:71,2 +DA:74,0 +DA:76,0 +DA:77,0 +DA:78,0 +DA:81,0 +DA:84,0 +DA:85,0 +DA:86,0 +DA:87,0 +DA:88,0 +DA:92,2 +DA:94,6 +DA:95,10 +DA:96,2 +DA:97,2 +DA:98,4 +DA:99,6 +DA:104,2 +DA:105,6 +DA:106,8 +DA:107,2 +DA:109,6 +DA:110,8 +DA:111,2 +DA:112,2 +DA:113,4 +DA:117,6 +DA:118,8 +DA:119,2 +DA:121,4 +LF:59 +LH:47 +end_of_record +SF:lib/data/daos/schedule_dao.g.dart +DA:7,0 +DA:8,0 +LF:2 +LH:0 +end_of_record +SF:lib/data/daos/schedule_dao.dart +DA:14,2 +DA:16,1 +DA:18,4 +DA:19,4 +DA:20,2 +DA:23,1 +DA:29,1 +DA:30,3 +DA:31,5 +DA:32,1 +DA:35,1 +DA:37,5 +DA:38,10 +DA:40,5 +DA:41,1 +DA:42,1 +DA:43,3 +DA:44,3 +DA:51,1 +DA:52,3 +DA:53,5 +DA:54,2 +DA:55,3 +DA:56,1 +DA:59,1 +DA:61,5 +DA:62,10 +DA:64,6 +DA:66,1 +DA:67,4 +DA:68,1 +DA:69,1 +DA:71,2 +DA:72,2 +DA:73,3 +DA:74,3 +DA:80,0 +DA:81,0 +DA:82,0 +DA:84,0 +DA:85,0 +DA:87,0 +DA:88,0 +DA:89,0 +DA:90,0 +LF:45 +LH:36 +end_of_record +SF:lib/data/daos/user_dao.dart +DA:12,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:24,0 +DA:29,0 +DA:30,0 +DA:31,0 +LF:11 +LH:0 +end_of_record +SF:lib/data/daos/user_dao.g.dart +DA:7,0 +LF:1 +LH:0 +end_of_record +SF:lib/data/tables/places_table.dart +DA:5,0 +DA:6,0 +DA:8,0 +DA:9,0 +LF:4 +LH:0 +end_of_record +SF:lib/data/tables/preparation_schedule_table.dart +DA:6,0 +DA:7,0 +DA:8,0 +DA:9,0 +DA:10,0 +DA:11,0 +DA:13,0 +DA:14,0 +LF:8 +LH:0 +end_of_record +SF:lib/data/tables/preparation_user_table.dart +DA:6,0 +DA:7,0 +DA:8,0 +DA:9,0 +DA:10,0 +DA:11,0 +DA:13,0 +DA:14,0 +LF:8 +LH:0 +end_of_record +SF:lib/data/tables/schedules_table.dart +DA:7,0 +DA:8,0 +DA:9,0 +DA:10,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:17,0 +DA:19,0 +DA:20,0 +LF:13 +LH:0 +end_of_record +SF:lib/data/tables/user_table.dart +DA:5,0 +DA:6,0 +DA:7,0 +DA:8,0 +DA:9,0 +DA:10,0 +DA:12,0 +DA:13,0 +LF:8 +LH:0 +end_of_record +SF:lib/domain/entities/preparation_step_entity.dart +DA:10,4 +DA:17,2 +DA:18,2 +DA:19,2 +DA:21,2 +DA:22,4 +DA:23,2 +DA:27,0 +DA:28,0 +DA:29,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:37,0 +DA:39,0 +DA:42,2 +DA:48,2 +DA:49,2 +DA:50,0 +DA:51,0 +DA:52,2 +DA:56,0 +DA:58,0 +LF:23 +LH:11 +end_of_record +SF:lib/domain/entities/preparation_entity.dart +DA:7,4 +DA:11,0 +DA:12,0 +DA:14,0 +DA:18,0 +DA:20,0 +DA:23,0 +DA:24,0 +LF:8 +LH:1 +end_of_record +SF:lib/data/tables/schedule_with_place_model.dart +DA:5,1 +DA:12,1 +DA:13,3 +DA:15,0 +DA:17,0 +LF:5 +LH:3 +end_of_record +SF:lib/domain/entities/user_entity.dart +DA:8,12 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:42,0 +DA:43,0 +LF:20 +LH:1 +end_of_record +SF:lib/core/constants/endpoint.dart +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:20,0 +DA:21,0 +DA:23,1 +DA:24,0 +DA:25,2 +DA:26,0 +DA:34,1 +DA:36,1 +DA:37,1 +DA:39,1 +DA:40,1 +DA:42,1 +DA:43,1 +DA:45,0 +DA:46,0 +DA:48,0 +DA:50,0 +DA:53,0 +LF:23 +LH:9 +end_of_record +SF:lib/data/data_sources/schedule_remote_data_source.dart +DA:29,1 +DA:31,1 +DA:35,1 +DA:36,3 +DA:37,1 +DA:38,2 +DA:41,1 +DA:48,0 +DA:52,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:58,0 +DA:65,1 +DA:68,4 +DA:69,2 +DA:72,1 +DA:79,0 +DA:82,0 +DA:83,0 +DA:84,0 +DA:89,0 +DA:92,0 +DA:99,0 +DA:102,0 +DA:103,0 +DA:105,0 +DA:106,0 +DA:108,0 +DA:115,0 +DA:120,0 +DA:121,0 +DA:122,0 +DA:124,0 +DA:125,0 +DA:126,0 +DA:127,0 +DA:128,0 +DA:131,0 +LF:39 +LH:11 +end_of_record +SF:lib/data/models/create_schedule_request_model.dart +DA:19,1 +DA:32,0 +DA:33,0 +DA:35,2 +DA:37,1 +DA:38,1 +DA:39,1 +DA:40,2 +DA:41,2 +DA:42,1 +DA:43,1 +DA:44,2 +DA:45,1 +DA:46,1 +DA:47,2 +DA:48,1 +LF:16 +LH:14 +end_of_record +SF:lib/data/models/create_schedule_request_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:24,1 +DA:26,1 +DA:27,1 +DA:28,1 +DA:29,1 +DA:30,1 +DA:31,2 +DA:32,1 +DA:33,1 +DA:34,1 +DA:35,1 +DA:36,1 +LF:24 +LH:12 +end_of_record +SF:lib/data/models/update_schedule_request_model.dart +DA:18,1 +DA:30,0 +DA:31,0 +DA:33,0 +DA:35,1 +DA:36,1 +DA:37,1 +DA:38,2 +DA:39,2 +DA:40,1 +DA:41,1 +DA:42,2 +DA:43,2 +DA:44,1 +DA:45,1 +LF:15 +LH:12 +end_of_record +SF:lib/data/models/update_schedule_request_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:23,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +LF:22 +LH:0 +end_of_record +SF:lib/domain/entities/place_entity.dart +DA:7,2 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +LF:9 +LH:1 +end_of_record +SF:lib/domain/entities/schedule_entity.dart +DA:20,2 +DA:34,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:68,0 +DA:69,0 +DA:70,0 +DA:71,0 +DA:75,0 +DA:77,0 +DA:80,1 +DA:84,0 +DA:87,1 +DA:89,2 +DA:92,0 +DA:93,0 +DA:94,0 +DA:95,0 +DA:96,0 +DA:97,0 +DA:98,0 +DA:99,0 +DA:100,0 +DA:101,0 +DA:102,0 +DA:103,0 +DA:104,0 +LF:50 +LH:4 +end_of_record +SF:lib/core/dio/app_dio.dart +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:22,0 +DA:27,0 +LF:6 +LH:0 +end_of_record +SF:lib/data/data_sources/preparation_local_data_source.dart +DA:27,0 +DA:29,0 +DA:32,0 +DA:33,0 +DA:36,0 +DA:39,0 +DA:40,0 +DA:43,0 +DA:46,0 +DA:47,0 +DA:50,0 +DA:53,0 +DA:54,0 +DA:57,0 +DA:60,0 +DA:61,0 +DA:64,0 +DA:66,0 +DA:68,0 +DA:69,0 +DA:72,0 +DA:73,0 +DA:77,0 +DA:80,0 +DA:82,0 +DA:83,0 +DA:86,0 +DA:87,0 +LF:28 +LH:0 +end_of_record +SF:lib/data/data_sources/preparation_remote_data_source.dart +DA:33,1 +DA:35,1 +DA:40,1 +DA:41,1 +DA:43,2 +DA:44,1 +DA:45,4 +DA:48,2 +DA:49,1 +DA:56,1 +DA:60,2 +DA:61,1 +DA:62,1 +DA:65,2 +DA:66,1 +DA:73,1 +DA:77,2 +DA:78,1 +DA:81,2 +DA:82,0 +DA:83,0 +DA:85,0 +DA:87,0 +DA:89,1 +DA:96,0 +DA:99,0 +DA:101,0 +DA:102,0 +DA:103,0 +DA:105,0 +DA:107,0 +DA:109,0 +DA:116,0 +DA:121,0 +DA:122,0 +DA:124,0 +DA:125,0 +DA:126,0 +DA:129,0 +DA:130,0 +DA:137,0 +DA:142,0 +DA:143,0 +DA:145,0 +DA:146,0 +DA:147,0 +DA:150,0 +DA:151,0 +LF:48 +LH:20 +end_of_record +SF:lib/data/data_sources/schedule_local_data_source.dart +DA:22,0 +DA:26,0 +DA:28,0 +DA:29,0 +DA:32,0 +DA:34,0 +DA:35,0 +DA:38,0 +DA:41,0 +DA:42,0 +DA:45,0 +DA:49,0 +DA:51,0 +DA:52,0 +DA:55,0 +DA:57,0 +DA:58,0 +LF:17 +LH:0 +end_of_record +SF:lib/data/models/create_defualt_preparation_request_model.dart +DA:13,2 +DA:19,0 +DA:21,0 +DA:23,1 +DA:24,1 +DA:26,2 +DA:30,2 +DA:31,4 +DA:33,2 +DA:34,6 +DA:35,2 +LF:11 +LH:9 +end_of_record +SF:lib/data/models/create_defualt_preparation_request_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:17,0 +DA:20,1 +DA:22,1 +DA:23,1 +DA:24,1 +DA:25,1 +LF:12 +LH:5 +end_of_record +SF:lib/data/data_sources/authentication_remote_data_source.dart +DA:30,0 +DA:32,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:48,0 +DA:55,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:67,0 +DA:68,0 +DA:69,0 +DA:70,0 +DA:72,0 +DA:79,0 +DA:83,0 +DA:84,0 +DA:85,0 +DA:87,0 +DA:88,0 +DA:89,0 +DA:90,0 +DA:92,0 +DA:99,0 +DA:103,0 +DA:104,0 +DA:105,0 +DA:107,0 +DA:108,0 +DA:109,0 +DA:110,0 +DA:112,0 +DA:119,0 +DA:122,0 +DA:123,0 +DA:124,0 +DA:125,0 +DA:127,0 +LF:43 +LH:0 +end_of_record +SF:lib/data/data_sources/notification_remote_data_source.dart +DA:14,0 +DA:16,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:24,0 +DA:25,0 +LF:7 +LH:0 +end_of_record +SF:lib/data/data_sources/preparation_with_time_local_data_source.dart +DA:20,0 +DA:23,0 +DA:24,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:36,0 +DA:39,0 +DA:42,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:49,0 +DA:50,0 +DA:52,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:62,0 +DA:64,0 +DA:67,0 +DA:69,0 +DA:70,0 +DA:71,0 +LF:34 +LH:0 +end_of_record +SF:lib/data/data_sources/token_local_data_source.dart +DA:22,0 +DA:24,0 +DA:25,0 +DA:28,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:36,0 +DA:40,0 +DA:42,0 +DA:43,0 +DA:46,0 +DA:48,0 +LF:13 +LH:0 +end_of_record +SF:lib/data/repositories/preparation_repository_impl.dart +DA:17,1 +DA:22,0 +DA:28,0 +DA:29,0 +DA:38,0 +DA:42,0 +DA:49,0 +DA:53,0 +DA:54,0 +DA:61,0 +DA:65,0 +DA:72,1 +DA:76,1 +DA:77,1 +DA:84,0 +DA:88,0 +LF:16 +LH:4 +end_of_record +SF:lib/data/repositories/schedule_repository_impl.dart +DA:16,1 +DA:17,1 +DA:21,1 +DA:26,0 +DA:28,0 +DA:30,1 +DA:33,2 +DA:35,1 +DA:36,5 +DA:42,1 +DA:45,2 +DA:47,1 +DA:48,5 +DA:54,1 +DA:57,2 +DA:58,1 +DA:59,5 +DA:66,1 +DA:71,2 +DA:72,1 +DA:73,5 +DA:80,1 +DA:83,2 +DA:84,5 +DA:85,1 +DA:86,1 +DA:93,0 +DA:96,0 +LF:28 +LH:24 +end_of_record +SF:lib/data/repositories/timed_preparation_repository_impl.dart +DA:10,0 +DA:12,0 +DA:14,0 +DA:17,0 +DA:19,0 +DA:22,0 +DA:25,0 +LF:7 +LH:0 +end_of_record +SF:lib/data/repositories/user_repository_impl.dart +DA:25,0 +DA:26,0 +DA:28,0 +DA:31,0 +DA:34,0 +DA:35,0 +DA:42,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:54,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:69,0 +DA:71,0 +DA:72,0 +DA:75,0 +DA:79,0 +DA:80,0 +DA:82,0 +DA:85,0 +DA:86,0 +DA:87,0 +DA:88,0 +DA:89,0 +DA:91,0 +DA:94,0 +DA:99,0 +DA:107,0 +DA:113,0 +DA:114,0 +DA:115,0 +DA:116,0 +DA:117,0 +DA:119,0 +DA:124,0 +DA:126,0 +LF:38 +LH:0 +end_of_record +SF:lib/domain/use-cases/create_custom_preparation_use_case.dart +DA:9,0 +DA:11,0 +DA:13,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/create_schedule_with_place_use_case.dart +DA:9,0 +DA:11,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/delete_schedule_use_case.dart +DA:9,0 +DA:11,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/finish_schedule_use_case.dart +DA:8,0 +DA:10,0 +DA:11,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/get_default_preparation_use_case.dart +DA:9,0 +DA:11,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart +DA:18,0 +DA:24,0 +DA:25,0 +DA:27,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:37,0 +DA:39,0 +DA:46,0 +DA:48,0 +DA:50,0 +LF:13 +LH:0 +end_of_record +SF:lib/domain/use-cases/get_preparation_by_schedule_id_use_case.dart +DA:9,0 +DA:11,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/get_schedule_by_id_use_case.dart +DA:9,0 +DA:11,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/get_schedules_by_date_use_case.dart +DA:9,0 +DA:11,0 +DA:13,0 +DA:14,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:21,0 +LF:9 +LH:0 +end_of_record +SF:lib/domain/use-cases/load_schedules_for_month_use_case.dart +DA:8,0 +DA:10,0 +DA:11,0 +DA:12,0 +DA:14,0 +LF:5 +LH:0 +end_of_record +SF:lib/domain/use-cases/load_schedules_for_week_use_case.dart +DA:7,0 +DA:9,0 +DA:10,0 +DA:11,0 +DA:13,0 +LF:5 +LH:0 +end_of_record +SF:lib/domain/use-cases/load_user_use_case.dart +DA:8,0 +DA:10,0 +DA:11,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/onboard_use_case.dart +DA:11,0 +DA:13,0 +DA:17,0 +DA:19,0 +LF:4 +LH:0 +end_of_record +SF:lib/domain/use-cases/save_timed_preparation_use_case.dart +DA:9,0 +DA:11,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/sign_out_use_case.dart +DA:8,0 +DA:10,0 +DA:11,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/stream_user_use_case.dart +DA:9,0 +DA:11,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/update_default_preparation_use_case.dart +DA:9,0 +DA:11,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/update_preparation_by_schedule_id_use_case.dart +DA:9,0 +DA:11,0 +DA:13,0 +LF:3 +LH:0 +end_of_record +SF:lib/domain/use-cases/update_schedule_use_case.dart +DA:9,0 +DA:11,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/presentation/app/bloc/auth/auth_state.dart +DA:10,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:16,0 +DA:21,0 +DA:29,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:39,0 +DA:40,0 +LF:12 +LH:0 +end_of_record +SF:lib/presentation/app/bloc/auth/auth_event.dart +DA:4,0 +DA:8,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/presentation/app/bloc/auth/auth_bloc.dart +DA:17,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:30,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:41,0 +DA:42,0 +DA:45,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:54,0 +DA:58,0 +DA:62,0 +DA:65,0 +DA:67,0 +DA:68,0 +LF:23 +LH:0 +end_of_record +SF:lib/presentation/app/bloc/schedule/schedule_event.dart +DA:4,8 +DA:6,0 +DA:7,0 +DA:11,4 +DA:13,0 +DA:14,0 +DA:20,0 +DA:24,0 +DA:25,0 +DA:29,4 +DA:31,0 +DA:32,0 +DA:36,0 +DA:38,0 +DA:39,0 +DA:45,0 +DA:47,0 +DA:48,0 +DA:52,0 +DA:58,0 +DA:60,0 +DA:61,0 +LF:22 +LH:3 +end_of_record +SF:lib/presentation/app/bloc/schedule/schedule_state.dart +DA:12,4 +DA:17,4 +DA:19,4 +DA:21,0 +DA:22,0 +DA:24,0 +DA:25,0 +DA:27,0 +DA:28,0 +DA:33,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:51,0 +DA:52,0 +LF:21 +LH:3 +end_of_record +SF:lib/presentation/app/bloc/schedule/schedule_bloc.dart +DA:18,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:39,0 +DA:41,0 +DA:43,0 +DA:44,0 +DA:46,0 +DA:47,0 +DA:52,0 +DA:55,0 +DA:56,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:68,0 +DA:69,0 +DA:70,0 +DA:71,0 +DA:75,0 +DA:78,0 +DA:80,0 +DA:81,0 +DA:82,0 +DA:83,0 +DA:87,0 +DA:88,0 +DA:90,0 +DA:91,0 +DA:94,0 +DA:95,0 +DA:97,0 +DA:100,0 +DA:102,0 +DA:103,0 +DA:104,0 +DA:106,0 +DA:107,0 +DA:108,0 +DA:111,0 +DA:113,0 +DA:114,0 +DA:116,0 +DA:118,0 +DA:119,0 +DA:120,0 +DA:122,0 +DA:126,0 +DA:127,0 +DA:129,0 +DA:131,0 +DA:132,0 +DA:137,0 +DA:138,0 +DA:139,0 +DA:141,0 +DA:142,0 +DA:143,0 +DA:144,0 +DA:145,0 +DA:146,0 +DA:150,0 +DA:153,0 +DA:154,0 +DA:155,0 +DA:156,0 +DA:159,0 +DA:160,0 +DA:161,0 +DA:162,0 +LF:81 +LH:0 +end_of_record +SF:lib/presentation/calendar/bloc/monthly_schedules_event.dart +DA:4,0 +DA:6,0 +DA:7,0 +DA:14,0 +DA:16,0 +DA:17,0 +DA:19,0 +DA:20,0 +DA:26,0 +DA:28,0 +DA:29,0 +DA:31,0 +DA:32,0 +DA:38,0 +DA:40,0 +DA:41,0 +LF:16 +LH:0 +end_of_record +SF:lib/presentation/calendar/bloc/monthly_schedules_state.dart +DA:6,0 +DA:19,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:37,0 +DA:39,0 +LF:11 +LH:0 +end_of_record +SF:lib/presentation/calendar/bloc/monthly_schedules_bloc.dart +DA:16,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:30,0 +DA:34,0 +DA:36,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:50,0 +DA:51,0 +DA:53,0 +DA:58,0 +DA:59,0 +DA:61,0 +DA:62,0 +DA:67,0 +DA:73,0 +DA:74,0 +DA:76,0 +DA:77,0 +DA:78,0 +DA:79,0 +DA:80,0 +DA:82,0 +DA:88,0 +DA:89,0 +DA:90,0 +DA:91,0 +DA:92,0 +DA:93,0 +DA:95,0 +DA:96,0 +DA:97,0 +DA:98,0 +DA:99,0 +DA:102,0 +DA:105,0 +DA:106,0 +DA:107,0 +DA:108,0 +DA:109,0 +DA:110,0 +DA:111,0 +DA:112,0 +DA:113,0 +DA:114,0 +DA:115,0 +DA:116,0 +DA:117,0 +DA:119,0 +DA:120,0 +DA:122,0 +DA:127,0 +DA:128,0 +DA:131,0 +DA:132,0 +DA:133,0 +DA:139,0 +DA:144,0 +DA:145,0 +DA:147,0 +DA:149,0 +DA:150,0 +LF:74 +LH:0 +end_of_record +SF:lib/presentation/early_late/bloc/early_late_screen_event.dart +DA:4,0 +DA:6,0 +DA:7,0 +DA:13,0 +DA:15,0 +DA:16,0 +DA:22,0 +DA:24,0 +DA:25,0 +DA:31,0 +DA:33,0 +DA:34,0 +LF:12 +LH:0 +end_of_record +SF:lib/presentation/early_late/bloc/early_late_screen_bloc.dart +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:18,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:25,0 +DA:26,0 +DA:28,0 +DA:29,0 +DA:31,0 +DA:32,0 +DA:36,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:49,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:54,0 +DA:56,0 +DA:58,0 +DA:59,0 +DA:60,0 +LF:31 +LH:0 +end_of_record +SF:lib/presentation/early_late/bloc/early_late_screen_state.dart +DA:4,0 +DA:6,0 +DA:7,0 +DA:18,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +LF:10 +LH:0 +end_of_record +SF:lib/presentation/home/bloc/weekly_schedules_state.dart +DA:6,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:21,0 +DA:22,0 +DA:24,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +LF:19 +LH:0 +end_of_record +SF:lib/presentation/home/bloc/weekly_schedules_event.dart +DA:4,0 +DA:6,0 +DA:7,0 +DA:13,0 +DA:15,0 +DA:16,0 +DA:18,0 +DA:19,0 +LF:8 +LH:0 +end_of_record +SF:lib/presentation/home/bloc/weekly_schedules_bloc.dart +DA:15,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:23,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:31,0 +DA:32,0 +LF:13 +LH:0 +end_of_record +SF:lib/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_event.dart +DA:4,0 +DA:6,0 +DA:7,0 +DA:11,0 +DA:14,0 +DA:15,0 +DA:19,0 +DA:21,0 +DA:22,0 +DA:26,0 +DA:28,0 +DA:29,0 +DA:33,0 +DA:37,0 +DA:38,0 +LF:15 +LH:0 +end_of_record +SF:lib/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_state.dart +DA:11,0 +DA:20,0 +DA:21,0 +DA:23,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +LF:8 +LH:0 +end_of_record +SF:lib/presentation/my_page/preparation_spare_time_edit/bloc/default_preparation_spare_time_form_bloc.dart +DA:15,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:30,0 +DA:32,0 +DA:36,0 +DA:38,0 +DA:41,0 +DA:45,0 +DA:47,0 +DA:48,0 +DA:50,0 +DA:55,0 +DA:57,0 +DA:58,0 +DA:60,0 +DA:61,0 +DA:67,0 +DA:69,0 +DA:70,0 +DA:76,0 +DA:81,0 +DA:82,0 +DA:83,0 +DA:84,0 +DA:87,0 +DA:91,0 +LF:30 +LH:0 +end_of_record +SF:lib/presentation/onboarding/cubit/onboarding_state.dart +DA:4,0 +DA:14,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:37,0 +DA:41,0 +DA:42,0 +DA:46,0 +DA:58,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:67,0 +DA:68,0 +DA:70,0 +DA:74,0 +DA:76,0 +LF:28 +LH:0 +end_of_record +SF:lib/presentation/onboarding/cubit/onboarding_cubit.dart +DA:12,0 +DA:14,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:26,0 +DA:30,0 +DA:34,0 +DA:37,0 +LF:11 +LH:0 +end_of_record +SF:lib/presentation/schedule_create/bloc/schedule_form_event.dart +DA:4,0 +DA:6,0 +DA:7,0 +DA:13,0 +DA:15,0 +DA:16,0 +DA:20,0 +DA:26,0 +DA:28,0 +DA:29,0 +DA:36,0 +DA:39,0 +DA:40,0 +DA:46,0 +DA:48,0 +DA:49,0 +DA:55,0 +DA:57,0 +DA:58,0 +DA:64,0 +DA:66,0 +DA:67,0 +DA:73,0 +DA:75,0 +DA:76,0 +DA:80,0 +DA:84,0 +DA:90,0 +DA:92,0 +DA:93,0 +LF:30 +LH:0 +end_of_record +SF:lib/presentation/schedule_create/bloc/schedule_form_bloc.dart +DA:21,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:52,0 +DA:56,0 +DA:61,0 +DA:64,0 +DA:66,0 +DA:68,0 +DA:69,0 +DA:70,0 +DA:71,0 +DA:72,0 +DA:73,0 +DA:76,0 +DA:77,0 +DA:82,0 +DA:86,0 +DA:91,0 +DA:93,0 +DA:95,0 +DA:107,0 +DA:111,0 +DA:114,0 +DA:118,0 +DA:119,0 +DA:120,0 +DA:121,0 +DA:122,0 +DA:123,0 +DA:124,0 +DA:129,0 +DA:133,0 +DA:136,0 +DA:140,0 +DA:143,0 +DA:147,0 +DA:150,0 +DA:155,0 +DA:162,0 +DA:163,0 +DA:168,0 +DA:172,0 +DA:173,0 +DA:174,0 +DA:175,0 +DA:176,0 +DA:180,0 +DA:184,0 +DA:185,0 +DA:186,0 +DA:187,0 +DA:188,0 +DA:192,0 +DA:194,0 +LF:65 +LH:0 +end_of_record +SF:lib/presentation/schedule_create/bloc/schedule_form_state.dart +DA:20,0 +DA:32,0 +DA:34,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:65,0 +DA:69,0 +DA:70,0 +DA:71,0 +DA:72,0 +DA:73,0 +DA:74,0 +DA:75,0 +DA:76,0 +DA:77,0 +DA:78,0 +DA:83,0 +DA:84,0 +DA:85,0 +DA:86,0 +DA:87,0 +DA:88,0 +DA:89,0 +DA:90,0 +DA:91,0 +DA:92,0 +DA:93,0 +DA:94,0 +LF:41 +LH:0 +end_of_record +SF:lib/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_event.dart +DA:4,0 +DA:6,0 +DA:7,0 +DA:13,0 +DA:15,0 +DA:16,0 +DA:22,0 +DA:24,0 +DA:25,0 +DA:31,0 +DA:34,0 +DA:35,0 +DA:43,0 +DA:46,0 +DA:47,0 +DA:55,0 +DA:58,0 +DA:59,0 +DA:67,0 +DA:70,0 +DA:71,0 +DA:76,0 +LF:22 +LH:0 +end_of_record +SF:lib/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_state.dart +DA:6,0 +DA:12,0 +DA:13,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:35,0 +DA:37,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:51,0 +DA:52,0 +DA:59,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:67,0 +DA:71,0 +DA:72,0 +DA:73,0 +DA:74,0 +DA:75,0 +LF:38 +LH:0 +end_of_record +SF:lib/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/bloc/preparation_form_bloc.dart +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:36,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:45,0 +DA:50,0 +DA:54,0 +DA:56,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:62,0 +DA:64,0 +DA:65,0 +DA:73,0 +DA:78,0 +DA:79,0 +DA:81,0 +DA:86,0 +DA:91,0 +DA:92,0 +DA:94,0 +DA:97,0 +DA:98,0 +DA:104,0 +DA:109,0 +DA:110,0 +DA:112,0 +DA:114,0 +DA:115,0 +DA:121,0 +DA:126,0 +DA:127,0 +DA:128,0 +DA:129,0 +DA:130,0 +DA:133,0 +DA:134,0 +DA:136,0 +DA:141,0 +DA:142,0 +DA:143,0 +DA:144,0 +DA:145,0 +DA:146,0 +DA:147,0 +DA:151,0 +DA:154,0 +LF:62 +LH:0 +end_of_record +SF:lib/core/services/navigation_service.dart +DA:9,0 +DA:10,0 +LF:2 +LH:0 +end_of_record +SF:lib/core/di/di_setup.dart +DA:5,0 +DA:7,0 +DA:12,0 +LF:3 +LH:0 +end_of_record +SF:lib/core/dio/adapters/mobile_adapter.dart +DA:4,0 +DA:5,0 +LF:2 +LH:0 +end_of_record +SF:lib/core/dio/interceptors/logger_interceptor.dart +DA:6,0 +DA:8,0 +DA:9,0 +DA:10,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:17,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:24,0 +DA:27,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:36,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +LF:23 +LH:0 +end_of_record +SF:lib/core/dio/interceptors/token_interceptor.dart +DA:9,0 +DA:23,0 +DA:27,0 +DA:29,0 +DA:31,0 +DA:33,0 +DA:36,0 +DA:38,0 +DA:41,0 +DA:46,0 +DA:48,0 +DA:49,0 +DA:52,0 +DA:53,0 +DA:56,0 +DA:60,0 +DA:69,0 +DA:70,0 +DA:71,0 +DA:74,0 +DA:75,0 +DA:77,0 +DA:80,0 +DA:82,0 +DA:84,0 +DA:88,0 +DA:89,0 +DA:93,0 +DA:97,0 +DA:99,0 +DA:100,0 +DA:102,0 +DA:104,0 +DA:105,0 +DA:106,0 +DA:110,0 +DA:111,0 +DA:112,0 +DA:114,0 +DA:117,0 +DA:121,0 +DA:126,0 +DA:128,0 +LF:43 +LH:0 +end_of_record +SF:lib/core/dio/transformers/logging_transformer.dart +DA:11,0 +DA:12,0 +DA:14,0 +DA:16,0 +DA:18,0 +DA:23,0 +DA:26,0 +LF:7 +LH:0 +end_of_record +SF:lib/data/models/get_user_response_model.dart +DA:16,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:38,0 +DA:39,0 +DA:41,0 +LF:13 +LH:0 +end_of_record +SF:lib/data/models/get_user_response_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:21,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +LF:18 +LH:0 +end_of_record +SF:lib/data/models/sign_in_user_response_model.dart +DA:16,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:38,0 +DA:39,0 +DA:41,0 +LF:13 +LH:0 +end_of_record +SF:lib/data/models/sign_in_user_response_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:21,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +LF:18 +LH:0 +end_of_record +SF:lib/data/models/sign_in_with_google_request_model.dart +DA:9,0 +DA:13,0 +DA:14,0 +DA:15,0 +LF:4 +LH:0 +end_of_record +SF:lib/data/models/sign_in_with_google_request_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:15,0 +DA:17,0 +DA:18,0 +LF:6 +LH:0 +end_of_record +SF:lib/data/models/sign_in_with_apple_request_model.dart +DA:12,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:25,0 +DA:26,0 +LF:8 +LH:0 +end_of_record +SF:lib/data/models/sign_in_with_apple_request_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:18,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +LF:12 +LH:0 +end_of_record +SF:lib/domain/entities/token_entity.dart +DA:8,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:20,0 +DA:21,0 +LF:7 +LH:0 +end_of_record +SF:lib/data/models/fcm_token_register_request_model.dart +DA:9,0 +DA:13,0 +DA:14,0 +DA:15,0 +LF:4 +LH:0 +end_of_record +SF:lib/data/models/fcm_token_register_request_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:15,0 +DA:17,0 +DA:18,0 +LF:6 +LH:0 +end_of_record +SF:lib/data/models/update_preparation_schedule_request_model.dart +DA:14,0 +DA:21,0 +DA:23,0 +DA:25,0 +DA:26,0 +DA:28,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:50,0 +DA:51,0 +DA:54,0 +DA:57,0 +DA:58,0 +DA:59,0 +LF:23 +LH:0 +end_of_record +SF:lib/data/models/update_preparation_schedule_request_model.g.dart +DA:9,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:19,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:25,0 +LF:12 +LH:0 +end_of_record +SF:lib/data/models/update_preparation_user_request_model.dart +DA:14,0 +DA:21,0 +DA:23,0 +DA:25,0 +DA:26,0 +DA:28,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:50,0 +DA:51,0 +DA:54,0 +DA:57,0 +DA:58,0 +LF:22 +LH:0 +end_of_record +SF:lib/data/models/update_preparation_user_request_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:18,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +LF:12 +LH:0 +end_of_record +SF:lib/data/models/create_preparation_schedule_request_model.dart +DA:14,1 +DA:21,0 +DA:23,0 +DA:25,1 +DA:26,1 +DA:28,1 +DA:30,1 +DA:31,1 +DA:32,1 +DA:33,2 +DA:34,1 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:50,0 +DA:51,0 +DA:54,1 +DA:57,2 +DA:58,1 +DA:59,1 +LF:23 +LH:13 +end_of_record +SF:lib/data/models/create_preparation_schedule_request_model.g.dart +DA:9,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:19,1 +DA:21,1 +DA:22,1 +DA:23,1 +DA:24,1 +DA:25,1 +LF:12 +LH:6 +end_of_record +SF:lib/data/models/get_preparation_step_response_model.dart +DA:15,0 +DA:22,0 +DA:23,0 +DA:25,0 +DA:26,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:37,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:50,0 +DA:51,0 +DA:52,0 +LF:20 +LH:0 +end_of_record +SF:lib/data/models/get_preparation_step_response_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:18,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +LF:12 +LH:0 +end_of_record +SF:lib/domain/entities/preparation_with_time_entity.dart +DA:7,0 +DA:9,0 +DA:11,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:23,0 +DA:27,0 +DA:30,0 +DA:31,0 +DA:35,0 +DA:37,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:49,0 +DA:50,0 +DA:53,0 +DA:54,0 +DA:57,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:67,0 +DA:71,0 +DA:72,0 +DA:73,0 +DA:77,0 +DA:78,0 +DA:80,0 +DA:81,0 +DA:85,0 +DA:86,0 +DA:87,0 +DA:88,0 +DA:89,0 +DA:94,0 +DA:95,0 +DA:96,0 +DA:97,0 +DA:101,0 +DA:102,0 +DA:104,0 +DA:105,0 +DA:106,0 +DA:107,0 +DA:111,0 +DA:114,0 +DA:122,0 +DA:123,0 +DA:130,0 +DA:133,0 +DA:136,0 +DA:137,0 +DA:138,0 +DA:139,0 +DA:140,0 +DA:144,0 +DA:146,0 +DA:148,0 +DA:149,0 +DA:152,0 +DA:153,0 +DA:156,0 +DA:157,0 +DA:158,0 +DA:164,0 +DA:167,0 +DA:168,0 +DA:173,0 +DA:176,0 +DA:177,0 +DA:178,0 +DA:179,0 +DA:180,0 +DA:184,0 +DA:186,0 +DA:189,0 +DA:190,0 +LF:87 +LH:0 +end_of_record +SF:lib/domain/entities/preparation_step_with_time_entity.dart +DA:7,0 +DA:16,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:44,0 +DA:46,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:54,0 +DA:55,0 +DA:56,0 +LF:23 +LH:0 +end_of_record +SF:lib/data/models/get_schedule_response_model.dart +DA:19,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:35,0 +DA:36,0 +DA:37,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +DA:47,0 +DA:48,0 +DA:50,0 +DA:53,0 +DA:55,0 +DA:57,0 +DA:59,0 +LF:19 +LH:0 +end_of_record +SF:lib/data/models/get_schedule_response_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:14,0 +DA:15,0 +DA:16,0 +DA:17,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:24,0 +DA:26,0 +DA:27,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:34,0 +DA:35,0 +LF:22 +LH:0 +end_of_record +SF:lib/data/models/create_preparation_step_request_model.dart +DA:14,2 +DA:21,0 +DA:23,0 +DA:25,0 +DA:26,0 +DA:28,2 +DA:30,2 +DA:31,2 +DA:32,2 +DA:33,4 +DA:34,2 +DA:38,0 +DA:39,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:43,0 +LF:17 +LH:7 +end_of_record +SF:lib/data/models/create_preparation_step_request_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:14,0 +DA:15,0 +DA:18,0 +DA:20,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +LF:12 +LH:0 +end_of_record +SF:lib/data/models/get_place_response_model.dart +DA:11,0 +DA:16,0 +DA:17,0 +DA:19,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +LF:12 +LH:0 +end_of_record +SF:lib/data/models/get_place_response_model.g.dart +DA:9,0 +DA:11,0 +DA:12,0 +DA:13,0 +DA:16,0 +DA:18,0 +DA:19,0 +DA:20,0 +LF:8 +LH:0 +end_of_record +SF:lib/domain/entities/schedule_with_preparation_entity.dart +DA:7,0 +DA:21,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:27,0 +DA:30,0 +DA:31,0 +DA:32,0 +DA:33,0 +DA:38,0 +DA:39,0 +DA:42,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:47,0 +DA:48,0 +DA:49,0 +DA:50,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:58,0 +DA:59,0 +DA:60,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:64,0 +DA:65,0 +DA:66,0 +DA:67,0 +DA:68,0 +DA:69,0 +LF:35 +LH:0 +end_of_record +SF:lib/presentation/shared/constants/early_late_text_images.dart +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:28,0 +DA:29,0 +DA:30,0 +DA:31,0 +DA:36,0 +DA:37,0 +DA:38,0 +DA:40,0 +DA:41,0 +DA:42,0 +DA:44,0 +DA:45,0 +DA:46,0 +DA:51,0 +DA:52,0 +DA:53,0 +DA:55,0 +DA:56,0 +DA:59,0 +DA:61,0 +DA:62,0 +DA:63,0 +DA:71,0 +DA:72,0 +DA:73,0 +DA:77,0 +DA:79,0 +DA:80,0 +DA:81,0 +DA:83,0 +DA:87,0 +DA:88,0 +DA:89,0 +DA:90,0 +DA:91,0 +DA:94,0 +DA:101,0 +DA:102,0 +DA:103,0 +DA:104,0 +DA:106,0 +LF:45 +LH:0 +end_of_record +SF:lib/presentation/onboarding/preparation_name_select/input_models/preparation_name_input_model.dart +DA:10,4 +DA:11,0 +DA:13,0 +DA:15,0 +LF:4 +LH:1 +end_of_record +SF:lib/presentation/onboarding/preparation_time/input_models/preparation_time_input_model.dart +DA:10,4 +DA:11,0 +DA:12,0 +DA:13,0 +DA:15,0 +DA:17,0 +LF:6 +LH:1 +end_of_record +SF:lib/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_cubit.dart +DA:11,0 +DA:18,0 +DA:19,0 +DA:20,0 +DA:21,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:27,0 +DA:30,0 +DA:31,0 +DA:32,0 +LF:12 +LH:0 +end_of_record +SF:lib/presentation/schedule_create/schedule_spare_and_preparing_time/preparation_form/cubit/preparation_step_form_state.dart +DA:4,0 +DA:9,0 +DA:16,0 +DA:22,0 +DA:23,0 +DA:24,0 +DA:25,0 +DA:26,0 +DA:30,0 +DA:31,0 +LF:10 +LH:0 +end_of_record diff --git a/widgetbook/macos/Flutter/GeneratedPluginRegistrant.swift b/widgetbook/macos/Flutter/GeneratedPluginRegistrant.swift index dc3be9f8..bb3bec86 100644 --- a/widgetbook/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/widgetbook/macos/Flutter/GeneratedPluginRegistrant.swift @@ -14,6 +14,7 @@ import flutter_web_auth import google_sign_in_ios import path_provider_foundation import shared_preferences_foundation +import sign_in_with_apple import sqlite3_flutter_libs import url_launcher_macos import webview_flutter_wkwebview @@ -28,6 +29,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FLTGoogleSignInPlugin.register(with: registry.registrar(forPlugin: "FLTGoogleSignInPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) + SignInWithApplePlugin.register(with: registry.registrar(forPlugin: "SignInWithApplePlugin")) Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "WebViewFlutterPlugin")) diff --git a/widgetbook/pubspec.lock b/widgetbook/pubspec.lock index 0e0d0d58..9acc1138 100644 --- a/widgetbook/pubspec.lock +++ b/widgetbook/pubspec.lock @@ -1115,6 +1115,30 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" + sign_in_with_apple: + dependency: transitive + description: + name: sign_in_with_apple + sha256: "8bd875c8e8748272749eb6d25b896f768e7e9d60988446d543fe85a37a2392b8" + url: "https://pub.dev" + source: hosted + version: "7.0.1" + sign_in_with_apple_platform_interface: + dependency: transitive + description: + name: sign_in_with_apple_platform_interface + sha256: "981bca52cf3bb9c3ad7ef44aace2d543e5c468bb713fd8dda4275ff76dfa6659" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + sign_in_with_apple_web: + dependency: transitive + description: + name: sign_in_with_apple_web + sha256: f316400827f52cafcf50d00e1a2e8a0abc534ca1264e856a81c5f06bd5b10fed + url: "https://pub.dev" + source: hosted + version: "3.0.0" simple_gesture_detector: dependency: transitive description: From b1885a0067d964872846aa7016fa3dc5822a63bf Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Mon, 24 Nov 2025 16:10:16 +0900 Subject: [PATCH 10/27] feat: add copyWith method to ScheduleEntity for improved immutability - Introduced a copyWith method in ScheduleEntity to facilitate the creation of modified instances while maintaining immutability. - This enhancement allows for easier updates to the doneStatus property without altering the original instance, improving state management. --- lib/domain/entities/schedule_entity.dart | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/lib/domain/entities/schedule_entity.dart b/lib/domain/entities/schedule_entity.dart index 079841c2..7961ad8c 100644 --- a/lib/domain/entities/schedule_entity.dart +++ b/lib/domain/entities/schedule_entity.dart @@ -72,6 +72,24 @@ class ScheduleEntity extends Equatable { ); } + ScheduleEntity copyWith({ + ScheduleDoneStatus? doneStatus, + }) { + return ScheduleEntity( + id: id, + place: place, + scheduleName: scheduleName, + scheduleTime: scheduleTime, + moveTime: moveTime, + isChanged: isChanged, + isStarted: isStarted, + scheduleSpareTime: scheduleSpareTime, + scheduleNote: scheduleNote, + latenessTime: latenessTime, + doneStatus: doneStatus ?? this.doneStatus, + ); + } + @override String toString() { return 'ScheduleEntity(id: $id, place: $place, scheduleName: $scheduleName, scheduleTime: $scheduleTime, moveTime: $moveTime, isChanged: $isChanged, isStarted: $isStarted, scheduleSpareTime: $scheduleSpareTime, scheduleNote: $scheduleNote, latenessTime: $latenessTime)'; From 0643250f309459030107e85ab12c6b169c23bd75 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Mon, 24 Nov 2025 16:10:29 +0900 Subject: [PATCH 11/27] feat: enhance schedule completion handling in ScheduleRepositoryImpl - Updated finishSchedule method to include logic for updating the doneStatus based on lateness time, improving state management. - Added functionality to emit updated schedule instances through the stream controller, ensuring real-time updates for schedule completion status. - Refactored getNearestUpcomingScheduleUseCase to handle exceptions more gracefully and ensure proper fetching of schedules based on their doneStatus. --- .../schedule_repository_impl.dart | 8 ++++ ...et_nearest_upcoming_schedule_use_case.dart | 42 +++++++++++-------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/lib/data/repositories/schedule_repository_impl.dart b/lib/data/repositories/schedule_repository_impl.dart index 79f9c3dc..9773369b 100644 --- a/lib/data/repositories/schedule_repository_impl.dart +++ b/lib/data/repositories/schedule_repository_impl.dart @@ -94,6 +94,14 @@ class ScheduleRepositoryImpl implements ScheduleRepository { Future finishSchedule(String scheduleId, int latenessTime) async { try { await scheduleRemoteDataSource.finishSchedule(scheduleId, latenessTime); + final lateStatus = latenessTime > 0 + ? ScheduleDoneStatus.lateEnd + : ScheduleDoneStatus.normalEnd; + final schedule = _scheduleStreamController.value + .firstWhere((schedule) => schedule.id == scheduleId); + _scheduleStreamController.add(Set.from(_scheduleStreamController.value) + ..remove(schedule) + ..add(schedule.copyWith(doneStatus: lateStatus))); } catch (e) { rethrow; } diff --git a/lib/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart b/lib/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart index cc2f1450..c3dde1f4 100644 --- a/lib/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart +++ b/lib/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:injectable/injectable.dart'; +import 'package:on_time_front/domain/entities/schedule_entity.dart'; import 'package:on_time_front/domain/entities/schedule_with_preparation_entity.dart'; import 'package:on_time_front/domain/entities/preparation_with_time_entity.dart'; import 'package:on_time_front/domain/repositories/timed_preparation_repository.dart'; @@ -30,25 +31,32 @@ class GetNearestUpcomingScheduleUseCase { _getScheduleByDateUseCase(now, now.add(const Duration(days: 2))); await for (final upcomingSchedule in upcomingScheduleStream) { if (upcomingSchedule.isNotEmpty) { - final schedule = upcomingSchedule.first; - - // First try to load locally stored timed preparation - final localTimed = - await _timedPreparationRepository.getTimedPreparation(schedule.id); - if (localTimed != null) { - yield ScheduleWithPreparationEntity.fromScheduleAndPreparationEntity( - schedule, localTimed); + try { + final schedule = upcomingSchedule.firstWhere( + (s) => s.doneStatus == ScheduleDoneStatus.notEnded, + orElse: () => throw Exception('No upcoming schedule found')); + + // First try to load locally stored timed preparation + final localTimed = await _timedPreparationRepository + .getTimedPreparation(schedule.id); + if (localTimed != null) { + yield ScheduleWithPreparationEntity + .fromScheduleAndPreparationEntity(schedule, localTimed); + continue; + } + + // Fallback to fetching canonical preparation from source + final preparation = + await _getPreparationByScheduleIdUseCase(schedule.id); + final scheduleWithPreparation = + ScheduleWithPreparationEntity.fromScheduleAndPreparationEntity( + schedule, + PreparationWithTimeEntity.fromPreparation(preparation)); + yield scheduleWithPreparation; + } catch (e) { + yield null; continue; } - - // Fallback to fetching canonical preparation from source - final preparation = - await _getPreparationByScheduleIdUseCase(schedule.id); - final scheduleWithPreparation = - ScheduleWithPreparationEntity.fromScheduleAndPreparationEntity( - schedule, - PreparationWithTimeEntity.fromPreparation(preparation)); - yield scheduleWithPreparation; } else { yield null; } From b70d4b56235cd597e8657b326a992e506298cf02 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Mon, 24 Nov 2025 21:16:01 +0900 Subject: [PATCH 12/27] feat: implement LoadSchedulesByDateUseCase and refactor schedule loading logic - Added LoadSchedulesByDateUseCase to fetch schedules for a specified date range, improving modularity and reusability. - Refactored LoadSchedulesForMonthUseCase and LoadSchedulesForWeekUseCase to utilize LoadSchedulesByDateUseCase, streamlining schedule retrieval logic. --- .../load_schedules_by_date_use_case.dart | 19 +++++++++++++++++++ .../load_schedules_for_month_use_case.dart | 8 ++++---- .../load_schedules_for_week_use_case.dart | 9 +++++---- 3 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 lib/domain/use-cases/load_schedules_by_date_use_case.dart diff --git a/lib/domain/use-cases/load_schedules_by_date_use_case.dart b/lib/domain/use-cases/load_schedules_by_date_use_case.dart new file mode 100644 index 00000000..2bd19a83 --- /dev/null +++ b/lib/domain/use-cases/load_schedules_by_date_use_case.dart @@ -0,0 +1,19 @@ +import 'package:injectable/injectable.dart'; +import 'package:on_time_front/domain/repositories/schedule_repository.dart'; + +@Injectable() +class LoadSchedulesByDateUseCase { + final ScheduleRepository _scheduleRepository; + + LoadSchedulesByDateUseCase(this._scheduleRepository); + + /// Loads schedules for the given date range. + /// This triggers fetching schedules from the remote data source + /// and updating the local cache/stream. + /// + /// [startDate] - Start date of the range (inclusive) + /// [endDate] - End date of the range (exclusive), or null for all schedules after startDate + Future call(DateTime startDate, DateTime? endDate) async { + await _scheduleRepository.getSchedulesByDate(startDate, endDate); + } +} diff --git a/lib/domain/use-cases/load_schedules_for_month_use_case.dart b/lib/domain/use-cases/load_schedules_for_month_use_case.dart index a92588d8..fabea404 100644 --- a/lib/domain/use-cases/load_schedules_for_month_use_case.dart +++ b/lib/domain/use-cases/load_schedules_for_month_use_case.dart @@ -1,16 +1,16 @@ import 'package:injectable/injectable.dart'; -import 'package:on_time_front/domain/repositories/schedule_repository.dart'; +import 'package:on_time_front/domain/use-cases/load_schedules_by_date_use_case.dart'; @Injectable() class LoadSchedulesForMonthUseCase { - final ScheduleRepository _scheduleRepository; + final LoadSchedulesByDateUseCase _loadSchedulesByDateUseCase; - LoadSchedulesForMonthUseCase(this._scheduleRepository); + LoadSchedulesForMonthUseCase(this._loadSchedulesByDateUseCase); Future call(DateTime date) async { final startOfMonth = DateTime(date.year, date.month, 1); final endOfMonth = DateTime(date.year, date.month + 1, 0); - await _scheduleRepository.getSchedulesByDate(startOfMonth, endOfMonth); + await _loadSchedulesByDateUseCase(startOfMonth, endOfMonth); } } diff --git a/lib/domain/use-cases/load_schedules_for_week_use_case.dart b/lib/domain/use-cases/load_schedules_for_week_use_case.dart index 85a4487a..6c88afc5 100644 --- a/lib/domain/use-cases/load_schedules_for_week_use_case.dart +++ b/lib/domain/use-cases/load_schedules_for_week_use_case.dart @@ -1,15 +1,16 @@ import 'package:injectable/injectable.dart'; -import 'package:on_time_front/domain/repositories/schedule_repository.dart'; +import 'package:on_time_front/domain/use-cases/load_schedules_by_date_use_case.dart'; @Injectable() class LoadSchedulesForWeekUseCase { - final ScheduleRepository _scheduleRepository; - LoadSchedulesForWeekUseCase(this._scheduleRepository); + final LoadSchedulesByDateUseCase _loadSchedulesByDateUseCase; + + LoadSchedulesForWeekUseCase(this._loadSchedulesByDateUseCase); Future call(DateTime date) async { final startOfWeek = date.subtract(Duration(days: date.weekday - 1)); final endOfWeek = startOfWeek.add(Duration(days: 7)); - await _scheduleRepository.getSchedulesByDate(startOfWeek, endOfWeek); + await _loadSchedulesByDateUseCase(startOfWeek, endOfWeek); } } From a0e51025e0207027f410a70c6c502de794aad6be Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Mon, 24 Nov 2025 21:16:55 +0900 Subject: [PATCH 13/27] feat: add preparation stream functionality to PreparationRepositoryImpl - Introduced a BehaviorSubject to manage a stream of preparation entities, allowing real-time updates. - Updated getPreparationByScheduleId and createDefaultPreparation methods to emit changes to the preparation stream. - Refactored the PreparationRepository interface to include the preparationStream getter, enhancing data flow management. --- .../preparation_repository_impl.dart | 23 ++++++++++++++++--- .../repositories/preparation_repository.dart | 4 +++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/data/repositories/preparation_repository_impl.dart b/lib/data/repositories/preparation_repository_impl.dart index cc2672f6..402b920e 100644 --- a/lib/data/repositories/preparation_repository_impl.dart +++ b/lib/data/repositories/preparation_repository_impl.dart @@ -8,17 +8,27 @@ import 'package:on_time_front/data/models/create_defualt_preparation_request_mod import 'package:on_time_front/domain/entities/preparation_entity.dart'; import 'package:on_time_front/domain/repositories/preparation_repository.dart'; +import 'package:rxdart/subjects.dart'; @Singleton(as: PreparationRepository) class PreparationRepositoryImpl implements PreparationRepository { final PreparationRemoteDataSource preparationRemoteDataSource; final PreparationLocalDataSource preparationLocalDataSource; + late final _preparationStreamController = + BehaviorSubject>.seeded( + const {}, + ); + PreparationRepositoryImpl({ required this.preparationRemoteDataSource, required this.preparationLocalDataSource, }); + @override + Stream> get preparationStream => + _preparationStreamController.asBroadcastStream(); + @override Future createDefaultPreparation( {required PreparationEntity preparationEntity, @@ -41,18 +51,22 @@ class PreparationRepositoryImpl implements PreparationRepository { try { await preparationRemoteDataSource.createCustomPreparation( preparationEntity, scheduleId); + _preparationStreamController.add( + Map.from(_preparationStreamController.value) + ..[scheduleId] = preparationEntity); } catch (e) { rethrow; } } @override - Future getPreparationByScheduleId( - String scheduleId) async { + Future getPreparationByScheduleId(String scheduleId) async { try { final remotePreparation = await preparationRemoteDataSource .getPreparationByScheduleId(scheduleId); - return remotePreparation; + _preparationStreamController.add( + Map.from(_preparationStreamController.value) + ..[scheduleId] = remotePreparation); } catch (e) { rethrow; } @@ -87,6 +101,9 @@ class PreparationRepositoryImpl implements PreparationRepository { try { await preparationRemoteDataSource.updatePreparationByScheduleId( preparationEntity, scheduleId); + _preparationStreamController.add( + Map.from(_preparationStreamController.value) + ..[scheduleId] = preparationEntity); } catch (e) { rethrow; } diff --git a/lib/domain/repositories/preparation_repository.dart b/lib/domain/repositories/preparation_repository.dart index 10edde1f..076c4f06 100644 --- a/lib/domain/repositories/preparation_repository.dart +++ b/lib/domain/repositories/preparation_repository.dart @@ -1,7 +1,9 @@ import 'package:on_time_front/domain/entities/preparation_entity.dart'; abstract interface class PreparationRepository { - Future getPreparationByScheduleId(String scheduleId); + Stream> get preparationStream; + + Future getPreparationByScheduleId(String scheduleId); Future getDefualtPreparation(); From 66d267b0b0e227f80240b066e9813cff87046a43 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Mon, 24 Nov 2025 21:17:31 +0900 Subject: [PATCH 14/27] feat: integrate LoadPreparationByScheduleIdUseCase and enhance GetNearestUpcomingScheduleUseCase - Added LoadPreparationByScheduleIdUseCase to facilitate loading preparation data from the remote source and updating local cache. - Updated GetNearestUpcomingScheduleUseCase to utilize the new LoadPreparationByScheduleIdUseCase for fetching preparation data, improving data retrieval logic. - Refactored getPreparationByScheduleId method to return preparation from a stream, enhancing real-time data handling. --- ...get_nearest_upcoming_schedule_use_case.dart | 4 ++++ ...et_preparation_by_schedule_id_use_case.dart | 12 +++++++++++- ...ad_preparation_by_schedule_id_use_case.dart | 18 ++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 lib/domain/use-cases/load_preparation_by_schedule_id_use_case.dart diff --git a/lib/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart b/lib/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart index c3dde1f4..5b882ca1 100644 --- a/lib/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart +++ b/lib/domain/use-cases/get_nearest_upcoming_schedule_use_case.dart @@ -6,18 +6,21 @@ import 'package:on_time_front/domain/entities/schedule_with_preparation_entity.d import 'package:on_time_front/domain/entities/preparation_with_time_entity.dart'; import 'package:on_time_front/domain/repositories/timed_preparation_repository.dart'; import 'package:on_time_front/domain/use-cases/get_preparation_by_schedule_id_use_case.dart'; +import 'package:on_time_front/domain/use-cases/load_preparation_by_schedule_id_use_case.dart'; import 'package:on_time_front/domain/use-cases/get_schedules_by_date_use_case.dart'; import 'package:on_time_front/domain/use-cases/load_schedules_for_week_use_case.dart'; @Injectable() class GetNearestUpcomingScheduleUseCase { final GetSchedulesByDateUseCase _getScheduleByDateUseCase; + final LoadPreparationByScheduleIdUseCase _loadPreparationByScheduleIdUseCase; final GetPreparationByScheduleIdUseCase _getPreparationByScheduleIdUseCase; final LoadSchedulesForWeekUseCase _loadSchedulesForWeekUseCase; final TimedPreparationRepository _timedPreparationRepository; GetNearestUpcomingScheduleUseCase( this._getScheduleByDateUseCase, + this._loadPreparationByScheduleIdUseCase, this._getPreparationByScheduleIdUseCase, this._loadSchedulesForWeekUseCase, this._timedPreparationRepository); @@ -46,6 +49,7 @@ class GetNearestUpcomingScheduleUseCase { } // Fallback to fetching canonical preparation from source + await _loadPreparationByScheduleIdUseCase(schedule.id); final preparation = await _getPreparationByScheduleIdUseCase(schedule.id); final scheduleWithPreparation = diff --git a/lib/domain/use-cases/get_preparation_by_schedule_id_use_case.dart b/lib/domain/use-cases/get_preparation_by_schedule_id_use_case.dart index feab35d0..2750d9f9 100644 --- a/lib/domain/use-cases/get_preparation_by_schedule_id_use_case.dart +++ b/lib/domain/use-cases/get_preparation_by_schedule_id_use_case.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:injectable/injectable.dart'; import 'package:on_time_front/domain/entities/preparation_entity.dart'; import 'package:on_time_front/domain/repositories/preparation_repository.dart'; @@ -8,7 +10,15 @@ class GetPreparationByScheduleIdUseCase { GetPreparationByScheduleIdUseCase(this._preparationRepository); + /// Gets preparation for the given schedule ID from the stream. + /// Returns the preparation entity if it exists in the stream. + /// + /// [scheduleId] - The ID of the schedule to get preparation for Future call(String scheduleId) async { - return await _preparationRepository.getPreparationByScheduleId(scheduleId); + return await _preparationRepository.preparationStream + .map((preparations) => preparations[scheduleId]) + .where((preparation) => preparation != null) + .cast() + .first; } } diff --git a/lib/domain/use-cases/load_preparation_by_schedule_id_use_case.dart b/lib/domain/use-cases/load_preparation_by_schedule_id_use_case.dart new file mode 100644 index 00000000..bcb5f423 --- /dev/null +++ b/lib/domain/use-cases/load_preparation_by_schedule_id_use_case.dart @@ -0,0 +1,18 @@ +import 'package:injectable/injectable.dart'; +import 'package:on_time_front/domain/repositories/preparation_repository.dart'; + +@Injectable() +class LoadPreparationByScheduleIdUseCase { + final PreparationRepository _preparationRepository; + + LoadPreparationByScheduleIdUseCase(this._preparationRepository); + + /// Loads preparation for the given schedule ID. + /// This triggers fetching preparation from the remote data source + /// and updating the local cache/stream. + /// + /// [scheduleId] - The ID of the schedule to load preparation for + Future call(String scheduleId) async { + await _preparationRepository.getPreparationByScheduleId(scheduleId); + } +} From 7b417dd0c72e0f7ac2587d20c9d6699684610c09 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Mon, 24 Nov 2025 21:28:45 +0900 Subject: [PATCH 15/27] feat: implement GetNextScheduleWithPreparationUseCase and LoadNextScheduleWithPreparationUseCase - Added GetNextScheduleWithPreparationUseCase to retrieve the next schedule along with its preparation data, enhancing scheduling functionality. - Introduced LoadNextScheduleWithPreparationUseCase to load schedules and preparation data from the server, improving data synchronization. - Enhanced localization with new messages for schedule overlap warnings and errors, providing better user feedback on scheduling conflicts. - Updated ScheduleDateTimeCubit to check for schedule overlaps and display appropriate messages, improving user experience during schedule creation. --- ...xt_schedule_with_preparation_use_case.dart | 128 +++++++++++ ...xt_schedule_with_preparation_use_case.dart | 36 +++ lib/l10n/app_en.arb | 18 ++ lib/l10n/app_ko.arb | 20 +- lib/l10n/app_localizations.dart | 12 + lib/l10n/app_localizations_en.dart | 10 + lib/l10n/app_localizations_ko.dart | 10 + .../bloc/schedule_form_bloc.dart | 4 + .../components/schedule_multi_page_form.dart | 5 +- .../cubit/schedule_date_time_cubit.dart | 143 +++++++++++- .../cubit/schedule_date_time_state.dart | 39 +++- .../screens/schedule_date_time_form.dart | 207 +++++++++++++----- 12 files changed, 567 insertions(+), 65 deletions(-) create mode 100644 lib/domain/use-cases/get_next_schedule_with_preparation_use_case.dart create mode 100644 lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart diff --git a/lib/domain/use-cases/get_next_schedule_with_preparation_use_case.dart b/lib/domain/use-cases/get_next_schedule_with_preparation_use_case.dart new file mode 100644 index 00000000..7e9fb769 --- /dev/null +++ b/lib/domain/use-cases/get_next_schedule_with_preparation_use_case.dart @@ -0,0 +1,128 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:injectable/injectable.dart'; +import 'package:on_time_front/domain/entities/schedule_with_preparation_entity.dart'; +import 'package:on_time_front/domain/entities/preparation_with_time_entity.dart'; +import 'package:on_time_front/domain/repositories/timed_preparation_repository.dart'; +import 'package:on_time_front/domain/use-cases/get_preparation_by_schedule_id_use_case.dart'; +import 'package:on_time_front/domain/use-cases/get_schedules_by_date_use_case.dart'; + +@Injectable() +class GetNextScheduleWithPreparationUseCase { + final GetSchedulesByDateUseCase _getSchedulesByDateUseCase; + final GetPreparationByScheduleIdUseCase _getPreparationByScheduleIdUseCase; + final TimedPreparationRepository _timedPreparationRepository; + + GetNextScheduleWithPreparationUseCase( + this._getSchedulesByDateUseCase, + this._getPreparationByScheduleIdUseCase, + this._timedPreparationRepository, + ); + + /// Gets the next closest schedule after the given DateTime with preparation data from the stream. + /// + /// [selectedDateTime] - The date and time to search from + /// [currentScheduleId] - Optional ID of the current schedule being edited (to exclude it) + /// [startDate] - Start date for the search range + /// [endDate] - End date for the search range + /// + /// Returns the next ScheduleWithPreparationEntity, or null if none found. + Future call({ + required DateTime selectedDateTime, + String? currentScheduleId, + required DateTime startDate, + required DateTime endDate, + }) async { + try { + // Get schedules from the stream + final schedules = + await _getSchedulesByDateUseCase(startDate, endDate).first; + + debugPrint('=== Schedule Filtering Debug ==='); + debugPrint('Selected datetime: $selectedDateTime'); + debugPrint('Current schedule ID (to exclude): $currentScheduleId'); + debugPrint('Date range: $startDate to $endDate'); + debugPrint('Total schedules found: ${schedules.length}'); + + for (final schedule in schedules) { + debugPrint( + 'Schedule: ${schedule.scheduleName} at ${schedule.scheduleTime}, doneStatus: ${schedule.doneStatus}, id: ${schedule.id}'); + } + + // Filter out the current schedule if editing, and find the next one after selectedDateTime + // Note: We check all schedules in the future, regardless of doneStatus, + // because we want to warn about overlaps even with completed schedules + final filteredSchedules = schedules.where((schedule) { + final isNotCurrent = schedule.id != currentScheduleId; + final isAfterSelected = schedule.scheduleTime.isAfter(selectedDateTime); + final timeComparison = + schedule.scheduleTime.compareTo(selectedDateTime); + + debugPrint( + 'Schedule ${schedule.scheduleName}: scheduleTime=${schedule.scheduleTime}, selectedDateTime=$selectedDateTime'); + debugPrint( + ' -> isNotCurrent=$isNotCurrent, isAfterSelected=$isAfterSelected, compareTo=$timeComparison (1=after, 0=same, -1=before), doneStatus=${schedule.doneStatus}'); + + return isNotCurrent && isAfterSelected; + }).toList(); + + debugPrint('Filtered schedules count: ${filteredSchedules.length}'); + if (filteredSchedules.isEmpty) { + debugPrint( + 'No schedules found after selected time - no overlap warning needed'); + } + debugPrint('================================'); + + if (filteredSchedules.isEmpty) { + return null; + } + + // Sort by scheduleTime and get the first one (closest) + filteredSchedules + .sort((a, b) => a.scheduleTime.compareTo(b.scheduleTime)); + final nextSchedule = filteredSchedules.first; + + // Get preparation data for the next schedule + PreparationWithTimeEntity preparation; + + // First try to load locally stored timed preparation + final localTimed = await _timedPreparationRepository + .getTimedPreparation(nextSchedule.id); + + if (localTimed != null) { + preparation = localTimed; + } else { + // Fallback to getting canonical preparation from stream + // Note: Preparation should be loaded before calling this use case + try { + final preparationEntity = + await _getPreparationByScheduleIdUseCase(nextSchedule.id).timeout( + const Duration(seconds: 5), + onTimeout: () { + throw TimeoutException( + 'Preparation not found in stream for schedule ${nextSchedule.id}', + ); + }, + ); + preparation = + PreparationWithTimeEntity.fromPreparation(preparationEntity); + } catch (e) { + // If preparation is not in stream, return null + debugPrint( + 'Preparation not found in stream for schedule ${nextSchedule.id}: $e'); + return null; + } + } + + // Create ScheduleWithPreparationEntity + return ScheduleWithPreparationEntity.fromScheduleAndPreparationEntity( + nextSchedule, + preparation, + ); + } catch (e) { + // On error, return null + return null; + } + } +} diff --git a/lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart b/lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart new file mode 100644 index 00000000..5cda4a0c --- /dev/null +++ b/lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart @@ -0,0 +1,36 @@ +import 'package:injectable/injectable.dart'; +import 'package:on_time_front/domain/use-cases/load_preparation_by_schedule_id_use_case.dart'; +import 'package:on_time_front/domain/use-cases/load_schedules_by_date_use_case.dart'; + +@Injectable() +class LoadNextScheduleWithPreparationUseCase { + final LoadSchedulesByDateUseCase _loadSchedulesByDateUseCase; + final LoadPreparationByScheduleIdUseCase _loadPreparationByScheduleIdUseCase; + + LoadNextScheduleWithPreparationUseCase( + this._loadSchedulesByDateUseCase, + this._loadPreparationByScheduleIdUseCase, + ); + + /// Loads schedules and preparation data from the server for the given date range. + /// This triggers fetching schedules and preparation from the remote data source + /// and updating the local cache/stream. + /// + /// [startDate] - Start date for the search range + /// [endDate] - End date for the search range + /// [scheduleId] - Optional schedule ID to load preparation for + Future call({ + required DateTime startDate, + required DateTime endDate, + String? scheduleId, + }) async { + // Load schedules for the date range + await _loadSchedulesByDateUseCase(startDate, endDate); + + // Load preparation for the specific schedule if provided + if (scheduleId != null) { + await _loadPreparationByScheduleIdUseCase(scheduleId); + } + } +} + diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index f41bd8c0..d9daa903 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -306,5 +306,23 @@ "totalTime": "Total time: ", "@totalTime": { "description": "Label for total preparation time" + }, + "scheduleOverlapWarning": "To avoid overlapping with the next schedule, you need to prepare within {minutes} minutes", + "@scheduleOverlapWarning": { + "description": "Warning message when schedule overlaps with next schedule", + "placeholders": { + "minutes": { + "type": "int" + } + } + }, + "scheduleOverlapError": "Schedule is already overlapping! You are {minutes} minutes late compared to the next schedule's preparation start time", + "@scheduleOverlapError": { + "description": "Error message when schedule is already overlapping with next schedule", + "placeholders": { + "minutes": { + "type": "int" + } + } } } \ No newline at end of file diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index 919994f4..6f0b43c8 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -71,5 +71,23 @@ , "editSpareTime": "여유시간 수정", "editPreparationTime": "준비시간 수정", - "totalTime": "총 시간: " + "totalTime": "총 시간: ", + "scheduleOverlapWarning": "다음 일정과 겹치지 않으려면 {minutes}분 안에 준비해야해요", + "@scheduleOverlapWarning": { + "description": "Warning message when schedule overlaps with next schedule", + "placeholders": { + "minutes": { + "type": "int" + } + } + }, + "scheduleOverlapError": "일정이 이미 겹쳤어요! 다음 일정 준비 시작 시간보다 {minutes}분 늦어요", + "@scheduleOverlapError": { + "description": "Error message when schedule is already overlapping with next schedule", + "placeholders": { + "minutes": { + "type": "int" + } + } + } } \ No newline at end of file diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 0270853f..2292656f 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -529,6 +529,18 @@ abstract class AppLocalizations { /// In en, this message translates to: /// **'Total time: '** String get totalTime; + + /// Warning message when schedule overlaps with next schedule + /// + /// In en, this message translates to: + /// **'To avoid overlapping with the next schedule, you need to prepare within {minutes} minutes'** + String scheduleOverlapWarning(int minutes); + + /// Error message when schedule is already overlapping with next schedule + /// + /// In en, this message translates to: + /// **'Schedule is already overlapping! You are {minutes} minutes late compared to the next schedule\'s preparation start time'** + String scheduleOverlapError(int minutes); } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 0bb8846a..5ed3f615 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -253,4 +253,14 @@ class AppLocalizationsEn extends AppLocalizations { @override String get totalTime => 'Total time: '; + + @override + String scheduleOverlapWarning(int minutes) { + return 'To avoid overlapping with the next schedule, you need to prepare within $minutes minutes'; + } + + @override + String scheduleOverlapError(int minutes) { + return 'Schedule is already overlapping! You are $minutes minutes late compared to the next schedule\'s preparation start time'; + } } diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index 4ebbfc0a..b88a1441 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -234,4 +234,14 @@ class AppLocalizationsKo extends AppLocalizations { @override String get totalTime => '총 시간: '; + + @override + String scheduleOverlapWarning(int minutes) { + return '다음 일정과 겹치지 않으려면 $minutes분 안에 준비해야해요'; + } + + @override + String scheduleOverlapError(int minutes) { + return '일정이 이미 겹쳤어요! 다음 일정 준비 시작 시간보다 $minutes분 늦어요'; + } } diff --git a/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart b/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart index 3b58ff61..ff847a88 100644 --- a/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart +++ b/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart @@ -8,6 +8,7 @@ import 'package:on_time_front/domain/use-cases/create_custom_preparation_use_cas import 'package:on_time_front/domain/use-cases/create_schedule_with_place_use_case.dart'; import 'package:on_time_front/domain/use-cases/get_default_preparation_use_case.dart'; import 'package:on_time_front/domain/use-cases/get_preparation_by_schedule_id_use_case.dart'; +import 'package:on_time_front/domain/use-cases/load_preparation_by_schedule_id_use_case.dart'; import 'package:on_time_front/domain/use-cases/get_schedule_by_id_use_case.dart'; import 'package:on_time_front/domain/use-cases/update_preparation_by_schedule_id_use_case.dart'; import 'package:on_time_front/domain/use-cases/update_schedule_use_case.dart'; @@ -19,6 +20,7 @@ part 'schedule_form_state.dart'; @Injectable() class ScheduleFormBloc extends Bloc { ScheduleFormBloc( + this._loadPreparationByScheduleIdUseCase, this._getPreparationByScheduleIdUseCase, this._getDefaultPreparationUseCase, this._getScheduleByIdUseCase, @@ -40,6 +42,7 @@ class ScheduleFormBloc extends Bloc { on(_onValidated); } + final LoadPreparationByScheduleIdUseCase _loadPreparationByScheduleIdUseCase; final GetPreparationByScheduleIdUseCase _getPreparationByScheduleIdUseCase; final GetDefaultPreparationUseCase _getDefaultPreparationUseCase; final GetScheduleByIdUseCase _getScheduleByIdUseCase; @@ -57,6 +60,7 @@ class ScheduleFormBloc extends Bloc { status: ScheduleFormStatus.loading, )); + await _loadPreparationByScheduleIdUseCase(event.scheduleId); final PreparationEntity preparationEntity = await _getPreparationByScheduleIdUseCase(event.scheduleId); diff --git a/lib/presentation/schedule_create/components/schedule_multi_page_form.dart b/lib/presentation/schedule_create/components/schedule_multi_page_form.dart index ccffbcde..1e30f3d6 100644 --- a/lib/presentation/schedule_create/components/schedule_multi_page_form.dart +++ b/lib/presentation/schedule_create/components/schedule_multi_page_form.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:on_time_front/core/di/di_setup.dart'; import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/components/top_bar.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart'; @@ -61,8 +62,8 @@ class _ScheduleMultiPageFormState extends State ), ), BlocProvider( - create: (context) => ScheduleDateTimeCubit( - scheduleFormBloc: context.read(), + create: (context) => getIt.get( + param1: context.read(), ), ), BlocProvider( diff --git a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart index 91adac14..280d5974 100644 --- a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart @@ -1,20 +1,33 @@ import 'package:equatable/equatable.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:formz/formz.dart'; +import 'package:injectable/injectable.dart'; +import 'package:on_time_front/domain/use-cases/get_next_schedule_with_preparation_use_case.dart'; +import 'package:on_time_front/domain/use-cases/load_next_schedule_with_preparation_use_case.dart'; +import 'package:on_time_front/l10n/app_localizations.dart'; import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_date_time/input_models/schedule_date_input_model.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_date_time/input_models/schedule_time_input_model.dart'; part 'schedule_date_time_state.dart'; +@Injectable() class ScheduleDateTimeCubit extends Cubit { - ScheduleDateTimeCubit({ - required this.scheduleFormBloc, - }) : super(ScheduleDateTimeState()) { + ScheduleDateTimeCubit( + @factoryParam this.scheduleFormBloc, + this._loadNextScheduleWithPreparationUseCase, + this._getNextScheduleWithPreparationUseCase, + ) : super(ScheduleDateTimeState()) { initialize(); } final ScheduleFormBloc scheduleFormBloc; + final LoadNextScheduleWithPreparationUseCase + _loadNextScheduleWithPreparationUseCase; + final GetNextScheduleWithPreparationUseCase + _getNextScheduleWithPreparationUseCase; void initialize() { final scheduleDateTimeState = @@ -31,6 +44,16 @@ class ScheduleDateTimeCubit extends Cubit { ScheduleDateInputModel.dirty(scheduleDate); emit(state.copyWith(scheduleDate: scheduleDateInputModel)); scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); + + // Always load nextSchedule when date changes + if (scheduleDateInputModel.isValid) { + _loadNextSchedule(scheduleDate); + } + + // Check for schedule overlap if time is already set + if (scheduleDateInputModel.isValid && state.scheduleTime.isValid) { + checkScheduleOverlap(); + } } void scheduleTimeChanged(DateTime scheduleTime) { @@ -38,6 +61,120 @@ class ScheduleDateTimeCubit extends Cubit { ScheduleTimeInputModel.dirty(scheduleTime); emit(state.copyWith(scheduleTime: scheduleTimeInputModel)); scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); + + // Never load nextSchedule, only check overlap + if (state.scheduleDate.isValid && scheduleTimeInputModel.isValid) { + checkScheduleOverlap(); + } + } + + Future _loadNextSchedule(DateTime scheduleDate) async { + try { + // Calculate date range: selected day and next day + final startDate = + DateTime(scheduleDate.year, scheduleDate.month, scheduleDate.day); + final endDate = startDate.add(const Duration(days: 2)); + + // Load schedules from server + await _loadNextScheduleWithPreparationUseCase( + startDate: startDate, + endDate: endDate, + ); + } catch (e) { + debugPrint('Error loading next schedule: $e'); + } + } + + Future checkScheduleOverlap() async { + if (state.scheduleDate.value == null || state.scheduleTime.value == null) { + return; + } + + emit(state.copyWith(clearOverlap: true)); + + try { + // Combine date and time + final selectedDate = state.scheduleDate.value!; + final selectedTime = state.scheduleTime.value!; + final selectedDateTime = DateTime( + selectedDate.year, + selectedDate.month, + selectedDate.day, + selectedTime.hour, + selectedTime.minute, + ); + + // Get the current schedule form state to check if editing + final formState = scheduleFormBloc.state; + final currentScheduleId = formState.id; + + // Calculate date range: selected day and next day + final startDate = + DateTime(selectedDate.year, selectedDate.month, selectedDate.day); + final endDate = startDate.add(const Duration(days: 2)); + + // Find next schedule with preparation from stream (no loading, already loaded) + debugPrint( + 'Checking overlap for: $selectedDateTime, currentScheduleId: $currentScheduleId'); + final nextSchedule = await _getNextScheduleWithPreparationUseCase( + selectedDateTime: selectedDateTime, + currentScheduleId: currentScheduleId, + startDate: startDate, + endDate: endDate, + ); + + debugPrint('Next schedule found: ${nextSchedule != null}'); + if (nextSchedule == null) { + emit(state.copyWith(clearOverlap: true)); + return; + } + + // Calculate preparation start time for next schedule + // preparationStartTime = scheduleTime - moveTime - preparation.totalDuration - scheduleSpareTime + final nextPreparationStartTime = nextSchedule.preparationStartTime; + + // Calculate time difference in minutes + final timeDifference = + nextPreparationStartTime.difference(selectedDateTime); + final minutesDifference = timeDifference.inMinutes; + + debugPrint('=== Schedule Overlap Debug ==='); + debugPrint('Next schedule name: ${nextSchedule.scheduleName}'); + debugPrint('Next schedule time: ${nextSchedule.scheduleTime}'); + debugPrint( + 'Next schedule preparation start time: $nextPreparationStartTime'); + debugPrint('Next schedule moveTime: ${nextSchedule.moveTime}'); + debugPrint( + 'Next schedule preparation totalDuration: ${nextSchedule.preparation.totalDuration}'); + debugPrint('Next schedule spareTime: ${nextSchedule.scheduleSpareTime}'); + debugPrint('Selected datetime: $selectedDateTime'); + debugPrint('Time difference: $timeDifference'); + debugPrint('Minutes difference: $minutesDifference'); + debugPrint('============================='); + + // Show warning if positive time difference, error if already overlapping (<= 0) + // Store minutesDifference (can be positive for warning or negative/zero for error) + // and isOverlapping flag (true if <= 0, false if > 0) + if (minutesDifference > 0) { + debugPrint('Showing warning with $minutesDifference minutes'); + emit(state.copyWith( + overlapMinutes: minutesDifference, + isOverlapping: false, + )); + } else { + // Already overlapping - show as error + debugPrint( + 'Showing error - already overlapping (minutesDifference: $minutesDifference)'); + emit(state.copyWith( + overlapMinutes: minutesDifference.abs(), + isOverlapping: true, + )); + } + } catch (e) { + // On error, clear overlap + debugPrint('Error checking schedule overlap: $e'); + emit(state.copyWith(clearOverlap: true)); + } } void scheduleDateTimeSubmitted() { diff --git a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart index af2394e8..597ebf34 100644 --- a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart +++ b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart @@ -4,20 +4,52 @@ class ScheduleDateTimeState extends Equatable { const ScheduleDateTimeState({ this.scheduleDate = const ScheduleDateInputModel.pure(), this.scheduleTime = const ScheduleTimeInputModel.pure(), + this.overlapMinutes, + this.isOverlapping = false, }); final ScheduleDateInputModel scheduleDate; final ScheduleTimeInputModel scheduleTime; + final int? overlapMinutes; + final bool isOverlapping; bool get isValid => Formz.validate([scheduleDate, scheduleTime]); + /// Returns true if there's an overlap warning or error to display + bool get hasOverlapMessage => overlapMinutes != null; + + /// Returns true if the overlap is an error (already overlapping, minutes <= 0) + bool get isOverlapError => isOverlapping; + + /// Returns the overlap message based on whether it's an error or warning + /// Requires BuildContext for localization + String? getOverlapMessage(BuildContext context) { + if (overlapMinutes == null) return null; + + final localizations = AppLocalizations.of(context)!; + final minutes = overlapMinutes!.abs(); + + if (isOverlapping) { + return localizations.scheduleOverlapError(minutes); + } else { + return localizations.scheduleOverlapWarning(minutes); + } + } + ScheduleDateTimeState copyWith({ ScheduleDateInputModel? scheduleDate, ScheduleTimeInputModel? scheduleTime, + int? overlapMinutes, + bool? isOverlapping, + bool clearOverlap = false, }) { return ScheduleDateTimeState( scheduleDate: scheduleDate ?? this.scheduleDate, scheduleTime: scheduleTime ?? this.scheduleTime, + overlapMinutes: + clearOverlap ? null : (overlapMinutes ?? this.overlapMinutes), + isOverlapping: + clearOverlap ? false : (isOverlapping ?? this.isOverlapping), ); } @@ -29,5 +61,10 @@ class ScheduleDateTimeState extends Equatable { } @override - List get props => [scheduleDate, scheduleTime]; + List get props => [ + scheduleDate, + scheduleTime, + overlapMinutes ?? 0, + isOverlapping, + ]; } diff --git a/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart b/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart index 2e07889f..c90fd1e4 100644 --- a/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart +++ b/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart @@ -17,70 +17,87 @@ class ScheduleDateTimeForm extends StatelessWidget { Widget build(BuildContext context) { return BlocBuilder( builder: (context, state) { - return Row( + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - flex: 2, - child: TextField( - readOnly: true, - decoration: InputDecoration( - labelText: AppLocalizations.of(context)!.appointmentTime, - hintText: _localizedDateString(context, DateTime.now()), - ), - controller: TextEditingController( - text: state.scheduleDate.value == null - ? null - : _localizedDateString( - context, state.scheduleDate.value!)), - onTap: () { - context.showCupertinoDatePickerModal( - title: AppLocalizations.of(context)!.enterDate, - mode: CupertinoDatePickerMode.date, - initialValue: state.scheduleDate.value ?? DateTime.now(), - onDisposed: () {}, - onSaved: (DateTime newDateTime) { - context - .read() - .scheduleDateChanged(newDateTime); + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 2, + child: TextField( + readOnly: true, + decoration: InputDecoration( + labelText: AppLocalizations.of(context)!.appointmentTime, + hintText: _localizedDateString(context, DateTime.now()), + ), + controller: TextEditingController( + text: state.scheduleDate.value == null + ? null + : _localizedDateString( + context, state.scheduleDate.value!)), + onTap: () { + context.showCupertinoDatePickerModal( + title: AppLocalizations.of(context)!.enterDate, + mode: CupertinoDatePickerMode.date, + initialValue: state.scheduleDate.value ?? DateTime.now(), + onDisposed: () {}, + onSaved: (DateTime newDateTime) { + context + .read() + .scheduleDateChanged(newDateTime); + }, + ); }, - ); - }, - ), - ), - SizedBox( - width: 30, - ), - Expanded( - flex: 1, - child: TextField( - readOnly: true, - decoration: InputDecoration( - labelText: '', - hintText: - DateFormat.jm(Localizations.localeOf(context).toString()) - .format(DateTime.now())), - controller: TextEditingController( - text: state.scheduleTime.value == null - ? null - : DateFormat.jm(Localizations.localeOf(context).toString()) - .format(state.scheduleTime.value!), + ), + ), + SizedBox( + width: 30, ), - onTap: () { - context.showCupertinoDatePickerModal( - title: AppLocalizations.of(context)!.enterTime, - mode: CupertinoDatePickerMode.time, - initialValue: state.scheduleTime.value ?? DateTime.now(), - onDisposed: () {}, - onSaved: (DateTime newDateTime) { - context - .read() - .scheduleTimeChanged(newDateTime); + Expanded( + flex: 1, + child: TextField( + readOnly: true, + decoration: InputDecoration( + labelText: '', + hintText: DateFormat.jm( + Localizations.localeOf(context).toString()) + .format(DateTime.now())), + controller: TextEditingController( + text: state.scheduleTime.value == null + ? null + : DateFormat.jm( + Localizations.localeOf(context).toString()) + .format(state.scheduleTime.value!), + ), + onTap: () { + context.showCupertinoDatePickerModal( + title: AppLocalizations.of(context)!.enterTime, + mode: CupertinoDatePickerMode.time, + initialValue: state.scheduleTime.value ?? DateTime.now(), + onDisposed: () {}, + onSaved: (DateTime newDateTime) { + context + .read() + .scheduleTimeChanged(newDateTime); + }, + ); }, - ); - }, - ), + ), + ), + ], ), + if (state.hasOverlapMessage) + Padding( + padding: const EdgeInsets.only(top: 8.0, left: 16.0), + child: state.isOverlapError + ? _ErrorMessageBubble( + message: state.getOverlapMessage(context)!, + ) + : _WarningMessageBubble( + message: state.getOverlapMessage(context)!, + ), + ), ], ); }); @@ -96,3 +113,77 @@ String _localizedDateString(BuildContext context, DateTime date) { .format(date); } } + +class _WarningMessageBubble extends StatelessWidget { + const _WarningMessageBubble({required this.message}); + + final String message; + + @override + Widget build(BuildContext context) { + final colorScheme = Theme.of(context).colorScheme; + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: colorScheme.primaryContainer, + ), + child: Row( + children: [ + Icon( + Icons.info_outline, + size: 20, + color: colorScheme.onPrimaryContainer, + ), + const SizedBox(width: 8), + Expanded( + child: Text( + message, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: colorScheme.onPrimaryContainer, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ); + } +} + +class _ErrorMessageBubble extends StatelessWidget { + const _ErrorMessageBubble({required this.message}); + + final String message; + + @override + Widget build(BuildContext context) { + final colorScheme = Theme.of(context).colorScheme; + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: colorScheme.errorContainer, + ), + child: Row( + children: [ + Icon( + Icons.error_outline, + size: 20, + color: colorScheme.onErrorContainer, + ), + const SizedBox(width: 8), + Expanded( + child: Text( + message, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: colorScheme.onErrorContainer, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ); + } +} From 5982d4f8309369a05718a61f00d530f6f4f5aaea Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Mon, 24 Nov 2025 22:55:10 +0900 Subject: [PATCH 16/27] feat: refactor LoadNextScheduleWithPreparationUseCase to load preparation for all schedules in date range - Updated LoadNextScheduleWithPreparationUseCase to utilize GetSchedulesByDateUseCase for fetching schedules. - Modified the call method to load preparation data for all schedules within the specified date range, improving data handling and synchronization. --- ...xt_schedule_with_preparation_use_case.dart | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart b/lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart index 5cda4a0c..e0e1c7e0 100644 --- a/lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart +++ b/lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart @@ -1,14 +1,17 @@ import 'package:injectable/injectable.dart'; +import 'package:on_time_front/domain/use-cases/get_schedules_by_date_use_case.dart'; import 'package:on_time_front/domain/use-cases/load_preparation_by_schedule_id_use_case.dart'; import 'package:on_time_front/domain/use-cases/load_schedules_by_date_use_case.dart'; @Injectable() class LoadNextScheduleWithPreparationUseCase { final LoadSchedulesByDateUseCase _loadSchedulesByDateUseCase; + final GetSchedulesByDateUseCase _getSchedulesByDateUseCase; final LoadPreparationByScheduleIdUseCase _loadPreparationByScheduleIdUseCase; LoadNextScheduleWithPreparationUseCase( this._loadSchedulesByDateUseCase, + this._getSchedulesByDateUseCase, this._loadPreparationByScheduleIdUseCase, ); @@ -18,19 +21,21 @@ class LoadNextScheduleWithPreparationUseCase { /// /// [startDate] - Start date for the search range /// [endDate] - End date for the search range - /// [scheduleId] - Optional schedule ID to load preparation for Future call({ required DateTime startDate, required DateTime endDate, - String? scheduleId, }) async { // Load schedules for the date range await _loadSchedulesByDateUseCase(startDate, endDate); - // Load preparation for the specific schedule if provided - if (scheduleId != null) { - await _loadPreparationByScheduleIdUseCase(scheduleId); - } + // Get the schedules that were loaded + final schedules = + await _getSchedulesByDateUseCase(startDate, endDate).first; + + // Load preparation for all schedules in the date range + await Future.wait( + schedules + .map((schedule) => _loadPreparationByScheduleIdUseCase(schedule.id)), + ); } } - From 50cdf38cac1ed5a2135b71e23255aa5fb863f5a2 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 04:39:09 +0900 Subject: [PATCH 17/27] feat: enhance schedule overlap handling and localization updates - Updated localization files to include schedule overlap warnings and errors with specific schedule names for better user feedback. - Refactored schedule overlap logic in ScheduleDateTimeCubit and related components to utilize new overlap duration calculations. - Introduced MessageBubble component for consistent display of overlap messages across different forms. - Enhanced state management in ScheduleFormSpareTimeCubit and SchedulePlaceMovingTimeCubit to track overlap status and duration, improving user experience during schedule creation. --- lib/l10n/app_en.arb | 10 +- lib/l10n/app_ko.arb | 10 +- lib/l10n/app_localizations.dart | 8 +- lib/l10n/app_localizations_en.dart | 8 +- lib/l10n/app_localizations_ko.dart | 8 +- .../bloc/schedule_form_bloc.dart | 2 + .../bloc/schedule_form_event.dart | 14 +- .../bloc/schedule_form_state.dart | 7 + .../components/message_bubble.dart | 55 ++++++++ .../cubit/schedule_date_time_cubit.dart | 31 +++-- .../cubit/schedule_date_time_state.dart | 32 +++-- .../screens/schedule_date_time_form.dart | 88 +------------ .../schedule_place_moving_time_cubit.dart | 41 +++++- .../schedule_place_moving_time_state.dart | 41 +++++- .../schedule_place_moving_time_form.dart | 14 +- .../cubit/schedule_form_spare_time_cubit.dart | 88 ++++++++++++- .../cubit/schedule_form_spare_time_state.dart | 53 +++++++- ...chedule_spare_and_preparing_time_form.dart | 123 ++++++++++-------- 18 files changed, 449 insertions(+), 184 deletions(-) create mode 100644 lib/presentation/schedule_create/components/message_bubble.dart diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index d9daa903..2ee9966f 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -307,21 +307,27 @@ "@totalTime": { "description": "Label for total preparation time" }, - "scheduleOverlapWarning": "To avoid overlapping with the next schedule, you need to prepare within {minutes} minutes", + "scheduleOverlapWarning": "To avoid overlapping with \"{scheduleName}\", you need to prepare within {minutes} minutes", "@scheduleOverlapWarning": { "description": "Warning message when schedule overlaps with next schedule", "placeholders": { "minutes": { "type": "int" + }, + "scheduleName": { + "type": "String" } } }, - "scheduleOverlapError": "Schedule is already overlapping! You are {minutes} minutes late compared to the next schedule's preparation start time", + "scheduleOverlapError": "Schedule is already overlapping with \"{scheduleName}\"! You are {minutes} minutes late compared to the next schedule's preparation start time", "@scheduleOverlapError": { "description": "Error message when schedule is already overlapping with next schedule", "placeholders": { "minutes": { "type": "int" + }, + "scheduleName": { + "type": "String" } } } diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index 6f0b43c8..10392dcf 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -72,21 +72,27 @@ "editSpareTime": "여유시간 수정", "editPreparationTime": "준비시간 수정", "totalTime": "총 시간: ", - "scheduleOverlapWarning": "다음 일정과 겹치지 않으려면 {minutes}분 안에 준비해야해요", + "scheduleOverlapWarning": "\"{scheduleName}\"과 겹치지 않으려면 {minutes}분 안에 준비해야해요", "@scheduleOverlapWarning": { "description": "Warning message when schedule overlaps with next schedule", "placeholders": { "minutes": { "type": "int" + }, + "scheduleName": { + "type": "String" } } }, - "scheduleOverlapError": "일정이 이미 겹쳤어요! 다음 일정 준비 시작 시간보다 {minutes}분 늦어요", + "scheduleOverlapError": "\"{scheduleName}\"과 이미 겹쳤어요! 다음 일정 준비 시작 시간보다 {minutes}분 늦어요", "@scheduleOverlapError": { "description": "Error message when schedule is already overlapping with next schedule", "placeholders": { "minutes": { "type": "int" + }, + "scheduleName": { + "type": "String" } } } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 2292656f..b1c46342 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -533,14 +533,14 @@ abstract class AppLocalizations { /// Warning message when schedule overlaps with next schedule /// /// In en, this message translates to: - /// **'To avoid overlapping with the next schedule, you need to prepare within {minutes} minutes'** - String scheduleOverlapWarning(int minutes); + /// **'To avoid overlapping with \"{scheduleName}\", you need to prepare within {minutes} minutes'** + String scheduleOverlapWarning(int minutes, String scheduleName); /// Error message when schedule is already overlapping with next schedule /// /// In en, this message translates to: - /// **'Schedule is already overlapping! You are {minutes} minutes late compared to the next schedule\'s preparation start time'** - String scheduleOverlapError(int minutes); + /// **'Schedule is already overlapping with \"{scheduleName}\"! You are {minutes} minutes late compared to the next schedule\'s preparation start time'** + String scheduleOverlapError(int minutes, String scheduleName); } class _AppLocalizationsDelegate diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 5ed3f615..1ca63516 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -255,12 +255,12 @@ class AppLocalizationsEn extends AppLocalizations { String get totalTime => 'Total time: '; @override - String scheduleOverlapWarning(int minutes) { - return 'To avoid overlapping with the next schedule, you need to prepare within $minutes minutes'; + String scheduleOverlapWarning(int minutes, String scheduleName) { + return 'To avoid overlapping with \"$scheduleName\", you need to prepare within $minutes minutes'; } @override - String scheduleOverlapError(int minutes) { - return 'Schedule is already overlapping! You are $minutes minutes late compared to the next schedule\'s preparation start time'; + String scheduleOverlapError(int minutes, String scheduleName) { + return 'Schedule is already overlapping with \"$scheduleName\"! You are $minutes minutes late compared to the next schedule\'s preparation start time'; } } diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index b88a1441..3a24f7a6 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -236,12 +236,12 @@ class AppLocalizationsKo extends AppLocalizations { String get totalTime => '총 시간: '; @override - String scheduleOverlapWarning(int minutes) { - return '다음 일정과 겹치지 않으려면 $minutes분 안에 준비해야해요'; + String scheduleOverlapWarning(int minutes, String scheduleName) { + return '\"$scheduleName\"과 겹치지 않으려면 $minutes분 안에 준비해야해요'; } @override - String scheduleOverlapError(int minutes) { - return '일정이 이미 겹쳤어요! 다음 일정 준비 시작 시간보다 $minutes분 늦어요'; + String scheduleOverlapError(int minutes, String scheduleName) { + return '\"$scheduleName\"과 이미 겹쳤어요! 다음 일정 준비 시작 시간보다 $minutes분 늦어요'; } } diff --git a/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart b/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart index ff847a88..7ab60177 100644 --- a/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart +++ b/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart @@ -127,6 +127,8 @@ class ScheduleFormBloc extends Bloc { event.scheduleTime.hour, event.scheduleTime.minute, ), + timeLeftUntilNextSchedulePreparation: + event.timeLeftUntilNextSchedulePreparation, )); } diff --git a/lib/presentation/schedule_create/bloc/schedule_form_event.dart b/lib/presentation/schedule_create/bloc/schedule_form_event.dart index bf0d518e..31310f5e 100644 --- a/lib/presentation/schedule_create/bloc/schedule_form_event.dart +++ b/lib/presentation/schedule_create/bloc/schedule_form_event.dart @@ -32,12 +32,20 @@ final class ScheduleFormScheduleNameChanged extends ScheduleFormEvent { final class ScheduleFormScheduleDateTimeChanged extends ScheduleFormEvent { final DateTime scheduleDate; final DateTime scheduleTime; + final Duration? timeLeftUntilNextSchedulePreparation; - const ScheduleFormScheduleDateTimeChanged( - {required this.scheduleDate, required this.scheduleTime}); + const ScheduleFormScheduleDateTimeChanged({ + required this.scheduleDate, + required this.scheduleTime, + this.timeLeftUntilNextSchedulePreparation, + }); @override - List get props => [scheduleDate, scheduleTime]; + List get props => [ + scheduleDate, + scheduleTime, + timeLeftUntilNextSchedulePreparation ?? const Duration(days: -999999), + ]; } final class ScheduleFormPlaceNameChanged extends ScheduleFormEvent { diff --git a/lib/presentation/schedule_create/bloc/schedule_form_state.dart b/lib/presentation/schedule_create/bloc/schedule_form_state.dart index 07db5a08..83bf7227 100644 --- a/lib/presentation/schedule_create/bloc/schedule_form_state.dart +++ b/lib/presentation/schedule_create/bloc/schedule_form_state.dart @@ -16,6 +16,7 @@ final class ScheduleFormState extends Equatable { final String? scheduleNote; final PreparationEntity? preparation; final bool isValid; + final Duration? timeLeftUntilNextSchedulePreparation; ScheduleFormState({ this.status = ScheduleFormStatus.initial, @@ -29,6 +30,7 @@ final class ScheduleFormState extends Equatable { this.scheduleNote, this.preparation, this.isValid = false, + this.timeLeftUntilNextSchedulePreparation, }) : id = id ?? Uuid().v7(); ScheduleFormState copyWith({ @@ -43,6 +45,7 @@ final class ScheduleFormState extends Equatable { String? scheduleNote, PreparationEntity? preparation, bool? isValid, + Duration? timeLeftUntilNextSchedulePreparation, }) { return ScheduleFormState( status: status ?? this.status, @@ -56,6 +59,9 @@ final class ScheduleFormState extends Equatable { scheduleNote: scheduleNote ?? this.scheduleNote, preparation: preparation ?? this.preparation, isValid: isValid ?? this.isValid, + timeLeftUntilNextSchedulePreparation: + timeLeftUntilNextSchedulePreparation ?? + this.timeLeftUntilNextSchedulePreparation, ); } @@ -92,5 +98,6 @@ final class ScheduleFormState extends Equatable { scheduleNote, preparation, isValid, + timeLeftUntilNextSchedulePreparation, ]; } diff --git a/lib/presentation/schedule_create/components/message_bubble.dart b/lib/presentation/schedule_create/components/message_bubble.dart new file mode 100644 index 00000000..b2088547 --- /dev/null +++ b/lib/presentation/schedule_create/components/message_bubble.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; + +enum MessageBubbleType { + warning, + error, +} + +class MessageBubble extends StatelessWidget { + const MessageBubble({ + super.key, + required this.message, + required this.type, + }); + + final String message; + final MessageBubbleType type; + + @override + Widget build(BuildContext context) { + final colorScheme = Theme.of(context).colorScheme; + final isError = type == MessageBubbleType.error; + + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: + isError ? colorScheme.errorContainer : colorScheme.primaryContainer, + ), + child: Row( + children: [ + Icon( + isError ? Icons.error_outline : Icons.info_outline, + size: 20, + color: isError + ? colorScheme.onErrorContainer + : colorScheme.onPrimaryContainer, + ), + const SizedBox(width: 8), + Expanded( + child: Text( + message, + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: isError + ? colorScheme.onErrorContainer + : colorScheme.onPrimaryContainer, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart index 280d5974..e2e3e1d2 100644 --- a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart @@ -39,33 +39,34 @@ class ScheduleDateTimeCubit extends Cubit { scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); } - void scheduleDateChanged(DateTime scheduleDate) { + Future scheduleDateChanged(DateTime scheduleDate) async { final ScheduleDateInputModel scheduleDateInputModel = ScheduleDateInputModel.dirty(scheduleDate); emit(state.copyWith(scheduleDate: scheduleDateInputModel)); - scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); // Always load nextSchedule when date changes if (scheduleDateInputModel.isValid) { - _loadNextSchedule(scheduleDate); + scheduleFormBloc.add(ScheduleFormValidated(isValid: false)); + await _loadNextSchedule(scheduleDate); } // Check for schedule overlap if time is already set if (scheduleDateInputModel.isValid && state.scheduleTime.isValid) { - checkScheduleOverlap(); + await checkScheduleOverlap(); } + scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); } - void scheduleTimeChanged(DateTime scheduleTime) { + Future scheduleTimeChanged(DateTime scheduleTime) async { final ScheduleTimeInputModel scheduleTimeInputModel = ScheduleTimeInputModel.dirty(scheduleTime); emit(state.copyWith(scheduleTime: scheduleTimeInputModel)); - scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); // Never load nextSchedule, only check overlap if (state.scheduleDate.isValid && scheduleTimeInputModel.isValid) { - checkScheduleOverlap(); + await checkScheduleOverlap(); } + scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); } Future _loadNextSchedule(DateTime scheduleDate) async { @@ -133,7 +134,7 @@ class ScheduleDateTimeCubit extends Cubit { // preparationStartTime = scheduleTime - moveTime - preparation.totalDuration - scheduleSpareTime final nextPreparationStartTime = nextSchedule.preparationStartTime; - // Calculate time difference in minutes + // Calculate time difference final timeDifference = nextPreparationStartTime.difference(selectedDateTime); final minutesDifference = timeDifference.inMinutes; @@ -153,21 +154,24 @@ class ScheduleDateTimeCubit extends Cubit { debugPrint('============================='); // Show warning if positive time difference, error if already overlapping (<= 0) - // Store minutesDifference (can be positive for warning or negative/zero for error) + // Store timeDifference (can be positive for warning or negative/zero for error) // and isOverlapping flag (true if <= 0, false if > 0) if (minutesDifference > 0) { debugPrint('Showing warning with $minutesDifference minutes'); emit(state.copyWith( - overlapMinutes: minutesDifference, + overlapDuration: timeDifference, isOverlapping: false, + nextScheduleName: nextSchedule.scheduleName, )); } else { // Already overlapping - show as error + // Store absolute value for display purposes, but keep the sign information in isOverlapping debugPrint( 'Showing error - already overlapping (minutesDifference: $minutesDifference)'); emit(state.copyWith( - overlapMinutes: minutesDifference.abs(), + overlapDuration: timeDifference.abs(), isOverlapping: true, + nextScheduleName: nextSchedule.scheduleName, )); } } catch (e) { @@ -178,10 +182,13 @@ class ScheduleDateTimeCubit extends Cubit { } void scheduleDateTimeSubmitted() { - if (state.scheduleDate.isValid && state.scheduleTime.isValid) { + if (state.scheduleDate.isValid && + state.scheduleTime.isValid && + state.isOverlapping == false) { scheduleFormBloc.add(ScheduleFormScheduleDateTimeChanged( scheduleDate: state.scheduleDate.value!, scheduleTime: state.scheduleTime.value!, + timeLeftUntilNextSchedulePreparation: state.overlapDuration, )); } } diff --git a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart index 597ebf34..7c9caa8a 100644 --- a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart +++ b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart @@ -4,19 +4,22 @@ class ScheduleDateTimeState extends Equatable { const ScheduleDateTimeState({ this.scheduleDate = const ScheduleDateInputModel.pure(), this.scheduleTime = const ScheduleTimeInputModel.pure(), - this.overlapMinutes, + this.overlapDuration, this.isOverlapping = false, + this.nextScheduleName, }); final ScheduleDateInputModel scheduleDate; final ScheduleTimeInputModel scheduleTime; - final int? overlapMinutes; + final Duration? overlapDuration; final bool isOverlapping; + final String? nextScheduleName; - bool get isValid => Formz.validate([scheduleDate, scheduleTime]); + bool get isValid => + Formz.validate([scheduleDate, scheduleTime]) && !isOverlapping; /// Returns true if there's an overlap warning or error to display - bool get hasOverlapMessage => overlapMinutes != null; + bool get hasOverlapMessage => overlapDuration != null; /// Returns true if the overlap is an error (already overlapping, minutes <= 0) bool get isOverlapError => isOverlapping; @@ -24,32 +27,36 @@ class ScheduleDateTimeState extends Equatable { /// Returns the overlap message based on whether it's an error or warning /// Requires BuildContext for localization String? getOverlapMessage(BuildContext context) { - if (overlapMinutes == null) return null; + if (overlapDuration == null) return null; final localizations = AppLocalizations.of(context)!; - final minutes = overlapMinutes!.abs(); + final minutes = overlapDuration!.inMinutes.abs(); + final scheduleName = nextScheduleName ?? ''; if (isOverlapping) { - return localizations.scheduleOverlapError(minutes); + return localizations.scheduleOverlapError(minutes, scheduleName); } else { - return localizations.scheduleOverlapWarning(minutes); + return localizations.scheduleOverlapWarning(minutes, scheduleName); } } ScheduleDateTimeState copyWith({ ScheduleDateInputModel? scheduleDate, ScheduleTimeInputModel? scheduleTime, - int? overlapMinutes, + Duration? overlapDuration, bool? isOverlapping, + String? nextScheduleName, bool clearOverlap = false, }) { return ScheduleDateTimeState( scheduleDate: scheduleDate ?? this.scheduleDate, scheduleTime: scheduleTime ?? this.scheduleTime, - overlapMinutes: - clearOverlap ? null : (overlapMinutes ?? this.overlapMinutes), + overlapDuration: + clearOverlap ? null : (overlapDuration ?? this.overlapDuration), isOverlapping: clearOverlap ? false : (isOverlapping ?? this.isOverlapping), + nextScheduleName: + clearOverlap ? null : (nextScheduleName ?? this.nextScheduleName), ); } @@ -64,7 +71,8 @@ class ScheduleDateTimeState extends Equatable { List get props => [ scheduleDate, scheduleTime, - overlapMinutes ?? 0, + overlapDuration ?? const Duration(), isOverlapping, + nextScheduleName ?? '', ]; } diff --git a/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart b/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart index c90fd1e4..1ebd3193 100644 --- a/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart +++ b/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart @@ -5,6 +5,7 @@ import 'package:intl/intl.dart'; import 'package:on_time_front/l10n/app_localizations.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart'; import 'package:on_time_front/presentation/shared/components/cupertino_picker_modal.dart'; +import 'package:on_time_front/presentation/schedule_create/components/message_bubble.dart'; //TODO: Format DateTime string //TODO: Extract Text Field widget @@ -90,13 +91,12 @@ class ScheduleDateTimeForm extends StatelessWidget { if (state.hasOverlapMessage) Padding( padding: const EdgeInsets.only(top: 8.0, left: 16.0), - child: state.isOverlapError - ? _ErrorMessageBubble( - message: state.getOverlapMessage(context)!, - ) - : _WarningMessageBubble( - message: state.getOverlapMessage(context)!, - ), + child: MessageBubble( + message: state.getOverlapMessage(context)!, + type: state.isOverlapError + ? MessageBubbleType.error + : MessageBubbleType.warning, + ), ), ], ); @@ -113,77 +113,3 @@ String _localizedDateString(BuildContext context, DateTime date) { .format(date); } } - -class _WarningMessageBubble extends StatelessWidget { - const _WarningMessageBubble({required this.message}); - - final String message; - - @override - Widget build(BuildContext context) { - final colorScheme = Theme.of(context).colorScheme; - return Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: colorScheme.primaryContainer, - ), - child: Row( - children: [ - Icon( - Icons.info_outline, - size: 20, - color: colorScheme.onPrimaryContainer, - ), - const SizedBox(width: 8), - Expanded( - child: Text( - message, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: colorScheme.onPrimaryContainer, - fontWeight: FontWeight.w500, - ), - ), - ), - ], - ), - ); - } -} - -class _ErrorMessageBubble extends StatelessWidget { - const _ErrorMessageBubble({required this.message}); - - final String message; - - @override - Widget build(BuildContext context) { - final colorScheme = Theme.of(context).colorScheme; - return Container( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: colorScheme.errorContainer, - ), - child: Row( - children: [ - Icon( - Icons.error_outline, - size: 20, - color: colorScheme.onErrorContainer, - ), - const SizedBox(width: 8), - Expanded( - child: Text( - message, - style: Theme.of(context).textTheme.bodyMedium?.copyWith( - color: colorScheme.onErrorContainer, - fontWeight: FontWeight.w500, - ), - ), - ), - ], - ), - ); - } -} diff --git a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart index f7b73f5e..0b419c65 100644 --- a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart @@ -1,6 +1,8 @@ import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:formz/formz.dart'; +import 'package:on_time_front/l10n/app_localizations.dart'; import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_place_moving_time.dart/input_models/schedule_moving_time_input_model.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_place_moving_time.dart/input_models/schedule_place_input_model.dart'; @@ -36,7 +38,44 @@ class SchedulePlaceMovingTimeCubit extends Cubit { void moveTimeChanged(Duration moveTime) { final ScheduleMovingTimeInputModel moveTimeInputModel = ScheduleMovingTimeInputModel.dirty(moveTime); - emit(state.copyWith(moveTime: moveTimeInputModel)); + + // Check for overlap if timeLeftUntilNextSchedulePreparation exists + final formState = scheduleFormBloc.state; + final timeLeftUntilNextSchedulePreparation = + formState.timeLeftUntilNextSchedulePreparation; + final oldMoveTime = formState.moveTime ?? Duration.zero; + + Duration? overlapDuration; + bool isOverlapping = false; + + if (timeLeftUntilNextSchedulePreparation != null && + formState.scheduleTime != null) { + // Calculate the change in moveTime + final moveTimeDifference = moveTime - oldMoveTime; + + // Calculate new time left: if moveTime increases, time left decreases + final newTimeLeft = + timeLeftUntilNextSchedulePreparation - moveTimeDifference; + final minutesDifference = newTimeLeft.inMinutes; + + if (minutesDifference <= 0) { + // Already overlapping - show as error + overlapDuration = newTimeLeft.abs(); + isOverlapping = true; + } else { + // Show warning if there's still time left + overlapDuration = newTimeLeft; + isOverlapping = false; + } + } + + emit(state.copyWith( + moveTime: moveTimeInputModel, + overlapDuration: overlapDuration, + isOverlapping: isOverlapping, + clearOverlap: overlapDuration == null, + )); + scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); } diff --git a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart index 4af6b586..c5bd11ad 100644 --- a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart +++ b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart @@ -4,20 +4,52 @@ class SchedulePlaceMovingTimeState extends Equatable { const SchedulePlaceMovingTimeState({ this.placeName = const SchedulePlaceInputModel.pure(), this.moveTime = const ScheduleMovingTimeInputModel.pure(), + this.overlapDuration, + this.isOverlapping = false, }); final SchedulePlaceInputModel placeName; final ScheduleMovingTimeInputModel moveTime; + final Duration? overlapDuration; + final bool isOverlapping; - bool get isValid => Formz.validate([placeName, moveTime]); + bool get isValid => Formz.validate([placeName, moveTime]) && !isOverlapping; + + /// Returns true if there's an overlap warning or error to display + bool get hasOverlapMessage => overlapDuration != null; + + /// Returns true if the overlap is an error (already overlapping, minutes <= 0) + bool get isOverlapError => isOverlapping; + + /// Returns the overlap message based on whether it's an error or warning + /// Requires BuildContext for localization + String? getOverlapMessage(BuildContext context) { + if (overlapDuration == null) return null; + + final localizations = AppLocalizations.of(context)!; + final minutes = overlapDuration!.inMinutes.abs(); + + if (isOverlapping) { + return localizations.scheduleOverlapError(minutes, ''); + } else { + return localizations.scheduleOverlapWarning(minutes, ''); + } + } SchedulePlaceMovingTimeState copyWith({ SchedulePlaceInputModel? placeName, ScheduleMovingTimeInputModel? moveTime, + Duration? overlapDuration, + bool? isOverlapping, + bool clearOverlap = false, }) { return SchedulePlaceMovingTimeState( placeName: placeName ?? this.placeName, moveTime: moveTime ?? this.moveTime, + overlapDuration: + clearOverlap ? null : (overlapDuration ?? this.overlapDuration), + isOverlapping: + clearOverlap ? false : (isOverlapping ?? this.isOverlapping), ); } @@ -31,5 +63,10 @@ class SchedulePlaceMovingTimeState extends Equatable { } @override - List get props => [placeName, moveTime]; + List get props => [ + placeName, + moveTime, + overlapDuration ?? const Duration(), + isOverlapping, + ]; } diff --git a/lib/presentation/schedule_create/schedule_place_moving_time.dart/screens/schedule_place_moving_time_form.dart b/lib/presentation/schedule_create/schedule_place_moving_time.dart/screens/schedule_place_moving_time_form.dart index 3841559c..300a114b 100644 --- a/lib/presentation/schedule_create/schedule_place_moving_time.dart/screens/schedule_place_moving_time_form.dart +++ b/lib/presentation/schedule_create/schedule_place_moving_time.dart/screens/schedule_place_moving_time_form.dart @@ -4,6 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:on_time_front/l10n/app_localizations.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart'; import 'package:on_time_front/presentation/shared/components/cupertino_picker_modal.dart'; +import 'package:on_time_front/presentation/schedule_create/components/message_bubble.dart'; class SchedulePlaceMovingTimeForm extends StatefulWidget { const SchedulePlaceMovingTimeForm({super.key}); @@ -35,6 +36,7 @@ class _SchedulePlaceMovingTimeFormState return BlocBuilder(builder: (context, state) { return Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ TextFormField( decoration: InputDecoration( @@ -76,7 +78,17 @@ class _SchedulePlaceMovingTimeFormState ), ), ], - ) + ), + if (state.hasOverlapMessage) + Padding( + padding: const EdgeInsets.only(top: 8.0, left: 16.0), + child: MessageBubble( + message: state.getOverlapMessage(context)!, + type: state.isOverlapError + ? MessageBubbleType.error + : MessageBubbleType.warning, + ), + ), ], ); }); diff --git a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart index 45e6cf8e..b0df0015 100644 --- a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart @@ -1,6 +1,9 @@ import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:formz/formz.dart'; +import 'package:on_time_front/l10n/app_localizations.dart'; +import 'package:on_time_front/domain/entities/preparation_entity.dart'; import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/input_models/schedule_spare_time_input_model.dart'; @@ -15,29 +18,112 @@ class ScheduleFormSpareTimeCubit extends Cubit { final ScheduleFormBloc scheduleFormBloc; + /// Checks for schedule overlap and returns overlap duration and overlapping status + /// Returns null overlapDuration if no overlap check is needed + ({Duration? overlapDuration, bool isOverlapping}) _checkOverlap({ + required Duration totalPreparationTime, + required Duration? moveTime, + required Duration? spareTime, + }) { + final formState = scheduleFormBloc.state; + final timeLeftUntilNextSchedulePreparation = + formState.timeLeftUntilNextSchedulePreparation; + + if (timeLeftUntilNextSchedulePreparation == null || + formState.scheduleTime == null || + moveTime == null || + spareTime == null) { + return (overlapDuration: null, isOverlapping: false); + } + + // Calculate new time left: if preparationTime increases, time left decreases + final newTimeLeft = timeLeftUntilNextSchedulePreparation - + totalPreparationTime - + moveTime - + spareTime; + final minutesDifference = newTimeLeft.inMinutes; + + if (minutesDifference <= 0) { + // Already overlapping - show as error + return ( + overlapDuration: newTimeLeft.abs(), + isOverlapping: true, + ); + } else { + // Show warning if there's still time left + return ( + overlapDuration: newTimeLeft, + isOverlapping: false, + ); + } + } + void initialize() { final schedulePlaceMovingTimeState = ScheduleFormSpareTimeState.fromScheduleFormState( scheduleFormBloc.state); emit(state.copyWith( spareTime: schedulePlaceMovingTimeState.spareTime, + preparation: schedulePlaceMovingTimeState.preparation, + totalPreparationTime: schedulePlaceMovingTimeState.totalPreparationTime, )); scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); } void spareTimeChanged(Duration value) { final spareTime = ScheduleSpareTimeInputModel.dirty(value); + + // Check for overlap using current form state values + final formState = scheduleFormBloc.state; + final overlapCheck = _checkOverlap( + totalPreparationTime: formState.totalPreparationTime, + moveTime: formState.moveTime, + spareTime: value, + ); + emit(state.copyWith( spareTime: spareTime, + overlapDuration: overlapCheck.overlapDuration, + isOverlapping: overlapCheck.isOverlapping, + clearOverlap: overlapCheck.overlapDuration == null, )); + scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); } void scheduleSpareTimeSubmitted() { - if (state.isValid) { + if (state.spareTime.isValid && state.spareTime.value != null) { scheduleFormBloc.add(ScheduleFormScheduleSpareTimeChanged( scheduleSpareTime: state.spareTime.value!, )); } + if (state.preparation != null) { + scheduleFormBloc.add(ScheduleFormPreparationChanged( + preparation: state.preparation!, + )); + } + } + + void preparationChanged(PreparationEntity preparation) { + final totalPreparationTime = preparation.totalDuration; + + // Check for overlap using current form state values + final formState = scheduleFormBloc.state; + final spareTime = state.spareTime.value ?? formState.scheduleSpareTime; + final overlapCheck = _checkOverlap( + totalPreparationTime: totalPreparationTime, + moveTime: formState.moveTime, + spareTime: spareTime, + ); + + emit(state.copyWith( + preparation: preparation, + totalPreparationTime: totalPreparationTime, + overlapDuration: overlapCheck.overlapDuration, + isOverlapping: overlapCheck.isOverlapping, + clearOverlap: overlapCheck.overlapDuration == null, + )); + + scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); } } diff --git a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart index 03361dcb..297d5159 100644 --- a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart +++ b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart @@ -3,16 +3,57 @@ part of 'schedule_form_spare_time_cubit.dart'; class ScheduleFormSpareTimeState extends Equatable { const ScheduleFormSpareTimeState({ this.spareTime = const ScheduleSpareTimeInputModel.pure(), + this.preparation, + this.totalPreparationTime = Duration.zero, + this.overlapDuration, + this.isOverlapping = false, }); final ScheduleSpareTimeInputModel spareTime; - bool get isValid => Formz.validate([spareTime]); + final PreparationEntity? preparation; + final Duration totalPreparationTime; + final Duration? overlapDuration; + final bool isOverlapping; + + bool get isValid => Formz.validate([spareTime]) && !isOverlapping; + + /// Returns true if there's an overlap warning or error to display + bool get hasOverlapMessage => overlapDuration != null; + + /// Returns true if the overlap is an error (already overlapping, minutes <= 0) + bool get isOverlapError => isOverlapping; + + /// Returns the overlap message based on whether it's an error or warning + /// Requires BuildContext for localization + String? getOverlapMessage(BuildContext context) { + if (overlapDuration == null) return null; + + final localizations = AppLocalizations.of(context)!; + final minutes = overlapDuration!.inMinutes.abs(); + + if (isOverlapping) { + return localizations.scheduleOverlapError(minutes, ''); + } else { + return localizations.scheduleOverlapWarning(minutes, ''); + } + } ScheduleFormSpareTimeState copyWith({ ScheduleSpareTimeInputModel? spareTime, + PreparationEntity? preparation, + Duration? totalPreparationTime, + Duration? overlapDuration, + bool? isOverlapping, + bool clearOverlap = false, }) { return ScheduleFormSpareTimeState( spareTime: spareTime ?? this.spareTime, + preparation: preparation ?? this.preparation, + totalPreparationTime: totalPreparationTime ?? this.totalPreparationTime, + overlapDuration: + clearOverlap ? null : (overlapDuration ?? this.overlapDuration), + isOverlapping: + clearOverlap ? false : (isOverlapping ?? this.isOverlapping), ); } @@ -21,9 +62,17 @@ class ScheduleFormSpareTimeState extends Equatable { return ScheduleFormSpareTimeState( spareTime: ScheduleSpareTimeInputModel.pure( state.scheduleSpareTime ?? Duration.zero), + preparation: state.preparation, + totalPreparationTime: state.totalPreparationTime, ); } @override - List get props => [spareTime, isValid]; + List get props => [ + spareTime, + preparation, + totalPreparationTime, + overlapDuration ?? const Duration(), + isOverlapping, + ]; } diff --git a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/screens/schedule_spare_and_preparing_time_form.dart b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/screens/schedule_spare_and_preparing_time_form.dart index 51e9de12..4b2f5e15 100644 --- a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/screens/schedule_spare_and_preparing_time_form.dart +++ b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/screens/schedule_spare_and_preparing_time_form.dart @@ -3,11 +3,11 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import 'package:on_time_front/domain/entities/preparation_entity.dart'; import 'package:on_time_front/presentation/app/bloc/auth/auth_bloc.dart'; -import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart'; import 'package:on_time_front/presentation/shared/components/cupertino_picker_modal.dart'; import 'package:on_time_front/l10n/app_localizations.dart'; import 'package:on_time_front/presentation/shared/utils/duration_format.dart'; +import 'package:on_time_front/presentation/schedule_create/components/message_bubble.dart'; class ScheduleSpareAndPreparingTimeForm extends StatefulWidget { const ScheduleSpareAndPreparingTimeForm({ @@ -26,65 +26,82 @@ class _ScheduleSpareAndPreparingTimeFormState @override Widget build(BuildContext context) { - final ScheduleFormBloc scheduleFormBloc = context.read(); - return BlocBuilder( + return BlocBuilder( builder: (context, state) { - return Row( + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - flex: 2, - child: FormField( - initialValue: Duration.zero, - builder: (field) => TextField( - readOnly: true, - decoration: InputDecoration( - labelText: - AppLocalizations.of(context)!.preparationTimeTitle), - controller: TextEditingController( - text: formatDuration(context, state.totalPreparationTime)), - onTap: () async { - final PreparationEntity? updatedPreparation = await context - .push('/preparationEdit', extra: state.preparation); - if (updatedPreparation != null) { - scheduleFormBloc.add(ScheduleFormPreparationChanged( - preparation: updatedPreparation)); - } - }, - ), - onSaved: (value) {}, - ), - ), - SizedBox( - width: 16, - ), - BlocBuilder( - builder: (context, spareTimeState) { - final Duration spareTime = spareTimeState.spareTime.value ?? - spareTimeState.spareTime.value ?? - context.select((AuthBloc appBloc) => - appBloc.state.user.mapOrNull((user) => user.spareTime))!; - return Expanded( - flex: 1, - child: TextField( - readOnly: true, - decoration: InputDecoration( - labelText: AppLocalizations.of(context)!.spareTime), - controller: TextEditingController( - text: formatDuration(context, spareTime)), - onTap: () { - context.showCupertinoMinutePickerModal( - title: AppLocalizations.of(context)!.enterTime, - initialValue: spareTime, - onSaved: (value) { + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + flex: 2, + child: FormField( + initialValue: Duration.zero, + builder: (field) => TextField( + readOnly: true, + decoration: InputDecoration( + labelText: + AppLocalizations.of(context)!.preparationTimeTitle), + controller: TextEditingController( + text: formatDuration( + context, state.totalPreparationTime)), + onTap: () async { + final PreparationEntity? updatedPreparation = + await context.push('/preparationEdit', + extra: state.preparation); + if (updatedPreparation != null) { context .read() - .spareTimeChanged(value); - }); + .preparationChanged(updatedPreparation); + } + }, + ), + onSaved: (value) {}, + ), + ), + SizedBox( + width: 16, + ), + Builder( + builder: (context) { + final Duration spareTime = state.spareTime.value ?? + context.select((AuthBloc appBloc) => appBloc.state.user + .mapOrNull((user) => user.spareTime))!; + return Expanded( + flex: 1, + child: TextField( + readOnly: true, + decoration: InputDecoration( + labelText: AppLocalizations.of(context)!.spareTime), + controller: TextEditingController( + text: formatDuration(context, spareTime)), + onTap: () { + context.showCupertinoMinutePickerModal( + title: AppLocalizations.of(context)!.enterTime, + initialValue: spareTime, + onSaved: (value) { + context + .read() + .spareTimeChanged(value); + }); + }, + ), + ); }, ), - ); - }), + ], + ), + if (state.hasOverlapMessage) + Padding( + padding: const EdgeInsets.only(top: 8.0, left: 16.0), + child: MessageBubble( + message: state.getOverlapMessage(context)!, + type: state.isOverlapError + ? MessageBubbleType.error + : MessageBubbleType.warning, + ), + ), ], ); }); From 194acf0821228b246b36a79087df6f7425f0be9e Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 04:51:57 +0900 Subject: [PATCH 18/27] feat: add nextScheduleName to schedule form state and events - Introduced nextScheduleName to ScheduleFormEvent, ScheduleFormState, and related components to enhance schedule overlap handling. - Updated localization messages in SchedulePlaceMovingTimeState and ScheduleFormSpareTimeState to include the next schedule name for better user feedback during scheduling conflicts. --- .../schedule_create/bloc/schedule_form_bloc.dart | 1 + .../schedule_create/bloc/schedule_form_event.dart | 3 +++ .../schedule_create/bloc/schedule_form_state.dart | 5 +++++ .../schedule_date_time/cubit/schedule_date_time_cubit.dart | 1 + .../cubit/schedule_place_moving_time_state.dart | 6 ++++-- .../cubit/schedule_form_spare_time_state.dart | 6 ++++-- 6 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart b/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart index 7ab60177..c7882872 100644 --- a/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart +++ b/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart @@ -129,6 +129,7 @@ class ScheduleFormBloc extends Bloc { ), timeLeftUntilNextSchedulePreparation: event.timeLeftUntilNextSchedulePreparation, + nextScheduleName: event.nextScheduleName, )); } diff --git a/lib/presentation/schedule_create/bloc/schedule_form_event.dart b/lib/presentation/schedule_create/bloc/schedule_form_event.dart index 31310f5e..98a57531 100644 --- a/lib/presentation/schedule_create/bloc/schedule_form_event.dart +++ b/lib/presentation/schedule_create/bloc/schedule_form_event.dart @@ -33,11 +33,13 @@ final class ScheduleFormScheduleDateTimeChanged extends ScheduleFormEvent { final DateTime scheduleDate; final DateTime scheduleTime; final Duration? timeLeftUntilNextSchedulePreparation; + final String? nextScheduleName; const ScheduleFormScheduleDateTimeChanged({ required this.scheduleDate, required this.scheduleTime, this.timeLeftUntilNextSchedulePreparation, + this.nextScheduleName, }); @override @@ -45,6 +47,7 @@ final class ScheduleFormScheduleDateTimeChanged extends ScheduleFormEvent { scheduleDate, scheduleTime, timeLeftUntilNextSchedulePreparation ?? const Duration(days: -999999), + nextScheduleName ?? '', ]; } diff --git a/lib/presentation/schedule_create/bloc/schedule_form_state.dart b/lib/presentation/schedule_create/bloc/schedule_form_state.dart index 83bf7227..76c9aa91 100644 --- a/lib/presentation/schedule_create/bloc/schedule_form_state.dart +++ b/lib/presentation/schedule_create/bloc/schedule_form_state.dart @@ -17,6 +17,7 @@ final class ScheduleFormState extends Equatable { final PreparationEntity? preparation; final bool isValid; final Duration? timeLeftUntilNextSchedulePreparation; + final String? nextScheduleName; ScheduleFormState({ this.status = ScheduleFormStatus.initial, @@ -31,6 +32,7 @@ final class ScheduleFormState extends Equatable { this.preparation, this.isValid = false, this.timeLeftUntilNextSchedulePreparation, + this.nextScheduleName, }) : id = id ?? Uuid().v7(); ScheduleFormState copyWith({ @@ -46,6 +48,7 @@ final class ScheduleFormState extends Equatable { PreparationEntity? preparation, bool? isValid, Duration? timeLeftUntilNextSchedulePreparation, + String? nextScheduleName, }) { return ScheduleFormState( status: status ?? this.status, @@ -62,6 +65,7 @@ final class ScheduleFormState extends Equatable { timeLeftUntilNextSchedulePreparation: timeLeftUntilNextSchedulePreparation ?? this.timeLeftUntilNextSchedulePreparation, + nextScheduleName: nextScheduleName ?? this.nextScheduleName, ); } @@ -99,5 +103,6 @@ final class ScheduleFormState extends Equatable { preparation, isValid, timeLeftUntilNextSchedulePreparation, + nextScheduleName, ]; } diff --git a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart index e2e3e1d2..ebac728e 100644 --- a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart @@ -189,6 +189,7 @@ class ScheduleDateTimeCubit extends Cubit { scheduleDate: state.scheduleDate.value!, scheduleTime: state.scheduleTime.value!, timeLeftUntilNextSchedulePreparation: state.overlapDuration, + nextScheduleName: state.nextScheduleName, )); } } diff --git a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart index c5bd11ad..5ea14706 100644 --- a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart +++ b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart @@ -28,11 +28,13 @@ class SchedulePlaceMovingTimeState extends Equatable { final localizations = AppLocalizations.of(context)!; final minutes = overlapDuration!.inMinutes.abs(); + final scheduleName = + context.read().state.nextScheduleName ?? ''; if (isOverlapping) { - return localizations.scheduleOverlapError(minutes, ''); + return localizations.scheduleOverlapError(minutes, scheduleName); } else { - return localizations.scheduleOverlapWarning(minutes, ''); + return localizations.scheduleOverlapWarning(minutes, scheduleName); } } diff --git a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart index 297d5159..74011967 100644 --- a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart +++ b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart @@ -30,11 +30,13 @@ class ScheduleFormSpareTimeState extends Equatable { final localizations = AppLocalizations.of(context)!; final minutes = overlapDuration!.inMinutes.abs(); + final scheduleName = + context.read().state.nextScheduleName ?? ''; if (isOverlapping) { - return localizations.scheduleOverlapError(minutes, ''); + return localizations.scheduleOverlapError(minutes, scheduleName); } else { - return localizations.scheduleOverlapWarning(minutes, ''); + return localizations.scheduleOverlapWarning(minutes, scheduleName); } } From 76265cc8cc524ec7df531f3a053c6ac955863f07 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 22:49:32 +0900 Subject: [PATCH 19/27] docs: add AI coding agent instructions and project architecture overview --- .github/copilot-instructions.md | 268 ++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 00000000..1d7aba1a --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,268 @@ +# OnTime Flutter Project - AI Coding Agent Instructions + +## Architecture Overview + +This is a **Flutter app** following **Clean Architecture** with three layers: + +- **Presentation** (`lib/presentation/`): Screens, widgets, BLoC/Cubit state management +- **Domain** (`lib/domain/`): Business logic, entities, use cases, repository interfaces +- **Data** (`lib/data/`): Repository implementations, data sources (remote/local), DAOs, database tables + +Data flows: UI → BLoC → UseCase → Repository → DataSource → API/DB + +## Critical Build Commands + +```bash +# ALWAYS run after pulling or modifying data models, entities, or DI +dart run build_runner build --delete-conflicting-outputs + +# Watch mode for development +dart run build_runner watch + +# Run tests +flutter test + +# Run app +flutter run +``` + +## Dependency Injection Pattern + +- Uses **Injectable** + **GetIt** for DI +- All repositories, use cases, BLoCs, and data sources must be annotated: + - `@Injectable()` for standard dependencies + - `@Singleton()` for app-wide singletons (e.g., `ScheduleBloc`, `AppDatabase`) + - `@LazySingleton()` for lazy-initialized singletons +- After adding `@Injectable()`, run `dart run build_runner build` +- Register as interface: `@Injectable(as: InterfaceName)` + +Example: + +```dart +@Injectable() +class UpdateScheduleUseCase { + final ScheduleRepository _repository; + UpdateScheduleUseCase(this._repository); +} + +@Singleton(as: ScheduleRepository) +class ScheduleRepositoryImpl implements ScheduleRepository { ... } +``` + +## State Management with BLoC + +- Use **BLoC** for complex state, **Cubit** for simpler scenarios +- BLoCs live in `lib/presentation/*/bloc/` directories +- Pattern: `on(_onEventName)` event handlers +- **Critical**: `ScheduleBloc` is a `@Singleton()` that manages automatic timer system for schedule start notifications (see `docs/Schedule-Timer-System.md`) +- Keep business logic in **use cases**, not BLoCs +- BLoCs coordinate between use cases and UI + +Example structure: + +```dart +@Injectable() +class MyBloc extends Bloc { + MyBloc(this._useCase) : super(MyState.initial()) { + on(_onMyEventHappened); + } + + Future _onMyEventHappened(MyEventHappened event, Emitter emit) async { + final result = await _useCase(); + emit(state.copyWith(data: result)); + } +} +``` + +## Data Layer Patterns + +### Entities (Domain) + +- Use **Equatable** for value equality (most entities) +- Or **Freezed** for advanced immutability (e.g., `UserEntity`) +- Live in `lib/domain/entities/` +- Example: `ScheduleEntity`, `PreparationEntity` + +### Data Models (Data Layer) + +- Use **json_serializable** for API models +- Live in `lib/data/models/` +- Must have `toEntity()` method to convert to domain entities +- Repository boundary: models → entities when leaving data layer + +### Database (Drift) + +- Tables defined in `lib/data/tables/` +- DAOs in `lib/data/daos/` +- Database: `lib/core/database/database.dart` with `@Singleton()` annotation +- Schema version tracked, migrations in `MigrationStrategy` + +### Data Sources + +- Abstract interface + implementation pattern + // ...existing code... + - Remote sources use Dio client (`lib/core/dio/app_dio.dart`) + - Local sources use Drift DAOs or SharedPreferences + - Example: `ScheduleRemoteDataSource` + `ScheduleRemoteDataSourceImpl` + +## Reactive Data Fetching Pattern + +The app uses a **reactive repository pattern** where UI updates automatically when data changes. + +1. **Repository**: Holds a `BehaviorSubject` (Stream) of data. + + - Methods like `getSchedulesByDate` fetch from API/DB and **add the result to the stream**. + - `scheduleStream` exposes this subject as a broadcast stream. + +2. **UseCase**: Transforms the repository stream. + + - Can use `async*` to yield transformed states. + - Combines multiple data sources if needed. + +3. **BLoC**: Subscribes to the UseCase stream. + // ...existing code... + - `listen()` to the stream in event handlers. + - `add()` new events to the BLoC when stream emits. + +Example `ScheduleRepositoryImpl`: + +```dart +@Singleton(as: ScheduleRepository) +class ScheduleRepositoryImpl implements ScheduleRepository { + late final _scheduleStreamController = BehaviorSubject>.seeded({}); + + @override + Stream> get scheduleStream => _scheduleStreamController.asBroadcastStream(); + + @override + Future> getSchedulesByDate(...) async { + final schedules = await remoteDataSource.getSchedulesByDate(...); + // Update the stream with new data + _scheduleStreamController.add(Set.from(_scheduleStreamController.value)..addAll(schedules)); + return schedules; + } +} +``` + +## Form Management & Validation + +The app uses a **Multi-Step Form Pattern** (e.g., `ScheduleMultiPageForm`): + +1. **Parent BLoC**: `ScheduleFormBloc` manages the overall form state and final submission. +2. **Step Cubits**: Each form step has its own Cubit (e.g., `ScheduleNameCubit`) that: + - Manages local UI state for that step. + - Communicates updates to the parent `ScheduleFormBloc`. +3. **Validation**: + - `ScheduleFormState` tracks `isValid` status. + - `TopBar` enables navigation buttons based on validity. + - `GlobalKey` is used for per-page field validation. + +## Data Transfer & Navigation + +- **Route Arguments**: Pass IDs (e.g., `scheduleId`) via `GoRouter` path parameters or `extra` object. +- **Screen Initialization**: + - Screens receive arguments in their constructor. + - BLoCs are initialized with these arguments (e.g., `ScheduleFormEditRequested(scheduleId)`). + - BLoCs fetch full data from Repositories/UseCases using the ID. + - **Avoid** passing full entity objects between screens; pass IDs and refetch/stream data. + +## Navigation (GoRouter) + +// ...existing code...Example `ScheduleRepositoryImpl`: + +```dart +@Singleton(as: ScheduleRepository) +class ScheduleRepositoryImpl implements ScheduleRepository { + late final _scheduleStreamController = BehaviorSubject>.seeded({}); + + @override + Stream> get scheduleStream => _scheduleStreamController.asBroadcastStream(); + + @override + Future> getSchedulesByDate(...) async { + final schedules = await remoteDataSource.getSchedulesByDate(...); + // Update the stream with new data + _scheduleStreamController.add(Set.from(_scheduleStreamController.value)..addAll(schedules)); + return schedules; + } +} +``` + +## Navigation (GoRouter) + +// ...existing code...## Navigation (GoRouter) + +- Configured in `lib/presentation/shared/router/go_router.dart` +- Uses declarative routing with redirect logic based on `AuthBloc` and `ScheduleBloc` state +- Routes defined with path and builder +- NavigationService (`lib/core/services/navigation_service.dart`) provides programmatic navigation + +## Code Generation Files + +**Never manually edit** generated files (`.g.dart`, `.freezed.dart`, `di_setup.config.dart`). These are created by: + +- `build_runner` for JSON serialization, Freezed, Injectable, Drift +- Regenerate after modifying annotated classes + +## Testing + +- Tests in `test/` mirror `lib/` structure +- Use Mockito for mocking dependencies +- Test helpers in `test/helpers/` +- Run coverage: `flutter test --coverage` + +## Commit Message Convention + +Follow **Conventional Commits** (enforced by commitlint): + +- Format: `(): ` +- Types: `feat`, `fix`, `refactor`, `perf`, `style`, `test`, `docs`, `build`, `ops`, `chore` +- Breaking changes: Add `!` before `:` (e.g., `feat(api)!: remove endpoint`) +- See `docs/Git.md` for detailed examples + +## Key Project Files + +- `lib/main.dart`: App entry point, Firebase initialization, DI setup +- `lib/presentation/app/screens/app.dart`: Root app widget +- `lib/core/di/di_setup.dart`: DI configuration +- `lib/core/database/database.dart`: Drift database setup +- `docs/Architecture.md`: Comprehensive architecture documentation +- `docs/Schedule-Timer-System.md`: Timer system details for ScheduleBloc + +## Common Patterns + +1. **Creating a new feature**: + + - Add entity in `domain/entities/` + - Create repository interface in `domain/repositories/` + - Add use cases in `domain/use-cases/` + - Implement repository in `data/repositories/` + - Add data sources (remote/local) in `data/data_sources/` + - Build UI with BLoC in `presentation//` + - Annotate all with `@Injectable()` and run build_runner + +2. **Adding API endpoint**: + + - Create request/response models in `data/models/` with `@JsonSerializable()` + - Add method to RemoteDataSource interface and implementation + - Update repository to use new data source method + - Run `dart run build_runner build` + +3. **Adding database table**: + - Define table in `data/tables/` + - Create DAO in `data/daos/` + - Add to `@DriftDatabase` annotation in `database.dart` + - Increment `schemaVersion` and add migration if needed + - Run `dart run build_runner build` + +## Environment & Configuration + +- Environment variables in `lib/core/constants/environment_variable.dart` +- Firebase configuration in `firebase_options.dart` +- Analysis options in `analysis_options.yaml` + +## Widgetbook + +- Component showcase at `widgetbook/` (separate sub-project) +- Hosted at: https://on-time-front-widgetbook.web.app/ +- Use for UI component development and testing From 1cd729792f46d1bfbdfa680f15ca4eaee6d879fa Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 22:53:26 +0900 Subject: [PATCH 20/27] refactor(domain): rename and update schedule preparation use cases - Rename GetNextScheduleWithPreparationUseCase to GetAdjacentSchedulesWithPreparationUseCase to support fetching both previous and next schedules. - Rename LoadNextScheduleWithPreparationUseCase to LoadAdjacentScheduleWithPreparationUseCase. - Add AdjacentSchedulesWithPreparationEntity to hold previous and next schedule data. --- ...ent_schedules_with_preparation_entity.dart | 17 ++ ...t_schedules_with_preparation_use_case.dart | 153 ++++++++++++++++++ ...xt_schedule_with_preparation_use_case.dart | 128 --------------- ...t_schedule_with_preparation_use_case.dart} | 4 +- 4 files changed, 172 insertions(+), 130 deletions(-) create mode 100644 lib/domain/entities/adjacent_schedules_with_preparation_entity.dart create mode 100644 lib/domain/use-cases/get_adjacent_schedules_with_preparation_use_case.dart delete mode 100644 lib/domain/use-cases/get_next_schedule_with_preparation_use_case.dart rename lib/domain/use-cases/{load_next_schedule_with_preparation_use_case.dart => load_adjacent_schedule_with_preparation_use_case.dart} (93%) diff --git a/lib/domain/entities/adjacent_schedules_with_preparation_entity.dart b/lib/domain/entities/adjacent_schedules_with_preparation_entity.dart new file mode 100644 index 00000000..8803d760 --- /dev/null +++ b/lib/domain/entities/adjacent_schedules_with_preparation_entity.dart @@ -0,0 +1,17 @@ +import 'package:on_time_front/domain/entities/schedule_with_preparation_entity.dart'; + +/// Result class containing both previous and next schedules relative to a selected time +class AdjacentSchedulesWithPreparationEntity { + final ScheduleWithPreparationEntity? previousSchedule; + final ScheduleWithPreparationEntity? nextSchedule; + + const AdjacentSchedulesWithPreparationEntity({ + this.previousSchedule, + this.nextSchedule, + }); + + bool get hasPrevious => previousSchedule != null; + bool get hasNext => nextSchedule != null; + bool get isEmpty => !hasPrevious && !hasNext; +} + diff --git a/lib/domain/use-cases/get_adjacent_schedules_with_preparation_use_case.dart b/lib/domain/use-cases/get_adjacent_schedules_with_preparation_use_case.dart new file mode 100644 index 00000000..e78fc7e5 --- /dev/null +++ b/lib/domain/use-cases/get_adjacent_schedules_with_preparation_use_case.dart @@ -0,0 +1,153 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:injectable/injectable.dart'; +import 'package:on_time_front/domain/entities/schedule_with_preparation_entity.dart'; +import 'package:on_time_front/domain/entities/preparation_with_time_entity.dart'; +import 'package:on_time_front/domain/entities/adjacent_schedules_with_preparation_entity.dart'; +import 'package:on_time_front/domain/use-cases/get_preparation_by_schedule_id_use_case.dart'; +import 'package:on_time_front/domain/use-cases/get_schedules_by_date_use_case.dart'; + +@Injectable() +class GetAdjacentSchedulesWithPreparationUseCase { + final GetSchedulesByDateUseCase _getSchedulesByDateUseCase; + final GetPreparationByScheduleIdUseCase _getPreparationByScheduleIdUseCase; + + GetAdjacentSchedulesWithPreparationUseCase( + this._getSchedulesByDateUseCase, + this._getPreparationByScheduleIdUseCase, + ); + + /// Gets both the previous and next closest schedules relative to the given DateTime with preparation data from the stream. + /// + /// [selectedDateTime] - The date and time to search from + /// [currentScheduleId] - Optional ID of the current schedule being edited (to exclude it) + /// [startDate] - Start date for the search range + /// [endDate] - End date for the search range + /// + /// Returns AdjacentSchedulesWithPreparationEntity containing both previous and next schedules (or null if not found). + Future call({ + required DateTime selectedDateTime, + String? currentScheduleId, + required DateTime startDate, + required DateTime endDate, + }) async { + try { + // Get schedules from the stream + final schedules = + await _getSchedulesByDateUseCase(startDate, endDate).first; + + debugPrint('=== Schedule Filtering Debug ==='); + debugPrint('Selected datetime: $selectedDateTime'); + debugPrint('Current schedule ID (to exclude): $currentScheduleId'); + debugPrint('Date range: $startDate to $endDate'); + debugPrint('Total schedules found: ${schedules.length}'); + + for (final schedule in schedules) { + debugPrint( + 'Schedule: ${schedule.scheduleName} at ${schedule.scheduleTime}, doneStatus: ${schedule.doneStatus}, id: ${schedule.id}'); + } + + // Filter out the current schedule if editing, and find the next one after selectedDateTime + // Note: We check all schedules in the future, regardless of doneStatus, + // because we want to warn about overlaps even with completed schedules + final filteredSchedules = schedules.where((schedule) { + final isNotCurrent = schedule.id != currentScheduleId; + final isAfterSelected = schedule.scheduleTime.isAfter(selectedDateTime); + final timeComparison = + schedule.scheduleTime.compareTo(selectedDateTime); + + debugPrint( + 'Schedule ${schedule.scheduleName}: scheduleTime=${schedule.scheduleTime}, selectedDateTime=$selectedDateTime'); + debugPrint( + ' -> isNotCurrent=$isNotCurrent, isAfterSelected=$isAfterSelected, compareTo=$timeComparison (1=after, 0=same, -1=before), doneStatus=${schedule.doneStatus}'); + + return isNotCurrent && isAfterSelected; + }).toList(); + + // Filter schedules before selectedDateTime for previous schedule + final previousSchedules = schedules.where((schedule) { + final isNotCurrent = schedule.id != currentScheduleId; + final isBeforeSelected = + schedule.scheduleTime.isBefore(selectedDateTime); + + debugPrint( + 'Previous check - Schedule ${schedule.scheduleName}: scheduleTime=${schedule.scheduleTime}, selectedDateTime=$selectedDateTime'); + debugPrint( + ' -> isNotCurrent=$isNotCurrent, isBeforeSelected=$isBeforeSelected'); + + return isNotCurrent && isBeforeSelected; + }).toList(); + + debugPrint( + 'Filtered schedules count (next): ${filteredSchedules.length}'); + debugPrint( + 'Filtered schedules count (previous): ${previousSchedules.length}'); + debugPrint('================================'); + + // Helper function to get preparation for a schedule + // For overlap checking, we use the canonical preparation from the stream + // (not locally stored timed preparations which are for tracking progress) + Future getScheduleWithPreparation( + schedule) async { + try { + // Try to get preparation from stream with a longer timeout + // Preparations should have been loaded by LoadAdjacentScheduleWithPreparationUseCase + final preparationEntity = + await _getPreparationByScheduleIdUseCase(schedule.id).timeout( + const Duration(seconds: 10), + onTimeout: () { + throw TimeoutException( + 'Preparation not found in stream for schedule ${schedule.id} after 10 seconds. ' + 'It may not have been loaded yet.', + ); + }, + ); + final preparation = + PreparationWithTimeEntity.fromPreparation(preparationEntity); + + // Create ScheduleWithPreparationEntity + return ScheduleWithPreparationEntity.fromScheduleAndPreparationEntity( + schedule, + preparation, + ); + } catch (e) { + // If preparation is not in stream, return null + // This can happen if the preparation hasn't been loaded yet or doesn't exist + debugPrint( + 'Preparation not found in stream for schedule ${schedule.id}: $e'); + return null; + } + } + + // Get next schedule + ScheduleWithPreparationEntity? nextSchedule; + if (filteredSchedules.isNotEmpty) { + // Sort by scheduleTime and get the first one (closest) + filteredSchedules + .sort((a, b) => a.scheduleTime.compareTo(b.scheduleTime)); + nextSchedule = + await getScheduleWithPreparation(filteredSchedules.first); + } + + // Get previous schedule + ScheduleWithPreparationEntity? previousSchedule; + if (previousSchedules.isNotEmpty) { + // Sort by scheduleTime descending and get the first one (closest before) + previousSchedules + .sort((a, b) => b.scheduleTime.compareTo(a.scheduleTime)); + previousSchedule = + await getScheduleWithPreparation(previousSchedules.first); + } + + return AdjacentSchedulesWithPreparationEntity( + previousSchedule: previousSchedule, + nextSchedule: nextSchedule, + ); + } catch (e) { + // On error, return empty result + debugPrint('Error in GetNextScheduleWithPreparationUseCase: $e'); + return const AdjacentSchedulesWithPreparationEntity(); + } + } +} diff --git a/lib/domain/use-cases/get_next_schedule_with_preparation_use_case.dart b/lib/domain/use-cases/get_next_schedule_with_preparation_use_case.dart deleted file mode 100644 index 7e9fb769..00000000 --- a/lib/domain/use-cases/get_next_schedule_with_preparation_use_case.dart +++ /dev/null @@ -1,128 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/foundation.dart'; -import 'package:injectable/injectable.dart'; -import 'package:on_time_front/domain/entities/schedule_with_preparation_entity.dart'; -import 'package:on_time_front/domain/entities/preparation_with_time_entity.dart'; -import 'package:on_time_front/domain/repositories/timed_preparation_repository.dart'; -import 'package:on_time_front/domain/use-cases/get_preparation_by_schedule_id_use_case.dart'; -import 'package:on_time_front/domain/use-cases/get_schedules_by_date_use_case.dart'; - -@Injectable() -class GetNextScheduleWithPreparationUseCase { - final GetSchedulesByDateUseCase _getSchedulesByDateUseCase; - final GetPreparationByScheduleIdUseCase _getPreparationByScheduleIdUseCase; - final TimedPreparationRepository _timedPreparationRepository; - - GetNextScheduleWithPreparationUseCase( - this._getSchedulesByDateUseCase, - this._getPreparationByScheduleIdUseCase, - this._timedPreparationRepository, - ); - - /// Gets the next closest schedule after the given DateTime with preparation data from the stream. - /// - /// [selectedDateTime] - The date and time to search from - /// [currentScheduleId] - Optional ID of the current schedule being edited (to exclude it) - /// [startDate] - Start date for the search range - /// [endDate] - End date for the search range - /// - /// Returns the next ScheduleWithPreparationEntity, or null if none found. - Future call({ - required DateTime selectedDateTime, - String? currentScheduleId, - required DateTime startDate, - required DateTime endDate, - }) async { - try { - // Get schedules from the stream - final schedules = - await _getSchedulesByDateUseCase(startDate, endDate).first; - - debugPrint('=== Schedule Filtering Debug ==='); - debugPrint('Selected datetime: $selectedDateTime'); - debugPrint('Current schedule ID (to exclude): $currentScheduleId'); - debugPrint('Date range: $startDate to $endDate'); - debugPrint('Total schedules found: ${schedules.length}'); - - for (final schedule in schedules) { - debugPrint( - 'Schedule: ${schedule.scheduleName} at ${schedule.scheduleTime}, doneStatus: ${schedule.doneStatus}, id: ${schedule.id}'); - } - - // Filter out the current schedule if editing, and find the next one after selectedDateTime - // Note: We check all schedules in the future, regardless of doneStatus, - // because we want to warn about overlaps even with completed schedules - final filteredSchedules = schedules.where((schedule) { - final isNotCurrent = schedule.id != currentScheduleId; - final isAfterSelected = schedule.scheduleTime.isAfter(selectedDateTime); - final timeComparison = - schedule.scheduleTime.compareTo(selectedDateTime); - - debugPrint( - 'Schedule ${schedule.scheduleName}: scheduleTime=${schedule.scheduleTime}, selectedDateTime=$selectedDateTime'); - debugPrint( - ' -> isNotCurrent=$isNotCurrent, isAfterSelected=$isAfterSelected, compareTo=$timeComparison (1=after, 0=same, -1=before), doneStatus=${schedule.doneStatus}'); - - return isNotCurrent && isAfterSelected; - }).toList(); - - debugPrint('Filtered schedules count: ${filteredSchedules.length}'); - if (filteredSchedules.isEmpty) { - debugPrint( - 'No schedules found after selected time - no overlap warning needed'); - } - debugPrint('================================'); - - if (filteredSchedules.isEmpty) { - return null; - } - - // Sort by scheduleTime and get the first one (closest) - filteredSchedules - .sort((a, b) => a.scheduleTime.compareTo(b.scheduleTime)); - final nextSchedule = filteredSchedules.first; - - // Get preparation data for the next schedule - PreparationWithTimeEntity preparation; - - // First try to load locally stored timed preparation - final localTimed = await _timedPreparationRepository - .getTimedPreparation(nextSchedule.id); - - if (localTimed != null) { - preparation = localTimed; - } else { - // Fallback to getting canonical preparation from stream - // Note: Preparation should be loaded before calling this use case - try { - final preparationEntity = - await _getPreparationByScheduleIdUseCase(nextSchedule.id).timeout( - const Duration(seconds: 5), - onTimeout: () { - throw TimeoutException( - 'Preparation not found in stream for schedule ${nextSchedule.id}', - ); - }, - ); - preparation = - PreparationWithTimeEntity.fromPreparation(preparationEntity); - } catch (e) { - // If preparation is not in stream, return null - debugPrint( - 'Preparation not found in stream for schedule ${nextSchedule.id}: $e'); - return null; - } - } - - // Create ScheduleWithPreparationEntity - return ScheduleWithPreparationEntity.fromScheduleAndPreparationEntity( - nextSchedule, - preparation, - ); - } catch (e) { - // On error, return null - return null; - } - } -} diff --git a/lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart b/lib/domain/use-cases/load_adjacent_schedule_with_preparation_use_case.dart similarity index 93% rename from lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart rename to lib/domain/use-cases/load_adjacent_schedule_with_preparation_use_case.dart index e0e1c7e0..6cddc92a 100644 --- a/lib/domain/use-cases/load_next_schedule_with_preparation_use_case.dart +++ b/lib/domain/use-cases/load_adjacent_schedule_with_preparation_use_case.dart @@ -4,12 +4,12 @@ import 'package:on_time_front/domain/use-cases/load_preparation_by_schedule_id_u import 'package:on_time_front/domain/use-cases/load_schedules_by_date_use_case.dart'; @Injectable() -class LoadNextScheduleWithPreparationUseCase { +class LoadAdjacentScheduleWithPreparationUseCase { final LoadSchedulesByDateUseCase _loadSchedulesByDateUseCase; final GetSchedulesByDateUseCase _getSchedulesByDateUseCase; final LoadPreparationByScheduleIdUseCase _loadPreparationByScheduleIdUseCase; - LoadNextScheduleWithPreparationUseCase( + LoadAdjacentScheduleWithPreparationUseCase( this._loadSchedulesByDateUseCase, this._getSchedulesByDateUseCase, this._loadPreparationByScheduleIdUseCase, From 7b3ab4caf2c503d4f6d3e1d962ac69f5325ba41b Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 22:53:49 +0900 Subject: [PATCH 21/27] feat(l10n): update schedule overlap error messages - Update scheduleOverlapError to include start time. - Add previousScheduleOverlapError for previous schedule conflicts. --- lib/l10n/app_en.arb | 16 ++++++++++++++-- lib/l10n/app_ko.arb | 14 +++++++++++++- lib/l10n/app_localizations.dart | 10 ++++++++-- lib/l10n/app_localizations_en.dart | 9 +++++++-- lib/l10n/app_localizations_ko.dart | 9 +++++++-- 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index f3a80557..6eb1732a 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -331,9 +331,21 @@ } } }, - "scheduleOverlapError": "Schedule is already overlapping with \"{scheduleName}\"! You are {minutes} minutes late compared to the next schedule's preparation start time", + "scheduleOverlapError": "Overlapped with next schedule {scheduleName}! Next schedule preparation starts at {startTime}", "@scheduleOverlapError": { "description": "Error message when schedule is already overlapping with next schedule", + "placeholders": { + "scheduleName": { + "type": "String" + }, + "startTime": { + "type": "String" + } + } + }, + "previousScheduleOverlapError": "Overlapped with \"{scheduleName}\"! You need to prepare {minutes} minutes earlier.", + "@previousScheduleOverlapError": { + "description": "Error message when schedule is already overlapping with previous schedule", "placeholders": { "minutes": { "type": "int" @@ -384,4 +396,4 @@ "description": "Button to send feedback and delete" } -} \ No newline at end of file +} \ No newline at end of file diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index 7ff01c0e..0a6f9fb6 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -86,9 +86,21 @@ } } }, - "scheduleOverlapError": "\"{scheduleName}\"과 이미 겹쳤어요! 다음 일정 준비 시작 시간보다 {minutes}분 늦어요", + "scheduleOverlapError": "다음 일정 {scheduleName}과 겹쳤어요! 다음 일정 준비 시작시간은 {startTime}이에요", "@scheduleOverlapError": { "description": "Error message when schedule is already overlapping with next schedule", + "placeholders": { + "scheduleName": { + "type": "String" + }, + "startTime": { + "type": "String" + } + } + }, + "previousScheduleOverlapError": "\"{scheduleName}\"과 겹쳤어요! {minutes}분 더 빨리 준비해야 해요", + "@previousScheduleOverlapError": { + "description": "Error message when schedule is already overlapping with previous schedule", "placeholders": { "minutes": { "type": "int" diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 7c10692b..6250160f 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -557,8 +557,14 @@ abstract class AppLocalizations { /// Error message when schedule is already overlapping with next schedule /// /// In en, this message translates to: - /// **'Schedule is already overlapping with \"{scheduleName}\"! You are {minutes} minutes late compared to the next schedule\'s preparation start time'** - String scheduleOverlapError(int minutes, String scheduleName); + /// **'Overlapped with next schedule {scheduleName}! Next schedule preparation starts at {startTime}'** + String scheduleOverlapError(String scheduleName, String startTime); + + /// Error message when schedule is already overlapping with previous schedule + /// + /// In en, this message translates to: + /// **'Overlapped with \"{scheduleName}\"! You need to prepare {minutes} minutes earlier.'** + String previousScheduleOverlapError(int minutes, String scheduleName); /// Confirmation text shown in the logout modal /// diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 08bb9f4c..7688ca92 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -269,8 +269,13 @@ class AppLocalizationsEn extends AppLocalizations { } @override - String scheduleOverlapError(int minutes, String scheduleName) { - return 'Schedule is already overlapping with \"$scheduleName\"! You are $minutes minutes late compared to the next schedule\'s preparation start time'; + String scheduleOverlapError(String scheduleName, String startTime) { + return 'Overlapped with next schedule $scheduleName! Next schedule preparation starts at $startTime'; + } + + @override + String previousScheduleOverlapError(int minutes, String scheduleName) { + return 'Overlapped with \"$scheduleName\"! You need to prepare $minutes minutes earlier.'; } @override diff --git a/lib/l10n/app_localizations_ko.dart b/lib/l10n/app_localizations_ko.dart index c1da98a6..fb8e691c 100644 --- a/lib/l10n/app_localizations_ko.dart +++ b/lib/l10n/app_localizations_ko.dart @@ -250,8 +250,13 @@ class AppLocalizationsKo extends AppLocalizations { } @override - String scheduleOverlapError(int minutes, String scheduleName) { - return '\"$scheduleName\"과 이미 겹쳤어요! 다음 일정 준비 시작 시간보다 $minutes분 늦어요'; + String scheduleOverlapError(String scheduleName, String startTime) { + return '다음 일정 $scheduleName과 겹쳤어요! 다음 일정 준비 시작시간은 $startTime이에요'; + } + + @override + String previousScheduleOverlapError(int minutes, String scheduleName) { + return '\"$scheduleName\"과 겹쳤어요! $minutes분 더 빨리 준비해야 해요'; } @override From cca733ea1eaf11bec01fec94334032f3fedced63 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 22:54:55 +0900 Subject: [PATCH 22/27] feat(schedule-create): implement adjacent schedule overlap detection - Update ScheduleDateTimeCubit to fetch and check both previous and next schedules. - Implement logic to calculate available time from previous schedule and overlap with next schedule. - Update ScheduleFormBloc to store maxAvailableTime and previousScheduleName. - Update UI to show overlap warnings/errors. --- .../bloc/schedule_form_bloc.dart | 15 +- .../bloc/schedule_form_event.dart | 12 +- .../bloc/schedule_form_state.dart | 22 +- .../cubit/schedule_date_time_cubit.dart | 232 +++++++++++++----- .../cubit/schedule_date_time_state.dart | 71 ++++-- .../screens/schedule_date_time_form.dart | 14 +- 6 files changed, 257 insertions(+), 109 deletions(-) diff --git a/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart b/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart index c7882872..303db620 100644 --- a/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart +++ b/lib/presentation/schedule_create/bloc/schedule_form_bloc.dart @@ -12,6 +12,7 @@ import 'package:on_time_front/domain/use-cases/load_preparation_by_schedule_id_u import 'package:on_time_front/domain/use-cases/get_schedule_by_id_use_case.dart'; import 'package:on_time_front/domain/use-cases/update_preparation_by_schedule_id_use_case.dart'; import 'package:on_time_front/domain/use-cases/update_schedule_use_case.dart'; +import 'package:on_time_front/presentation/app/bloc/auth/auth_bloc.dart'; import 'package:uuid/uuid.dart'; part 'schedule_form_event.dart'; @@ -28,6 +29,7 @@ class ScheduleFormBloc extends Bloc { this._createCustomPreparationUseCase, this._updateScheduleUseCase, this._updatePreparationByScheduleIdUseCase, + @factoryParam this._authBloc, ) : super(ScheduleFormState()) { on(_onEditRequested); on(_onCreateRequested); @@ -51,6 +53,7 @@ class ScheduleFormBloc extends Bloc { final UpdateScheduleUseCase _updateScheduleUseCase; final UpdatePreparationByScheduleIdUseCase _updatePreparationByScheduleIdUseCase; + final AuthBloc _authBloc; Future _onEditRequested( ScheduleFormEditRequested event, @@ -94,6 +97,11 @@ class ScheduleFormBloc extends Bloc { final PreparationEntity defaultPreparationStepList = await _getDefaultPreparationUseCase(); + // Get spareTime from user model + final userSpareTime = _authBloc.state.user.mapOrNull( + (user) => user.spareTime, + ); + emit(state.copyWith( status: ScheduleFormStatus.success, id: Uuid().v7(), @@ -102,7 +110,7 @@ class ScheduleFormBloc extends Bloc { scheduleTime: null, moveTime: null, isChanged: null, - scheduleSpareTime: null, + scheduleSpareTime: userSpareTime, scheduleNote: null, preparation: defaultPreparationStepList, )); @@ -127,9 +135,8 @@ class ScheduleFormBloc extends Bloc { event.scheduleTime.hour, event.scheduleTime.minute, ), - timeLeftUntilNextSchedulePreparation: - event.timeLeftUntilNextSchedulePreparation, - nextScheduleName: event.nextScheduleName, + maxAvailableTime: event.maxAvailableTime, + previousScheduleName: event.previousScheduleName, )); } diff --git a/lib/presentation/schedule_create/bloc/schedule_form_event.dart b/lib/presentation/schedule_create/bloc/schedule_form_event.dart index 98a57531..50493099 100644 --- a/lib/presentation/schedule_create/bloc/schedule_form_event.dart +++ b/lib/presentation/schedule_create/bloc/schedule_form_event.dart @@ -32,22 +32,22 @@ final class ScheduleFormScheduleNameChanged extends ScheduleFormEvent { final class ScheduleFormScheduleDateTimeChanged extends ScheduleFormEvent { final DateTime scheduleDate; final DateTime scheduleTime; - final Duration? timeLeftUntilNextSchedulePreparation; - final String? nextScheduleName; + final Duration? maxAvailableTime; + final String? previousScheduleName; const ScheduleFormScheduleDateTimeChanged({ required this.scheduleDate, required this.scheduleTime, - this.timeLeftUntilNextSchedulePreparation, - this.nextScheduleName, + this.maxAvailableTime, + this.previousScheduleName, }); @override List get props => [ scheduleDate, scheduleTime, - timeLeftUntilNextSchedulePreparation ?? const Duration(days: -999999), - nextScheduleName ?? '', + maxAvailableTime ?? const Duration(days: -999999), + previousScheduleName ?? '', ]; } diff --git a/lib/presentation/schedule_create/bloc/schedule_form_state.dart b/lib/presentation/schedule_create/bloc/schedule_form_state.dart index 76c9aa91..e2e21f12 100644 --- a/lib/presentation/schedule_create/bloc/schedule_form_state.dart +++ b/lib/presentation/schedule_create/bloc/schedule_form_state.dart @@ -16,8 +16,8 @@ final class ScheduleFormState extends Equatable { final String? scheduleNote; final PreparationEntity? preparation; final bool isValid; - final Duration? timeLeftUntilNextSchedulePreparation; - final String? nextScheduleName; + final Duration? maxAvailableTime; + final String? previousScheduleName; ScheduleFormState({ this.status = ScheduleFormStatus.initial, @@ -31,8 +31,8 @@ final class ScheduleFormState extends Equatable { this.scheduleNote, this.preparation, this.isValid = false, - this.timeLeftUntilNextSchedulePreparation, - this.nextScheduleName, + this.maxAvailableTime, + this.previousScheduleName, }) : id = id ?? Uuid().v7(); ScheduleFormState copyWith({ @@ -47,8 +47,8 @@ final class ScheduleFormState extends Equatable { String? scheduleNote, PreparationEntity? preparation, bool? isValid, - Duration? timeLeftUntilNextSchedulePreparation, - String? nextScheduleName, + Duration? maxAvailableTime, + String? previousScheduleName, }) { return ScheduleFormState( status: status ?? this.status, @@ -62,10 +62,8 @@ final class ScheduleFormState extends Equatable { scheduleNote: scheduleNote ?? this.scheduleNote, preparation: preparation ?? this.preparation, isValid: isValid ?? this.isValid, - timeLeftUntilNextSchedulePreparation: - timeLeftUntilNextSchedulePreparation ?? - this.timeLeftUntilNextSchedulePreparation, - nextScheduleName: nextScheduleName ?? this.nextScheduleName, + maxAvailableTime: maxAvailableTime ?? this.maxAvailableTime, + previousScheduleName: previousScheduleName ?? this.previousScheduleName, ); } @@ -102,7 +100,7 @@ final class ScheduleFormState extends Equatable { scheduleNote, preparation, isValid, - timeLeftUntilNextSchedulePreparation, - nextScheduleName, + maxAvailableTime, + previousScheduleName, ]; } diff --git a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart index ebac728e..dcaa3e80 100644 --- a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart @@ -4,12 +4,13 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:formz/formz.dart'; import 'package:injectable/injectable.dart'; -import 'package:on_time_front/domain/use-cases/get_next_schedule_with_preparation_use_case.dart'; -import 'package:on_time_front/domain/use-cases/load_next_schedule_with_preparation_use_case.dart'; +import 'package:on_time_front/domain/use-cases/get_adjacent_schedules_with_preparation_use_case.dart'; +import 'package:on_time_front/domain/use-cases/load_adjacent_schedule_with_preparation_use_case.dart'; import 'package:on_time_front/l10n/app_localizations.dart'; import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_date_time/input_models/schedule_date_input_model.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_date_time/input_models/schedule_time_input_model.dart'; +import 'package:on_time_front/domain/entities/adjacent_schedules_with_preparation_entity.dart'; part 'schedule_date_time_state.dart'; @@ -17,16 +18,16 @@ part 'schedule_date_time_state.dart'; class ScheduleDateTimeCubit extends Cubit { ScheduleDateTimeCubit( @factoryParam this.scheduleFormBloc, - this._loadNextScheduleWithPreparationUseCase, + this._loadAdjacentSchedulesWithPreparationUseCase, this._getNextScheduleWithPreparationUseCase, ) : super(ScheduleDateTimeState()) { initialize(); } final ScheduleFormBloc scheduleFormBloc; - final LoadNextScheduleWithPreparationUseCase - _loadNextScheduleWithPreparationUseCase; - final GetNextScheduleWithPreparationUseCase + final LoadAdjacentScheduleWithPreparationUseCase + _loadAdjacentSchedulesWithPreparationUseCase; + final GetAdjacentSchedulesWithPreparationUseCase _getNextScheduleWithPreparationUseCase; void initialize() { @@ -47,7 +48,7 @@ class ScheduleDateTimeCubit extends Cubit { // Always load nextSchedule when date changes if (scheduleDateInputModel.isValid) { scheduleFormBloc.add(ScheduleFormValidated(isValid: false)); - await _loadNextSchedule(scheduleDate); + await _loadAdjacentSchedules(scheduleDate); } // Check for schedule overlap if time is already set @@ -69,20 +70,21 @@ class ScheduleDateTimeCubit extends Cubit { scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); } - Future _loadNextSchedule(DateTime scheduleDate) async { + Future _loadAdjacentSchedules(DateTime scheduleDate) async { try { - // Calculate date range: selected day and next day - final startDate = - DateTime(scheduleDate.year, scheduleDate.month, scheduleDate.day); - final endDate = startDate.add(const Duration(days: 2)); + // Calculate date range: previous day, selected day, and next day + // This matches the range used in checkScheduleOverlap + final dateRange = _getDateRange(scheduleDate); + final startDate = dateRange.startDate; + final endDate = dateRange.endDate; // Load schedules from server - await _loadNextScheduleWithPreparationUseCase( + await _loadAdjacentSchedulesWithPreparationUseCase( startDate: startDate, endDate: endDate, ); } catch (e) { - debugPrint('Error loading next schedule: $e'); + debugPrint('Error loading adjacent schedules: $e'); } } @@ -91,7 +93,7 @@ class ScheduleDateTimeCubit extends Cubit { return; } - emit(state.copyWith(clearOverlap: true)); + emit(state.copyWith(clearOverlap: true, clearPreviousOverlap: true)); try { // Combine date and time @@ -109,75 +111,158 @@ class ScheduleDateTimeCubit extends Cubit { final formState = scheduleFormBloc.state; final currentScheduleId = formState.id; - // Calculate date range: selected day and next day - final startDate = - DateTime(selectedDate.year, selectedDate.month, selectedDate.day); - final endDate = startDate.add(const Duration(days: 2)); + // Calculate date range: previous day, selected day, and next day + // This matches the range used in _loadAdjacentSchedules + final dateRange = _getDateRange(selectedDate); + final startDate = dateRange.startDate; + final endDate = dateRange.endDate; - // Find next schedule with preparation from stream (no loading, already loaded) + // Find adjacent schedules (previous and next) with preparation from stream debugPrint( 'Checking overlap for: $selectedDateTime, currentScheduleId: $currentScheduleId'); - final nextSchedule = await _getNextScheduleWithPreparationUseCase( + final AdjacentSchedulesWithPreparationEntity adjacentSchedules = + await _getNextScheduleWithPreparationUseCase( selectedDateTime: selectedDateTime, currentScheduleId: currentScheduleId, startDate: startDate, endDate: endDate, ); - debugPrint('Next schedule found: ${nextSchedule != null}'); - if (nextSchedule == null) { + debugPrint( + 'Previous schedule found: ${adjacentSchedules.hasPrevious}, Next schedule found: ${adjacentSchedules.hasNext}'); + + // Check overlap with next schedule + if (adjacentSchedules.hasNext && adjacentSchedules.nextSchedule != null) { + final nextSchedule = adjacentSchedules.nextSchedule!; + + // Calculate preparation start time for next schedule + // preparationStartTime = scheduleTime - moveTime - preparation.totalDuration - scheduleSpareTime + final nextPreparationStartTime = nextSchedule.preparationStartTime; + + // Calculate time difference + final timeDifference = + nextPreparationStartTime.difference(selectedDateTime); + final minutesDifference = timeDifference.inMinutes; + + debugPrint('=== Next Schedule Overlap Debug ==='); + debugPrint('Next schedule name: ${nextSchedule.scheduleName}'); + debugPrint('Next schedule time: ${nextSchedule.scheduleTime}'); + debugPrint( + 'Next schedule preparation start time: $nextPreparationStartTime'); + debugPrint('Next schedule moveTime: ${nextSchedule.moveTime}'); + debugPrint( + 'Next schedule preparation totalDuration: ${nextSchedule.preparation.totalDuration}'); + debugPrint( + 'Next schedule spareTime: ${nextSchedule.scheduleSpareTime}'); + debugPrint('Selected datetime: $selectedDateTime'); + debugPrint('Time difference: $timeDifference'); + debugPrint('Minutes difference: $minutesDifference'); + debugPrint('==================================='); + + // Show warning if positive time difference, error if already overlapping (<= 0) + if (minutesDifference > 0) { + debugPrint('Showing warning with $minutesDifference minutes'); + // User requested to show only error when overlap, no warning for next schedule + emit(state.copyWith( + clearOverlap: true, + )); + } else { + // Already overlapping - show as error + debugPrint( + 'Showing error - already overlapping (minutesDifference: $minutesDifference)'); + emit(state.copyWith( + isOverlapping: true, + nextScheduleName: nextSchedule.scheduleName, + nextPreparationStartTime: nextPreparationStartTime, + )); + } + } else { + // No next schedule found, clear next overlap emit(state.copyWith(clearOverlap: true)); - return; } - // Calculate preparation start time for next schedule - // preparationStartTime = scheduleTime - moveTime - preparation.totalDuration - scheduleSpareTime - final nextPreparationStartTime = nextSchedule.preparationStartTime; + // Check overlap with previous schedule + if (adjacentSchedules.hasPrevious && + adjacentSchedules.previousSchedule != null) { + final previousSchedule = adjacentSchedules.previousSchedule!; - // Calculate time difference - final timeDifference = - nextPreparationStartTime.difference(selectedDateTime); - final minutesDifference = timeDifference.inMinutes; + // Calculate when previous schedule ends + // Previous schedule ends at: scheduleTime (since preparation is before schedule time) + final previousScheduleEndTime = previousSchedule.scheduleTime; - debugPrint('=== Schedule Overlap Debug ==='); - debugPrint('Next schedule name: ${nextSchedule.scheduleName}'); - debugPrint('Next schedule time: ${nextSchedule.scheduleTime}'); - debugPrint( - 'Next schedule preparation start time: $nextPreparationStartTime'); - debugPrint('Next schedule moveTime: ${nextSchedule.moveTime}'); - debugPrint( - 'Next schedule preparation totalDuration: ${nextSchedule.preparation.totalDuration}'); - debugPrint('Next schedule spareTime: ${nextSchedule.scheduleSpareTime}'); - debugPrint('Selected datetime: $selectedDateTime'); - debugPrint('Time difference: $timeDifference'); - debugPrint('Minutes difference: $minutesDifference'); - debugPrint('============================='); - - // Show warning if positive time difference, error if already overlapping (<= 0) - // Store timeDifference (can be positive for warning or negative/zero for error) - // and isOverlapping flag (true if <= 0, false if > 0) - if (minutesDifference > 0) { - debugPrint('Showing warning with $minutesDifference minutes'); - emit(state.copyWith( - overlapDuration: timeDifference, - isOverlapping: false, - nextScheduleName: nextSchedule.scheduleName, - )); - } else { - // Already overlapping - show as error - // Store absolute value for display purposes, but keep the sign information in isOverlapping + // Calculate time difference + // If negative, selected time is before previous schedule ends (overlapping) + // If positive, selected time is after previous schedule ends (no overlap) + final timeDifference = + selectedDateTime.difference(previousScheduleEndTime); + final minutesDifference = timeDifference.inMinutes; + + debugPrint('=== Previous Schedule Overlap Debug ==='); + debugPrint('Previous schedule name: ${previousSchedule.scheduleName}'); + debugPrint('Previous schedule time: ${previousSchedule.scheduleTime}'); debugPrint( - 'Showing error - already overlapping (minutesDifference: $minutesDifference)'); + 'Previous schedule totalDuration: ${previousSchedule.totalDuration}'); + debugPrint('Previous schedule end time: $previousScheduleEndTime'); + debugPrint('Selected datetime: $selectedDateTime'); + debugPrint('Time difference: $timeDifference'); + debugPrint('Minutes difference: $minutesDifference'); + debugPrint('======================================'); + + // If minutesDifference < 0, it means selected time is before previous ends (overlapping) + // If minutesDifference >= 0, it means selected time is after previous ends (no overlap) + if (minutesDifference < 0) { + // Selected time is before previous schedule ends - overlapping + // This case should theoretically not happen if we assume preparation is before schedule time and we are creating a new schedule + // But if it does, we treat it as available time being negative? + // Or just show it as available time (which will be negative) + debugPrint( + 'Showing error - overlapping with previous schedule (minutesDifference: $minutesDifference)'); + emit(state.copyWith( + previousOverlapDuration: + timeDifference, // Keep negative duration? Or abs? + // If we remove isPreviousOverlapping, we just store the duration. + // The state will decide if it's a warning based on duration value. + // But wait, hasPreviousOverlapMessage logic: + // return previousOverlapDuration!.inMinutes < 180; + // If negative, it is < 180, so it returns true (warning). + // But negative means overlap, which should be error? + // The user said "impossible to overlap with previous schedule". + // So we assume minutesDifference >= 0 always? + // If so, we just handle the >= 0 case. + previousScheduleName: previousSchedule.scheduleName, + )); + } else { + // No overlap with previous schedule + // Show warning only if available time is small (e.g., less than 3 hours) + final isSmallTime = minutesDifference < 180; + + if (isSmallTime) { + debugPrint( + 'Showing warning - small available time from previous schedule (minutesDifference: $minutesDifference)'); + emit(state.copyWith( + previousOverlapDuration: timeDifference, + previousScheduleName: previousSchedule.scheduleName, + )); + } else { + debugPrint( + 'Not showing warning - available time is large (minutesDifference: $minutesDifference)'); + emit(state.copyWith( + previousOverlapDuration: timeDifference, + previousScheduleName: previousSchedule.scheduleName, + // clearPreviousOverlap: true, // Do not clear if we want to keep the value + )); + } + } + } else { + // No previous schedule found, clear previous overlap emit(state.copyWith( - overlapDuration: timeDifference.abs(), - isOverlapping: true, - nextScheduleName: nextSchedule.scheduleName, + clearPreviousOverlap: true, )); } } catch (e) { - // On error, clear overlap + // On error, clear both overlaps debugPrint('Error checking schedule overlap: $e'); - emit(state.copyWith(clearOverlap: true)); + emit(state.copyWith(clearOverlap: true, clearPreviousOverlap: true)); } } @@ -185,12 +270,27 @@ class ScheduleDateTimeCubit extends Cubit { if (state.scheduleDate.isValid && state.scheduleTime.isValid && state.isOverlapping == false) { + // If not overlapping, previousOverlapDuration holds the available time (if any) + // If it is null, it means no previous schedule or cleared. + // But wait, if we cleared it because it was large, we lost it? + // In the previous step, I decided NOT to clear it if it is large, but just set it. + // But then the warning would show. + // I need to update ScheduleDateTimeState.hasPreviousOverlapMessage to only show if small. + scheduleFormBloc.add(ScheduleFormScheduleDateTimeChanged( scheduleDate: state.scheduleDate.value!, scheduleTime: state.scheduleTime.value!, - timeLeftUntilNextSchedulePreparation: state.overlapDuration, - nextScheduleName: state.nextScheduleName, + maxAvailableTime: state.previousOverlapDuration, + previousScheduleName: state.previousScheduleName, )); } } + + ({DateTime startDate, DateTime endDate}) _getDateRange(DateTime date) { + final baseDate = DateTime(date.year, date.month, date.day); + return ( + startDate: baseDate.subtract(const Duration(days: 1)), + endDate: baseDate.add(const Duration(days: 2)), + ); + } } diff --git a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart index 7c9caa8a..d6b265ee 100644 --- a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart +++ b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_state.dart @@ -4,59 +4,94 @@ class ScheduleDateTimeState extends Equatable { const ScheduleDateTimeState({ this.scheduleDate = const ScheduleDateInputModel.pure(), this.scheduleTime = const ScheduleTimeInputModel.pure(), - this.overlapDuration, this.isOverlapping = false, this.nextScheduleName, + this.nextPreparationStartTime, + this.previousOverlapDuration, + this.previousScheduleName, }); final ScheduleDateInputModel scheduleDate; final ScheduleTimeInputModel scheduleTime; - final Duration? overlapDuration; final bool isOverlapping; final String? nextScheduleName; + final DateTime? nextPreparationStartTime; + final Duration? previousOverlapDuration; + final String? previousScheduleName; bool get isValid => Formz.validate([scheduleDate, scheduleTime]) && !isOverlapping; - /// Returns true if there's an overlap warning or error to display - bool get hasOverlapMessage => overlapDuration != null; + /// Returns true if there's an overlap warning or error to display (for next schedule) + bool get hasOverlapMessage => isOverlapping; - /// Returns true if the overlap is an error (already overlapping, minutes <= 0) - bool get isOverlapError => isOverlapping; + /// Returns true if there's an overlap warning or error to display (for previous schedule) + bool get hasPreviousOverlapMessage { + if (previousOverlapDuration == null) return false; + // Warning only if small time (< 3 hours) + return previousOverlapDuration!.inMinutes < 180; + } + + /// Returns true if there's any overlap message to display + bool get hasAnyOverlapMessage => + hasOverlapMessage || hasPreviousOverlapMessage; - /// Returns the overlap message based on whether it's an error or warning + /// Returns the overlap message for next schedule based on whether it's an error or warning /// Requires BuildContext for localization String? getOverlapMessage(BuildContext context) { - if (overlapDuration == null) return null; + if (!isOverlapping) return null; final localizations = AppLocalizations.of(context)!; - final minutes = overlapDuration!.inMinutes.abs(); final scheduleName = nextScheduleName ?? ''; - if (isOverlapping) { - return localizations.scheduleOverlapError(minutes, scheduleName); - } else { - return localizations.scheduleOverlapWarning(minutes, scheduleName); + String startTime = ''; + if (nextPreparationStartTime != null) { + final timeOfDay = TimeOfDay.fromDateTime(nextPreparationStartTime!); + startTime = timeOfDay.format(context); } + + return localizations.scheduleOverlapError(scheduleName, startTime); + } + + /// Returns the overlap message for previous schedule based on whether it's an error or warning + /// Requires BuildContext for localization + String? getPreviousOverlapMessage(BuildContext context) { + if (previousOverlapDuration == null) return null; + + final localizations = AppLocalizations.of(context)!; + final minutes = previousOverlapDuration!.inMinutes.abs(); + final scheduleName = previousScheduleName ?? ''; + + return localizations.scheduleOverlapWarning(minutes, scheduleName); } ScheduleDateTimeState copyWith({ ScheduleDateInputModel? scheduleDate, ScheduleTimeInputModel? scheduleTime, - Duration? overlapDuration, bool? isOverlapping, String? nextScheduleName, + DateTime? nextPreparationStartTime, + Duration? previousOverlapDuration, + String? previousScheduleName, bool clearOverlap = false, + bool clearPreviousOverlap = false, }) { return ScheduleDateTimeState( scheduleDate: scheduleDate ?? this.scheduleDate, scheduleTime: scheduleTime ?? this.scheduleTime, - overlapDuration: - clearOverlap ? null : (overlapDuration ?? this.overlapDuration), isOverlapping: clearOverlap ? false : (isOverlapping ?? this.isOverlapping), nextScheduleName: clearOverlap ? null : (nextScheduleName ?? this.nextScheduleName), + nextPreparationStartTime: clearOverlap + ? null + : (nextPreparationStartTime ?? this.nextPreparationStartTime), + previousOverlapDuration: clearPreviousOverlap + ? null + : (previousOverlapDuration ?? this.previousOverlapDuration), + previousScheduleName: clearPreviousOverlap + ? null + : (previousScheduleName ?? this.previousScheduleName), ); } @@ -71,8 +106,10 @@ class ScheduleDateTimeState extends Equatable { List get props => [ scheduleDate, scheduleTime, - overlapDuration ?? const Duration(), isOverlapping, nextScheduleName ?? '', + nextPreparationStartTime ?? DateTime(0), + previousOverlapDuration ?? const Duration(), + previousScheduleName ?? '', ]; } diff --git a/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart b/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart index 1ebd3193..508a0a30 100644 --- a/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart +++ b/lib/presentation/schedule_create/schedule_date_time/screens/schedule_date_time_form.dart @@ -88,14 +88,20 @@ class ScheduleDateTimeForm extends StatelessWidget { ), ], ), - if (state.hasOverlapMessage) + if (state.hasPreviousOverlapMessage) + Padding( + padding: const EdgeInsets.only(top: 8.0, left: 16.0), + child: MessageBubble( + message: state.getPreviousOverlapMessage(context)!, + type: MessageBubbleType.warning, + ), + ), + if (state.isOverlapping) Padding( padding: const EdgeInsets.only(top: 8.0, left: 16.0), child: MessageBubble( message: state.getOverlapMessage(context)!, - type: state.isOverlapError - ? MessageBubbleType.error - : MessageBubbleType.warning, + type: MessageBubbleType.error, ), ), ], From c919729986225e8677958de9a77c42d6090b4308 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 22:55:29 +0900 Subject: [PATCH 23/27] feat(schedule-create): update moving and spare time steps for overlap detection - Update SchedulePlaceMovingTimeCubit to use maxAvailableTime for overlap checks. - Update ScheduleFormSpareTimeCubit to use maxAvailableTime for overlap checks. - Update UI to show overlap warnings/errors in these steps. --- .../cubit/schedule_place_moving_time_cubit.dart | 11 ++++------- .../cubit/schedule_place_moving_time_state.dart | 4 ++-- .../screens/schedule_place_moving_time_form.dart | 4 ++-- .../cubit/schedule_form_spare_time_cubit.dart | 11 ++++------- .../cubit/schedule_form_spare_time_state.dart | 4 ++-- .../schedule_spare_and_preparing_time_form.dart | 4 ++-- 6 files changed, 16 insertions(+), 22 deletions(-) diff --git a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart index 0b419c65..e470aa85 100644 --- a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart @@ -39,23 +39,20 @@ class SchedulePlaceMovingTimeCubit extends Cubit { final ScheduleMovingTimeInputModel moveTimeInputModel = ScheduleMovingTimeInputModel.dirty(moveTime); - // Check for overlap if timeLeftUntilNextSchedulePreparation exists + // Check for overlap if maxAvailableTime exists final formState = scheduleFormBloc.state; - final timeLeftUntilNextSchedulePreparation = - formState.timeLeftUntilNextSchedulePreparation; + final maxAvailableTime = formState.maxAvailableTime; final oldMoveTime = formState.moveTime ?? Duration.zero; Duration? overlapDuration; bool isOverlapping = false; - if (timeLeftUntilNextSchedulePreparation != null && - formState.scheduleTime != null) { + if (maxAvailableTime != null && formState.scheduleTime != null) { // Calculate the change in moveTime final moveTimeDifference = moveTime - oldMoveTime; // Calculate new time left: if moveTime increases, time left decreases - final newTimeLeft = - timeLeftUntilNextSchedulePreparation - moveTimeDifference; + final newTimeLeft = maxAvailableTime - moveTimeDifference; final minutesDifference = newTimeLeft.inMinutes; if (minutesDifference <= 0) { diff --git a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart index 5ea14706..8dc9305d 100644 --- a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart +++ b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_state.dart @@ -29,10 +29,10 @@ class SchedulePlaceMovingTimeState extends Equatable { final localizations = AppLocalizations.of(context)!; final minutes = overlapDuration!.inMinutes.abs(); final scheduleName = - context.read().state.nextScheduleName ?? ''; + context.read().state.previousScheduleName ?? ''; if (isOverlapping) { - return localizations.scheduleOverlapError(minutes, scheduleName); + return localizations.previousScheduleOverlapError(minutes, scheduleName); } else { return localizations.scheduleOverlapWarning(minutes, scheduleName); } diff --git a/lib/presentation/schedule_create/schedule_place_moving_time.dart/screens/schedule_place_moving_time_form.dart b/lib/presentation/schedule_create/schedule_place_moving_time.dart/screens/schedule_place_moving_time_form.dart index 300a114b..f8af0de4 100644 --- a/lib/presentation/schedule_create/schedule_place_moving_time.dart/screens/schedule_place_moving_time_form.dart +++ b/lib/presentation/schedule_create/schedule_place_moving_time.dart/screens/schedule_place_moving_time_form.dart @@ -83,11 +83,11 @@ class _SchedulePlaceMovingTimeFormState Padding( padding: const EdgeInsets.only(top: 8.0, left: 16.0), child: MessageBubble( - message: state.getOverlapMessage(context)!, + message: state.getOverlapMessage(context)!, type: state.isOverlapError ? MessageBubbleType.error : MessageBubbleType.warning, - ), + ), ), ], ); diff --git a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart index b0df0015..744c4cac 100644 --- a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart @@ -26,10 +26,9 @@ class ScheduleFormSpareTimeCubit extends Cubit { required Duration? spareTime, }) { final formState = scheduleFormBloc.state; - final timeLeftUntilNextSchedulePreparation = - formState.timeLeftUntilNextSchedulePreparation; + final maxAvailableTime = formState.maxAvailableTime; - if (timeLeftUntilNextSchedulePreparation == null || + if (maxAvailableTime == null || formState.scheduleTime == null || moveTime == null || spareTime == null) { @@ -37,10 +36,8 @@ class ScheduleFormSpareTimeCubit extends Cubit { } // Calculate new time left: if preparationTime increases, time left decreases - final newTimeLeft = timeLeftUntilNextSchedulePreparation - - totalPreparationTime - - moveTime - - spareTime; + final newTimeLeft = + maxAvailableTime - totalPreparationTime - moveTime - spareTime; final minutesDifference = newTimeLeft.inMinutes; if (minutesDifference <= 0) { diff --git a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart index 74011967..c82fd29e 100644 --- a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart +++ b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_state.dart @@ -31,10 +31,10 @@ class ScheduleFormSpareTimeState extends Equatable { final localizations = AppLocalizations.of(context)!; final minutes = overlapDuration!.inMinutes.abs(); final scheduleName = - context.read().state.nextScheduleName ?? ''; + context.read().state.previousScheduleName ?? ''; if (isOverlapping) { - return localizations.scheduleOverlapError(minutes, scheduleName); + return localizations.previousScheduleOverlapError(minutes, scheduleName); } else { return localizations.scheduleOverlapWarning(minutes, scheduleName); } diff --git a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/screens/schedule_spare_and_preparing_time_form.dart b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/screens/schedule_spare_and_preparing_time_form.dart index 4b2f5e15..22bc4ddc 100644 --- a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/screens/schedule_spare_and_preparing_time_form.dart +++ b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/screens/schedule_spare_and_preparing_time_form.dart @@ -96,11 +96,11 @@ class _ScheduleSpareAndPreparingTimeFormState Padding( padding: const EdgeInsets.only(top: 8.0, left: 16.0), child: MessageBubble( - message: state.getOverlapMessage(context)!, + message: state.getOverlapMessage(context)!, type: state.isOverlapError ? MessageBubbleType.error : MessageBubbleType.warning, - ), + ), ), ], ); From 8e677a28d3e5631b151d6dcf4848446acc0bc7a2 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 22:56:05 +0900 Subject: [PATCH 24/27] feat(schedule-create): inject AuthBloc into ScheduleFormBloc - Pass AuthBloc to ScheduleFormBloc in ScheduleCreateScreen and ScheduleEditScreen. - This allows accessing user spare time settings. --- .../schedule_create/screens/schedule_create_screen.dart | 6 ++++-- .../schedule_create/screens/schedule_edit_screen.dart | 5 ++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/presentation/schedule_create/screens/schedule_create_screen.dart b/lib/presentation/schedule_create/screens/schedule_create_screen.dart index 70758c1e..18e51cc6 100644 --- a/lib/presentation/schedule_create/screens/schedule_create_screen.dart +++ b/lib/presentation/schedule_create/screens/schedule_create_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:on_time_front/core/di/di_setup.dart'; +import 'package:on_time_front/presentation/app/bloc/auth/auth_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/components/schedule_multi_page_form.dart'; @@ -21,8 +22,9 @@ class ScheduleCreateScreen extends StatelessWidget { const BorderRadius.vertical(top: Radius.circular(24)), ), child: BlocProvider( - create: (context) => getIt.get() - ..add(ScheduleFormCreateRequested()), + create: (context) => getIt.get( + param1: context.read(), + )..add(ScheduleFormCreateRequested()), child: BlocBuilder( builder: (context, state) { return ScheduleMultiPageForm( diff --git a/lib/presentation/schedule_create/screens/schedule_edit_screen.dart b/lib/presentation/schedule_create/screens/schedule_edit_screen.dart index 9ff8a68e..a4f46730 100644 --- a/lib/presentation/schedule_create/screens/schedule_edit_screen.dart +++ b/lib/presentation/schedule_create/screens/schedule_edit_screen.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:on_time_front/core/di/di_setup.dart'; +import 'package:on_time_front/presentation/app/bloc/auth/auth_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/components/schedule_multi_page_form.dart'; @@ -23,7 +24,9 @@ class ScheduleEditScreen extends StatelessWidget { const BorderRadius.vertical(top: Radius.circular(24)), ), child: BlocProvider( - create: (context) => getIt.get() + create: (context) => getIt.get( + param1: context.read(), + ) ..add(ScheduleFormEditRequested(scheduleId: scheduleId)), child: BlocBuilder( builder: (context, state) { From 4290bbcdc5b3cbfff2158488aba12f2bdfb32e90 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 23:05:22 +0900 Subject: [PATCH 25/27] feat(schedule-overlap): introduce schedule overlap warning threshold constant and update overlap detection logic --- .../cubit/schedule_date_time_cubit.dart | 4 +++- .../cubit/schedule_place_moving_time_cubit.dart | 6 +++++- .../cubit/schedule_form_spare_time_cubit.dart | 8 +++++++- lib/presentation/shared/constants/constants.dart | 1 + 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart index dcaa3e80..ae01bf32 100644 --- a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart @@ -11,6 +11,7 @@ import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bl import 'package:on_time_front/presentation/schedule_create/schedule_date_time/input_models/schedule_date_input_model.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_date_time/input_models/schedule_time_input_model.dart'; import 'package:on_time_front/domain/entities/adjacent_schedules_with_preparation_entity.dart'; +import 'package:on_time_front/presentation/shared/constants/constants.dart'; part 'schedule_date_time_state.dart'; @@ -234,7 +235,8 @@ class ScheduleDateTimeCubit extends Cubit { } else { // No overlap with previous schedule // Show warning only if available time is small (e.g., less than 3 hours) - final isSmallTime = minutesDifference < 180; + final isSmallTime = + minutesDifference < scheduleOverlapWarningThresholdMinutes; if (isSmallTime) { debugPrint( diff --git a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart index e470aa85..818be5c4 100644 --- a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart @@ -6,6 +6,7 @@ import 'package:on_time_front/l10n/app_localizations.dart'; import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_place_moving_time.dart/input_models/schedule_moving_time_input_model.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_place_moving_time.dart/input_models/schedule_place_input_model.dart'; +import 'package:on_time_front/presentation/shared/constants/constants.dart'; part 'schedule_place_moving_time_state.dart'; @@ -59,10 +60,13 @@ class SchedulePlaceMovingTimeCubit extends Cubit { // Already overlapping - show as error overlapDuration = newTimeLeft.abs(); isOverlapping = true; - } else { + } else if (minutesDifference < scheduleOverlapWarningThresholdMinutes) { // Show warning if there's still time left overlapDuration = newTimeLeft; isOverlapping = false; + } else { + overlapDuration = null; + isOverlapping = false; } } diff --git a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart index 744c4cac..af4c5c30 100644 --- a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart @@ -6,6 +6,7 @@ import 'package:on_time_front/l10n/app_localizations.dart'; import 'package:on_time_front/domain/entities/preparation_entity.dart'; import 'package:on_time_front/presentation/schedule_create/bloc/schedule_form_bloc.dart'; import 'package:on_time_front/presentation/schedule_create/schedule_spare_and_preparing_time/input_models/schedule_spare_time_input_model.dart'; +import 'package:on_time_front/presentation/shared/constants/constants.dart'; part 'schedule_form_spare_time_state.dart'; @@ -46,12 +47,17 @@ class ScheduleFormSpareTimeCubit extends Cubit { overlapDuration: newTimeLeft.abs(), isOverlapping: true, ); - } else { + } else if (minutesDifference < scheduleOverlapWarningThresholdMinutes) { // Show warning if there's still time left return ( overlapDuration: newTimeLeft, isOverlapping: false, ); + } else { + return ( + overlapDuration: null, + isOverlapping: false, + ); } } diff --git a/lib/presentation/shared/constants/constants.dart b/lib/presentation/shared/constants/constants.dart index 7c5a3f3f..6553acef 100644 --- a/lib/presentation/shared/constants/constants.dart +++ b/lib/presentation/shared/constants/constants.dart @@ -1,4 +1,5 @@ const double appBarHeight = 56.0; +const int scheduleOverlapWarningThresholdMinutes = 180; enum PreparationStateEnum { yet, // 준비 전 From e68a8b5485c2c77e98d95ba8fbb671a54c89d98f Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 23:34:05 +0900 Subject: [PATCH 26/27] feat(schedule-create): initialize cubits after submitting each page and update spare time state with overlap checks --- .../components/schedule_multi_page_form.dart | 37 +++++++++---------- .../cubit/schedule_date_time_cubit.dart | 4 +- .../schedule_place_moving_time_cubit.dart | 4 +- .../cubit/schedule_form_spare_time_cubit.dart | 15 ++++++-- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/lib/presentation/schedule_create/components/schedule_multi_page_form.dart b/lib/presentation/schedule_create/components/schedule_multi_page_form.dart index 1e30f3d6..50be14eb 100644 --- a/lib/presentation/schedule_create/components/schedule_multi_page_form.dart +++ b/lib/presentation/schedule_create/components/schedule_multi_page_form.dart @@ -124,14 +124,26 @@ class _ScheduleMultiPageFormState extends State switch (_pageCubitTypes[_tabController.index]) { case const (ScheduleNameCubit): context.read().scheduleNameSubmitted(); + // Initialize next cubit after submitting current page + WidgetsBinding.instance.addPostFrameCallback((_) { + context.read().initialize(); + }); break; case const (ScheduleDateTimeCubit): context.read().scheduleDateTimeSubmitted(); + // Initialize next cubit after submitting current page + WidgetsBinding.instance.addPostFrameCallback((_) { + context.read().initialize(); + }); break; case const (SchedulePlaceMovingTimeCubit): context .read() .schedulePlaceMovingTimeSubmitted(); + // Initialize next cubit after submitting current page + WidgetsBinding.instance.addPostFrameCallback((_) { + context.read().initialize(); + }); break; case const (ScheduleFormSpareTimeCubit): context.read().scheduleSpareTimeSubmitted(); @@ -139,7 +151,7 @@ class _ScheduleMultiPageFormState extends State } if (_tabController.index < _tabController.length - 1) { _updateCurrentPageIndex(_tabController.index + 1); - _revalidateCurrentStep(context); + _reinitializeCurrentStep(context); } else { widget.onSaved?.call(); Navigator.of(context).pop(); // Close the form @@ -167,7 +179,6 @@ class _ScheduleMultiPageFormState extends State } void _updateCurrentPageIndex(int index) { - final previousIndex = _tabController.index; _tabController.index = index; _pageViewController.animateToPage( index, @@ -176,31 +187,19 @@ class _ScheduleMultiPageFormState extends State ); } - void _revalidateCurrentStep(BuildContext context) { + void _reinitializeCurrentStep(BuildContext context) { switch (_pageCubitTypes[_tabController.index]) { case const (ScheduleNameCubit): - final currentState = context.read().state; - context - .read() - .add(ScheduleFormValidated(isValid: currentState.isValid)); + context.read().initialize(); break; case const (ScheduleDateTimeCubit): - final currentState = context.read().state; - context - .read() - .add(ScheduleFormValidated(isValid: currentState.isValid)); + context.read().initialize(); break; case const (SchedulePlaceMovingTimeCubit): - final currentState = context.read().state; - context - .read() - .add(ScheduleFormValidated(isValid: currentState.isValid)); + context.read().initialize(); break; case const (ScheduleFormSpareTimeCubit): - final currentState = context.read().state; - context - .read() - .add(ScheduleFormValidated(isValid: currentState.isValid)); + context.read().initialize(); break; } } diff --git a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart index ae01bf32..19593c3a 100644 --- a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart @@ -21,9 +21,7 @@ class ScheduleDateTimeCubit extends Cubit { @factoryParam this.scheduleFormBloc, this._loadAdjacentSchedulesWithPreparationUseCase, this._getNextScheduleWithPreparationUseCase, - ) : super(ScheduleDateTimeState()) { - initialize(); - } + ) : super(ScheduleDateTimeState()); final ScheduleFormBloc scheduleFormBloc; final LoadAdjacentScheduleWithPreparationUseCase diff --git a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart index 818be5c4..86a3177c 100644 --- a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart @@ -12,9 +12,7 @@ part 'schedule_place_moving_time_state.dart'; class SchedulePlaceMovingTimeCubit extends Cubit { SchedulePlaceMovingTimeCubit({required this.scheduleFormBloc}) - : super(SchedulePlaceMovingTimeState()) { - initialize(); - } + : super(SchedulePlaceMovingTimeState()); final ScheduleFormBloc scheduleFormBloc; diff --git a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart index af4c5c30..6e528860 100644 --- a/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_spare_and_preparing_time/cubit/schedule_form_spare_time_cubit.dart @@ -13,9 +13,7 @@ part 'schedule_form_spare_time_state.dart'; class ScheduleFormSpareTimeCubit extends Cubit { ScheduleFormSpareTimeCubit({ required this.scheduleFormBloc, - }) : super(ScheduleFormSpareTimeState()) { - initialize(); - } + }) : super(ScheduleFormSpareTimeState()); final ScheduleFormBloc scheduleFormBloc; @@ -65,10 +63,21 @@ class ScheduleFormSpareTimeCubit extends Cubit { final schedulePlaceMovingTimeState = ScheduleFormSpareTimeState.fromScheduleFormState( scheduleFormBloc.state); + + final formState = scheduleFormBloc.state; + final overlapCheck = _checkOverlap( + totalPreparationTime: schedulePlaceMovingTimeState.totalPreparationTime, + moveTime: formState.moveTime, + spareTime: schedulePlaceMovingTimeState.spareTime.value, + ); + emit(state.copyWith( spareTime: schedulePlaceMovingTimeState.spareTime, preparation: schedulePlaceMovingTimeState.preparation, totalPreparationTime: schedulePlaceMovingTimeState.totalPreparationTime, + overlapDuration: overlapCheck.overlapDuration, + isOverlapping: overlapCheck.isOverlapping, + clearOverlap: overlapCheck.overlapDuration == null, )); scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); } From d2eb1151cab546881ad76e2eeb8c913eeca419e7 Mon Sep 17 00:00:00 2001 From: jjoonleo Date: Tue, 25 Nov 2025 23:37:32 +0900 Subject: [PATCH 27/27] feat(schedule-overlap): implement schedule overlap checks in ScheduleDateTimeCubit and SchedulePlaceMovingTimeCubit --- .../cubit/schedule_date_time_cubit.dart | 9 ++++++ .../schedule_place_moving_time_cubit.dart | 28 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart index 19593c3a..6a70ee12 100644 --- a/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_date_time/cubit/schedule_date_time_cubit.dart @@ -36,6 +36,15 @@ class ScheduleDateTimeCubit extends Cubit { scheduleDate: scheduleDateTimeState.scheduleDate, scheduleTime: scheduleDateTimeState.scheduleTime, )); + + // Check for schedule overlap if both date and time are valid + if (scheduleDateTimeState.scheduleDate.isValid && + scheduleDateTimeState.scheduleTime.isValid) { + // Load adjacent schedules first, then check overlap + _loadAdjacentSchedules(scheduleDateTimeState.scheduleDate.value!) + .then((_) => checkScheduleOverlap()); + } + scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); } diff --git a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart index 86a3177c..0fac0420 100644 --- a/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart +++ b/lib/presentation/schedule_create/schedule_place_moving_time.dart/cubit/schedule_place_moving_time_cubit.dart @@ -20,9 +20,37 @@ class SchedulePlaceMovingTimeCubit extends Cubit { final schedulePlaceMovingTimeState = SchedulePlaceMovingTimeState.fromScheduleFormState( scheduleFormBloc.state); + + // Check for overlap using current form state values + final formState = scheduleFormBloc.state; + final maxAvailableTime = formState.maxAvailableTime; + final moveTime = schedulePlaceMovingTimeState.moveTime.value; + + Duration? overlapDuration; + bool isOverlapping = false; + + if (maxAvailableTime != null && formState.scheduleTime != null) { + // Calculate new time left + final newTimeLeft = maxAvailableTime - moveTime; + final minutesDifference = newTimeLeft.inMinutes; + + if (minutesDifference <= 0) { + // Already overlapping - show as error + overlapDuration = newTimeLeft.abs(); + isOverlapping = true; + } else if (minutesDifference < scheduleOverlapWarningThresholdMinutes) { + // Show warning if there's still time left + overlapDuration = newTimeLeft; + isOverlapping = false; + } + } + emit(state.copyWith( placeName: schedulePlaceMovingTimeState.placeName, moveTime: schedulePlaceMovingTimeState.moveTime, + overlapDuration: overlapDuration, + isOverlapping: isOverlapping, + clearOverlap: overlapDuration == null, )); scheduleFormBloc.add(ScheduleFormValidated(isValid: state.isValid)); }