Skip to content

Commit c3ad98e

Browse files
committed
[BOOK-506] feat: 기록 상세 화면 감정 표시 개편 - #270
1 parent 193f034 commit c3ad98e

File tree

61 files changed

+1138
-169
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1138
-169
lines changed

src/Projects/BKData/Sources/API/AuthAPI.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public enum AuthAPI {
1616

1717
extension AuthAPI: RequestTarget {
1818
public var baseURL: String {
19-
return "\(APIConfig.baseURL)/auth"
19+
return "\(APIConfig.baseURLv1)/auth"
2020
}
2121

2222
public var path: String {

src/Projects/BKData/Sources/API/BookAPI.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ enum BookAPI {
1414

1515
extension BookAPI: RequestTarget {
1616
var baseURL: String {
17-
return "\(APIConfig.baseURL)/books"
17+
return "\(APIConfig.baseURLv1)/books"
1818
}
1919

2020
var path: String {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright © 2025 Booket. All rights reserved
2+
3+
import Foundation
4+
5+
enum EmotionAPI {
6+
case fetchEmotions
7+
}
8+
9+
extension EmotionAPI: RequestTarget {
10+
var baseURL: String {
11+
return "\(APIConfig.baseURLv2)/emotions"
12+
}
13+
14+
var path: String {
15+
switch self {
16+
case .fetchEmotions:
17+
return ""
18+
}
19+
}
20+
21+
var method: HTTPMethod {
22+
switch self {
23+
case .fetchEmotions:
24+
return .get
25+
}
26+
}
27+
28+
var headers: [String: String] {
29+
return [
30+
"Content-Type": "application/json"
31+
]
32+
}
33+
34+
var body: Encodable? {
35+
return nil
36+
}
37+
38+
var query: [String: Any] {
39+
return [:]
40+
}
41+
}

src/Projects/BKData/Sources/API/HomeAPI.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ enum HomeAPI {
88

99
extension HomeAPI: RequestTarget {
1010
var baseURL: String {
11-
return "\(APIConfig.baseURL)/home"
11+
return "\(APIConfig.baseURLv1)/home"
1212
}
1313

1414
var path: String {

src/Projects/BKData/Sources/API/RecordAPI.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,7 @@ enum RecordAPI {
1414

1515
extension RecordAPI: RequestTarget {
1616
var baseURL: String {
17-
switch self {
18-
case .fetch, .seed:
19-
return "\(APIConfig.baseV2URL)/reading-records"
20-
default:
21-
return "\(APIConfig.baseURL)/reading-records"
22-
}
17+
return "\(APIConfig.baseURLv2)/reading-records"
2318
}
2419

2520
var path: String {
@@ -46,7 +41,7 @@ extension RecordAPI: RequestTarget {
4641
case .fetch, .detail, .seed:
4742
return .get
4843
case .patch:
49-
return .patch
44+
return .put // V2 API uses PUT instead of PATCH
5045
case .delete:
5146
return .delete
5247
}

src/Projects/BKData/Sources/API/UserAPI.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ enum UserAPI {
1111

1212
extension UserAPI: RequestTarget {
1313
var baseURL: String {
14-
return "\(APIConfig.baseURL)/users/me"
14+
return "\(APIConfig.baseURLv1)/users/me"
1515
}
1616

1717
var path: String {

src/Projects/BKData/Sources/Constant/APIConfig.swift

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,22 @@ private final class BKDataBundleToken {}
66

77
enum APIConfig {
88
private static let bundle = Bundle(for: BKDataBundleToken.self)
9-
10-
static let baseURL: String = {
9+
10+
/// API Base URL (xcconfig에서 /api까지만 포함)
11+
private static let baseURL: String = {
1112
guard let value = bundle.object(forInfoDictionaryKey: "BASE_API_URL") as? String else {
1213
fatalError("Can't load environment: BKData.BASE_API_URL")
1314
}
1415
return value
1516
}()
16-
17-
static let baseV2URL: String = {
18-
guard let value = bundle.object(forInfoDictionaryKey: "BASE_API_V2_URL") as? String else {
19-
fatalError("Can't load environment: BKData.BASE_API_V2_URL")
20-
}
21-
return value
17+
18+
/// V1 API Base URL (auth, books, users, home)
19+
static let baseURLv1: String = {
20+
return baseURL + "/v1"
21+
}()
22+
23+
/// V2 API Base URL (emotions, reading-records)
24+
static let baseURLv2: String = {
25+
return baseURL + "/v2"
2226
}()
2327
}

src/Projects/BKData/Sources/DTO/Request/InsertRecordRequestDTO.swift

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,33 @@ import BKDomain
44
import Foundation
55

66
struct InsertRecordRequestDTO: Encodable {
7-
let pageNumber: Int
7+
let pageNumber: Int?
88
let quote: String
99
let review: String?
10-
let emotionTags: [String]
11-
10+
let primaryEmotion: String
11+
let detailEmotionTagIds: [String]
12+
1213
init(
13-
pageNumber: Int,
14+
pageNumber: Int?,
1415
quote: String,
1516
review: String?,
16-
emotionTags: [String]
17+
primaryEmotion: String,
18+
detailEmotionTagIds: [String]
1719
) {
1820
self.pageNumber = pageNumber
1921
self.quote = quote
2022
self.review = review
21-
self.emotionTags = emotionTags
23+
self.primaryEmotion = primaryEmotion
24+
self.detailEmotionTagIds = detailEmotionTagIds
2225
}
23-
26+
2427
init(data: RecordVO) {
2528
self.init(
2629
pageNumber: data.pageNumber,
2730
quote: data.quote,
28-
review: data.review,
29-
emotionTags: data.emotionTags
31+
review: data.memo,
32+
primaryEmotion: data.primaryEmotion.rawValue,
33+
detailEmotionTagIds: data.detailEmotionIds
3034
)
3135
}
3236
}

src/Projects/BKData/Sources/DTO/Response/DetailRecordResponseDTO.swift

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,20 @@
33
import BKDomain
44
import Foundation
55

6-
public struct DetailRecordResponseDTO: Decodable {
7-
public let id: String
8-
public let userBookId: String
9-
public let pageNumber: Int
10-
public let quote: String
11-
public let review: String?
12-
public let emotionTags: [Emotion]
13-
public let createdAt: String
14-
public let updatedAt: String
15-
public let bookTitle: String
16-
public let bookPublisher: String
17-
public let bookCoverImageUrl: URL
18-
public let author: String
6+
struct DetailRecordResponseDTO: Decodable {
7+
let id: String
8+
let userBookId: String
9+
let pageNumber: Int?
10+
let quote: String
11+
let review: String?
12+
let primaryEmotion: PrimaryEmotionDTO
13+
let detailEmotions: [DetailEmotionDTO]
14+
let createdAt: String
15+
let updatedAt: String
16+
let bookTitle: String
17+
let bookPublisher: String
18+
let bookCoverImageUrl: URL
19+
let author: String
1920
}
2021

2122
extension DetailRecordResponseDTO {
@@ -26,7 +27,8 @@ extension DetailRecordResponseDTO {
2627
pageNumber: pageNumber,
2728
quote: quote,
2829
review: review,
29-
emotionTags: emotionTags,
30+
primaryEmotion: primaryEmotion.toDomain() ?? .other,
31+
detailEmotions: detailEmotions.map { $0.toDomain() },
3032
createdAt: DateParser.parseISO8601(createdAt) ?? .distantPast,
3133
updatedAt: DateParser.parseISO8601(updatedAt),
3234
bookTitle: bookTitle,
@@ -41,11 +43,11 @@ extension DetailRecordResponseDTO {
4143
public struct DetailRecordV2ResponseDTO: Decodable {
4244
public let id: String
4345
public let userBookId: String
44-
public let pageNumber: Int
46+
public let pageNumber: Int?
4547
public let quote: String
4648
public let review: String?
4749
public let primaryEmotion: PrimaryEmotionResponseDTO
48-
public let detailEmotions: [DetailEmotionResponseDTO?]
50+
public let detailEmotions: [DetailEmotionResponseDTO]
4951
public let createdAt: String
5052
public let updatedAt: String
5153
public let bookTitle: String
@@ -62,7 +64,8 @@ extension DetailRecordV2ResponseDTO {
6264
pageNumber: pageNumber,
6365
quote: quote,
6466
review: review,
65-
emotionTags: [primaryEmotion.displayName],
67+
primaryEmotion: primaryEmotion.toDomain(),
68+
detailEmotions: detailEmotions.map { $0.toDomain() },
6669
createdAt: DateParser.parseISO8601(createdAt) ?? .distantPast,
6770
updatedAt: DateParser.parseISO8601(updatedAt),
6871
bookTitle: bookTitle,
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright © 2025 Booket. All rights reserved
2+
3+
import BKDomain
4+
import Foundation
5+
6+
// MARK: - API Response DTO
7+
8+
struct EmotionListResponseDTO: Decodable {
9+
let emotions: [EmotionGroupDTO]
10+
}
11+
12+
struct EmotionGroupDTO: Decodable {
13+
let code: String
14+
let displayName: String
15+
let detailEmotions: [DetailEmotionDTO]
16+
}
17+
18+
struct DetailEmotionDTO: Decodable {
19+
let id: String
20+
let name: String
21+
}
22+
23+
// MARK: - Mapping to Domain
24+
25+
extension EmotionGroupDTO {
26+
func toDomain() -> EmotionGroup? {
27+
guard let primaryEmotion = PrimaryEmotion(rawValue: code) else {
28+
return nil
29+
}
30+
return EmotionGroup(
31+
primaryEmotion: primaryEmotion,
32+
displayName: displayName,
33+
detailEmotions: detailEmotions.map { $0.toDomain() }
34+
)
35+
}
36+
}
37+
38+
extension DetailEmotionDTO {
39+
func toDomain() -> DetailEmotion {
40+
return DetailEmotion(id: id, name: name)
41+
}
42+
}
43+
44+
// MARK: - Response에서 사용하는 DTO (기록 조회 시)
45+
46+
struct PrimaryEmotionDTO: Decodable {
47+
let code: String
48+
let displayName: String
49+
50+
func toDomain() -> PrimaryEmotion? {
51+
return PrimaryEmotion(rawValue: code)
52+
}
53+
}

0 commit comments

Comments
 (0)