Skip to content

Commit 30b0e74

Browse files
committed
refactor(backend): migrate exports to clean architecture
1 parent e88a703 commit 30b0e74

File tree

16 files changed

+246
-164
lines changed

16 files changed

+246
-164
lines changed

backend/src/main/java/com/paligot/confily/backend/Server.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import com.paligot.confily.backend.categories.infrastructure.api.registerAdminCa
55
import com.paligot.confily.backend.categories.infrastructure.api.registerCategoriesRoutes
66
import com.paligot.confily.backend.events.infrastructure.api.registerAdminEventRoutes
77
import com.paligot.confily.backend.events.infrastructure.api.registerEventRoutes
8-
import com.paligot.confily.backend.export.registerAdminExportRoutes
9-
import com.paligot.confily.backend.export.registerExportRoutes
8+
import com.paligot.confily.backend.export.infrastructure.api.registerAdminExportRoutes
9+
import com.paligot.confily.backend.export.infrastructure.api.registerExportRoutes
1010
import com.paligot.confily.backend.formats.infrastructure.api.registerAdminFormatsRoutes
1111
import com.paligot.confily.backend.formats.infrastructure.api.registerFormatsRoutes
1212
import com.paligot.confily.backend.internals.infrastructure.ktor.plugins.IdentificationPlugin

backend/src/main/java/com/paligot/confily/backend/export/ExportModule.kt

Lines changed: 0 additions & 50 deletions
This file was deleted.

backend/src/main/java/com/paligot/confily/backend/export/EventMappers.kt renamed to backend/src/main/java/com/paligot/confily/backend/export/application/EventMappers.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
@file:Suppress("TooManyFunctions")
22

3-
package com.paligot.confily.backend.export
3+
package com.paligot.confily.backend.export.application
44

55
import com.paligot.confily.backend.internals.application.convertToModel
66
import com.paligot.confily.backend.internals.infrastructure.firestore.EventEntity

backend/src/main/java/com/paligot/confily/backend/export/ExportEventRepository.kt renamed to backend/src/main/java/com/paligot/confily/backend/export/application/ExportEventAdminRepositoryDefault.kt

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
package com.paligot.confily.backend.export
1+
package com.paligot.confily.backend.export.application
22

3-
import com.paligot.confily.backend.NotFoundException
3+
import com.paligot.confily.backend.export.domain.ExportAdminRepository
44
import com.paligot.confily.backend.internals.infrastructure.firestore.EventEntity
55
import com.paligot.confily.backend.internals.infrastructure.firestore.EventFirestore
66
import com.paligot.confily.backend.internals.infrastructure.firestore.MapEntity
@@ -14,32 +14,27 @@ import com.paligot.confily.backend.map.application.convertToModel
1414
import com.paligot.confily.backend.qanda.application.convertToModel
1515
import com.paligot.confily.backend.team.application.convertToModel
1616
import com.paligot.confily.models.ExportEvent
17+
import com.paligot.confily.models.TeamMember
1718
import kotlinx.coroutines.CoroutineDispatcher
1819
import kotlinx.coroutines.Dispatchers
1920
import kotlinx.coroutines.async
2021
import kotlinx.coroutines.coroutineScope
2122

