Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,20 @@ class TimerLocalDataSource

suspend fun deleteSimpleTimer(localId: String) {
val memberId = currentMemberId() ?: return
val current = timerDao.getSimpleTimer(memberId, localId) ?: return
if (current.serverId == null && current.inFlightState == null) {
timerDao.deleteSimpleTimer(memberId, localId)
return
database.withTransaction {
val current = timerDao.getSimpleTimer(memberId, localId) ?: return@withTransaction
if (current.serverId == null && current.inFlightState == null) {
timerDao.deleteSimpleTimer(memberId, localId)
return@withTransaction
}
timerDao.upsertSimpleTimer(
current.copy(
syncState = SyncState.DELETE_PENDING,
pendingEditId = newId(),
editedAt = now(),
),
)
}
timerDao.upsertSimpleTimer(
current.copy(
syncState = SyncState.DELETE_PENDING,
pendingEditId = newId(),
editedAt = now(),
),
)
}

suspend fun getCustomTimers(): List<CustomTimerEntity> {
Expand Down Expand Up @@ -156,18 +158,20 @@ class TimerLocalDataSource

suspend fun deleteCustomTimer(localId: String) {
val memberId = currentMemberId() ?: return
val current = timerDao.getCustomTimer(memberId, localId) ?: return
if (current.serverId == null && current.inFlightState == null) {
timerDao.deleteCustomTimer(memberId, localId)
return
database.withTransaction {
val current = timerDao.getCustomTimer(memberId, localId) ?: return@withTransaction
if (current.serverId == null && current.inFlightState == null) {
timerDao.deleteCustomTimer(memberId, localId)
return@withTransaction
}
timerDao.upsertCustomTimer(
current.copy(
syncState = SyncState.DELETE_PENDING,
pendingEditId = newId(),
editedAt = now(),
),
)
}
timerDao.upsertCustomTimer(
current.copy(
syncState = SyncState.DELETE_PENDING,
pendingEditId = newId(),
editedAt = now(),
),
)
}

suspend fun getPendingSimpleTimers(): List<SimpleTimerEntity> {
Expand Down Expand Up @@ -356,6 +360,7 @@ class TimerLocalDataSource
lastSyncError = null,
),
)
timerDao.deleteSyncedSimpleTimerDuplicates(memberId, serverId, snapshot.localId)
}
}
}
Expand Down Expand Up @@ -391,6 +396,7 @@ class TimerLocalDataSource
lastSyncError = null,
),
)
timerDao.deleteSyncedCustomTimerDuplicates(memberId, serverId, snapshot.localId)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,6 @@ package com.project200.data.dto

import java.time.LocalDateTime

data class GetSimpleTimersDTO(
val simpleTimerCount: Int,
val simpleTimers: List<SimpleTimerDTO>,
)

data class SimpleTimerDTO(
val simpleTimerId: Long,
val time: Int,
val updatedAt: LocalDateTime? = null,
)

data class SimpleTimerRequest(
val time: Int,
val createRequestId: String? = null,
val editId: String? = null,
val editedAt: Long? = null,
)

