Skip to content

Feature/#45 - 온보딩/잠금 네비게이션 라우팅 및 OnboardingStatusClient 구현 - #52

Merged
dlguszoo merged 11 commits into
developfrom
feature/#45
Jul 25, 2026
Merged

Feature/#45 - 온보딩/잠금 네비게이션 라우팅 및 OnboardingStatusClient 구현#52
dlguszoo merged 11 commits into
developfrom
feature/#45

Conversation

@dlguszoo

@dlguszoo dlguszoo commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

✨ What’s this PR?

📌 관련 이슈 (Related Issue)


🧶 주요 변경 내용 (Summary)

  • SettingsRepository → OnboardingStatusUseCase → OnboardingStatusClient 레이어 스택 구현 (온보딩 여부)
  • OnboardingContainerFeature/View 도입으로 DVStepIndicator 단일 인스턴스 공유 (온보딩→잠금 전환 시 애니메이션 연속성 확보)
  • AppFeature에서 onboardingStatus 기반 온보딩/잠금/메인 분기 라우팅 구현
  • OnboardingFeature iCloud sync 3초 타이머 연결 (추후 실제 콜백으로 교체 예정)

📸 스크린샷 (Optional)

2026-07-24.2.31.30.mov
2026-07-24.2.30.20.mov

🧪 테스트 / 검증 내역

  • 최초 실행 시 온보딩 화면 진입 확인
  • 온보딩 완료 후 재실행 시 잠금 화면 진입 확인
  • Not Now 탭 → syncing 없이 바로 다음 단계 전환 확인
  • Enable Sync 탭 → 3초 후 잠금 화면 전환 확인
  • 온보딩→잠금 전환 시 DVStepIndicator step 3으로 애니메이션 연속 확인

💬 기타 공유 사항

  • AppFeature multiple optional 설계 의도
    • @Reducer enum으로 타입 수준에서 하나의 scene만 활성화되도록 시도했으나, TCA의 @Reducer enum이 @presents(modal) 전용이라 always-present scene 상태에는 공개 API가 지원되지 않아 multiple optional 방식을 유지했습니다. reducer 로직으로 불변식을 보장합니다.

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

  • 접근성 Label과 localization은 후에 처리할 예정입니다.
  • window min/max 크기는 논의 후 확정할 예정입니다.

Summary by CodeRabbit

  • 새로운 기능

    • 온보딩 완료 상태를 저장하고 다음 실행 시 이어갈 수 있습니다.
    • 온보딩 완료 후 잠금 해제 화면을 거쳐 메인 화면으로 이동합니다.
    • 온보딩 및 잠금 화면 흐름과 단계 표시 UI를 추가했습니다.
    • 온보딩 동기화 진행 상태와 완료 처리를 지원합니다.
    • 비밀 저장소 및 프로젝트 화면에 필요한 문구와 한국어 번역을 추가했습니다.
  • 개선

    • 앱 창 크기와 제목 표시줄을 조정해 화면 구성을 개선했습니다.
    • 화면 전반에서 색상 스타일을 안정적으로 사용할 수 있습니다.

@dlguszoo dlguszoo self-assigned this Jul 23, 2026
@dlguszoo dlguszoo added the ✨ Feature 새로운 기능 개발 label Jul 23, 2026
@dlguszoo dlguszoo linked an issue Jul 23, 2026 that may be closed by this pull request
12 tasks
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

온보딩 완료 상태를 UserDefaults에 저장하고 TCA 의존성으로 연결했습니다. 앱은 상태에 따라 온보딩, 잠금, 메인 화면을 전환하며, 관련 화면·윈도우·로컬라이즈 설정을 갱신합니다.

Changes

온보딩 상태 저장과 의존성 연결