2223
@Suppress("LongParameterList")
23-
class ExportEventRepository(
24+
class ExportEventAdminRepositoryDefault(
2425
private val eventDao: EventFirestore,
2526
private val eventStorage: EventStorage,
2627
private val qAndAFirestore: QAndAFirestore,
2728
private val teamFirestore: TeamFirestore,
2829
private val mapFirestore: MapFirestore,
2930
private val partnerFirestore: PartnerFirestore,
3031
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
31-
) {
32-
suspend fun get(eventId: String): ExportEvent {
33-
val eventDb = eventDao.get(eventId)
34-
return eventStorage.getEventFile(eventId, eventDb.eventUpdatedAt)
35-
?: throw NotFoundException("Event $eventId Not Found")
36-
}
37-
38-
suspend fun export(eventId: String) = coroutineScope {
32+
) : ExportAdminRepository<ExportEvent> {
33+
override suspend fun export(eventId: String): ExportEvent {
3934
val eventDb = eventDao.get(eventId)
4035
val event = buildEvent(eventDb)
4136
eventStorage.uploadEventFile(eventId, eventDb.eventUpdatedAt, event)
42-
return@coroutineScope event
37+
return event
4338
}
4439

4540
private suspend fun buildEvent(event: EventEntity): ExportEvent = coroutineScope {
@@ -58,9 +53,9 @@ class ExportEventRepository(
5853
)
5954
}
6055

61-
private suspend fun teamMembers(eventDb: EventEntity) = coroutineScope {
56+
private fun teamMembers(eventDb: EventEntity): Map<String, List<TeamMember>> {
6257
val orderMap = eventDb.teamGroups.associate { it.name to it.order }
63-
return@coroutineScope teamFirestore.getAll(eventDb.slugId)
58+
return teamFirestore.getAll(eventDb.slugId)
6459
.asSequence()
6560
.sortedBy { orderMap[it.teamName] ?: 0 }
6661
.groupBy { it.teamName }
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.paligot.confily.backend.export.application
2+
3+
import com.paligot.confily.backend.NotFoundException
4+
import com.paligot.confily.backend.export.domain.ExportRepository
5+
import com.paligot.confily.backend.internals.infrastructure.firestore.EventFirestore
6+
import com.paligot.confily.backend.internals.infrastructure.storage.EventStorage
7+
import com.paligot.confily.models.ExportEvent
8+
9+
class ExportEventRepositoryDefault(
10+
private val eventDao: EventFirestore,
11+
private val eventStorage: EventStorage
12+
) : ExportRepository<ExportEvent> {
13+
override suspend fun get(eventId: String): ExportEvent {
14+
val eventDb = eventDao.get(eventId)
15+
return eventStorage.getEventFile(eventId, eventDb.eventUpdatedAt)
16+
?: throw NotFoundException("Event $eventId Not Found")
17+
}
18+
}

backend/src/main/java/com/paligot/confily/backend/export/ExportPartnersRepository.kt renamed to backend/src/main/java/com/paligot/confily/backend/export/application/ExportPartnersAdminRepositoryDefault.kt

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
package com.paligot.confily.backend.export
1+
package com.paligot.confily.backend.export.application
22

3-
import com.paligot.confily.backend.NotFoundException
43
import com.paligot.confily.backend.activities.application.convertToModel
4+
import com.paligot.confily.backend.export.domain.ExportAdminRepository
55
import com.paligot.confily.backend.internals.infrastructure.firestore.ActivityFirestore
66
import com.paligot.confily.backend.internals.infrastructure.firestore.EventEntity
77
import com.paligot.confily.backend.internals.infrastructure.firestore.EventFirestore
@@ -16,25 +16,19 @@ import kotlinx.coroutines.Dispatchers
1616
import kotlinx.coroutines.async
1717
import kotlinx.coroutines.coroutineScope
1818

19-
class ExportPartnersRepository(
19+
class ExportPartnersAdminRepositoryDefault(
2020
private val eventFirestore: EventFirestore,
2121
private val eventStorage: EventStorage,
2222
private val partnerFirestore: PartnerFirestore,
2323
private val jobFirestore: JobFirestore,
2424
private val activityFirestore: ActivityFirestore,
2525
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
26-
) {
27-
suspend fun get(eventId: String): PartnersActivities {
28-
val eventDb = eventFirestore.get(eventId)
29-
return eventStorage.getPartnersFile(eventId, eventDb.partnersUpdatedAt)
30-
?: throw NotFoundException("Partners $eventId Not Found")
31-
}
32-
33-
suspend fun export(eventId: String) = coroutineScope {
26+
) : ExportAdminRepository<PartnersActivities> {
27+
override suspend fun export(eventId: String): PartnersActivities {
3428
val eventDb = eventFirestore.get(eventId)
3529
val partners = buildPartnersActivities(eventDb)
3630
eventStorage.uploadPartnersFile(eventId, eventDb.partnersUpdatedAt, partners)
37-
return@coroutineScope partners
31+
return partners
3832
}
3933

4034
private suspend fun buildPartnersActivities(eventDb: EventEntity): PartnersActivities =
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.paligot.confily.backend.export.application
2+
3+
import com.paligot.confily.backend.NotFoundException
4+
import com.paligot.confily.backend.export.domain.ExportRepository
5+
import com.paligot.confily.backend.internals.infrastructure.firestore.EventFirestore
6+
import com.paligot.confily.backend.internals.infrastructure.storage.EventStorage
7+
import com.paligot.confily.models.PartnersActivities
8+
9+
class ExportPartnersRepositoryDefault(
10+
private val eventFirestore: EventFirestore,
11+
private val eventStorage: EventStorage
12+
) : ExportRepository<PartnersActivities> {
13+
override suspend fun get(eventId: String): PartnersActivities {
14+
val eventDb = eventFirestore.get(eventId)
15+
return eventStorage.getPartnersFile(eventId, eventDb.partnersUpdatedAt)
16+
?: throw NotFoundException("Partners $eventId Not Found")
17+
}
18+
}

backend/src/main/java/com/paligot/confily/backend/export/ExportPlanningRepository.kt renamed to backend/src/main/java/com/paligot/confily/backend/export/application/ExportPlanningAdminRepositoryDefault.kt

Lines changed: 6 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
package com.paligot.confily.backend.export
1+
package com.paligot.confily.backend.export.application
22

3-
import com.paligot.confily.backend.NotFoundException
43
import com.paligot.confily.backend.categories.application.convertToModel
4+
import com.paligot.confily.backend.export.domain.ExportAdminRepository
55
import com.paligot.confily.backend.formats.application.convertToModel
66
import com.paligot.confily.backend.internals.infrastructure.firestore.CategoryFirestore
77
import com.paligot.confily.backend.internals.infrastructure.firestore.EventEntity
@@ -22,11 +22,9 @@ import kotlinx.coroutines.CoroutineDispatcher
2222
import kotlinx.coroutines.Dispatchers
2323
import kotlinx.coroutines.async
2424
import kotlinx.coroutines.coroutineScope
25-
import java.time.LocalDateTime
26-
import java.time.format.DateTimeFormatter
2725

2826
@Suppress("LongParameterList")
29-
class ExportPlanningRepository(
27+
class ExportPlanningAdminRepositoryDefault(
3028
private val eventFirestore: EventFirestore,
3129
private val eventStorage: EventStorage,
3230
private val speakerFirestore: SpeakerFirestore,
@@ -36,78 +34,14 @@ class ExportPlanningRepository(
3634
private val tagFirestore: TagFirestore,
3735
private val scheduleItemFirestore: ScheduleItemFirestore,
3836
private val dispatcher: CoroutineDispatcher = Dispatchers.IO
39-
) {
40-
suspend fun get(eventId: String): AgendaV4 {
41-
val eventDb = eventFirestore.get(eventId)
42-
return eventStorage.getPlanningFile(eventId, eventDb.agendaUpdatedAt)
43-
?: throw NotFoundException("Planning $eventId Not Found")
44-
}
45-
46-
suspend fun export(eventId: String) = coroutineScope {
37+
) : ExportAdminRepository<AgendaV4> {
38+
override suspend fun export(eventId: String): AgendaV4 {
4739
val eventDb = eventFirestore.get(eventId)
4840
val planning = buildPlanning(eventDb)
4941
eventStorage.uploadPlanningFile(eventId, eventDb.agendaUpdatedAt, planning)
50-
return@coroutineScope planning
42+
return planning
5143
}
5244

53-
suspend fun getCsv(eventId: String): String {
54-
val agenda = get(eventId)
55-
val dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME
56-
val schedules = agenda.schedules
57-
.sortedWith(
58-
compareBy(
59-
{ LocalDateTime.parse(it.startTime, dateTimeFormatter) },
60-
{ it.order }
61-
)
62-
)
63-
val sessionsById = agenda.sessions.associateBy { it.id }
64-
val formatsById = agenda.formats.associateBy { it.id }
65-
val categoriesById = agenda.categories.associateBy { it.id }
66-
val speakersById = agenda.speakers.associateBy { it.id }
67-
val headers = listOf(
68-
"start_time",
69-
"end_time",
70-
"room",
71-
"session_title",
72-
"session_description",
73-
"session_format",
74-
"session_category",
75-
"session_level",
76-
"speakers"
77-
)
78-
val csvRows = mutableListOf(headers.joinToString(","))
79-
for (schedule in schedules) {
80-
val session = sessionsById[schedule.sessionId]
81-
if (session is com.paligot.confily.models.Session.Talk) {
82-
val format = formatsById[session.formatId]?.name ?: ""
83-
val category = categoriesById[session.categoryId]?.name ?: ""
84-
val speakers = session.speakers
85-
.mapNotNull { speakersById[it]?.displayName }
86-
.joinToString(", ")
87-
val row = listOf(
88-
schedule.startTime,
89-
schedule.endTime,
90-
schedule.room,
91-
session.title,
92-
session.abstract.replace("\n", " "),
93-
format,
94-
category,
95-
session.level ?: "",
96-
speakers
97-
).map { protect(it) }
98-
csvRows.add(row.joinToString(","))
99-
}
100-
}
101-
return csvRows.joinToString("\n")
102-
}
103-
104-
private fun protect(value: String): String =
105-
if (value.contains(",") || value.contains('"')) {
106-
"\"${value.replace("\"", "\"\"")}\""
107-
} else {
108-
value
109-
}
110-
11145
private suspend fun buildPlanning(eventDb: EventEntity) = coroutineScope {
11246
val schedules = async(context = dispatcher) {
11347
scheduleItemFirestore.getAll(eventDb.slugId).map { it.convertToModelV4() }
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.paligot.confily.backend.export.application
2+
3+
import com.paligot.confily.backend.NotFoundException
4+
import com.paligot.confily.backend.export.domain.ExportPlanningRepository
5+
import com.paligot.confily.backend.internals.infrastructure.firestore.EventFirestore
6+
import com.paligot.confily.backend.internals.infrastructure.storage.EventStorage
7+
import com.paligot.confily.models.AgendaV4
8+
import com.paligot.confily.models.Session
9+
import java.time.LocalDateTime
10+
import java.time.format.DateTimeFormatter
11+
12+
@Suppress("LongParameterList")
13+
class ExportPlanningRepositoryDefault(
14+
private val eventFirestore: EventFirestore,
15+
private val eventStorage: EventStorage
16+
) : ExportPlanningRepository {
17+
override suspend fun get(eventId: String): AgendaV4 {
18+
val eventDb = eventFirestore.get(eventId)
19+
return eventStorage.getPlanningFile(eventId, eventDb.agendaUpdatedAt)
20+
?: throw NotFoundException("Planning $eventId Not Found")
21+
}
22+
23+
override suspend fun getCsv(eventId: String): String {
24+
val agenda = get(eventId)
25+
val dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME
26+
val schedules = agenda.schedules
27+
.sortedWith(
28+
compareBy(
29+
{ LocalDateTime.parse(it.startTime, dateTimeFormatter) },
30+
{ it.order }
31+
)
32+
)
33+
val sessionsById = agenda.sessions.associateBy { it.id }
34+
val formatsById = agenda.formats.associateBy { it.id }
35+
val categoriesById = agenda.categories.associateBy { it.id }
36+
val speakersById = agenda.speakers.associateBy { it.id }
37+
val headers = listOf(
38+
"start_time",
39+
"end_time",
40+
"room",
41+
"session_title",
42+
"session_description",
43+
"session_format",
44+
"session_category",
45+
"session_level",
46+
"speakers"
47+
)
48+
val csvRows = mutableListOf(headers.joinToString(","))
49+
for (schedule in schedules) {
50+
val session = sessionsById[schedule.sessionId]
51+
if (session is Session.Talk) {
52+
val format = formatsById[session.formatId]?.name ?: ""
53+
val category = categoriesById[session.categoryId]?.name ?: ""
54+
val speakers = session.speakers
55+
.mapNotNull { speakersById[it]?.displayName }
56+
.joinToString(", ")
57+
val row = listOf(
58+
schedule.startTime,
59+
schedule.endTime,
60+
schedule.room,
61+
session.title,
62+
session.abstract.replace("\n", " "),
63+
format,
64+
category,
65+
session.level ?: "",
66+
speakers
67+
).map { protect(it) }
68+
csvRows.add(row.joinToString(","))
69+
}
70+
}
71+
return csvRows.joinToString("\n")
72+
}
73+
74+
private fun protect(value: String): String =
75+
if (value.contains(",") || value.contains('"')) {
76+
"\"${value.replace("\"", "\"\"")}\""
77+
} else {
78+
value
79+
}
80+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.paligot.confily.backend.export.domain
2+
3+
interface ExportAdminRepository<T> {
4+
suspend fun export(eventId: String): T
5+
}

0 commit comments

Comments
 (0)