data class GetCustomTimerListDTO(
val customTimerCount: Int,
val customTimers: List<CustomTimerSummaryDTO>,
Expand Down Expand Up @@ -70,17 +52,3 @@ data class PatchCustomTimerTitleRequest(
val editId: String? = null,
val editedAt: Long? = null,
)

data class SimpleTimerIdDTO(
val simpleTimerId: Long,
val updatedAt: LocalDateTime? = null,
)

data class TimerMutationResponseDTO(
val updatedAt: LocalDateTime? = null,
)

data class DeleteTimerRequestDTO(
val editId: String? = null,
val editedAt: Long? = null,
)
26 changes: 26 additions & 0 deletions data/src/main/java/com/project200/data/dto/SimpleTimerDTO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.project200.data.dto

import java.time.LocalDateTime

data class GetSimpleTimersDTO(
val simpleTimerCount: Int,
val simpleTimers: List<SimpleTimerDTO>,
)

data class SimpleTimerDTO(
val simpleTimerId: Long,
val time: Int,
val updatedAt: LocalDateTime? = null,
)

data class SimpleTimerRequest(
val time: Int,
val createRequestId: String? = null,
val editId: String? = null,
val editedAt: Long? = null,
)

data class SimpleTimerIdDTO(
val simpleTimerId: Long,
val updatedAt: LocalDateTime? = null,
)
12 changes: 12 additions & 0 deletions data/src/main/java/com/project200/data/dto/TimerMutationDTO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.project200.data.dto

import java.time.LocalDateTime

data class TimerMutationResponseDTO(
val updatedAt: LocalDateTime? = null,
)

data class DeleteTimerRequestDTO(
val editId: String? = null,
val editedAt: Long? = null,
)
24 changes: 24 additions & 0 deletions data/src/main/java/com/project200/data/local/dao/TimerDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ interface TimerDao {
localId: String,
)

/** 생성 완료 행과 서버 목록이 같은 서버 타이머를 만들면 동기화 완료 중복 행을 지웁니다 */
@Query(
"DELETE FROM simple_timer " +
"WHERE memberId = :memberId AND serverId = :serverId AND localId != :localId AND syncState = :synced",
)
suspend fun deleteSyncedSimpleTimerDuplicates(
memberId: String,
serverId: Long,
localId: String,
synced: SyncState = SyncState.SYNCED,
)

@Query(
"SELECT * FROM custom_timer " +
"WHERE memberId = :memberId AND syncState != :excluded " +
Expand All @@ -70,6 +82,18 @@ interface TimerDao {
localId: String,
)

/** 생성 완료 행과 서버 목록이 같은 서버 타이머를 만들면 동기화 완료 중복 행을 지웁니다 */
@Query(
"DELETE FROM custom_timer " +
"WHERE memberId = :memberId AND serverId = :serverId AND localId != :localId AND syncState = :synced",
)
suspend fun deleteSyncedCustomTimerDuplicates(
memberId: String,
serverId: Long,
localId: String,
synced: SyncState = SyncState.SYNCED,
)

/** 대기 행이 걸린 서버ID입니다. 서버 목록 반영에서 건드리면 안 됩니다 */
@Query(
"SELECT serverId FROM simple_timer " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,42 @@ class TimerLocalDataSourceTest {
assertThat(saved.inFlightState).isNull()
}

@Test
fun `생성 완료와 서버 목록 반영이 겹치면 심플 중복 행을 원래 localId로 합친다`() =
runTest {
// Given
val localId = dataSource.createSimpleTimer(time = 60)!!
val snapshot = dataSource.claimSimpleTimer(MEMBER_ID, localId)!!
dataSource.replaceSyncedSimpleTimers(listOf(ServerSimpleTimer(serverId = 7L, time = 60)))

// When
dataSource.completeSimple(snapshot, serverId = 7L)

// Then
val saved = database.timerDao().getSimpleTimers(MEMBER_ID)
assertThat(saved).hasSize(1)
assertThat(saved.single().localId).isEqualTo(localId)
}

@Test
fun `생성 완료와 서버 목록 반영이 겹치면 커스텀 중복 행을 원래 localId로 합친다`() =
runTest {
// Given
val localId = dataSource.createCustomTimer(name = "8세트", steps = steps)!!
val snapshot = dataSource.claimCustomTimer(MEMBER_ID, localId)!!
dataSource.replaceSyncedCustomTimers(
listOf(ServerCustomTimer(serverId = 9L, name = "8세트", steps = steps)),
)

// When
dataSource.completeCustom(snapshot, serverId = 9L)

// Then
val saved = database.timerDao().getCustomTimers(MEMBER_ID)
assertThat(saved).hasSize(1)
assertThat(saved.single().localId).isEqualTo(localId)
}

@Test
fun `전송 실패 - 마지막 오류 코드를 기록하고 성공 시 지운다`() =
runTest {
Expand Down
Loading