Skip to content

[Fix-T3-207] 루틴 삭제하기 기능 QA 이슈 수정 #80

Merged
choijungp merged 4 commits intodevelopfrom
fix/delete-routine
Feb 6, 2026
Merged

[Fix-T3-207] 루틴 삭제하기 기능 QA 이슈 수정 #80
choijungp merged 4 commits intodevelopfrom
fix/delete-routine

Conversation

@choijungp
Copy link
Contributor

@choijungp choijungp commented Feb 6, 2026

🌁 Background

루틴 삭제하기 기능 관련 QA 대응했어용 ~~

📱 Screenshot

1. 당일 루틴 삭제 후 토스트 메시지 확인

당일 루틴 삭제
당일 루틴 삭제
  • 당일 루틴 (반복 x) 삭제 시, 바로 삭제에 관련한 확인 창 뜸
  • 삭제 완료 시, 해당 루틴은 삭제되고 토스트 메시지 뷰가 표시됨

2. 반복 루틴 삭제 후 토스트 메시지 · 루틴 상태 확인

반복 루틴 삭제
Simulator Screen Recording - iPhone 16 Pro - 2026-02-06 at 17 47 56
  • 기존 2월 2일 ~ 2월 13일까지 월, 수, 금 반복 설정된 루틴이 존재함
  • 이때 6일에서 루틴을 반복 삭제할 경우, 그 이후 루틴들(2월 9일 ~ 2월 13일)은 바로 삭제되고 이전 루틴들은 수정 버튼이 사라짐
  • 기존에 남아있는 루틴(2월 2일 ~ 2월 6일)을 다시 삭제할 경우 반복 루틴이 아닌 당일 루틴으로 인식되고 루틴을 삭제할 수 있음
  • 토스트 메시지도 잘 표시됨

👩‍💻 Contents

  • ToastView show 함수 확장 (추후 루틴 수정 토스트 메시지 대비)
  • 루틴 삭제 후 토스트 메시지 띄우기
  • 삭제된 루틴에 대하여 수정 버튼 없애기
  • 삭제된 루틴에 대하여 반복 루틴 삭제 기능 막기

📣 Related Issue

  • close #T3-207

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 루틴 삭제 시 사용자에게 확인 메시지를 표시하는 토스트 UI 추가
    • 토스트 메시지 내용 동적 업데이트 기능 지원
  • 개선 사항

    • 삭제된 루틴에 대해 편집 버튼을 숨기는 처리 추가
    • 루틴 목록 조회 시마다 기존 캐시 데이터 초기화

@choijungp choijungp self-assigned this Feb 6, 2026
@coderabbitai
Copy link

coderabbitai bot commented Feb 6, 2026

개요

편집 버튼이 삭제되지 않은 루틴에만 조건부로 표시되도록 수정되었으며, ToastView가 선택적 메시지 매개변수를 수용하도록 개선되었습니다. 삭제된 루틴 토스트 알림 기능을 지원하기 위해 프로토콜에 isDeleted 속성이 추가되었고, 뷰 컨트롤러가 알림 구독을 통해 토스트 메시지를 표시합니다.

변경 사항

응집 단위 / 파일 요약
루틴 카드 UI
Projects/Presentation/Sources/Common/Component/RoutineCardView.swift
편집 버튼이 routine.isDeleted가 false일 때만 뷰 계층에 추가 및 레이아웃되도록 조건부 처리 추가
토스트 메시지 기능
Projects/Presentation/Sources/Common/Component/ToastView.swift
메시지 속성을 가변으로 변경하고, showToastMessageView 메서드가 선택적 메시지 매개변수를 받아 런타임에 메시지 업데이트 가능
알림 및 프로토콜 확장
Projects/Presentation/Sources/Common/Extension/Notification+.swift, Projects/Presentation/Sources/Common/Protocol/RoutineProtocol.swift
삭제된 루틴 토스트 표시를 위한 showDeletedRoutineToast 알림 상수와 RoutineProtocol에 isDeleted 속성 추가
루틴 모델
Projects/Presentation/Sources/Onboarding/Model/RecommendedRoutine.swift
RecommendedRoutine 구조체에 isDeleted 속성 추가 (기본값: false)
루틴 목록 뷰
Projects/Presentation/Sources/RoutineList/View/RoutineListViewController.swift
토스트 뷰 UI 추가, showDeletedRoutineToast 알림 구독 구현, 삭제 조건 확장
루틴 목록 뷰 모델
Projects/Presentation/Sources/RoutineList/ViewModel/RoutineListViewModel.swift
fetchRoutines에서 캐시 초기화, deleteRoutine 후 토스트 알림 발송, showDeletedRoutineToastMessageView 헬퍼 함수 추가

시퀀스 다이어그램

sequenceDiagram
    participant User
    participant RoutineListVC as RoutineListViewController
    participant RoutineListVM as RoutineListViewModel
    participant NotificationCenter
    participant ToastView

    User->>RoutineListVC: 루틴 삭제 작동
    RoutineListVC->>RoutineListVM: deleteRoutine 호출
    RoutineListVM->>RoutineListVM: 루틴 삭제 실행
    RoutineListVM->>RoutineListVM: showDeletedRoutineToastMessageView 호출
    RoutineListVM->>RoutineListVM: 0.6초 지연
    RoutineListVM->>NotificationCenter: .showDeletedRoutineToast 발송
    NotificationCenter->>RoutineListVC: 알림 수신
    RoutineListVC->>ToastView: showToastMessageView(message) 호출
    ToastView->>User: 삭제 완료 토스트 메시지 표시
