Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (4)
📝 WalkthroughWalkthrough홈 화면 대시보드 네트워크 연동을 추가했습니다. DTO·엔드포인트·리포지토리 구현과 DI 변경이 포함되며, Splash 네비게이션이 UserDefaults 기반으로 분기하도록 수정되었습니다. 에셋 카탈로그 Splash Contents.json 파일 두 개가 삭제되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Factory as "ViewFactory\n(renders HomeView)"
participant Container as "DIContainer"
participant Repo as "DefaultHomeRepository"
participant Network as "NetworkService"
participant API as "HomeAPI"
participant Defaults as "UserDefaults"
participant ViewModel as "HomeViewModel"
participant View as "HomeView"
Factory->>Container: resolve(HomeViewModel)
Container->>Repo: construct DefaultHomeRepository(with NetworkService, UserDefaultService)
Container-->>ViewModel: provide(repository)
Factory->>View: HomeView(viewModel)
View->>ViewModel: onAppear()
ViewModel->>Repo: fetchDashboard()
Repo->>Defaults: read userID
Defaults-->>Repo: userID
Repo->>Network: request(HomeAPI.fetchDashboard(userID))
Network->>API: GET /api/main-dashboard (with auth header)
API-->>Network: JSON DashboardDTO
Network-->>Repo: decoded DashboardDTO
Repo->>Repo: dto.toEntity()
Repo-->>ViewModel: DashboardEntity
ViewModel->>View: update dashboardData
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/ProcedurePhase+.swift (1)
10-21: LGTM!Presentation 레이어에서
displayText를 제공하는 것은 적절한 관심사 분리입니다. 모든 case가 처리되어 있습니다.향후 다국어 지원이 필요할 경우
NSLocalizedString을 고려해 보세요.
🤖 Fix all issues with AI agents
In `@Cherrish-iOS/Cherrish-iOS/Data/Model/Dashboard/RecentProcedureDTO.swift`:
- Around line 25-36: convertToPhase(_:)'s default branch silently returns
.sensitive for unexpected phase strings which hides API changes; update this
function to log or call assertionFailure (or both) when an unknown phase is
encountered and then return a safe fallback. Specifically, in convertToPhase(_
phase: String) check the unmatched case, call assertionFailure("Unexpected
phase: \(phase)") and/or send the value to your logging facility, then return a
clear fallback (e.g., .sensitive) so callers still get a valid ProcedurePhase;
keep references to the function name convertToPhase and the enum ProcedurePhase
to locate and modify the code.
In `@Cherrish-iOS/Cherrish-iOS/Data/Model/Dashboard/UpcomingProcedureDTO.swift`:
- Around line 10-26: The UpcomingProcedureDTO struct and its toEntity() method
are duplicated between this file and DashboardDTO.swift; remove the duplicate by
keeping a single canonical definition and updating references accordingly:
choose either to keep UpcomingProcedureDTO (and its toEntity() ->
UpcomingProcedureEntity) in this file under Dashboard/ subdirectory and delete
the duplicate block in DashboardDTO.swift, or consolidate all related DTOs into
DashboardDTO.swift and delete this file; after removal, ensure imports/usages
reference the retained type and run build to fix any import paths.
In `@Cherrish-iOS/Cherrish-iOS/Data/Model/DashboardDTO.swift`:
- Around line 56-67: convertToPhase(_: String) currently maps unknown phase
strings to .sensitive which hides new/invalid API values; update this by adding
an explicit .unknown case to the ProcedurePhase enum (or a throwing/optional
return) and change convertToPhase to return .unknown for unmatched values, and
also emit a diagnostic log (using NSLog/OSLog or your existing logging facility)
including the unexpected phase string so you can detect new API values at
runtime; ensure callers handle the new .unknown (or optional/throws) case
appropriately.
- Around line 10-31: DashboardDTO.swift currently defines RecentProcedureDTO and
UpcomingProcedureDTO but those same structs are already defined in
Dashboard/RecentProcedureDTO.swift and Dashboard/UpcomingProcedureDTO.swift;
remove the duplicate struct definitions from DashboardDTO.swift and import or
reference the single canonical definitions instead. Specifically, keep
DashboardDTO struct in DashboardDTO.swift, delete the local RecentProcedureDTO
and UpcomingProcedureDTO declarations there, and ensure any usages (e.g., the
properties recentProcedures: [RecentProcedureDTO] and upcomingProcedures:
[UpcomingProcedureDTO]) resolve to the existing Dashboard/RecentProcedureDTO and
Dashboard/UpcomingProcedureDTO types (add an import or update module visibility
if needed). Ensure Codable/Decodable conformance is consistent in the canonical
files and run build to verify no unresolved references remain.
In `@Cherrish-iOS/Cherrish-iOS/Data/Network/EndPoint/HomeAPI.swift`:
- Around line 36-41: The headers computed property in HomeAPI (var headers:
HeaderType) is using a userID passed in by callers, but DefaultHomeRepository
currently hardcodes userID = 2; change the repository to obtain the real
authenticated user id (e.g. read from UserDefaults using UserDefaultsKey.userID
or the app's auth/session provider) and pass that value into
HomeAPI.fetchDashboard(userID:) instead of the literal 2 so HeaderType.withAuth
receives the actual user id.
In `@Cherrish-iOS/Cherrish-iOS/Data/Repository/HomeRepository.swift`:
- Around line 18-23: HomeRepository currently hardcodes let userID = 2 when
calling networkService.request(HomeAPI.fetchDashboard(userID: userID)), causing
wrong data to be fetched; update HomeRepository to obtain the user ID
dynamically from the app's session/auth layer (e.g., an injected UserSession or
AuthService: currentUser.id or userID property) before calling
HomeAPI.fetchDashboard, handle the case where the current user is missing (throw
an error or return early) and keep decoding to DashboardDTO and converting with
dto.toEntity() as before.
| private func convertToPhase(_ phase: String) -> ProcedurePhase { | ||
| switch phase { | ||
| case "SENSITIVE": | ||
| return .sensitive | ||
| case "CAUTION": | ||
| return .caution | ||
| case "RECOVERY": | ||
| return .recovery | ||
| default: | ||
| return .sensitive | ||
| } | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
예상치 못한 phase 값에 대한 처리 개선을 권장합니다.
default case에서 .sensitive를 반환하면 API 계약 변경이나 예상치 못한 값이 조용히 무시됩니다. 디버깅을 위해 로그를 남기거나 assertionFailure를 추가하는 것을 고려해 보세요.
♻️ 권장 수정안
private func convertToPhase(_ phase: String) -> ProcedurePhase {
switch phase {
case "SENSITIVE":
return .sensitive
case "CAUTION":
return .caution
case "RECOVERY":
return .recovery
default:
+ `#if` DEBUG
+ assertionFailure("Unknown phase value: \(phase)")
+ `#endif`
return .sensitive
}
}📝 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.
| private func convertToPhase(_ phase: String) -> ProcedurePhase { | |
| switch phase { | |
| case "SENSITIVE": | |
| return .sensitive | |
| case "CAUTION": | |
| return .caution | |
| case "RECOVERY": | |
| return .recovery | |
| default: | |
| return .sensitive | |
| } | |
| } | |
| private func convertToPhase(_ phase: String) -> ProcedurePhase { | |
| switch phase { | |
| case "SENSITIVE": | |
| return .sensitive | |
| case "CAUTION": | |
| return .caution | |
| case "RECOVERY": | |
| return .recovery | |
| default: | |
| `#if` DEBUG | |
| assertionFailure("Unknown phase value: \(phase)") | |
| `#endif` | |
| return .sensitive | |
| } | |
| } |
🤖 Prompt for AI Agents
In `@Cherrish-iOS/Cherrish-iOS/Data/Model/Dashboard/RecentProcedureDTO.swift`
around lines 25 - 36, convertToPhase(_:)'s default branch silently returns
.sensitive for unexpected phase strings which hides API changes; update this
function to log or call assertionFailure (or both) when an unknown phase is
encountered and then return a safe fallback. Specifically, in convertToPhase(_
phase: String) check the unmatched case, call assertionFailure("Unexpected
phase: \(phase)") and/or send the value to your logging facility, then return a
clear fallback (e.g., .sensitive) so callers still get a valid ProcedurePhase;
keep references to the function name convertToPhase and the enum ProcedurePhase
to locate and modify the code.
| struct UpcomingProcedureDTO: Decodable { | ||
| let date: String | ||
| let name: String | ||
| let count: Int | ||
| let dDay: Int | ||
| } | ||
|
|
||
| extension UpcomingProcedureDTO { | ||
| func toEntity() -> UpcomingProcedureEntity { | ||
| UpcomingProcedureEntity( | ||
| date: date, | ||
| name: name, | ||
| count: count, | ||
| dDay: dDay | ||
| ) | ||
| } | ||
| } |
There was a problem hiding this comment.
DashboardDTO.swift와 중복되는 코드입니다.
이 파일의 UpcomingProcedureDTO와 toEntity() 구현이 DashboardDTO.swift (라인 26-31, 70-78)에도 동일하게 존재합니다. 중복을 제거하고 하나의 위치에서만 정의하도록 통합해야 합니다.
권장 방안: Dashboard/ 서브디렉토리에 개별 DTO 파일들을 유지하고, DashboardDTO.swift에서는 해당 파일들을 import하여 사용하거나, 반대로 DashboardDTO.swift에 모든 관련 DTO를 통합하세요.
🤖 Prompt for AI Agents
In `@Cherrish-iOS/Cherrish-iOS/Data/Model/Dashboard/UpcomingProcedureDTO.swift`
around lines 10 - 26, The UpcomingProcedureDTO struct and its toEntity() method
are duplicated between this file and DashboardDTO.swift; remove the duplicate by
keeping a single canonical definition and updating references accordingly:
choose either to keep UpcomingProcedureDTO (and its toEntity() ->
UpcomingProcedureEntity) in this file under Dashboard/ subdirectory and delete
the duplicate block in DashboardDTO.swift, or consolidate all related DTOs into
DashboardDTO.swift and delete this file; after removal, ensure imports/usages
reference the retained type and run build to fix any import paths.
| private func convertToPhase(_ phase: String) -> ProcedurePhase { | ||
| switch phase { | ||
| case "SENSITIVE": | ||
| return .sensitive | ||
| case "CAUTION": | ||
| return .caution | ||
| case "RECOVERY": | ||
| return .recovery | ||
| default: | ||
| return .sensitive | ||
| } | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
알 수 없는 phase 값에 대한 로깅 또는 명시적 처리를 추가하세요.
default 케이스에서 .sensitive를 반환하면 API에서 새로운 phase 값이 추가되었을 때 이를 감지하지 못하고 잘못된 상태가 표시될 수 있습니다. 최소한 로깅을 추가하거나, 별도의 unknown 케이스를 고려해 보세요.
♻️ 권장 수정 방안
private func convertToPhase(_ phase: String) -> ProcedurePhase {
switch phase {
case "SENSITIVE":
return .sensitive
case "CAUTION":
return .caution
case "RECOVERY":
return .recovery
default:
+ assertionFailure("Unknown phase value received: \(phase)")
return .sensitive
}
}📝 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.
| private func convertToPhase(_ phase: String) -> ProcedurePhase { | |
| switch phase { | |
| case "SENSITIVE": | |
| return .sensitive | |
| case "CAUTION": | |
| return .caution | |
| case "RECOVERY": | |
| return .recovery | |
| default: | |
| return .sensitive | |
| } | |
| } | |
| private func convertToPhase(_ phase: String) -> ProcedurePhase { | |
| switch phase { | |
| case "SENSITIVE": | |
| return .sensitive | |
| case "CAUTION": | |
| return .caution | |
| case "RECOVERY": | |
| return .recovery | |
| default: | |
| assertionFailure("Unknown phase value received: \(phase)") | |
| return .sensitive | |
| } | |
| } |
🤖 Prompt for AI Agents
In `@Cherrish-iOS/Cherrish-iOS/Data/Model/DashboardDTO.swift` around lines 56 -
67, convertToPhase(_: String) currently maps unknown phase strings to .sensitive
which hides new/invalid API values; update this by adding an explicit .unknown
case to the ProcedurePhase enum (or a throwing/optional return) and change
convertToPhase to return .unknown for unmatched values, and also emit a
diagnostic log (using NSLog/OSLog or your existing logging facility) including
the unexpected phase string so you can detect new API values at runtime; ensure
callers handle the new .unknown (or optional/throws) case appropriately.
| var headers: HeaderType { | ||
| switch self { | ||
| case .fetchDashboard(let userID): | ||
| return .withAuth(userID: userID) | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find HomeRepository.swift and check for hardcoded userID
fd "HomeRepository.swift" -x cat -n {}Repository: TEAM-Cherrish/Cherrish-iOS
Length of output: 3205
🏁 Script executed:
#!/bin/bash
# Search for userID patterns across Swift files
rg -n "userID" --type swift -B 2 -A 2 | head -100Repository: TEAM-Cherrish/Cherrish-iOS
Length of output: 3767
🏁 Script executed:
#!/bin/bash
# Look for userID = 2 specifically
rg -n "userID\s*=\s*2" --type swiftRepository: TEAM-Cherrish/Cherrish-iOS
Length of output: 158
실제 사용자 ID를 사용하도록 수정이 필요합니다.
DefaultHomeRepository.swift 18번째 줄에서 userID = 2로 하드코딩되어 있습니다. 현재 인증된 사용자의 ID를 가져와서 사용하도록 수정해야 합니다. UserDefaultsKey.userID가 이미 정의되어 있으므로, 저장된 사용자 ID를 활용하거나 인증 정보로부터 실제 사용자 ID를 가져와야 합니다.
🤖 Prompt for AI Agents
In `@Cherrish-iOS/Cherrish-iOS/Data/Network/EndPoint/HomeAPI.swift` around lines
36 - 41, The headers computed property in HomeAPI (var headers: HeaderType) is
using a userID passed in by callers, but DefaultHomeRepository currently
hardcodes userID = 2; change the repository to obtain the real authenticated
user id (e.g. read from UserDefaults using UserDefaultsKey.userID or the app's
auth/session provider) and pass that value into HomeAPI.fetchDashboard(userID:)
instead of the literal 2 so HeaderType.withAuth receives the actual user id.
| let userID = 2 | ||
| let dto = try await networkService.request( | ||
| HomeAPI.fetchDashboard(userID: userID), | ||
| decodingType: DashboardDTO.self | ||
| ) | ||
| return dto.toEntity() |
There was a problem hiding this comment.
하드코딩된 userID를 동적으로 가져와야 합니다.
userID = 2가 하드코딩되어 있어 현재 로그인한 사용자가 아닌 항상 동일한 사용자의 대시보드 데이터를 가져오게 됩니다. 이는 다른 사용자가 앱을 사용할 때 잘못된 데이터가 표시되는 심각한 문제를 야기합니다.
사용자 세션 또는 인증 서비스에서 현재 사용자 ID를 동적으로 가져오도록 수정해야 합니다.
🐛 권장 수정 방안
struct DefaultHomeRepository: HomeInterface {
private let networkService: NetworkService
+ private let userSession: UserSessionProvider // 또는 적절한 인증 서비스
- init(networkService: NetworkService) {
+ init(networkService: NetworkService, userSession: UserSessionProvider) {
self.networkService = networkService
+ self.userSession = userSession
}
func fetchDashboard() async throws -> DashboardEntity {
- let userID = 2
+ let userID = userSession.currentUserID
let dto = try await networkService.request(
HomeAPI.fetchDashboard(userID: userID),
decodingType: DashboardDTO.self
)
return dto.toEntity()
}
}🤖 Prompt for AI Agents
In `@Cherrish-iOS/Cherrish-iOS/Data/Repository/HomeRepository.swift` around lines
18 - 23, HomeRepository currently hardcodes let userID = 2 when calling
networkService.request(HomeAPI.fetchDashboard(userID: userID)), causing wrong
data to be fetched; update HomeRepository to obtain the user ID dynamically from
the app's session/auth layer (e.g., an injected UserSession or AuthService:
currentUser.id or userID property) before calling HomeAPI.fetchDashboard, handle
the case where the current user is missing (throw an error or return early) and
keep decoding to DashboardDTO and converting with dto.toEntity() as before.
There was a problem hiding this comment.
userID = 1로 변경해주세용! 서버에서 1로 쓰신답니다~~
|
|
||
| struct HomeView: View { | ||
| @StateObject private var viewModel = DIContainer.shared.resolve(type: HomeViewModel.self)! | ||
| @ObservedObject var viewModel: HomeViewModel |
There was a problem hiding this comment.
여기 혹시 모르니까 StateObject로 받는 게 어떤가요?
| private func convertToPhase(_ phase: String) -> ProcedurePhase { | ||
| switch phase { | ||
| case "SENSITIVE": | ||
| return .sensitive | ||
| case "CAUTION": | ||
| return .caution | ||
| case "RECOVERY": | ||
| return .recovery | ||
| default: | ||
| return .sensitive | ||
| } | ||
| } |
| let userID = 2 | ||
| let dto = try await networkService.request( | ||
| HomeAPI.fetchDashboard(userID: userID), | ||
| decodingType: DashboardDTO.self | ||
| ) | ||
| return dto.toEntity() |
There was a problem hiding this comment.
userID = 1로 변경해주세용! 서버에서 1로 쓰신답니다~~
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@Cherrish-iOS/Cherrish-iOS/Data/Repository/HomeRepository.swift`:
- Around line 18-23: The code is calling
networkService.request(HomeAPI.fetchDashboard(userID: userID), ...) without
guarding that UserDefaults.standard.integer(forKey:
UserDefaultsKey.userID.rawValue) returns 0 when unset; add a guard in
HomeRepository (or the function that performs this fetch) checking that userID
!= 0 and, if it is 0, either throw a domain-specific error (e.g.,
MissingUserIDError) or return/route to the onboarding flow instead of calling
networkService.request; update callers to handle the thrown error or routing
decision accordingly so fetchDashboard and DashboardDTO decoding never run with
an invalid userID.
♻️ Duplicate comments (1)
Cherrish-iOS/Cherrish-iOS/Data/Model/RecentProcedureDTO.swift (1)
25-34: 알 수 없는 phase 처리에 진단 로그를 추가하세요.Line 25-34의
default에서.sensitive로 고정하면 API 변경을 놓치기 쉽습니다. 최소한 디버그 로그/assertionFailure를 추가해 진단 가능하게 해주세요.🔧 제안 수정
private func convertToPhase(_ phase: String) -> ProcedurePhase { switch phase { case "SENSITIVE": return .sensitive case "CAUTION": return .caution case "RECOVERY": return .recovery default: + `#if` DEBUG + assertionFailure("Unknown phase value: \(phase)") + `#endif` return .sensitive } }
| let userID = UserDefaults.standard.integer(forKey: UserDefaultsKey.userID.rawValue) | ||
|
|
||
| let dto = try await networkService.request( | ||
| HomeAPI.fetchDashboard(userID: userID), | ||
| decodingType: DashboardDTO.self | ||
| ) |
There was a problem hiding this comment.
userID 미설정(0)일 때 API 호출을 막아야 합니다.
Line 18-23에서 integer(forKey:)는 키가 없으면 0을 반환합니다. userID가 0일 때 바로 호출되면 잘못된 사용자 데이터 요청/에러가 발생할 수 있으므로, 명확히 가드 후 에러를 던지거나 상위에서 온보딩 플로우로 보내는 처리가 필요합니다.
🔧 제안 수정
func fetchDashboard() async throws -> DashboardEntity {
let userID = UserDefaults.standard.integer(forKey: UserDefaultsKey.userID.rawValue)
+ guard userID != 0 else {
+ throw HomeRepositoryError.missingUserID // 프로젝트 에러 타입에 맞게 조정
+ }
let dto = try await networkService.request(
HomeAPI.fetchDashboard(userID: userID),
decodingType: DashboardDTO.self
)🤖 Prompt for AI Agents
In `@Cherrish-iOS/Cherrish-iOS/Data/Repository/HomeRepository.swift` around lines
18 - 23, The code is calling
networkService.request(HomeAPI.fetchDashboard(userID: userID), ...) without
guarding that UserDefaults.standard.integer(forKey:
UserDefaultsKey.userID.rawValue) returns 0 when unset; add a guard in
HomeRepository (or the function that performs this fetch) checking that userID
!= 0 and, if it is 0, either throw a domain-specific error (e.g.,
MissingUserIDError) or return/route to the onboarding flow instead of calling
networkService.request; update callers to handle the thrown error or routing
decision accordingly so fetchDashboard and DashboardDTO decoding never run with
an invalid userID.

🔗 연결된 이슈
네트워크 로그
📄 작업 내용