Coverage Summary for Class: WorkspaceMemberRepositoryImpl (com.georgeci.moneysurfer.data.repository)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| WorkspaceMemberRepositoryImpl |
75%
(9/12)
|
50%
(9/18)
|
93.8%
(60/64)
|
90.2%
(540/599)
|
| WorkspaceMemberRepositoryImpl$getAll$$inlined$map$1 |
0%
(0/2)
|
|
| WorkspaceMemberRepositoryImpl$getAll$$inlined$map$1$1 |
|
| WorkspaceMemberRepositoryImpl$getAll$$inlined$map$1$2 |
0%
(0/1)
|
|
| WorkspaceMemberRepositoryImpl$getAll$$inlined$map$1$2$1 |
|
| WorkspaceMemberRepositoryImpl$getById$1 |
|
| WorkspaceMemberRepositoryImpl$getByUserId-SyNjzC0$$inlined$map$1 |
0%
(0/2)
|
|
| WorkspaceMemberRepositoryImpl$getByUserId-SyNjzC0$$inlined$map$1$1 |
|
| WorkspaceMemberRepositoryImpl$getByUserId-SyNjzC0$$inlined$map$1$2 |
0%
(0/1)
|
|
| WorkspaceMemberRepositoryImpl$getByUserId-SyNjzC0$$inlined$map$1$2$1 |
|
| WorkspaceMemberRepositoryImpl$getByWorkspaceId-DBbEM4U$$inlined$map$1 |
0%
(0/2)
|
|
| WorkspaceMemberRepositoryImpl$getByWorkspaceId-DBbEM4U$$inlined$map$1$1 |
|
| WorkspaceMemberRepositoryImpl$getByWorkspaceId-DBbEM4U$$inlined$map$1$2 |
0%
(0/1)
|
|
| WorkspaceMemberRepositoryImpl$getByWorkspaceId-DBbEM4U$$inlined$map$1$2$1 |
|
| WorkspaceMemberRepositoryImpl$insert$1 |
|
| WorkspaceMemberRepositoryImpl$markLeft$1 |
|
| WorkspaceMemberRepositoryImpl$markRemoved$1 |
|
| WorkspaceMemberRepositoryImpl$update$1 |
|
| Total |
42.9%
(9/21)
|
50%
(9/18)
|
93.8%
(60/64)
|
90.2%
(540/599)
|
package com.georgeci.moneysurfer.data.repository
import com.georgeci.moneysurfer.data.db.dao.WorkspaceMemberDao
import com.georgeci.moneysurfer.data.db.entity.WorkspaceMemberEntity
import com.georgeci.moneysurfer.domain.model.WorkspaceMember
import com.georgeci.moneysurfer.domain.model.WorkspaceMemberStatus
import com.georgeci.moneysurfer.domain.model.WorkspaceRole
import com.georgeci.moneysurfer.domain.primitives.ClockUseCase
import com.georgeci.moneysurfer.domain.primitives.UserId
import com.georgeci.moneysurfer.domain.primitives.WorkspaceId
import com.georgeci.moneysurfer.domain.repositories.WorkspaceMemberRepository
import com.georgeci.moneysurfer.domain.sync.SyncEntityTypes
import com.georgeci.moneysurfer.sync.repository.MutationOperation
import com.georgeci.moneysurfer.sync.repository.OutboxEnqueuer
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import org.koin.core.annotation.Single
@Single(binds = [WorkspaceMemberRepository::class])
class WorkspaceMemberRepositoryImpl(
private val dao: WorkspaceMemberDao,
private val outboxEnqueuer: OutboxEnqueuer,
private val clock: ClockUseCase,
private val timeFormatter: TimeFormatter,
) : WorkspaceMemberRepository {
override fun getAll(): Flow<List<WorkspaceMember>> =
dao.getAll().map { list -> list.map { it.toDomain() } }
override fun getByWorkspaceId(workspaceId: WorkspaceId): Flow<List<WorkspaceMember>> =
dao.getByWorkspaceId(workspaceId.value).map { list -> list.map { it.toDomain() } }
override fun getByUserId(userId: UserId): Flow<List<WorkspaceMember>> =
dao.getByUserId(userId.value).map { list -> list.map { it.toDomain() } }
override suspend fun getById(userId: UserId, workspaceId: WorkspaceId): WorkspaceMember? =
dao.getById(userId.value, workspaceId.value)?.toDomain()
override suspend fun insert(member: WorkspaceMember) {
val entity = member.toEntity()
dao.insert(entity)
enqueueUpsert(entity, MutationOperation.INSERT)
}
override suspend fun update(member: WorkspaceMember) {
val existingCreatedAt = dao.getById(member.userId.value, member.workspaceId.value)?.createdAt
val entity = member.toEntity().copy(
createdAt = existingCreatedAt ?: member.toEntity().createdAt,
updatedAt = clock.now().toEpochMilliseconds(),
)
dao.update(entity)
enqueueUpsert(entity, MutationOperation.UPDATE)
}
override suspend fun markRemoved(
userId: UserId,
workspaceId: WorkspaceId,
removedByUserId: UserId?,
) {
val current = dao.getById(userId.value, workspaceId.value) ?: return
val now = clock.now().toEpochMilliseconds()
val updated = current.copy(
status = WorkspaceMemberStatus.REMOVED.name,
removedAt = now,
updatedAt = now,
)
dao.upsert(updated)
enqueueUpsert(updated, MutationOperation.UPDATE)
}
override suspend fun markLeft(userId: UserId, workspaceId: WorkspaceId) {
val current = dao.getById(userId.value, workspaceId.value) ?: return
val now = clock.now().toEpochMilliseconds()
val updated = current.copy(
status = WorkspaceMemberStatus.LEFT.name,
leftAt = now,
updatedAt = now,
)
dao.upsert(updated)
enqueueUpsert(updated, MutationOperation.UPDATE)
}
private suspend fun enqueueUpsert(entity: WorkspaceMemberEntity, operation: MutationOperation) {
outboxEnqueuer.enqueueUpsert(
entityType = SyncEntityTypes.WORKSPACE_MEMBER,
entityId = entity.userId,
scopeKey = entity.workspaceId,
operation = operation,
)
}
private fun WorkspaceMemberEntity.toDomain() = WorkspaceMember(
userId = UserId(userId),
workspaceId = WorkspaceId(workspaceId),
role = WorkspaceRole.entries.firstOrNull { it.name == role } ?: WorkspaceRole.VIEWER,
status = WorkspaceMemberStatus.entries.firstOrNull { it.name == status }
?: WorkspaceMemberStatus.ACTIVE,
displayName = displayName,
email = email,
addedByUserId = addedByUserId?.let(::UserId),
createdAt = timeFormatter.parseInstant(createdAt),
updatedAt = timeFormatter.parseInstant(updatedAt),
leftAt = timeFormatter.parseInstantOrNull(leftAt),
removedAt = timeFormatter.parseInstantOrNull(removedAt),
)
private fun WorkspaceMember.toEntity() = WorkspaceMemberEntity(
userId = userId.value,
workspaceId = workspaceId.value,
role = role.name,
status = status.name,
displayName = displayName,
email = email,
addedByUserId = addedByUserId?.value,
createdAt = timeFormatter.formatInstant(createdAt),
updatedAt = timeFormatter.formatInstant(updatedAt),
leftAt = timeFormatter.formatInstantOrNull(leftAt),
removedAt = timeFormatter.formatInstantOrNull(removedAt),
)
}