Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f56f969
refactor(afternote): 상세 응답 DTO 를 BE 실코드에 동기화 (#676)
OnlyReadOneBook Aug 23, 2026
7c6e935
Merge branch 'develop' into chore/676
OnlyReadOneBook Aug 24, 2026
b315e8c
Merge remote-tracking branch 'origin/develop' into chore/676
OnlyReadOneBook Aug 24, 2026
2f83ee5
refactor(konsist): 해소된 예외 항목은 실패가 아니라 경고로 알린다
OnlyReadOneBook Aug 24, 2026
95a37f4
refactor(mindrecord): 데일리질문 답변 응답 DTO 의 보정형 기본값을 걷어낸다
OnlyReadOneBook Aug 24, 2026
a3c983b
fix(test): DetailReceiver.phone 제거를 androidTest 픽스처에 반영
OnlyReadOneBook Aug 24, 2026
1ac702d
refactor(konsist): mindrecord 잔여 2건은 고치지 말고 목록에 등재한다
OnlyReadOneBook Aug 24, 2026
a3b85bb
refactor(afternote): data/mapper 를 레포 표준 명명·평면 배치로 정리
OnlyReadOneBook Aug 24, 2026
cc9987e
Merge branch 'develop' into refactor/932-mapper-naming
OnlyReadOneBook Aug 25, 2026
720463a
Merge branch 'develop' into chore/676
OnlyReadOneBook Aug 25, 2026
e579c03
Merge remote-tracking branch 'origin/develop' into chore/676
OnlyReadOneBook Aug 26, 2026
0aa9cce
Merge remote-tracking branch 'origin/develop' into refactor/932-mappe…
OnlyReadOneBook Aug 26, 2026
a14bf0b
Merge branch 'develop' into chore/676
OnlyReadOneBook Aug 26, 2026
39e6228
Merge branch 'develop' into refactor/932-mapper-naming
OnlyReadOneBook Aug 26, 2026
84e3c08
Merge branch 'develop' into refactor/932-mapper-naming
OnlyReadOneBook Aug 26, 2026
b797bdd
Merge branch 'develop' into chore/676
OnlyReadOneBook Aug 26, 2026
0d79c82
Merge branch 'develop' into chore/676
OnlyReadOneBook Aug 26, 2026
88f7f42
Merge branch 'chore/676' into refactor/932-mapper-naming
OnlyReadOneBook Aug 26, 2026
dd29f51
Merge branch 'develop' into chore/676
OnlyReadOneBook Aug 26, 2026
4e96eab
Merge branch 'chore/676' into refactor/932-mapper-naming
OnlyReadOneBook Aug 26, 2026
501c7b1
Merge branch 'develop' into chore/676
OnlyReadOneBook Aug 26, 2026
a4952ff
Merge branch 'chore/676' into refactor/932-mapper-naming
OnlyReadOneBook Aug 26, 2026
0bc1cf5
Merge pull request #1050 from Afternote/refactor/932-mapper-naming
OnlyReadOneBook Aug 26, 2026
96311d5
Merge branch 'develop' into chore/676
OnlyReadOneBook Aug 26, 2026
b6ec3ad
Merge branch 'develop' into chore/676
OnlyReadOneBook Aug 26, 2026
453ea05
test(afternote): 상세 타임스탬프 픽스처를 맞춘다
OnlyReadOneBook Aug 26, 2026
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 @@ -585,14 +585,13 @@ private fun authorDetail(): Detail =
Detail(
id = 73L,
serviceName = "Instagram",
timestamps = DetailTimestamps(createdAt = "2026.08.20", updatedAt = "2026.08.22"),
timestamps = DetailTimestamps(updatedAt = "2026.08.22"),
receivers =
listOf(
DetailReceiver(
receiverId = 7L,
name = "김수신",
relation = "가족",
phone = "",
),
),
leaveMessageBlocks =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ data class AfternoteDetailDto(
@SerialName("afternoteId") val afternoteId: Long,
@SerialName("category") val category: String,
@SerialName("title") val title: String,
@SerialName("createdAt") val createdAt: String = "",
@SerialName("isDraft") val isDraft: Boolean,
@SerialName("updatedAt") val updatedAt: String = "",
@SerialName("credentials") val credentials: AfternoteCredentialsDto? = null,
@SerialName("receivers") val receivers: List<AfternoteDetailReceiverDto>? = null,
@SerialName("receivers") val receivers: List<AfternoteDetailReceiverDto>,
@SerialName("actions") val processingMethods: List<String>? = null,
@SerialName("leaveMessage") val leaveMessage: List<LeaveMessageBlockDto>? = null,
@SerialName("playlist") val memorial: AfternotePlaylistDto? = null,
Expand Down Expand Up @@ -87,7 +87,6 @@ data class AfternoteDetailReceiverDto(
@SerialName("receiverId") val receiverId: Long? = null,
@SerialName("name") val name: String? = null,
@SerialName("relation") val relation: String? = null,
@SerialName("phone") val phone: String? = null,
)

@Serializable
Expand All @@ -96,6 +95,7 @@ data class AfternoteListItemDto(
@SerialName("title") val title: String,
@SerialName("category") val category: String,
@SerialName("createdAt") val createdAt: String,
@SerialName("isDraft") val isDraft: Boolean,
)

@Serializable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ fun afternoteTypeFromServerCategory(value: String): AfternoteType? {
if (normalized == LEGACY_MEMORIAL_CATEGORY) return AfternoteType.MEMORIAL
return serverCategoryByType.entries.firstOrNull { it.value == normalized }?.key
}

/** 서버 `category` → [AfternoteType]. 대응이 없으면 [AfternoteType.SOCIAL_NETWORK] 로 폴백한다. */
fun categoryToAfternoteType(category: String): AfternoteType = afternoteTypeFromServerCategory(category) ?: AfternoteType.SOCIAL_NETWORK
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package com.afternote.feature.afternote.data.mapper.response
package com.afternote.feature.afternote.data.mapper

import com.afternote.feature.afternote.data.dto.AfternoteDetailDto
import com.afternote.feature.afternote.data.dto.AfternoteDetailReceiverDto
import com.afternote.feature.afternote.data.dto.AfternotePlaylistDto
import com.afternote.feature.afternote.data.dto.AfternoteSongDto
import com.afternote.feature.afternote.data.mapper.afternoteTypeFromServerCategory
import com.afternote.feature.afternote.data.mapper.formatDateFromServer
import com.afternote.feature.afternote.data.mapper.toLeaveMessageBlocks
import com.afternote.feature.afternote.domain.AfternoteType
import com.afternote.feature.afternote.domain.model.author.Detail
import com.afternote.feature.afternote.domain.model.author.DetailContent
Expand All @@ -25,7 +22,7 @@ import kotlin.collections.mapNotNull
* 임의의 종류로 메우면 라벨·아이콘·처리 방법이 다른 종류의 것으로 표시된다(#1048).
* 던진 예외는 `AfternoteRepositoryImpl.safeCall` 이 잡아 `Result.failure` 로 옮긴다.
*/
fun AfternoteDetailDto.toDetailDomain(): Detail {
fun AfternoteDetailDto.toDomain(): Detail {
val resolvedType =
requireNotNull(afternoteTypeFromServerCategory(category)) {
"해석할 수 없는 애프터노트 종류다: afternoteId=$afternoteId category=$category"
Expand Down Expand Up @@ -82,11 +79,10 @@ private fun AfternoteDetailDto.toPublishedCredentials() =

// DTO 는 방어적으로 receiverId 가 nullable 이지만 서버 스펙상 필수 필드다 — 없는 항목은
// 도메인으로 올리지 않는다(식별자 없는 수신자는 저장·수정 어디에도 쓸 수 없다).
private fun List<AfternoteDetailReceiverDto>?.toDomain() = this?.mapNotNull { it.toDomain() }.orEmpty()
private fun List<AfternoteDetailReceiverDto>.toDomain() = mapNotNull { it.toDomain() }

private fun AfternoteDetailDto.toTimestamps(): DetailTimestamps =
DetailTimestamps(
createdAt = formatDateFromServer(createdAt),
updatedAt = formatDateFromServer(updatedAt),
)

Expand All @@ -107,7 +103,6 @@ private fun AfternoteDetailReceiverDto.toDomain(): DetailReceiver? =
receiverId = id,
name = name ?: "",
relation = relation ?: "",
phone = phone ?: "",
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,26 @@ package com.afternote.feature.afternote.data.mapper
import com.afternote.feature.afternote.data.dto.AfternoteCreateAccountRequestDto
import com.afternote.feature.afternote.data.dto.AfternoteCreateGalleryRequestDto
import com.afternote.feature.afternote.data.dto.AfternoteCreatePlaylistRequestDto
import com.afternote.feature.afternote.data.dto.AfternoteCredentialsDto
import com.afternote.feature.afternote.data.dto.AfternoteMemorialVideoDto
import com.afternote.feature.afternote.data.dto.AfternotePlaylistDto
import com.afternote.feature.afternote.data.dto.AfternoteReceiverRefDto
import com.afternote.feature.afternote.data.dto.AfternoteSongDto
import com.afternote.feature.afternote.data.dto.AfternoteUpdateRequestDto
import com.afternote.feature.afternote.domain.AfternoteType
import com.afternote.feature.afternote.domain.model.author.AfternoteAccountCredentials
import com.afternote.feature.afternote.domain.model.author.AfternoteUpdatePayload
import com.afternote.feature.afternote.domain.model.author.CreateAccountPayload
import com.afternote.feature.afternote.domain.model.author.CreateGalleryPayload
import com.afternote.feature.afternote.domain.model.author.CreateMemorialPayload
import com.afternote.feature.afternote.domain.model.author.MemorialSongPayload
import com.afternote.feature.afternote.domain.model.author.MemorialVideoPayload
import com.afternote.feature.afternote.domain.model.author.MemorialWritePayload
import com.afternote.feature.afternote.domain.model.author.ReceiverRefPayload

/**
* 도메인 → 요청 wire. 요청 바디 루트는 `toRequest`, 그 안에 실리는 부분 DTO 는 `toDto` 다.
*/

fun AfternoteUpdatePayload.toRequest() =
AfternoteUpdateRequestDto(
Expand All @@ -18,7 +31,7 @@ fun AfternoteUpdatePayload.toRequest() =
processingMethods = processingMethods,
leaveMessage = leaveMessageBlocks.toDto(),
credentials = credentials?.toDto(),
receivers = receivers?.toDto(),
receivers = receivers?.map { it.toDto() },
memorial = memorial?.toDto(),
)

Expand Down Expand Up @@ -69,3 +82,34 @@ fun CreateMemorialPayload.toRequest() =
leaveMessage = leaveMessageBlocks.toDto(),
receivers = receiverIds.map { AfternoteReceiverRefDto(receiverId = it) },
)

fun MemorialWritePayload.toDto() =
AfternotePlaylistDto(
memorialPhotoUrl = memorialPhotoUrl,
songs = songs.map { it.toDto() },
memorialVideo = memorialVideo?.toDto(),
)

fun MemorialSongPayload.toDto() =
AfternoteSongDto(
title = title,
artist = artist,
coverUrl = coverUrl,
)

fun MemorialVideoPayload.toDto() =
AfternoteMemorialVideoDto(
videoUrl = videoUrl,
thumbnailUrl = thumbnailUrl,
)

fun AfternoteAccountCredentials.toDto() =
AfternoteCredentialsDto(
id = id,
password = password,
)

fun ReceiverRefPayload.toDto() =
AfternoteReceiverRefDto(
receiverId = receiverId,
)

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import androidx.paging.PagingData
import com.afternote.core.common.result.runCatchingCancellable
import com.afternote.core.network.model.requireData
import com.afternote.core.network.model.requireStatus
import com.afternote.feature.afternote.data.mapper.response.toDetailDomain
import com.afternote.feature.afternote.data.mapper.toBusinessRequest
import com.afternote.feature.afternote.data.mapper.toDomain
import com.afternote.feature.afternote.data.mapper.toRequest
import com.afternote.feature.afternote.data.mapper.toServerCategory
import com.afternote.feature.afternote.data.mapper.toSocialRequest
Expand Down Expand Up @@ -56,7 +56,7 @@ class AfternoteRepositoryImpl

override suspend fun getDetail(id: Long): Result<Detail> =
safeCall {
api.getAfternoteDetail(afternoteId = id).requireData().toDetailDomain()
api.getAfternoteDetail(afternoteId = id).requireData().toDomain()
}

override suspend fun createSocial(payload: CreateAccountPayload): Result<Long> =
Expand Down
Loading
Loading