Skip to content

Feature/#74 - SecretDetail Feature 기반 구현 및 MainFeature 라우팅 연결 - #78

Merged
doyeonk429 merged 5 commits into
developfrom
feature/#74
Aug 8, 2026
Merged

Feature/#74 - SecretDetail Feature 기반 구현 및 MainFeature 라우팅 연결#78
doyeonk429 merged 5 commits into
developfrom
feature/#74

Conversation

@doyeonk429

@doyeonk429 doyeonk429 commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

✨ What's this PR?

📌 관련 이슈 (Related Issue)


🧶 주요 변경 내용 (Summary)

  • SecretDetailFeature TCA Reducer 신규 구현 — 시크릿 상세 조회 화면의 상태 관리(viewing/editing 모드, payload 복호화, 프로젝트 목록 로딩)
  • SecretDetailView 신규 구현 — 시크릿 메타 정보 및 복호화된 payload를 표시하는 3-column detail 뷰
  • SecretDetailError 도메인 에러 → AlertState 매핑 헬퍼 추가
  • SecretClient.revealPayload 엔드포인트 추가 — 생체인증 후 암호화된 payload를 CreateSecretPayload로 복호화·반환
  • MainFeature에 SecretDetail 라우팅 연결 — secretList delegate의 secretSelected 이벤트로 detail 진입/해제
  • 사이드바 프로젝트 전환 시 secretDetail state 정리 — 잔존 detail 뷰 방지

🧪 테스트 / 검증 내역

  • SecretDetailFeatureTests — task 시 payload/projects 로딩, payload 실패 시 alert, didTapClose delegate 검증
  • MainFeatureTests — secretSelected 라우팅 진입/해제, 사이드바 전환 시 secretDetail 정리 검증
  • DVPresentation 전체 테스트 통과 확인

💬 기타 공유 사항

  • 수정 모드(editing)의 실제 저장 로직은 이번 PR 스코프 밖 — didTapEdit, didTapCancelEdit, didTapSave Action은 .none 반환으로 stub 처리
  • SecretClient+LiverevealPayload 구현은 secretType별 dispatch + metadata JSON 병합 구조
  • preview용 revealPayload도 secretType별 샘플 데이터로 추가

🙇🏻‍♀️ 리뷰 가이드 (선택)

  • SecretDetailFeature.body.task 시 payload 복호화와 프로젝트 로딩을 .merge로 병렬 수행하는 구조
  • MainFeaturesecretSelected delegate 처리 시 IdentifiedArray 조회로 Secret 인스턴스를 넘기는 흐름
  • SecretDetailError.map — 도메인 에러를 사용자 친화적 AlertState로 변환하는 패턴
  • SecretClient+Live.revealPayload — secretType별 payload 복호화 dispatch 로직

Summary by CodeRabbit

  • 새 기능

    • 비밀 목록에서 항목을 선택하면 상세 화면에서 내용을 확인할 수 있습니다.
    • 생체 인증 후 비밀 내용을 복호화해 표시합니다.
    • 상세 화면에서 보기 및 편집 모드를 제공하고, 닫기·취소·저장 동작을 지원합니다.
    • 선택된 비밀이 없을 때 안내 문구를 표시합니다.
  • 개선 사항

    • 복호화 실패, 인증 필요, 예기치 않은 오류를 구분해 안내합니다.
    • 상세 화면의 표시 영역 크기와 레이아웃을 개선했습니다.
  • 테스트

    • 비밀 선택, 상세 화면 종료, 인증 및 복호화 오류 동작을 검증했습니다.

- 사이드바 selection 변경 시 state.secretDetail을 nil로 초기화 (이전 Secret의 detail이 잔류하는 버그)
- dispatchRevealPayload의 default에 assertionFailure 추가로 무효 타입 조합 조기 감지
- task_success 테스트 주석: mock 동기 반환으로 receive 순서가 결정적임을 명시
@doyeonk429 doyeonk429 self-assigned this Aug 8, 2026
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@doyeonk429, you've reached your PR review limit, so we couldn't start this review.

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 @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f1b06a9d-0e20-4b23-98e2-00fe97b58cb6

📥 Commits

Reviewing files that changed from the base of the PR and between ff4796e and 386250f.

📒 Files selected for processing (7)
  • Projects/DVPresentation/Resources/Localizable.xcstrings
  • Projects/DVPresentation/Sources/Dependencies/SecretClient.swift
  • Projects/DVPresentation/Sources/Features/Main/MainView.swift
  • Projects/DVPresentation/Sources/Features/SecretDetail/Model/SecretDetailError.swift
  • Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailFeature.swift
  • Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swift
  • Projects/DVPresentation/Tests/SecretDetail/SecretDetailFeatureTests.swift

Walkthrough