Loading

코드 리뷰 예상 소요 시간

🎯 3 (보통) | ⏱️ ~20분

🐰 루틴 삭제되면 토스트로 알려주고,
편집 버튼은 조건부로 숨기네요.
메시지는 이제 유연하게,
프로토콜도 함께 성장하고,
알림으로 연결된 컴포넌트들이
부드럽게 춤을 춥니다! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
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 PR 제목이 변경사항의 주요 내용을 명확하게 설명합니다. 루틴 삭제 기능의 QA 이슈 수정이라는 핵심 목적을 잘 나타냅니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/delete-routine

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
Projects/Presentation/Sources/RoutineList/ViewModel/RoutineListViewModel.swift (1)

76-82: ⚠️ Potential issue | 🟡 Minor

routines.removeAll()로 인한 일시적 빈 상태 가능성.

removeAll()과 루프 완료 사이에 사용자가 날짜를 선택하면 fetchDailyRoutine()이 빈 딕셔너리를 읽어 빈 화면이 잠깐 표시될 수 있습니다. routines 딕셔너리에 대한 접근이 Task (백그라운드)와 메인 스레드에서 동시에 발생할 수 있는 점도 참고해 주세요. 현재 PR에서 새로 도입된 패턴은 아니지만 removeAll() 추가로 경합 윈도우가 넓어졌습니다.

🧹 Nitpick comments (4)
Projects/Presentation/Sources/Common/Component/ToastView.swift (1)

65-69: 기존 API를 깨지 않으면서 메시지 동적 업데이트를 지원하는 깔끔한 확장입니다.

한 가지 참고: self.message 프로퍼티는 configureAttribute() 이후에는 다시 읽히지 않으므로, Line 67의 self.message = message 할당은 현재로선 불필요합니다. messageLabel.text만 업데이트하면 충분합니다. 다만 향후 확장을 위한 방어적 코딩으로 보면 괜찮습니다.

Projects/Presentation/Sources/RoutineList/ViewModel/RoutineListViewModel.swift (1)

121-123: 토스트 표시 타이밍이 데이터 갱신과 분리되어 있습니다.

fetchRoutines()는 내부적으로 새로운 Task를 생성하므로 비동기로 실행됩니다. showDeletedRoutineToastMessageView()는 fetch 완료를 기다리지 않고 바로 호출되며, 내부의 0.6초 딜레이는 네트워크 속도에 따라 불안정합니다. 네트워크가 느리면 토스트가 먼저 표시되고 이전 데이터가 아직 화면에 남아있을 수 있습니다.

fetchRoutinesResultSubjecttrue를 emit한 후에 토스트를 표시하는 것이 더 안정적입니다.

♻️ 제안: fetch 완료 후 토스트 표시

ViewModel에서 삭제 성공 시 별도 플래그를 설정하고, fetchRoutinesResultPublisher 구독 쪽에서 토스트를 트리거하는 방식을 고려해보세요:

     private func deleteRoutine(isDeleteAllRoutines: Bool) {
         guard let routineId = selectedRoutine.value?.id else {
             deleteRoutineResultSubject.send(false)
             return
         }
 
         Task {
             do {
                 if isDeleteAllRoutines {
                     try await routineRepository.deleteAllRoutine(routineId: routineId)
                 } else {
                     try await routineRepository.deleteDailyRoutine(routineId: routineId)
                 }
                 deleteRoutineResultSubject.send(true)
+                shouldShowDeleteToast = true
                 fetchRoutines()
-                showDeletedRoutineToastMessageView()
             } catch {
                 deleteRoutineResultSubject.send(false)
             }
         }
     }

그리고 fetchRoutinesResultPublisher 구독에서 플래그를 확인하여 토스트를 표시하면 fetch 완료와 정확히 동기화됩니다.

Projects/Presentation/Sources/RoutineList/View/RoutineListViewController.swift (2)

144-151: NotificationCenter 구독이 VC 인스턴스 범위를 넘어설 수 있습니다.

NotificationCenter는 글로벌 브로드캐스트이므로, 만약 네비게이션 스택에 RoutineListViewController가 여러 개 존재하게 되면 모든 인스턴스에서 토스트가 표시됩니다. 현재 앱 플로우에서는 문제없을 가능성이 높지만, ViewModel의 기존 Combine Output 패턴을 활용하면 더 안전합니다 (예: deleteRoutineResultPublisher 구독 시점에서 토스트 트리거). 이 부분은 ViewModel 쪽 리뷰 코멘트와도 연관됩니다.


32-33: 빈 문자열로 초기화된 ToastView 참고.

ToastView(message: "")로 초기화 후 실제 표시 시 showToastMessageView(message:)로 메시지를 전달하고 있어 동작에는 문제없습니다. deleteToastMessage를 초기화 시점에 바로 전달하면 코드 의도가 더 명확해질 수 있습니다.

♻️ 제안
-    private let deleteToastMessage: String = "삭제가 완료되었습니다."
-    private var toastMessageView = ToastView(message: "")
+    private var toastMessageView = ToastView(message: "삭제가 완료되었습니다.")

이 경우 notification handler에서 showToastMessageView()를 message 파라미터 없이 호출할 수 있습니다.

@choijungp choijungp merged commit 74bfa16 into develop Feb 6, 2026
2 checks passed
@choijungp choijungp deleted the fix/delete-routine branch February 6, 2026 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant