Feature/#74 - SecretDetail Feature 기반 구현 및 MainFeature 라우팅 연결 - #78
Conversation
- 사이드바 selection 변경 시 state.secretDetail을 nil로 초기화 (이전 Secret의 detail이 잔류하는 버그) - dispatchRevealPayload의 default에 assertionFailure 추가로 무효 타입 조합 조기 감지 - task_success 테스트 주석: mock 동기 반환으로 receive 순서가 결정적임을 명시
|
Warning Review limit reached
Next review available in: 20 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
WalkthroughSecret payload 공개 API와 유형별 구현을 추가했습니다. ChangesSecret 상세 화면 흐름
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: Sequence Diagram(s)sequenceDiagram
participant SecretListFeature
participant MainFeature
participant SecretDetailFeature
participant ProjectClient
participant SecretClient
participant SecretDetailView
SecretListFeature->>MainFeature: secretSelected(secret)
MainFeature->>SecretDetailFeature: 상세 상태 생성
SecretDetailView->>SecretDetailFeature: task
par 프로젝트 목록 로딩
SecretDetailFeature->>ProjectClient: fetchProjects()
and payload 공개
SecretDetailFeature->>SecretClient: revealPayload(secret)
end
ProjectClient-->>SecretDetailFeature: projects 응답
SecretClient-->>SecretDetailFeature: payload 또는 오류
SecretDetailFeature-->>SecretDetailView: 화면 상태와 alert 갱신
SecretDetailView->>MainFeature: closed delegate
MainFeature->>MainFeature: 상세 상태와 selectedSecretID 초기화
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 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
🧹 Nitpick comments (2)
Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swift (1)
24-45: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
body의 중첩 레이아웃을 private subview로 분리하세요.
body에 상단 바, 모드 분기, 편집 하단 바가 직접 구현되어 있습니다.contentBody와editingFooter를 extension의private var로 분리하세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swift` around lines 24 - 45, SecretDetailView의 body에 직접 중첩된 레이아웃을 private 서브뷰로 분리하세요. 상단 바와 모드 분기 영역은 contentBody로, Divider와 Cancel/Save 버튼을 포함한 편집 하단 영역은 editingFooter로 extension의 private var에 추출하고, body에서는 해당 프로퍼티들을 호출하도록 변경하세요.Source: Path instructions
Projects/DVPresentation/Sources/Features/SecretDetail/Model/SecretDetailError.swift (1)
3-5: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value모듈 import 순서를 정리하세요.
내장 프레임워크를 먼저 배치하세요. 그 뒤에 빈 줄을 추가하세요. 이후 외부 및 프로젝트 모듈을 알파벳순으로 배치하세요.
Projects/DVPresentation/Sources/Features/SecretDetail/Model/SecretDetailError.swift#L3-L5:Foundation을 먼저 배치하고 나머지 모듈과 구분하세요.Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailFeature.swift#L3-L5:Foundation을 먼저 배치하고 나머지 모듈과 구분하세요.Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swift#L3-L6:SwiftUI를 먼저 배치하고 나머지 모듈과 구분하세요.Projects/DVPresentation/Tests/SecretDetail/SecretDetailFeatureTests.swift#L3-L8:Foundation,Testing을 먼저 배치하고 나머지 모듈과 구분하세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Projects/DVPresentation/Sources/Features/SecretDetail/Model/SecretDetailError.swift` around lines 3 - 5, 정리된 import 순서를 모든 지정 위치에 적용하세요. Projects/DVPresentation/Sources/Features/SecretDetail/Model/SecretDetailError.swift 3-5와 Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailFeature.swift 3-5에서는 Foundation을 먼저 두고 빈 줄 뒤 외부 및 프로젝트 모듈을 알파벳순으로 배치하세요. Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swift 3-6에서는 SwiftUI를 먼저 두고, Projects/DVPresentation/Tests/SecretDetail/SecretDetailFeatureTests.swift 3-8에서는 Foundation과 Testing을 먼저 둔 뒤 빈 줄과 알파벳순의 나머지 모듈을 배치하세요.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Projects/DVPresentation/Sources/Dependencies/SecretClient.swift`:
- Around line 59-82: Update the dummyClient revealPayload closure to dispatch on
the `(secret.secretType, secret.subType)` pair, matching `dispatchRevealPayload`
in the live implementation. Return the corresponding CreateSecretPayload case
for oauth/serviceAccount, sshAndCredentials/sslTlsCertificate, and etc/custom
instead of collapsing each pair to one payload type. Preserve the existing
preview payload values while aligning every subtype’s payload structure with the
live behavior.
In `@Projects/DVPresentation/Sources/Features/Main/MainView.swift`:
- Around line 84-87: Update MainView.swift lines 84-87 to use an English
localization source key and look it up from the .module bundle. Add the
corresponding English source string and Korean translation in
Projects/DVPresentation/Resources/Localizable.xcstrings lines 46-48; ensure
untranslated languages fall back to the English text rather than Korean.
In
`@Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailFeature.swift`:
- Around line 134-135: SecretDetailFeature의 didTapEdit, didTapCancelEdit,
didTapSave 처리에서 현재의 .none 반환을 수정하세요. 편집 기능을 지원할 준비가 되지 않았다면 SecretDetailView의
Edit, Cancel, Save 컨트롤을 숨기고, 지원한다면 didTapEdit에서 editFields를 초기화한 뒤 mode를
.editing으로 전환하며 didTapCancelEdit에서는 편집 필드를 폐기하고 .viewing으로 돌아가도록 구현하세요.
In
`@Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swift`:
- Around line 80-105: Update viewingBody and editingBody to render
payloadState.loading, payloadState.loaded, and payloadState.failed states
instead of only store.secret.name. In the loaded state, display the decrypted
CreateSecretPayload fields according to its type alongside metadata from
store.secret, while preserving the existing title styling and providing
appropriate loading and failure content.
- Line 46: SecretDetailView의 View modifier 체인에 SecretDetailFeature의 alert 상태와
액션을 연결하는 .alert store scope를 추가하세요. 기존 .task { store.send(.task) } 동작은 유지하고,
state.alert가 설정되면 사용자에게 해당 오류가 표시되도록 \.alert 상태와 \.alert 액션을 사용하세요.
In `@Projects/DVPresentation/Tests/SecretDetail/SecretDetailFeatureTests.swift`:
- Around line 64-70: Update SecretDetailFeatureTests so assertions do not assume
the `.merge` effects complete in projectsResponse → payloadResponse order; apply
this to the success case at
Projects/DVPresentation/Tests/SecretDetail/SecretDetailFeatureTests.swift:64-70,
the payload-failure case at :89-95, and the authentication-failure case at
:113-119. Use order-independent assertions or otherwise explicitly control
effect completion order while preserving each scenario’s expected state updates.
---
Nitpick comments:
In
`@Projects/DVPresentation/Sources/Features/SecretDetail/Model/SecretDetailError.swift`:
- Around line 3-5: 정리된 import 순서를 모든 지정 위치에 적용하세요.
Projects/DVPresentation/Sources/Features/SecretDetail/Model/SecretDetailError.swift
3-5와
Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailFeature.swift
3-5에서는 Foundation을 먼저 두고 빈 줄 뒤 외부 및 프로젝트 모듈을 알파벳순으로 배치하세요.
Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swift
3-6에서는 SwiftUI를 먼저 두고,
Projects/DVPresentation/Tests/SecretDetail/SecretDetailFeatureTests.swift 3-8에서는
Foundation과 Testing을 먼저 둔 뒤 빈 줄과 알파벳순의 나머지 모듈을 배치하세요.
In
`@Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swift`:
- Around line 24-45: SecretDetailView의 body에 직접 중첩된 레이아웃을 private 서브뷰로 분리하세요. 상단
바와 모드 분기 영역은 contentBody로, Divider와 Cancel/Save 버튼을 포함한 편집 하단 영역은 editingFooter로
extension의 private var에 추출하고, body에서는 해당 프로퍼티들을 호출하도록 변경하세요.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 0a1902c2-e5d0-4c91-977e-f426447e6fb4
📒 Files selected for processing (10)
Projects/DVPresentation/Resources/Localizable.xcstringsProjects/DVPresentation/Sources/Dependencies/SecretClient.swiftProjects/DVPresentation/Sources/Features/Main/MainFeature.swiftProjects/DVPresentation/Sources/Features/Main/MainView.swiftProjects/DVPresentation/Sources/Features/SecretDetail/Model/SecretDetailError.swiftProjects/DVPresentation/Sources/Features/SecretDetail/SecretDetailFeature.swiftProjects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swiftProjects/DVPresentation/Tests/Main/MainFeatureTests.swiftProjects/DVPresentation/Tests/SecretDetail/SecretDetailFeatureTests.swiftProjects/Devault/Sources/Composition/Dependencies/SecretClient+Live.swift
- SecretDetailView에 alert modifier를 연결해 payload 복호화/인증 실패가 사용자에게 노출되도록 수정 - detail 컬럼 안내 문구를 영어 source key로 교체하고 module 번들 조회 적용 - 상태 전이가 없어 동작하지 않던 Edit 버튼 숨김 - SecretDetail 신규 파일 import 순서를 프로젝트 컨벤션에 맞춰 정리 - dummyClient subType 분기와 payload 렌더링 미구현 지점에 후속 작업 주석 추가
✨ What's this PR?
📌 관련 이슈 (Related Issue)
🧶 주요 변경 내용 (Summary)
SecretDetailFeatureTCA Reducer 신규 구현 — 시크릿 상세 조회 화면의 상태 관리(viewing/editing 모드, payload 복호화, 프로젝트 목록 로딩)SecretDetailView신규 구현 — 시크릿 메타 정보 및 복호화된 payload를 표시하는 3-column detail 뷰SecretDetailError도메인 에러 → AlertState 매핑 헬퍼 추가SecretClient.revealPayload엔드포인트 추가 — 생체인증 후 암호화된 payload를CreateSecretPayload로 복호화·반환MainFeature에 SecretDetail 라우팅 연결 —secretListdelegate의secretSelected이벤트로 detail 진입/해제secretDetailstate 정리 — 잔존 detail 뷰 방지🧪 테스트 / 검증 내역
SecretDetailFeatureTests— task 시 payload/projects 로딩, payload 실패 시 alert, didTapClose delegate 검증MainFeatureTests— secretSelected 라우팅 진입/해제, 사이드바 전환 시 secretDetail 정리 검증💬 기타 공유 사항
didTapEdit,didTapCancelEdit,didTapSaveAction은.none반환으로 stub 처리SecretClient+Live의revealPayload구현은 secretType별 dispatch + metadata JSON 병합 구조revealPayload도 secretType별 샘플 데이터로 추가🙇🏻♀️ 리뷰 가이드 (선택)
SecretDetailFeature.body—.task시 payload 복호화와 프로젝트 로딩을.merge로 병렬 수행하는 구조MainFeature—secretSelecteddelegate 처리 시IdentifiedArray조회로Secret인스턴스를 넘기는 흐름SecretDetailError.map— 도메인 에러를 사용자 친화적 AlertState로 변환하는 패턴SecretClient+Live.revealPayload— secretType별 payload 복호화 dispatch 로직Summary by CodeRabbit
새 기능
개선 사항
테스트