Layer / File(s) Summary
저장소·유스케이스·TCA 의존성
Projects/DVDomain/..., Projects/DVData/..., Projects/DVPresentation/Sources/Dependencies/..., Projects/Devault/Sources/Composition/...
SettingsRepositoryOnboardingStatusUseCase 계약 및 구현을 추가하고, UserDefaults와 OnboardingStatusClient live 구현을 연결합니다.

온보딩·잠금 상태 전환

Layer / File(s) Summary
상태 모델과 리듀서 전환
Projects/DVPresentation/Sources/Features/AppFeature.swift, .../OnboardingFeature.swift, .../OnboardingContainerFeature.swift, .../LockFeature.swift
온보딩 완료 여부에 따라 온보딩·잠금·메인 상태를 설정하고, 각 delegate 액션으로 다음 상태를 생성하거나 전환합니다.

온보딩 화면과 앱 화면 분기

Layer / File(s) Summary
화면 렌더링과 프리뷰
Projects/DVPresentation/Sources/Features/AppView.swift, .../Onboarding/*, .../Lock/*
AppView가 상태별 화면을 선택하고, 컨테이너가 온보딩 또는 잠금 화면을 렌더링하도록 변경합니다. 단계 표시기와 잠금 화면 레이아웃도 조정합니다.

앱 셸 및 표시 리소스

Layer / File(s) Summary
공용 API·윈도우·리소스 설정
Projects/DVDesign/..., Projects/DVPresentation/Project.swift, Projects/DVPresentation/Resources/..., Projects/Devault/Sources/DevaultApp.swift
DVColor modifier를 공개하고 Lottie 의존성, 로컬라이즈 문자열, 윈도우 스타일과 기본 크기를 갱신합니다.

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

Sequence Diagram(s)

sequenceDiagram
  participant AppFeature
  participant OnboardingStatusClient
  participant OnboardingContainerFeature
  participant OnboardingFeature
  participant LockFeature
  AppFeature->>OnboardingStatusClient: hasCompleted()
  OnboardingStatusClient-->>AppFeature: 완료 여부 반환
  AppFeature->>OnboardingContainerFeature: 온보딩 상태 설정
  OnboardingContainerFeature->>OnboardingFeature: 단계 액션 전달
  OnboardingFeature-->>OnboardingContainerFeature: completed
  OnboardingContainerFeature->>LockFeature: 잠금 상태 생성
  LockFeature-->>OnboardingContainerFeature: unlockCompleted
  OnboardingContainerFeature-->>AppFeature: completed
  AppFeature->>OnboardingStatusClient: setCompleted()
Loading

Possibly related PRs

Suggested reviewers: yeseonglee

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning 온보딩 분기와 상태 의존성은 맞지만, Content/Detail/Sidebar/CreateSecret placeholder 연결과 Project alert는 빠졌습니다. MainFeature에 Content/Detail/Sidebar/CreateSecret 스코프와 alert placeholder를 추가하고, 각 뷰를 이슈에 맞는 임시 화면으로 맞춰주세요.
Out of Scope Changes check ⚠️ Warning SettingsRepository 계층, LockFeature, DVDesign 접근제어, 로컬라이즈 문자열 등 이슈 #45 범위를 넘는 변경이 다수 포함됐습니다. 이슈 범위에 맞춰 온보딩/메인 분기와 네비게이션 골격에 필요한 변경만 남기고, 기반 정리성 수정은 별도 PR로 분리하세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 온보딩/잠금 라우팅과 OnboardingStatusClient 구현이라는 핵심 변경을 잘 요약합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/#45

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.

@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: 2

🧹 Nitpick comments (3)
Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift (1)

15-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

스토어 접근 범위를 최소화하세요.

각 View는 init(store:)로만 Store를 주입받고 파일 내부에서만 사용하므로 @Bindable private var store로 제한하세요. MainView는 기존 호출 형태를 유지하도록 내부 init(store:)를 명시적으로 추가하면 됩니다.

  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift#L15-L15: public을 제거하고 private으로 제한하세요.

  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingContainerView.swift#L14-L14: public을 제거하고 private으로 제한하세요.

  • Projects/DVPresentation/Sources/Features/Lock/LockView.swift#L14-L14: public을 제거하고 private으로 제한하세요.

  • Projects/DVPresentation/Sources/Features/Main/MainView.swift#L14-L14: private으로 제한하고 필요한 init(store:)를 추가하세요.

    As per path instructions, "접근 제어가 가능한 가장 엄격한 수준인지 확인하세요."

🤖 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/Onboarding/OnboardingView.swift` at
line 15, 스토어 접근 범위를 각 View 파일 내부로 제한하세요.
Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift:15-15의
OnboardingView,
Projects/DVPresentation/Sources/Features/Onboarding/OnboardingContainerView.swift:14-14의
OnboardingContainerView,
Projects/DVPresentation/Sources/Features/Lock/LockView.swift:14-14의 LockView에서
`@Bindable` store의 public 접근 제어자를 private으로 변경하세요.
Projects/DVPresentation/Sources/Features/Main/MainView.swift:14-14의 MainView도
private으로 변경하고, 기존 init(store:) 호출 형태를 유지하도록 명시적인 내부 초기화를 추가하세요.

Source: Path instructions

Projects/Devault/Sources/Composition/Dependencies/OnboardingStatusClient+Live.swift (1)

3-6: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

모듈 import를 알파벳 순으로 정렬해 주세요.

DVData, DVDomain, DVPresentation 순으로 정리하면 파일 구성 규칙과 일치합니다.

수정 예시
 import ComposableArchitecture
-import DVPresentation
-import DVDomain
 import DVData
+import DVDomain
+import DVPresentation

As per path instructions, "모듈 임포트가 알파벳 순으로 정렬되어 있는지 확인하세요."

🤖 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/Devault/Sources/Composition/Dependencies/OnboardingStatusClient`+Live.swift
around lines 3 - 6, Sort the module imports at the top of
OnboardingStatusClient+Live.swift alphabetically, placing DVData, DVDomain, and
DVPresentation in that order while preserving the ComposableArchitecture import
according to the file’s import-ordering convention.

Source: Path instructions

Projects/DVPresentation/Sources/Features/Onboarding/OnboardingFeature.swift (1)

86-92: 🎯 Functional Correctness | 🔵 Trivial

실제 동기화 결과로 완료를 결정해 주세요.

현재는 3초 후 항상 완료 처리하므로 동기화 실패·취소 상황도 다음 단계로 진행됩니다. 목업 범위를 넘는 동작이라면 동기화 클라이언트의 성공 결과에서만 .syncingCompleted를 전송하고, 실패 시 재시도 상태를 제공해야 합니다. 원하시면 해당 의존성과 실패 상태까지 포함한 리듀서 구성을 제안하겠습니다.

🤖 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/Onboarding/OnboardingFeature.swift`
around lines 86 - 92, Update the .didTapEnableSync effect to use the actual
iCloud synchronization client result instead of clock.sleep and unconditional
.syncingCompleted. Send .syncingCompleted only after a successful sync, and
transition to the existing or newly added retry state on failure or
cancellation, including the required sync dependency in the reducer
configuration.
🤖 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/DVDesign/Sources/Foundations/Color/View`+DVColor.swift:
- Around line 14-16: Update the dvScreenBackground declaration to explicitly use
public access control, and ensure its containing extension uses the default
access level instead of public extension. Preserve the method signature and
implementation.

In `@Projects/DVPresentation/Sources/Features/AppFeature.swift`:
- Around line 16-19: AppFeature.State의 onboarding, locked, main 프로퍼티를 외부에서 변경할 수
없도록 필요한 accessor 수준으로 setter 접근을 제한하고, .task 재전송을 포함한 모든 route 전환 전에 세 상태를 모두
nil로 초기화한 뒤 대상 상태만 설정하세요. reducer 외부에서도 onboarding·locked·main 중 하나만 non-nil이라는
불변식이 유지되도록 기존 전환 흐름을 수정하세요.

---

Nitpick comments:
In
`@Projects/Devault/Sources/Composition/Dependencies/OnboardingStatusClient`+Live.swift:
- Around line 3-6: Sort the module imports at the top of
OnboardingStatusClient+Live.swift alphabetically, placing DVData, DVDomain, and
DVPresentation in that order while preserving the ComposableArchitecture import
according to the file’s import-ordering convention.

In `@Projects/DVPresentation/Sources/Features/Onboarding/OnboardingFeature.swift`:
- Around line 86-92: Update the .didTapEnableSync effect to use the actual
iCloud synchronization client result instead of clock.sleep and unconditional
.syncingCompleted. Send .syncingCompleted only after a successful sync, and
transition to the existing or newly added retry state on failure or
cancellation, including the required sync dependency in the reducer
configuration.

In `@Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift`:
- Line 15: 스토어 접근 범위를 각 View 파일 내부로 제한하세요.
Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift:15-15의
OnboardingView,
Projects/DVPresentation/Sources/Features/Onboarding/OnboardingContainerView.swift:14-14의
OnboardingContainerView,
Projects/DVPresentation/Sources/Features/Lock/LockView.swift:14-14의 LockView에서
`@Bindable` store의 public 접근 제어자를 private으로 변경하세요.
Projects/DVPresentation/Sources/Features/Main/MainView.swift:14-14의 MainView도
private으로 변경하고, 기존 init(store:) 호출 형태를 유지하도록 명시적인 내부 초기화를 추가하세요.
🪄 Autofix (Beta)

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: 599fd296-1603-416b-96ca-bd0f217b7670

📥 Commits

Reviewing files that changed from the base of the PR and between 8aa24c2 and 11fe82d.

📒 Files selected for processing (28)
  • .gitignore
  • Projects/DVData/Sources/RepositoryImpl/Settings/SettingsRepositoryImpl.swift
  • Projects/DVData/Sources/RepositoryImpl/Settings/UserDefaultsKey.swift
  • Projects/DVDesign/Resources/progress.lottie
  • Projects/DVDesign/Sources/Components/DVButton.swift
  • Projects/DVDesign/Sources/Components/DVCategory.swift
  • Projects/DVDesign/Sources/Components/DVStepIndicator.swift
  • Projects/DVDesign/Sources/Foundations/Color/View+DVColor.swift
  • Projects/DVDomain/Sources/Repository/Interface/SettingsRepository.swift
  • Projects/DVDomain/Sources/UseCase/Impl/Settings/OnboardingStatusUseCaseImpl.swift
  • Projects/DVDomain/Sources/UseCase/Interface/Settings/OnboardingStatusUseCase.swift
  • Projects/DVPresentation/Project.swift
  • Projects/DVPresentation/Sources/Dependencies/OnboardingStatusClient.swift
  • Projects/DVPresentation/Sources/Features/AppFeature.swift
  • Projects/DVPresentation/Sources/Features/AppView.swift
  • Projects/DVPresentation/Sources/Features/Lock/LockFeature.swift
  • Projects/DVPresentation/Sources/Features/Lock/LockView.swift
  • Projects/DVPresentation/Sources/Features/Main/MainView.swift
  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingContainerFeature.swift
  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingContainerView.swift
  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingFeature.swift
  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift
  • Projects/DVPresentation/Sources/Features/Sidebar/SidebarFeature.swift
  • Projects/DVPresentation/Sources/Features/Sidebar/SidebarView.swift
  • Projects/Devault/Sources/Composition/Dependencies/OnboardingStatusClient+Live.swift
  • Projects/Devault/Sources/DevaultApp.swift
  • Tuist/Package.swift
  • Tuist/ProjectDescriptionHelpers/TargetDependency+External.swift

Comment thread Projects/DVDesign/Sources/Foundations/Color/View+DVColor.swift Outdated
Comment thread Projects/DVPresentation/Sources/Features/AppFeature.swift Outdated
@doyeonk429

Copy link
Copy Markdown
Contributor

⚠️ Warning (개선 권장)

  • OnboardingStatusClient 클로저에 @sendable 누락 (OnboardingStatusClient.swift:11-12)
    public var hasCompleted: () -> Bool = { false }
    public var setCompleted: () -> Void
  • TCA_GUIDELINES §6.4의 표준 예시(SecretClient)는 @sendable (_ id: UUID) async throws -> Secret? 형태. 스트릭트
    컨커런시 활성화 시 클라이언트가 Sendable을 만족하지 못해 경고 대상. @sendable 추가 권장.
  • onboardingStatus.setCompleted()가 Reducer 동기 본문에서 side effect (AppFeature.swift:69)
    @dependency 주입이라 테스트에서 대체 가능해 강한 위반은 아니지만, TCA 관용은 side effect를 .run { setCompleted() }로
    감싸는 쪽이다. UserDefaults 쓰기라 실무 리스크는 낮다.
  • public extension View (View+DVColor.swift:5-17) — CodeRabbit 이미 지적
    CODING_GUIDELINES §2 위반. 각 함수마다 public을 붙이는 형태로 변경.
  • 매직 넘버 3 (OnboardingContainerFeature.swift:30)
    DVStepIndicator(totalSteps: 4, currentStep: 3)와 함께 “마지막 스텝”을 의미한다. totalSteps가 바뀌면 두 파일 모두
    손대야 한다. 상수로 뽑거나 totalSteps - 1로 파생하는 편이 안전.

@doyeonk429

Copy link
Copy Markdown
Contributor

🚨 Critical (반드시 수정)

  • LockFeature.isPostOnboarding이 dead state (LockFeature.swift:16)
    세 곳에서 세팅되지만(AppFeature:60, OnboardingContainerFeature:21,62), LockView에서 한 번도 읽히지 않는다.
    Preview에서만 다른 값으로 인스턴스화될 뿐 실제 UI 분기 없음.
    • 원래 의도(온보딩 직후엔 다른 문구/버튼이었을 가능성?)를 살릴 게 아니면 필드를 제거하거나, 살릴 거라면 View
      분기(isPostOnboarding에 따른 문구·CTA 차이)를 붙여야 한다.
  • .task 재실행 시 라우트 불변식 깨짐 (AppFeature.swift:58-64) — CodeRabbit도 지적
    .task는 State를 nil로 초기화하지 않고 바로 새 서브페이지를 할당한다. 뷰 identity가 재구성되어 .task가 다시 발화하는
    상황(윈도우 재오픈, 스킴 라우팅 등)에서 main이 지워지지 않은 채 locked가 추가로 세팅될 수 있다. AppView의 if let ...
    else if let ... 우선순위 덕에 눈에는 안 띄지만, invariant(“항상 하나만 non-nil”)는 깨진다.
    case .task:
    state.onboarding = nil
    state.locked = nil
    state.main = nil // 명시적 리셋
    if onboardingStatus.hasCompleted() { ... }
  • 더불어 public internal(set) var는 외부에서 nil 어사인이 가능한 채로 남아 있다. public private(set) var로 좁혀
    reducer 밖에서 절대 못 바꾸게 하는 편이 안전. 굳이 public 유지가 필요 없다면 internal(set) 대신 그냥 internal로
    낮춰도 된다.

@doyeonk429 doyeonk429 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

코멘트 달았으니 선택적으로 반영 부탁

dlguszoo added 2 commits July 25, 2026 11:24
1.  hasCompleted, setCompleted 클로저에 @sendable 추가
2. setCompleted() → .run { _ in onboardingStatus.setCompleted() }
3. Step: CaseIterable 추가, 3 → Step.allCases.count - 1, 4 → Step.allCases.count
4. isPostOnboarding 제거 — DVStepIndicator 표시는 뷰 계층으로 결정
5. public internal(set) → var (internal)
@dlguszoo

Copy link
Copy Markdown
Contributor Author

코멘트 달았으니 선택적으로 반영 부탁

모두 반영 완료했습니다!

@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: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Projects/DVPresentation/Sources/Features/Lock/LockFeature.swift (1)

45-46: 🔒 Security & Privacy | 🔴 Critical | 🏗️ Heavy lift

인증 성공 전에는 잠금 해제 delegate를 보내면 안 됩니다.

현재 버튼 탭만으로 .unlockCompleted를 보내며, 부모는 즉시 메인 화면으로 전환합니다. 생체 인증/시스템 인증이 성공한 경우에만 delegate를 전송하도록 인증 의존성을 연결하세요.

🤖 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/Lock/LockFeature.swift` around lines
45 - 46, Update the .didTapUnlock handling in LockFeature so it initiates the
configured biometric/system authentication instead of immediately sending
.delegate(.unlockCompleted). Send the unlockCompleted delegate only from the
authentication-success path, while preserving the locked state when
authentication fails or is cancelled.
🧹 Nitpick comments (2)
Projects/Devault/Sources/Composition/Dependencies/OnboardingStatusClient+Live.swift (1)

3-6: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

임포트 순서를 정렬해 주세요.

DVData, DVDomain, DVPresentation 순으로 정렬하면 됩니다. As per path instructions, "모듈 임포트가 알파벳 순으로 정렬되어 있는지 확인하세요."

🤖 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/Devault/Sources/Composition/Dependencies/OnboardingStatusClient`+Live.swift
around lines 3 - 6, 정렬 대상인 모듈 임포트를 알파벳 순서인 DVData, DVDomain, DVPresentation 순으로
재배치하고, ComposableArchitecture 임포트는 기존 위치를 유지하세요.

Source: Path instructions

Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift (1)

117-142: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

브랜드 아이콘/로고 뷰를 공용 View 파일로 추출해 주세요.

동일한 UI가 두 화면에 복제되어 변경 시 디자인이 쉽게 어긋납니다.

  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift#L117-L142: 로컬 appIconappIconWithLogoView를 공용 뷰로 교체하세요.
  • Projects/DVPresentation/Sources/Features/Lock/LockView.swift#L48-L59: 동일 공용 뷰를 사용하도록 교체하세요.

As per path instructions, "동일한 뷰가 2곳 이상 사용되거나, 독립적인 State/로직을 갖거나, 50줄 이상이면 별도 View 파일 분리를 제안하세요."

🤖 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/Onboarding/OnboardingView.swift`
around lines 117 - 142, Extract the duplicated brand icon/logo UI into a shared
View file, preserving the existing appIcon styling and DeVault logo typography.
In
Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift:117-142,
remove the local appIcon and appIconWithLogoView implementations and use the
shared view; in
Projects/DVPresentation/Sources/Features/Lock/LockView.swift:48-59, replace the
duplicate UI with the same shared view.

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/Resources/Localizable.xcstrings`:
- Around line 4-56: Localizable.xcstrings의 새 로컬라이즈 항목을 완성하세요. sourceLanguage가
en인 각 영문 키에 지원 로케일에 맞는 en 및 ko stringUnit을 추가하고, “목록을 불러오지 못했어요”와 “시크릿이 없어요”는
의도된 한국어 키인지 확인해 en 번역을 추가하거나 소스 언어 키에서 제거하세요.

---

Outside diff comments:
In `@Projects/DVPresentation/Sources/Features/Lock/LockFeature.swift`:
- Around line 45-46: Update the .didTapUnlock handling in LockFeature so it
initiates the configured biometric/system authentication instead of immediately
sending .delegate(.unlockCompleted). Send the unlockCompleted delegate only from
the authentication-success path, while preserving the locked state when
authentication fails or is cancelled.

---

Nitpick comments:
In
`@Projects/Devault/Sources/Composition/Dependencies/OnboardingStatusClient`+Live.swift:
- Around line 3-6: 정렬 대상인 모듈 임포트를 알파벳 순서인 DVData, DVDomain, DVPresentation 순으로
재배치하고, ComposableArchitecture 임포트는 기존 위치를 유지하세요.

In `@Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift`:
- Around line 117-142: Extract the duplicated brand icon/logo UI into a shared
View file, preserving the existing appIcon styling and DeVault logo typography.
In
Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift:117-142,
remove the local appIcon and appIconWithLogoView implementations and use the
shared view; in
Projects/DVPresentation/Sources/Features/Lock/LockView.swift:48-59, replace the
duplicate UI with the same shared view.
🪄 Autofix (Beta)

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: 7649378e-3cbf-41ee-a595-7cd20999f966

📥 Commits

Reviewing files that changed from the base of the PR and between ebc4a44 and a977613.

📒 Files selected for processing (19)
  • Projects/DVData/Sources/RepositoryImpl/Settings/SettingsRepositoryImpl.swift
  • Projects/DVData/Sources/RepositoryImpl/Settings/UserDefaultsKey.swift
  • Projects/DVDesign/Sources/Foundations/Color/View+DVColor.swift
  • Projects/DVDomain/Sources/Repository/Interface/SettingsRepository.swift
  • Projects/DVDomain/Sources/UseCase/Impl/Settings/OnboardingStatusUseCaseImpl.swift
  • Projects/DVDomain/Sources/UseCase/Interface/Settings/OnboardingStatusUseCase.swift
  • Projects/DVPresentation/Project.swift
  • Projects/DVPresentation/Resources/Localizable.xcstrings
  • Projects/DVPresentation/Sources/Dependencies/OnboardingStatusClient.swift
  • Projects/DVPresentation/Sources/Features/AppFeature.swift
  • Projects/DVPresentation/Sources/Features/AppView.swift
  • Projects/DVPresentation/Sources/Features/Lock/LockFeature.swift
  • Projects/DVPresentation/Sources/Features/Lock/LockView.swift
  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingContainerFeature.swift
  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingContainerView.swift
  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingFeature.swift
  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingView.swift
  • Projects/Devault/Sources/Composition/Dependencies/OnboardingStatusClient+Live.swift
  • Projects/Devault/Sources/DevaultApp.swift
🚧 Files skipped from review as they are similar to previous changes (8)
  • Projects/DVDomain/Sources/Repository/Interface/SettingsRepository.swift
  • Projects/DVDomain/Sources/UseCase/Interface/Settings/OnboardingStatusUseCase.swift
  • Projects/Devault/Sources/DevaultApp.swift
  • Projects/DVData/Sources/RepositoryImpl/Settings/SettingsRepositoryImpl.swift
  • Projects/DVPresentation/Sources/Features/AppView.swift
  • Projects/DVPresentation/Sources/Dependencies/OnboardingStatusClient.swift
  • Projects/DVPresentation/Sources/Features/Onboarding/OnboardingFeature.swift
  • Projects/DVPresentation/Sources/Features/AppFeature.swift

Comment on lines +4 to +56
"Access your secrets on all your\nApple devices, securely encrypted." : {

},
"Content" : {
"comment" : "The title of the main content section in the preview.",
"isCommentAutoGenerated" : true
},
"Create Project" : {

},
"De" : {

},
"Detail" : {

},
"Development" : {
"If Touch ID is unavailable,\nsystem password will be used" : {

},
"Enterprise" : {
"LOGO" : {

},
"Failed to load projects" : {
"No expire" : {

},
"Individual" : {
"Placeholder row %@" : {

},
"Production" : {
"Project" : {

},
"Staging" : {
"Project Name" : {

},
"Team" : {
"Save" : {

},
"Sidebar" : {
"comment" : "The text that appears in the sidebar of the main view.",
"isCommentAutoGenerated" : true
"Select Project" : {

},
"SSL Required" : {

},
"This may take a moment..." : {

},
"Vault" : {

},
"목록을 불러오지 못했어요" : {

},
"The project list couldn't be loaded. Please try again later." : {
"시크릿이 없어요" : {

@coderabbitai coderabbitai Bot Jul 25, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file excerpt =="
if [ -f Projects/DVPresentation/Resources/Localizable.xcstrings ]; then
  sed -n '1,90p' Projects/DVPresentation/Resources/Localizable.xcstrings
else
  echo "file not found"
fi

echo
echo "== xcstrings files =="
git ls-files '*xcstrings' || true

echo
echo "== localization metadata search =="
rg -n '"sourceLanguage"|"localizations"|"KO"|"ko"|"en"' -g '*xcstrings' . || true

echo
echo "== localizable key usages =="
rg -n '"목록을 불러오지 못했어요"|"시크릿이 없어요"|"Access your secrets on all your|App Store Review|Content"|"Create Project"|"No expire"|"Placeholder row"|"This may take a moment"|LOGO|Project Name|SSL Required' .

Repository: DevaultProject/Devault-macOS

Length of output: 3662


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json, pathlib
p = pathlib.Path("Projects/DVPresentation/Resources/Localizable.xcstrings")
if not p.exists():
    print("missing")
    raise SystemExit
data = json.loads(p.read_text())
print("sourceLanguage:", data.get("sourceLanguage"))
for key, obj in data.get("strings", {}).items():
    if key in [
        "Access your secrets on all your\nApple devices, securely encrypted.",
        "Content",
        "Create Project",
        "De",
        "Detail",
        "If Touch ID is unavailable,\nsystem password will be used",
        "LOGO",
        "No expire",
        "Placeholder row %@",
        "Project",
        "Project Name",
        "Save",
        "Select Project",
        "SSL Required",
        "This may take a moment...",
        "Vault",
        "목록을 불러오지 못했어요",
        "시크릿이 없어요",
    ]:
        local = obj.get("localizations", {})
        print(key)
        for locale, lodata in local.items():
            print(" ", locale, lodata.get("stringUnit", {}))
PY

Repository: DevaultProject/Devault-macOS

Length of output: 485


로컬라이즈 단위를 채워 주세요.

sourceLanguageen인데 새 영문 키에는 ko 번역이 없고, 목록을 불러오지 못했어요/시크릭이 없어요en 번역 없이 한국어가 소스 키로 남아 있습니다. Localizable.xcstrings가 앱 로케일용인지 확인하고, 지원 대상 로케일에는 en/ko stringUnit을 추가하거나 의도하지 않은 소스 언어 키는 제거해 주세요.

🤖 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/Resources/Localizable.xcstrings` around lines 4 - 56,
Localizable.xcstrings의 새 로컬라이즈 항목을 완성하세요. sourceLanguage가 en인 각 영문 키에 지원 로케일에 맞는
en 및 ko stringUnit을 추가하고, “목록을 불러오지 못했어요”와 “시크릿이 없어요”는 의도된 한국어 키인지 확인해 en 번역을
추가하거나 소스 언어 키에서 제거하세요.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

client 구현과 함께 다음 이슈에서 처리할 예정

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@dlguszoo 알겠습니다. 이번 PR 범위에서는 보류하고, 클라이언트 구현 이슈에서 Localizable.xcstringsen/ko stringUnit과 소스 키 언어를 함께 정리하면 됩니다.

원하시면 해당 후속 GitHub 이슈를 생성해 드릴까요?

@dlguszoo
dlguszoo requested a review from doyeonk429 July 25, 2026 02:51
@dlguszoo
dlguszoo merged commit f2ee18c into develop Jul 25, 2026
1 check passed
@dlguszoo
dlguszoo deleted the feature/#45 branch July 25, 2026 02: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: Navigation 패턴 구현 및 온보딩 분기 처리

2 participants