Skip to content

루틴 스케줄 실패 저장 원자성 보정#231

Merged
gaeng2y merged 1 commit into
developfrom
feature/#220-atomic
May 22, 2026
Merged

루틴 스케줄 실패 저장 원자성 보정#231
gaeng2y merged 1 commit into
developfrom
feature/#220-atomic

Conversation

@gaeng2y

@gaeng2y gaeng2y commented May 22, 2026

Copy link
Copy Markdown
Owner

📝 Summary

루틴 저장/수정/삭제 중 AlarmKit 스케줄 재구성이 실패했을 때 저장소와 실제 알림 상태가 다른 성공 상태로 남지 않도록 원자성을 보정했습니다.

🎯 Type of Change

  • ✨ New feature (새로운 기능 추가)
  • 🐛 Bug fix (버그 수정)
  • 🔧 Configuration (설정 변경)
  • ♻️ Refactoring (코드 리팩토링)
  • 📝 Documentation (문서 수정)
  • 🎨 UI/UX (디자인 변경)
  • ⚡ Performance (성능 개선)
  • 🛡️ Security (보안 강화)
  • 🧪 Test (테스트 추가/수정)
  • 🔨 Build (빌드 시스템 수정)

🔗 Related Issues

📋 Changes Made

Added

  • RoutineError.scheduleFailed를 추가해 스케줄 실패를 권한 실패와 분리했습니다.
  • 스케줄 실패 prompt에 다시 시도 및 알림 없이 저장 CTA를 추가했습니다.
  • Repository/ViewModel 테스트에 스케줄 실패와 알림 없이 저장 복구 흐름을 추가했습니다.

Changed

  • RoutineRepositoryImpl이 후보 스케줄 재구성 성공 후에만 UserDefaults 루틴 저장소를 커밋하도록 변경했습니다.
  • 저장/수정/삭제 스케줄 실패 시 이전 활성 루틴 스케줄 복구를 시도하도록 변경했습니다.
  • 루틴 알림 원자성 정책을 Docs/reliability-recovery.mdDocs/product-specs/routine-notifications.md에 반영했습니다.

Fixed

  • AlarmKit 스케줄 실패 후 활성 루틴이 실제 예약된 것처럼 저장/표시될 수 있는 불일치 가능성을 수정했습니다.
  • 삭제/수정 흐름에서도 스케줄 실패 시 저장소가 먼저 바뀌지 않도록 보정했습니다.

Removed

  • 없음

🔍 Technical Details

  • 저장소 커밋 순서를 scheduleNotifications -> saveRoutines로 바꿔 새 활성 루틴이 스케줄 성공 없이 저장되지 않게 했습니다.
  • 스케줄 실패를 catch하면 이전 저장 상태의 활성 루틴 목록으로 AlarmKit 재구성을 한 번 best-effort로 시도하고 RoutineError.scheduleFailed를 throw합니다.
  • Presentation은 scheduleFailure prompt를 통해 에디터를 유지하고 사용자가 재시도하거나 비활성 루틴으로 저장할 수 있게 합니다.

📸 Screenshots / Videos

Before

첨부 없음

After

첨부 없음

✅ Testing

Test Plan

  • 앱 빌드 성공
  • 기존 기능 영향 없음
  • Debug 모드 정상 작동
  • Release 모드 정상 작동
  • Widget Extension 정상 작동 (해당시)

Test Environment

  • iOS Version: iOS Simulator 26.5
  • Device: iPhone 17 Pro Simulator (125B9A31-6A4A-466D-A8AB-410730B22446)
  • Xcode Version: local xcodebuild

Test Results

  • make lint 통과
  • make arch-check 통과
  • xcodebuild test -workspace Mulimi.xcworkspace -scheme DataLayer -destination 'platform=iOS Simulator,id=125B9A31-6A4A-466D-A8AB-410730B22446' -sdk iphonesimulator -derivedDataPath /tmp/MulimiDataLayerTest -quiet 통과
  • xcodebuild test -workspace Mulimi.xcworkspace -scheme PresentationLayer -destination 'platform=iOS Simulator,id=125B9A31-6A4A-466D-A8AB-410730B22446' -sdk iphonesimulator -derivedDataPath /tmp/MulimiPresentationLayerTest -quiet 통과
  • xcodebuild build -workspace Mulimi.xcworkspace -scheme Mulimi -destination 'generic/platform=iOS' CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO -quiet 통과

참고: iPhone 16 Pro, OS=latest destination은 로컬에 없어 iPhone 17 Pro, iOS 26.5 시뮬레이터로 재실행했습니다.

🚨 Breaking Changes

  • Yes (아래에 설명)
  • No

📌 Additional Notes

  • PR은 우선 draft로 생성했습니다.
  • AlarmKit rollback 재구성은 실패해도 원래 스케줄 실패를 사용자에게 안내하고 저장소 커밋은 중단합니다.

👀 Review Checklist

  • 코드가 프로젝트의 코딩 컨벤션을 따르고 있나요?
  • 새로운 의존성이 필요한가요? 없음
  • 문서 업데이트가 필요한가요? 반영 완료
  • 데이터베이스 마이그레이션이 필요한가요? 없음
  • 환경 설정 변경이 필요한가요? 없음

@gaeng2y gaeng2y marked this pull request as ready for review May 22, 2026 12:32
@gaeng2y gaeng2y merged commit f96f95f into develop May 22, 2026
2 checks passed
@gaeng2y gaeng2y deleted the feature/#220-atomic branch May 22, 2026 12:33
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