Skip to content

Commit a9139b2

Browse files
authored
Merge pull request #573 from DevKor-github/feature/issue-545-schedule-data-source-contracts
refactor: decouple schedule data source contracts
2 parents 67909d6 + 0808b28 commit a9139b2

8 files changed

Lines changed: 331 additions & 166 deletions
Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
import 'package:on_time_front/core/database/database.dart';
2-
import 'package:on_time_front/data/mappers/domain_persistence_mappers.dart';
3-
import 'package:on_time_front/domain/entities/schedule_entity.dart';
2+
import 'package:on_time_front/data/tables/schedule_with_place_model.dart';
43

54
abstract interface class ScheduleLocalDataSource {
6-
Future<void> createSchedule(ScheduleEntity scheduleEntity);
5+
Future<void> createSchedule(ScheduleWithPlace schedule);
76

8-
Future<List<ScheduleEntity>> getSchedulesByDate(
7+
Future<List<ScheduleWithPlace>> getSchedulesByDate(
98
DateTime startDate,
109
DateTime? endDate,
1110
);
1211

13-
Future<ScheduleEntity> getScheduleById(String id);
12+
Future<ScheduleWithPlace> getScheduleById(String id);
1413

15-
Future<void> updateSchedule(ScheduleEntity scheduleEntity);
14+
Future<void> updateSchedule(Schedule schedule);
1615

17-
Future<void> deleteSchedule(ScheduleEntity scheduleEntity);
16+
Future<void> deleteSchedule(Schedule schedule);
1817
}
1918

2019
// Not registered with DI; schedule repository persistence is remote-only.
@@ -24,38 +23,30 @@ class ScheduleLocalDataSourceImpl implements ScheduleLocalDataSource {
2423
ScheduleLocalDataSourceImpl({required this.appDatabase});
2524

2625
@override
27-
Future<void> createSchedule(ScheduleEntity scheduleEntity) async {
28-
await appDatabase.scheduleDao.createSchedule(
29-
scheduleEntity.toScheduleWithPlaceRow(),
30-
);
26+
Future<void> createSchedule(ScheduleWithPlace schedule) async {
27+
await appDatabase.scheduleDao.createSchedule(schedule);
3128
}
3229

3330
@override
34-
Future<void> deleteSchedule(ScheduleEntity schedulEntity) async {
35-
await appDatabase.scheduleDao.deleteSchedule(schedulEntity.toScheduleRow());
31+
Future<void> deleteSchedule(Schedule schedule) async {
32+
await appDatabase.scheduleDao.deleteSchedule(schedule);
3633
}
3734

3835
@override
39-
Future<ScheduleEntity> getScheduleById(String id) async {
40-
final scheduleWithPlaceModel = await appDatabase.scheduleDao
41-
.getScheduleById(id);
42-
return scheduleWithPlaceModel.toScheduleEntity();
36+
Future<ScheduleWithPlace> getScheduleById(String id) async {
37+
return appDatabase.scheduleDao.getScheduleById(id);
4338
}
4439

4540
@override
46-
Future<List<ScheduleEntity>> getSchedulesByDate(
41+
Future<List<ScheduleWithPlace>> getSchedulesByDate(
4742
DateTime startDate,
4843
DateTime? endDate,
4944
) async {
50-
final scheduleWithPlaceModel = await appDatabase.scheduleDao
51-
.getSchedulesByDate(startDate, endDate);
52-
return scheduleWithPlaceModel.map((e) => e.toScheduleEntity()).toList();
45+
return appDatabase.scheduleDao.getSchedulesByDate(startDate, endDate);
5346
}
5447

5548
@override
56-
Future<void> updateSchedule(ScheduleEntity scheduleEntity) async {
57-
await appDatabase.scheduleDao.updateSchedule(
58-
scheduleEntity.toScheduleRow(),
59-
);
49+
Future<void> updateSchedule(Schedule schedule) async {
50+
await appDatabase.scheduleDao.updateSchedule(schedule);
6051
}
6152
}

lib/data/data_sources/schedule_remote_data_source.dart

Lines changed: 18 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,19 @@ import 'package:on_time_front/data/models/create_schedule_request_model.dart';
66
import 'package:on_time_front/data/models/get_schedule_response_model.dart';
77
import 'package:on_time_front/data/models/update_schedule_request_model.dart';
88

9-
import 'package:on_time_front/domain/entities/schedule_entity.dart';
10-
119
abstract interface class ScheduleRemoteDataSource {
12-
Future<void> createSchedule(ScheduleEntity schedule);
10+
Future<void> createSchedule(CreateScheduleRequestModel schedule);
1311

14-
Future<List<ScheduleEntity>> getSchedulesByDate(
12+
Future<List<GetScheduleResponseModel>> getSchedulesByDate(
1513
DateTime startDate,
1614
DateTime? endDate,
1715
);
1816

19-
Future<ScheduleEntity> getScheduleById(String id);
17+
Future<GetScheduleResponseModel> getScheduleById(String id);
2018

21-
Future<void> updateSchedule(
22-
ScheduleEntity schedule, {
23-
bool includePreparationSource = false,
24-
});
19+
Future<void> updateSchedule(UpdateScheduleRequestModel schedule);
2520

26-
Future<void> deleteSchedule(ScheduleEntity schedule);
21+
Future<void> deleteSchedule(String scheduleId);
2722

2823
Future<void> startSchedule(String scheduleId);
2924

@@ -36,13 +31,11 @@ class ScheduleRemoteDataSourceImpl implements ScheduleRemoteDataSource {
3631
ScheduleRemoteDataSourceImpl(this.dio);
3732

3833
@override
39-
Future<void> createSchedule(ScheduleEntity schedule) async {
34+
Future<void> createSchedule(CreateScheduleRequestModel schedule) async {
4035
try {
41-
CreateScheduleRequestModel createScheduleModel =
42-
CreateScheduleRequestModel.fromEntity(schedule);
4336
final result = await dio.post(
4437
Endpoint.createSchedule,
45-
data: createScheduleModel.toJson(),
38+
data: schedule.toJson(),
4639
);
4740
if (result.statusCode == 200) {
4841
return;
@@ -55,19 +48,11 @@ class ScheduleRemoteDataSourceImpl implements ScheduleRemoteDataSource {
5548
}
5649

5750
@override
58-
Future<void> updateSchedule(
59-
ScheduleEntity schedule, {
60-
bool includePreparationSource = false,
61-
}) async {
51+
Future<void> updateSchedule(UpdateScheduleRequestModel schedule) async {
6252
try {
63-
UpdateScheduleRequestModel updateScheduleModel =
64-
UpdateScheduleRequestModel.fromEntity(
65-
schedule,
66-
includePreparationSource: includePreparationSource,
67-
);
6853
final result = await dio.put(
69-
Endpoint.updateSchedule(schedule.id),
70-
data: updateScheduleModel.toJson(),
54+
Endpoint.updateSchedule(schedule.scheduleId),
55+
data: schedule.toJson(),
7156
);
7257
if (result.statusCode == 200) {
7358
return;
@@ -80,9 +65,9 @@ class ScheduleRemoteDataSourceImpl implements ScheduleRemoteDataSource {
8065
}
8166

8267
@override
83-
Future<void> deleteSchedule(ScheduleEntity schedule) async {
68+
Future<void> deleteSchedule(String scheduleId) async {
8469
try {
85-
final result = await dio.delete(Endpoint.deleteScheduleById(schedule.id));
70+
final result = await dio.delete(Endpoint.deleteScheduleById(scheduleId));
8671
if (result.statusCode == 200) {
8772
return;
8873
} else {
@@ -125,13 +110,13 @@ class ScheduleRemoteDataSourceImpl implements ScheduleRemoteDataSource {
125110
}
126111

127112
@override
128-
Future<ScheduleEntity> getScheduleById(String id) async {
113+
Future<GetScheduleResponseModel> getScheduleById(String id) async {
129114
try {
130115
final result = await dio.get(Endpoint.getScheduleById(id));
131116
if (result.statusCode == 200) {
132117
final GetScheduleResponseModel schedule =
133118
GetScheduleResponseModel.fromJson(result.data["data"]);
134-
return schedule.toEntity();
119+
return schedule;
135120
} else {
136121
throw Exception('Error getting schedules');
137122
}
@@ -141,7 +126,7 @@ class ScheduleRemoteDataSourceImpl implements ScheduleRemoteDataSource {
141126
}
142127

143128
@override
144-
Future<List<ScheduleEntity>> getSchedulesByDate(
129+
Future<List<GetScheduleResponseModel>> getSchedulesByDate(
145130
DateTime startDate,
146131
DateTime? endDate,
147132
) async {
@@ -154,9 +139,9 @@ class ScheduleRemoteDataSourceImpl implements ScheduleRemoteDataSource {
154139
},
155140
);
156141
if (result.statusCode == 200) {
157-
final List<ScheduleEntity> schedules = result.data["data"]
158-
.map<ScheduleEntity>(
159-
(e) => GetScheduleResponseModel.fromJson(e).toEntity(),
142+
final List<GetScheduleResponseModel> schedules = result.data["data"]
143+
.map<GetScheduleResponseModel>(
144+
(e) => GetScheduleResponseModel.fromJson(e),
160145
)
161146
.toList();
162147
return schedules;

lib/data/repositories/schedule_repository_impl.dart

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import 'dart:async';
33
import 'package:collection/collection.dart';
44
import 'package:injectable/injectable.dart';
55
import 'package:on_time_front/data/data_sources/schedule_remote_data_source.dart';
6+
import 'package:on_time_front/data/models/create_schedule_request_model.dart';
7+
import 'package:on_time_front/data/models/update_schedule_request_model.dart';
68
import 'package:on_time_front/domain/entities/schedule_entity.dart';
79
import 'package:on_time_front/domain/repositories/schedule_repository.dart';
810
import 'package:on_time_front/domain/repositories/timed_preparation_repository.dart';
@@ -47,7 +49,9 @@ class ScheduleRepositoryImpl implements ScheduleRepository {
4749
@override
4850
Future<void> createSchedule(ScheduleEntity schedule) async {
4951
try {
50-
await scheduleRemoteDataSource.createSchedule(schedule);
52+
await scheduleRemoteDataSource.createSchedule(
53+
CreateScheduleRequestModel.fromEntity(schedule),
54+
);
5155
_emitUpsertedSchedule(schedule);
5256
} catch (e) {
5357
rethrow;
@@ -57,7 +61,7 @@ class ScheduleRepositoryImpl implements ScheduleRepository {
5761
@override
5862
Future<void> deleteSchedule(ScheduleEntity schedule) async {
5963
try {
60-
await scheduleRemoteDataSource.deleteSchedule(schedule);
64+
await scheduleRemoteDataSource.deleteSchedule(schedule.id);
6165
await _clearTimedPreparationSafe(schedule.id);
6266
_emitScheduleSet(
6367
Set.from(_scheduleStreamController.value)
@@ -81,7 +85,9 @@ class ScheduleRepositoryImpl implements ScheduleRepository {
8185
@override
8286
Future<ScheduleEntity> getScheduleById(String id) async {
8387
try {
84-
final schedule = await scheduleRemoteDataSource.getScheduleById(id);
88+
final schedule = (await scheduleRemoteDataSource.getScheduleById(
89+
id,
90+
)).toEntity();
8591
if (_isEnded(schedule.doneStatus)) {
8692
await _clearTimedPreparationSafe(schedule.id);
8793
}
@@ -98,10 +104,10 @@ class ScheduleRepositoryImpl implements ScheduleRepository {
98104
DateTime? endDate,
99105
) async {
100106
try {
101-
final schedules = await scheduleRemoteDataSource.getSchedulesByDate(
107+
final schedules = (await scheduleRemoteDataSource.getSchedulesByDate(
102108
startDate,
103109
endDate,
104-
);
110+
)).map((schedule) => schedule.toEntity()).toList();
105111
for (final schedule in schedules) {
106112
if (_isEnded(schedule.doneStatus)) {
107113
await _clearTimedPreparationSafe(schedule.id);
@@ -125,13 +131,15 @@ class ScheduleRepositoryImpl implements ScheduleRepository {
125131
}) async {
126132
try {
127133
await scheduleRemoteDataSource.updateSchedule(
128-
schedule,
129-
includePreparationSource: includePreparationSource,
134+
UpdateScheduleRequestModel.fromEntity(
135+
schedule,
136+
includePreparationSource: includePreparationSource,
137+
),
130138
);
131139
await _clearTimedPreparationSafe(schedule.id);
132-
final refreshedSchedule = await scheduleRemoteDataSource.getScheduleById(
140+
final refreshedSchedule = (await scheduleRemoteDataSource.getScheduleById(
133141
schedule.id,
134-
);
142+
)).toEntity();
135143
if (_isEnded(refreshedSchedule.doneStatus)) {
136144
await _clearTimedPreparationSafe(refreshedSchedule.id);
137145
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import 'dart:io';
2+
3+
import 'package:flutter_test/flutter_test.dart';
4+
5+
void main() {
6+
test(
7+
'schedule remote data source contract does not expose domain entities',
8+
() {
9+
final violations = _scheduleEntityViolations(
10+
'lib/data/data_sources/schedule_remote_data_source.dart',
11+
);
12+
13+
expect(violations, isEmpty);
14+
},
15+
);
16+
17+
test(
18+
'schedule local data source contract does not expose domain entities',
19+
() {
20+
final violations = _scheduleEntityViolations(
21+
'lib/data/data_sources/schedule_local_data_source.dart',
22+
);
23+
24+
expect(violations, isEmpty);
25+
},
26+
);
27+
}
28+
29+
List<String> _scheduleEntityViolations(String path) {
30+
final lines = File(path).readAsLinesSync();
31+
return [
32+
for (var index = 0; index < lines.length; index++)
33+
if (lines[index].contains('domain/entities/schedule_entity.dart') ||
34+
lines[index].contains('ScheduleEntity'))
35+
'$path:${index + 1}: ${lines[index].trim()}',
36+
];
37+
}

0 commit comments

Comments
 (0)