Secret payload 공개 API와 유형별 구현을 추가했습니다. SecretDetailFeatureSecretDetailView를 구현했습니다. MainFeature에 상세 화면 라우팅을 연결하고, 로딩·오류·종료 동작을 테스트했습니다.

Changes

Secret 상세 화면 흐름

Layer / File(s) Summary
Payload 공개 의존성
Projects/DVPresentation/Sources/Dependencies/SecretClient.swift, Projects/Devault/Sources/Composition/Dependencies/SecretClient+Live.swift
SecretClient.revealPayload를 추가했습니다. Secret 유형과 하위 유형에 따라 payload를 공개하고 CreateSecretPayload로 변환합니다.
상세 상태와 payload 로딩
Projects/DVPresentation/Sources/Features/SecretDetail/Model/SecretDetailError.swift, Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailFeature.swift
조회·수정 상태, 프로젝트 목록, payload 로딩, 오류 매핑, alert, 종료 delegate를 추가했습니다. 프로젝트 목록과 payload를 병렬로 로드합니다.
Main 라우팅과 상세 UI
Projects/DVPresentation/Sources/Features/Main/MainFeature.swift, Projects/DVPresentation/Sources/Features/Main/MainView.swift, Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swift, Projects/DVPresentation/Resources/Localizable.xcstrings
Secret 선택 시 상세 상태를 생성하고 SecretDetailView를 표시합니다. 상세 화면 종료 시 선택 상태를 초기화합니다. 선택된 Secret이 없을 때 안내 문구를 표시합니다.
상세 흐름 검증
Projects/DVPresentation/Tests/Main/MainFeatureTests.swift, Projects/DVPresentation/Tests/SecretDetail/SecretDetailFeatureTests.swift
Secret 선택, 선택 해제, 상세 종료, 초기 상태, payload 성공, 복호화 실패, 인증 실패를 검증합니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

Suggested labels: ✅ Test

Suggested reviewers: dlguszoo, yeseonglee

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 초기화
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.15% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 SecretDetailFeature 구현과 MainFeature 라우팅 연결이라는 주요 변경 사항을 정확하고 간결하게 설명합니다.
Linked Issues check ✅ Passed SecretDetailFeature 구현, 상세 화면 표시, MainFeature 라우팅, 닫기 delegate, 로딩 및 테스트 요구 사항을 충족합니다 [#74].
Out of Scope Changes check ✅ Passed 변경 사항은 SecretDetailFeature와 라우팅 구현에 직접 관련되며, 저장 로직은 명시된 범위대로 stub 처리되었습니다.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#74

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@doyeonk429 doyeonk429 added the ✨ Feature 새로운 기능 개발 label Aug 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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에 상단 바, 모드 분기, 편집 하단 바가 직접 구현되어 있습니다. contentBodyeditingFooter를 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

📥 Commits

Reviewing files that changed from the base of the PR and between 3bd416a and ff4796e.

📒 Files selected for processing (10)
  • Projects/DVPresentation/Resources/Localizable.xcstrings
  • Projects/DVPresentation/Sources/Dependencies/SecretClient.swift
  • Projects/DVPresentation/Sources/Features/Main/MainFeature.swift
  • Projects/DVPresentation/Sources/Features/Main/MainView.swift
  • Projects/DVPresentation/Sources/Features/SecretDetail/Model/SecretDetailError.swift
  • Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailFeature.swift
  • Projects/DVPresentation/Sources/Features/SecretDetail/SecretDetailView.swift
  • Projects/DVPresentation/Tests/Main/MainFeatureTests.swift
  • Projects/DVPresentation/Tests/SecretDetail/SecretDetailFeatureTests.swift
  • Projects/Devault/Sources/Composition/Dependencies/SecretClient+Live.swift

Comment thread Projects/DVPresentation/Sources/Dependencies/SecretClient.swift
Comment thread Projects/DVPresentation/Sources/Features/Main/MainView.swift Outdated
- SecretDetailView에 alert modifier를 연결해 payload 복호화/인증 실패가 사용자에게 노출되도록 수정
- detail 컬럼 안내 문구를 영어 source key로 교체하고 module 번들 조회 적용
- 상태 전이가 없어 동작하지 않던 Edit 버튼 숨김
- SecretDetail 신규 파일 import 순서를 프로젝트 컨벤션에 맞춰 정리
- dummyClient subType 분기와 payload 렌더링 미구현 지점에 후속 작업 주석 추가
@doyeonk429
doyeonk429 merged commit 37f52cf into develop Aug 8, 2026
1 check passed
@doyeonk429
doyeonk429 deleted the feature/#74 branch August 8, 2026 04:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 새로운 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: SecretDetail Feature 기반 + MainFeature 라우팅

2 participants