Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
c10eb10
[feat]: 기록장 조회 response 생성 (#71)
Nico1eKim Aug 8, 2025
5b3b041
[feat]: 기록장 조회 service 작성 (#71)
Nico1eKim Aug 8, 2025
895f3e6
[feat]: 기록장 조회 repository 작성 (#71)
Nico1eKim Aug 8, 2025
0c0e960
[feat]: 정렬 enum 생성 (#71)
Nico1eKim Aug 8, 2025
c78770e
[feat]: 기록장 조회 viewmodel 생성 (#71)
Nico1eKim Aug 8, 2025
f8c2504
[feat]: 기록장 screen에 데이터 연결 (#71)
Nico1eKim Aug 8, 2025
0e48948
[feat]: 기록장 navigation 연결 (#71)
Nico1eKim Aug 8, 2025
bd1975d
[ui]: 필터쪽 디자인 수정 (#71)
Nico1eKim Aug 8, 2025
be8b564
[refactor]: 페이지 필터링 제대로 적용되도록 수정 (#71)
Nico1eKim Aug 8, 2025
7bdd7da
[feat]: 기록 작성 request, response 생성 (#71)
Nico1eKim Aug 8, 2025
7bfed3b
[feat]: 기록 작성 request, service 작성 (#71)
Nico1eKim Aug 8, 2025
2a72200
[feat]: 기록 작성 request, repository 작성 (#71)
Nico1eKim Aug 8, 2025
5ac5643
[feat]: 기록 작성 viewmodel 생성 (#71)
Nico1eKim Aug 8, 2025
e2c03e6
[feat]: 기록 작성 로직 screen에 적용 (#71)
Nico1eKim Aug 8, 2025
8f21cfd
[feat]: 기록 작성 navigation 연결 (#71)
Nico1eKim Aug 8, 2025
9882cbd
[refactor]: 기록 작성 완료시 내기록 탭으로 이동하도록 수정 (#71)
Nico1eKim Aug 8, 2025
7e20b53
[refactor]: 기록 작성 완료 시 progress bar 나타나도록 수정 (#71)
Nico1eKim Aug 8, 2025
5225503
[refactor]: 모임방 화면에서 투표 클릭하면 페이지 필터 걸어서 이동하도록 수정 (#71)
Nico1eKim Aug 10, 2025
c5ca340
Merge branch 'develop' of https://github.com/THIP-TextHip/THIP-Androi…
Nico1eKim Aug 11, 2025
6366fa1
Merge branch 'develop' of https://github.com/THIP-TextHip/THIP-Androi…
Nico1eKim Aug 11, 2025
5f4d446
[fix]: group navigation 함수 누락 수정 (#71)
Nico1eKim Aug 11, 2025
464bfed
[feat]: 책 전체 페이지 수, 총평 가능 여부 조회 response 생성 (#71)
Nico1eKim Aug 11, 2025
80832dc
[feat]: 책 전체 페이지 수, 총평 가능 여부 조회 service 작성 (#71)
Nico1eKim Aug 11, 2025
de6f588
[feat]: 책 전체 페이지 수, 총평 가능 여부 조회 repository 작성 (#71)
Nico1eKim Aug 11, 2025
868c89d
[feat]: 책 전체 페이지 수, 총평 가능 여부 조회 viewmodel, navigation 작성 (#71)
Nico1eKim Aug 11, 2025
71fe1bb
[feat]: 투표 생성 request, response 작성 (#71)
Nico1eKim Aug 11, 2025
e78faaf
[feat]: 투표 생성 service 작성 (#71)
Nico1eKim Aug 11, 2025
1088396
[feat]: 투표 생성 repository 작성 (#71)
Nico1eKim Aug 11, 2025
72a299f
[feat]: 투표 생성 viewmodel, naviagation 작성하고 screen에 연결 (#71)
Nico1eKim Aug 12, 2025
a3587dd
[refactor]: 기록에서 총평보기 활성화 적용 (#71)
Nico1eKim Aug 12, 2025
b18b536
[chore]: 투표 생성하기 네이밍 수정 (#71)
Nico1eKim Aug 12, 2025
762dd72
[refactor]: 총평 기록 없을 때 내용 수정 (#71)
Nico1eKim Aug 12, 2025
32ffc32
[feat]: 투표하기 request, response 작성 (#71)
Nico1eKim Aug 12, 2025
8e9002e
[feat]: 투표하기 service 작성 (#71)
Nico1eKim Aug 12, 2025
1d64855
[feat]: 투표하기 repository 작성 (#71)
Nico1eKim Aug 12, 2025
d8df01e
[fix]: api 잘못된거 수정 (#71)
Nico1eKim Aug 12, 2025
4380431
[ui]: 투표 버튼 오른쪽 코너 가려지도록 수정 (#71)
Nico1eKim Aug 12, 2025
9fad483
[feat]: 투표하기 viewmodel 작성 및 screen에 연결 (#71)
Nico1eKim Aug 12, 2025
9fad327
[feat]: 기록 삭제하기 response 생성 (#71)
Nico1eKim Aug 12, 2025
593845c
[feat]: 기록 삭제하기 service 작성 (#71)
Nico1eKim Aug 12, 2025
524708a
[feat]: 기록 삭제하기 repository 작성 (#71)
Nico1eKim Aug 12, 2025
6b56cb9
[feat]: 기록 삭제하기 viewmodel 작성 및 screen에 연결 (#71)
Nico1eKim Aug 12, 2025
c192fef
[feat]: 기록 좋아요 response, request 생성 (#71)
Nico1eKim Aug 12, 2025
26dc7e5
[feat]: 기록 좋아요 service 작성 (#71)
Nico1eKim Aug 12, 2025
fc710d1
[feat]: 기록 좋아요 repository 작성 (#71)
Nico1eKim Aug 12, 2025
b28de01
[feat]: 기록 좋아요 viewmodel 작성 및 screen 연결 (#71)
Nico1eKim Aug 12, 2025
8524d55
Merge branch 'develop' of https://github.com/THIP-TextHip/THIP-Androi…
Nico1eKim Aug 12, 2025
60d45c4
Merge branch 'develop' of https://github.com/THIP-TextHip/THIP-Androi…
Nico1eKim Aug 12, 2025
1866fcc
[refactor]: 독서메이트 aliasName 수정 (#71)
Nico1eKim Aug 12, 2025
612da00
[refactor]: 기록, 투표 총평으로 생성할 수 있게 수정 (#71)
Nico1eKim Aug 12, 2025
a34a03c
[refactor]: bottom bar에 padding 추가 (#71)
Nico1eKim Aug 13, 2025
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
@@ -0,0 +1,16 @@
package com.texthip.thip.data.model.rooms.request

import kotlinx.serialization.Serializable

@Serializable
data class RoomsCreateVoteRequest(
val page: Int,
val isOverview: Boolean,
val content: String,
val voteItemList: List<VoteItem>
)

@Serializable
data class VoteItem(
val itemName: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.texthip.thip.data.model.rooms.request

import kotlinx.serialization.Serializable

@Serializable
data class RoomsPostsLikesRequest(
val type: Boolean,
val roomPostType: String,
Comment on lines +7 to +8
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

roomPostType 유효값 검증 위치 확인

문자열을 유지한다면 어디선가 유효값 검증이 필요합니다(예: 레포지토리에서 화이트리스트). 누락 시 서버 4xx/5xx 유발 가능.

레포지토리에서 검증/정규화가 있는지 점검해 주세요:


🏁 Script executed:

#!/bin/bash
set -euxo pipefail
rg -n --glob '!**/build/**' 'roomPostType|RoomsPostsLikesRequest' app | sed -n '1,200p'

Length of output: 1210


roomPostType 값 검증 추가 필요
현재 RoomsPostsLikesRequest 에 전달되는 roomPostType 은 String 형태로만 정의되어 있으며, 호출 지점이나 repository/service 계층 어디에서도 허용 가능한 값(화이트리스트 등)을 검증하는 로직이 없습니다. 검증이 빠질 경우 잘못된 값 전송 시 서버에서 4xx/5xx 에러가 발생할 수 있습니다.

검토가 필요한 주요 위치:

  • app/src/main/java/com/texthip/thip/data/repository/RoomsRepository.kt:126 (RoomsPostsLikesRequest 생성부)
  • app/src/main/java/com/texthip/thip/ui/group/note/viewmodel/GroupNoteViewModel.kt:174 (postType 전달부)

repository 또는 service 계층에서 enum 클래스, 화이트리스트 체크 등으로 유효값 검증/정규화를 추가해 주세요.

🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/data/model/rooms/request/RoomsPostsLikesRequest.kt
around lines 7-8, roomPostType is an unchecked String which can cause 4xx/5xx
errors downstream; add validation/normalization in the repository or service
when constructing RoomsPostsLikesRequest (see RoomsRepository.kt line ~126 and
GroupNoteViewModel.kt line ~174): define an enum or whitelist of allowed post
types, validate the incoming value against it, map/normalize valid values, and
reject/throw a clear IllegalArgumentException (or return a controlled error) for
invalid values so only validated values are passed into RoomsPostsLikesRequest.

)
Comment on lines +5 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

불리언 type의 의미를 드러내는 이름으로 변경 (isLike) + @SerialName로 API 호환

좋아요/해제 의미가 분명하도록 isLike 등으로 변경하고 JSON 키는 유지하세요.

다음 변경을 제안합니다:

 package com.texthip.thip.data.model.rooms.request

 import kotlinx.serialization.Serializable
+import kotlinx.serialization.SerialName

 @Serializable
 data class RoomsPostsLikesRequest(
-    val type: Boolean,
+    @SerialName("type")
+    val isLike: Boolean,
     val roomPostType: String,
 )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Serializable
data class RoomsPostsLikesRequest(
val type: Boolean,
val roomPostType: String,
)
package com.texthip.thip.data.model.rooms.request
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
@Serializable
data class RoomsPostsLikesRequest(
@SerialName("type")
val isLike: Boolean,
val roomPostType: String,
)
🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/data/model/rooms/request/RoomsPostsLikesRequest.kt
around lines 5-9, rename the Boolean property `type` to a meaningfully named
`isLike` and keep JSON compatibility by annotating it with @SerialName("type");
update the data class property declaration accordingly (retain @Serializable)
and then search/replace any usages or constructor calls to use `isLike` (or map
incoming JSON) so compilation and API contract remain correct.

Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.texthip.thip.data.model.rooms.request

import kotlinx.serialization.Serializable

@Serializable
data class RoomsPostsRequestParams(
val type: String,
val sort: String? = null,
val pageStart: Int? = null,
val pageEnd: Int? = null,
val isOverview: Boolean? = null,
val isPageFilter: Boolean? = null,
val cursor: String? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.texthip.thip.data.model.rooms.request

import kotlinx.serialization.Serializable

@Serializable
data class RoomsRecordRequest(
val page: Int,
val isOverview: Boolean = false,
val content: String,
)
Comment on lines +5 to +10
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

직렬화 키 네이밍과 선택적 필드 포함 여부 검증 필요.

  • 백엔드가 snake_case를 요구한다면 @SerialName("is_overview") 등 명시가 필요합니다.
  • isOverview=true일 때 page를 보내지 말아야 한다면(또는 반대) 현재 모델(page: Int)이 항상 포함되는 형태라 계약 위반 가능성이 있습니다. 필요 시 page를 Int?로 두고(또는 @EncodeDefault Mode.NEVER) Json 설정(explicitNulls=false)과 함께 조건부 포함을 보장해야 합니다.

다음 스크립트로 기존 코드베이스의 직렬화 관례와 Json 설정을 확인해 주세요:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) @SerialName 사용 현황:"
rg -n '@SerialName\(' -A2 app/src/main/java

echo
echo "2) Request 모델들 직렬화 어노테이션 요약:"
fd -t f -e kt 'Request.kt' app/src/main/java | while read -r f; do
  echo "=== $f ==="
  rg -n '@Serializable|@SerialName|data class' "$f"
done

echo
echo "3) kotlinx.serialization Json 설정(explicitNulls 등) 확인:"
rg -n 'Json\s*\{' -A5 -U
rg -n 'explicitNulls\s*=\s*(true|false)' -U

Length of output: 17285


직렬화 키 네이밍 일관성 및 선택적 필드 포함 처리

  • 이 프로젝트의 JSON 키는 snake_case가 아닌 camelCase(roomId, isPublic 등)로 사용되며, 대부분의 Request 모델에서
    @SerialName("camelCaseKey")를 명시하고 있습니다.
    RoomsRecordRequest의 모든 프로퍼티에도 아래처럼 @SerialName을 추가해 주세요.

    @Serializable
    data class RoomsRecordRequest(
        @SerialName("page")       val page: Int,
        @SerialName("isOverview") val isOverview: Boolean = false,
        @SerialName("content")    val content: String,
    )
  • NetworkModule 설정(encodeDefaults = true, explicitNulls = false) 상으로는

    • 기본값(default)인 isOverview = false도 항상 직렬화됩니다.
    • null인 프로퍼티만 JSON에서 생략되므로,
      isOverview == true일 때 page를 보내지 않으려면
      @SerialName("page")
      val page: Int? = null
      처럼 page를 nullable로 선언하고 기본값을 null로 두면 됩니다.
  • 최종적으로 Backend 계약에 따라

    • camelCase가 아닌 snake_case를 요구하는지
    • isOverview에 따라 page의 선택적 포함 여부
      등을 재확인해 주세요.
🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/data/model/rooms/request/RoomsRecordRequest.kt
around lines 5-10, add explicit @SerialName annotations for every property to
match the project’s camelCase JSON naming (e.g., @SerialName("page"),
@SerialName("isOverview"), @SerialName("content")), and if the API expects
omitting page when isOverview == true change page to a nullable property with a
default of null (val page: Int? = null) so it won’t be serialized unless
present; finally, verify with the backend whether keys should be camelCase or
snake_case and whether page must be optional based on isOverview.

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.texthip.thip.data.model.rooms.request

import kotlinx.serialization.Serializable

@Serializable
data class RoomsVoteRequest(
val voteItemId: Int,
val type: Boolean
)
Comment on lines +5 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

호출부 빌드 안정성 확인 (명명 인자 사용 여부)

프로퍼티명을 변경하면 RoomsVoteRequest(type = ...)처럼 명명 인자를 쓰는 호출부가 깨질 수 있습니다. 포지셔널 인자만 쓰는 경우는 안전합니다.

호출부를 점검해 주세요:


🏁 Script executed:

#!/bin/bash
set -euxo pipefail

# RoomsVoteRequest 생성 시 명명 인자 사용 여부 확인
rg -n --glob '!**/build/**' 'RoomsVoteRequest\(' -A2 app | sed -n '1,200p'

Length of output: 751


명명 인자 사용으로 인한 빌드 불안정 확인 필요

RoomsVoteRequest 호출부에서 명명 인자(voteItemId = …, type = …)를 사용 중이므로, 데이터 클래스 프로퍼티명을 변경하면 해당 호출부가 깨집니다. 호출부를 아래 위치에서 확인하고, 프로퍼티명 변경 시 함께 수정하거나 포지셔널 인자로 전환해 주세요.

· app/src/main/java/com/texthip/thip/data/repository/RoomsRepository.kt
– 라인 106–108:

request = RoomsVoteRequest(
    voteItemId = voteItemId,
    type = type
)
🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/data/model/rooms/request/RoomsVoteRequest.kt
around lines 5–9, the data class uses property names referenced via named
arguments at call sites (see RoomsRepository.kt lines 106–108), so renaming
properties will break builds; to fix, either keep the current property names
unchanged, or add stable serial/JSON names (via @SerialName) while keeping the
Kotlin property names, or update all call sites to use positional arguments
instead of named args so renames won’t break callers. Ensure whichever approach
you choose is applied consistently across the repository and update
RoomsRepository.kt if you change to positional args or change property names.

🛠️ Refactor suggestion

의미 모호한 불리언 필드명 type → 도메인 의미 반영 (isSelected) + @SerialName로 API 호환 유지

불리언 type은 의미가 모호합니다. 읽기성과 유지보수를 위해 의미가 드러나는 이름으로 바꾸고, 서버 JSON 키는 @SerialName("type")으로 유지하세요.

다음 변경을 제안합니다:

 package com.texthip.thip.data.model.rooms.request

 import kotlinx.serialization.Serializable
+import kotlinx.serialization.SerialName

 @Serializable
 data class RoomsVoteRequest(
     val voteItemId: Int,
-    val type: Boolean
+    @SerialName("type")
+    val isSelected: Boolean,
 )

호출부에서 명명 인자를 사용하고 있다면 함께 수정이 필요합니다.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@Serializable
data class RoomsVoteRequest(
val voteItemId: Int,
val type: Boolean
)
package com.texthip.thip.data.model.rooms.request
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerialName
@Serializable
data class RoomsVoteRequest(
val voteItemId: Int,
@SerialName("type")
val isSelected: Boolean,
)
🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/data/model/rooms/request/RoomsVoteRequest.kt
around lines 5 to 9, rename the ambiguous boolean property `type` to a
descriptive name such as `isSelected` and annotate it with @SerialName("type")
to preserve JSON compatibility; update the data class property name, add the
@SerialName import/annotation, and search & update all call sites that use named
arguments to use the new property name (or keep positional args unchanged) so
compilation and API behavior remain correct.

Comment on lines +6 to +9
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

불명확한 필드명(type) 개선 + API 키 고정(@SerialName) 제안

Boolean에 “type”은 의미가 모호합니다. 도메인 의미(선택/해제 등)가 드러나도록 프로퍼티명을 개선하고, 서버 키는 @SerialName으로 고정해 API 스키마와 도메인 모델을 분리하는 것을 권장합니다.

  • 백엔드에서 실제로 "type"이 Boolean인지(문자열/정수 아님) 확인 부탁드립니다.
  • ID가 Long 범위일 가능성이 있으면 Int → Long 전환 검토 바랍니다.

적용 예시:

 package com.texthip.thip.data.model.rooms.request

-import kotlinx.serialization.Serializable
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable

 @Serializable
 data class RoomsVoteRequest(
-    val voteItemId: Int,
-    val type: Boolean
+    @SerialName("voteItemId") val voteItemId: Int,
+    @SerialName("type") val isSelected: Boolean
 )

🏁 Script executed:

#!/bin/bash
set -e
# 1. Locate usages of RoomsVoteRequest in Retrofit or service interfaces
rg "RoomsVoteRequest" -n

# 2. Search for vote-related endpoints to see how 'type' is used
rg "@POST" -n app/src
rg "vote" -n app/src

# 3. Check for existing @SerialName annotations in model packages for consistency
rg "@SerialName" -n app/src

Length of output: 22360


불명확한 필드명(type) 개선 및 @SerialName 적용 제안

Boolean 타입의 type은 “투표”인지 “취소”인지 도메인 의미가 드러나지 않아 가독성이 떨어집니다. 또한 API 스키마와 도메인 모델을 분리하기 위해 @SerialName을 명시적으로 적용하는 것이 좋습니다.

적용 예시 (app/src/main/java/com/texthip/thip/data/model/rooms/request/RoomsVoteRequest.kt):

-import kotlinx.serialization.Serializable
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable

 @Serializable
 data class RoomsVoteRequest(
-    val voteItemId: Int,
-    val type: Boolean
+    @SerialName("voteItemId") val voteItemId: Int,
+    @SerialName("type")       val isSelected: Boolean
 )

검증 요청:

  • 백엔드에서 실제로 "type" 필드가 Boolean 형태로 내려오는지 확인 부탁드립니다.
  • voteItemId가 Long 범위여서 Int로 처리하기 어려운 경우 Int → Long 전환을 검토해 주세요.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
data class RoomsVoteRequest(
val voteItemId: Int,
val type: Boolean
)
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class RoomsVoteRequest(
@SerialName("voteItemId") val voteItemId: Int,
@SerialName("type") val isSelected: Boolean
)
🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/data/model/rooms/request/RoomsVoteRequest.kt
around lines 6-9, the Boolean field named `type` is unclear and the class lacks
explicit serialization name mapping; rename the field to a descriptive name such
as `isVote: Boolean` (or `isCancel: Boolean` if that matches domain semantics)
and add @SerialName("type") on that property to keep the API schema mapping, and
if backend uses 64-bit ids change `voteItemId: Int` to `voteItemId: Long`
(confirm with backend whether `"type"` is actually Boolean and whether IDs
exceed Int range).

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.texthip.thip.data.model.rooms.response

import kotlinx.serialization.Serializable

@Serializable
data class RoomsBookPageResponse(
val totalBookPage: Int,
val recentBookPage: Int,
val isOverviewPossible: Boolean,
val roomId: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.texthip.thip.data.model.rooms.response

import kotlinx.serialization.Serializable

@Serializable
data class RoomsCreateVoteResponse(
val voteId: Int,
val roomId: Int
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.texthip.thip.data.model.rooms.response

import kotlinx.serialization.Serializable

@Serializable
data class RoomsDeleteRecordResponse(
val roomId: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.texthip.thip.data.model.rooms.response

import kotlinx.serialization.Serializable

@Serializable
data class RoomsPostsLikesResponse(
val postId: Int,
val isLiked: Boolean,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.texthip.thip.data.model.rooms.response

import kotlinx.serialization.Serializable

@Serializable
data class RoomsPostsResponse(
val postList: List<PostList>,
val roomId: Int,
val isbn: String,
val isOverviewEnabled: Boolean,
val nextCursor: String?,
val isLast: Boolean,
)
Comment on lines +7 to +13
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

직렬화 안정성 강화: 기본값 부여로 MissingFieldException 예방

백엔드가 특정 필드를 조건부로 생략하는 경우를 대비해 컬렉션/옵셔널 필드에 기본값을 부여해 두는 것이 안전합니다.

다음과 같이 기본값을 제안합니다.

 data class RoomsPostsResponse(
-    val postList: List<PostList>,
+    val postList: List<PostList> = emptyList(),
@@
-    val nextCursor: String?,
+    val nextCursor: String? = null,
-    val isLast: Boolean,
+    val isLast: Boolean = false,
 )
@@
-    val profileImageUrl: String?,
+    val profileImageUrl: String? = null,
@@
-    val voteItems: List<VoteItems>,
+    val voteItems: List<VoteItems> = emptyList(),

비투표형 포스트에서 voteItems가 누락되더라도 디코딩이 안전해집니다.

Also applies to: 23-24, 30-31

🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/data/model/rooms/response/RoomsPostsResponse.kt
around lines 7-13 (and likewise update related DTOs referenced at lines 23-24
and 30-31), several collection/optional properties lack safe default values
which can cause MissingFieldException during deserialization; update the Kotlin
data classes to provide sensible defaults (e.g., val postList: List<PostList> =
emptyList(), nullable strings to = null or "" as appropriate, booleans to a safe
default like false, and optional cursors to null) so decoding remains safe when
backend omits conditional fields — apply the same defaulting pattern to the
other mentioned fields at lines 23-24 and 30-31.


@Serializable
data class PostList(
val postId: Int,
val postDate: String,
val postType: String,
val page: Int,
val userId: Int,
val nickName: String,
val profileImageUrl: String?,
val content: String,
val likeCount: Int,
val commentCount: Int,
val isLiked: Boolean,
val isWriter: Boolean,
val isLocked: Boolean,
val voteItems: List<VoteItems>,
)

@Serializable
data class VoteItems(
val voteItemId: Int,
val itemName: String,
val percentage: Int,
val isVoted: Boolean,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.texthip.thip.data.model.rooms.response

import kotlinx.serialization.Serializable

@Serializable
data class RoomsRecordResponse(
val recordId: Int,
val roomId: Int,
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ data class UserList(
val userId: Int,
val nickname: String,
val imageUrl: String,
val alias: String,
val aliasName: String,
val followerCount: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.texthip.thip.data.model.rooms.response

import kotlinx.serialization.Serializable

@Serializable
data class RoomsVoteResponse(
val voteItemId: Int,
val roomId: Int,
val type: Boolean,
)
Comment on lines +5 to +10
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

응답 불리언 필드 type의 의미 명확화 (isSelected) + @SerialName 유지

요청/응답 모델 모두 동일한 도메인 용어를 사용하면 이해가 쉬워집니다. 요청과 동일하게 isSelected로 정렬하고 서버 JSON 키는 유지하세요.

다음 변경을 제안합니다:

 package com.texthip.thip.data.model.rooms.response

 import kotlinx.serialization.Serializable
+import kotlinx.serialization.SerialName

 @Serializable
 data class RoomsVoteResponse(
     val voteItemId: Int,
     val roomId: Int,
-    val type: Boolean,
+    @SerialName("type")
+    val isSelected: Boolean,
 )
🤖 Prompt for AI Agents
In
app/src/main/java/com/texthip/thip/data/model/rooms/response/RoomsVoteResponse.kt
around lines 5 to 10, the boolean property name `type` is unclear; rename the
Kotlin property to `isSelected` to match request models and domain terminology,
and annotate it with @SerialName("type") so the JSON key remains `type` for
compatibility; update any references/usages to the new property name and ensure
kotlinx.serialization.SerialName is imported.

109 changes: 109 additions & 0 deletions app/src/main/java/com/texthip/thip/data/repository/RoomsRepository.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package com.texthip.thip.data.repository

import com.texthip.thip.data.model.base.handleBaseResponse
import com.texthip.thip.data.model.rooms.request.RoomsCreateVoteRequest
import com.texthip.thip.data.model.rooms.request.RoomsPostsLikesRequest
import com.texthip.thip.data.model.rooms.request.RoomsRecordRequest
import com.texthip.thip.data.model.rooms.request.RoomsVoteRequest
import com.texthip.thip.data.model.rooms.request.VoteItem
import com.texthip.thip.data.service.RoomsService
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -24,4 +29,108 @@ class RoomsRepository @Inject constructor(
roomId = roomId
).handleBaseResponse().getOrThrow()
}

suspend fun getRoomsPosts(
roomId: Int,
type: String = "group",
sort: String? = "latest",
Comment on lines +35 to +36
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

기본 파라미터 값 검증 필요

sort 파라미터의 기본값이 "latest"로 설정되어 있지만, API가 지원하는 정렬 옵션들이 무엇인지 명확하지 않습니다. 잘못된 값이 전달될 경우를 대비한 검증이 필요할 수 있습니다.


🏁 Script executed:

#!/bin/bash
# Description: API가 지원하는 정렬 옵션 확인

# swagger 문서나 API 명세 파일 검색
fd -e json -e yaml -e md | xargs rg -A 5 "sort.*latest|sorting.*options" 

# 정렬 관련 상수나 enum 확인
ast-grep --pattern 'enum $_SortType {
  $$$
}'

# 정렬 관련 타입 정의 확인
rg -A 3 "enum.*Sort|object.*Sort|companion.*Sort"

Length of output: 496


🏁 Script executed:

#!/bin/bash
# Display full enum entries for supported sort options
sed -n '1,200p' app/src/main/java/com/texthip/thip/utils/type/SortType.kt

Length of output: 546


🏁 Script executed:

#!/bin/bash
# Show context around the sort parameter in RoomsRepository
sed -n '1,100p' app/src/main/java/com/texthip/thip/data/repository/RoomsRepository.kt

Length of output: 3014


🏁 Script executed:

#!/bin/bash
# Locate and display the service interface for getRoomsPosts
file="$(rg -l 'interface RoomsService' -g '*.kt')"
echo "RoomsService file: $file"
sed -n '1,200p' "$file" | sed -n '/getRoomsPosts/,/)/p'

Length of output: 469


Sort 파라미터에 enum 기반 검증 추가 필요

현재 getRoomsPosts 메서드는 sort: String? = "latest"로 설정되어 있어 기본값 “latest”는 SortType enum에 들어있지만, 잘못된 값이 들어올 경우 API 호출 시 예기치 않은 결과를 초래할 수 있습니다. SortType enum(LATEST("latest"), LIKE("like"), COMMENT("comment"))을 활용해 타입 안전성을 보장하고 기본·잘못된 입력 모두를 검증하도록 수정하는 것을 제안합니다.

수정 포인트:

  • app/src/main/java/com/texthip/thip/data/repository/RoomsRepository.kt
    getRoomsPosts 시그니처와 API 호출부 변경
  • (선택) app/src/main/java/com/texthip/thip/utils/type/SortType.kt
    • 이미 정의된 fromApiKey 메서드 활용 검토

예시 diff:

@@ RoomsRepository.kt
- suspend fun getRoomsPosts(
-     roomId: Int,
-     type: String = "group",
-     sort: String? = "latest",
+ suspend fun getRoomsPosts(
+     roomId: Int,
+     type: String = "group",
+     sort: SortType = SortType.LATEST,
     pageStart: Int? = null,
     pageEnd: Int? = null,
     isOverview: Boolean? = false,
     isPageFilter: Boolean? = false,
     cursor: String? = null,
 ) = runCatching {
     roomsService.getRoomsPosts(
         roomId = roomId,
         type = type,
-        sort = sort,
+        sort = sort.apiKey,
         pageStart = pageStart,
         pageEnd = pageEnd,
         isOverview = isOverview,
         isPageFilter = isPageFilter,
         cursor = cursor
     ).handleBaseResponse().getOrThrow()
 }

이렇게 변경하면

  1. 기본값 ‘LATEST’는 enum으로 보장
  2. 외부 입력이 들어올 때도 SortType.fromApiKey(...) 혹은 enum 파라미터 덕분에 유효성 검증이 이루어집니다.
  3. API에 항상 올바른 apiKey 값만 전달되어 안정성이 높아집니다.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
type: String = "group",
sort: String? = "latest",
// app/src/main/java/com/texthip/thip/data/repository/RoomsRepository.kt
suspend fun getRoomsPosts(
roomId: Int,
type: String = "group",
sort: SortType = SortType.LATEST,
pageStart: Int? = null,
pageEnd: Int? = null,
isOverview: Boolean? = false,
isPageFilter: Boolean? = false,
cursor: String? = null
) = runCatching {
roomsService.getRoomsPosts(
roomId = roomId,
type = type,
sort = sort.apiKey,
pageStart = pageStart,
pageEnd = pageEnd,
isOverview = isOverview,
isPageFilter = isPageFilter,
cursor = cursor
)
.handleBaseResponse()
.getOrThrow()
}
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/data/repository/RoomsRepository.kt around
lines 35-36, replace the String sort parameter with the SortType enum (default
to SortType.LATEST) in getRoomsPosts, and ensure any external String input is
converted/validated via SortType.fromApiKey(...) before calling the API; update
the API call to send the enum's apiKey (e.g., sort.apiKey) so only validated
enum values go to the backend.

pageStart: Int? = null,
pageEnd: Int? = null,
isOverview: Boolean? = false,
isPageFilter: Boolean? = false,
cursor: String? = null,
) = runCatching {
roomsService.getRoomsPosts(
roomId = roomId,
type = type,
sort = sort,
pageStart = pageStart,
pageEnd = pageEnd,
isOverview = isOverview,
isPageFilter = isPageFilter,
cursor = cursor
).handleBaseResponse().getOrThrow()
}

suspend fun postRoomsRecord(
roomId: Int,
content: String,
isOverview: Boolean = false,
page: Int = 0
) = runCatching {
roomsService.postRoomsRecord(
roomId = roomId,
request = RoomsRecordRequest(
page = page,
isOverview = isOverview,
content = content
)
).handleBaseResponse().getOrThrow()
}

suspend fun postRoomsCreateVote(
roomId: Int,
page: Int,
isOverview: Boolean,
content: String,
voteItemList: List<VoteItem>
) = runCatching {
roomsService.postRoomsCreateVote(
roomId = roomId,
request = RoomsCreateVoteRequest(
page = page,
isOverview = isOverview,
content = content,
voteItemList = voteItemList
)
).handleBaseResponse().getOrThrow()
}

suspend fun getRoomsBookPage(
roomId: Int,
) = runCatching {
roomsService.getRoomsBookPage(
roomId = roomId
).handleBaseResponse().getOrThrow()
}

suspend fun postRoomsVote(
roomId: Int,
voteId: Int,
voteItemId: Int,
type: Boolean
) = runCatching {
Comment on lines +101 to +102
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Boolean 타입 파라미터명 일관성 부족

type: Boolean 파라미터명이 모호합니다. 다른 메서드들에서는 isOverview, isPageFilter 같은 명확한 boolean 네이밍을 사용하는데, 여기서만 type이라는 일반적인 이름을 사용합니다.

파라미터명을 더 명확하게 변경하는 것을 권장합니다:

    suspend fun postRoomsVote(
        roomId: Int,
        voteId: Int,
        voteItemId: Int,
-       type: Boolean
+       isVoteFor: Boolean  // 또는 isPositiveVote, isAgree 등
    ) = runCatching {
        roomsService.postRoomsVote(
            roomId = roomId,
            voteId = voteId,
            request = RoomsVoteRequest(
                voteItemId = voteItemId,
-               type = type
+               type = isVoteFor
            )
        ).handleBaseResponse().getOrThrow()
    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
type: Boolean
) = runCatching {
suspend fun postRoomsVote(
roomId: Int,
voteId: Int,
voteItemId: Int,
isVoteFor: Boolean // 또는 isPositiveVote, isAgree 등
) = runCatching {
roomsService.postRoomsVote(
roomId = roomId,
voteId = voteId,
request = RoomsVoteRequest(
voteItemId = voteItemId,
type = isVoteFor
)
).handleBaseResponse().getOrThrow()
}

roomsService.postRoomsVote(
roomId = roomId,
voteId = voteId,
request = RoomsVoteRequest(
voteItemId = voteItemId,
type = type
)
).handleBaseResponse().getOrThrow()
}

suspend fun deleteRoomsRecord(
roomId: Int,
recordId: Int
) = runCatching {
roomsService.deleteRoomsRecord(
roomId = roomId,
recordId = recordId
).handleBaseResponse().getOrThrow()
}

suspend fun postRoomsPostsLikes(
postId: Int,
type: Boolean,
roomPostType: String
) = runCatching {
roomsService.postRoomsPostsLikes(
postId = postId,
request = RoomsPostsLikesRequest(
type = type,
roomPostType = roomPostType
)
).handleBaseResponse().getOrThrow()
}
}
63 changes: 63 additions & 0 deletions app/src/main/java/com/texthip/thip/data/service/RoomsService.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
package com.texthip.thip.data.service

import com.texthip.thip.data.model.base.BaseResponse
import com.texthip.thip.data.model.rooms.request.RoomsCreateVoteRequest
import com.texthip.thip.data.model.rooms.request.RoomsPostsLikesRequest
import com.texthip.thip.data.model.rooms.request.RoomsRecordRequest
import com.texthip.thip.data.model.rooms.request.RoomsVoteRequest
import com.texthip.thip.data.model.rooms.response.RoomsBookPageResponse
import com.texthip.thip.data.model.rooms.response.RoomsCreateVoteResponse
import com.texthip.thip.data.model.rooms.response.RoomsDeleteRecordResponse
import com.texthip.thip.data.model.rooms.response.RoomsPlayingResponse
import com.texthip.thip.data.model.rooms.response.RoomsPostsLikesResponse
import com.texthip.thip.data.model.rooms.response.RoomsPostsResponse
import com.texthip.thip.data.model.rooms.response.RoomsRecordResponse
import com.texthip.thip.data.model.rooms.response.RoomsUsersResponse
import com.texthip.thip.data.model.rooms.response.RoomsVoteResponse
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Path
import retrofit2.http.Query

interface RoomsService {
@GET("rooms/{roomId}/playing")
Expand All @@ -16,4 +31,52 @@ interface RoomsService {
suspend fun getRoomsUsers(
@Path("roomId") roomId: Int
): BaseResponse<RoomsUsersResponse>

@GET("rooms/{roomId}/posts")
suspend fun getRoomsPosts(
@Path("roomId") roomId: Int,
@Query("type") type: String = "group",
@Query("sort") sort: String? = "latest",
@Query("pageStart") pageStart: Int? = null,
@Query("pageEnd") pageEnd: Int? = null,
@Query("isOverview") isOverview: Boolean? = false,
@Query("isPageFilter") isPageFilter: Boolean? = false,
@Query("cursor") cursor: String? = null,
): BaseResponse<RoomsPostsResponse>

@POST("rooms/{roomId}/record")
suspend fun postRoomsRecord(
@Path("roomId") roomId: Int,
@Body request: RoomsRecordRequest
): BaseResponse<RoomsRecordResponse>

@POST("rooms/{roomId}/vote")
suspend fun postRoomsCreateVote(
@Path("roomId") roomId: Int,
@Body request: RoomsCreateVoteRequest
): BaseResponse<RoomsCreateVoteResponse>

@GET("rooms/{roomId}/book-page")
suspend fun getRoomsBookPage(
@Path("roomId") roomId: Int,
): BaseResponse<RoomsBookPageResponse>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

불필요한 trailing comma 제거

Line 62의 roomId 파라미터 뒤에 trailing comma가 있습니다.

-        @Path("roomId") roomId: Int,
+        @Path("roomId") roomId: Int
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
): BaseResponse<RoomsBookPageResponse>
@GET("/rooms/{roomId}/book")
suspend fun getRoomsBookPage(
@Path("roomId") roomId: Int
): BaseResponse<RoomsBookPageResponse>
🤖 Prompt for AI Agents
In app/src/main/java/com/texthip/thip/data/service/RoomsService.kt around line
62, there's an unnecessary trailing comma after the roomId parameter; remove the
trailing comma so the function signature ends cleanly (no extra comma after the
last parameter) and reformat the line to ensure Kotlin compiles and style is
consistent.


@POST("rooms/{roomId}/vote/{voteId}")
suspend fun postRoomsVote(
@Path("roomId") roomId: Int,
@Path("voteId") voteId: Int,
@Body request: RoomsVoteRequest
): BaseResponse<RoomsVoteResponse>

@DELETE("rooms/{roomId}/record/{recordId}")
suspend fun deleteRoomsRecord(
@Path("roomId") roomId: Int,
@Path("recordId") recordId: Int
): BaseResponse<RoomsDeleteRecordResponse>

@POST("room-posts/{postId}/likes")
suspend fun postRoomsPostsLikes(
@Path("postId") postId: Int,
@Body request: RoomsPostsLikesRequest
): BaseResponse<RoomsPostsLikesResponse>
}
Loading