Skip to content

[Feat] 서버 선택 기능의 로컬 우선 저장 기반 구현 - #95

Draft
MinHeokChoi wants to merge 1 commit into
feat/#92-account-lifecyclefrom
feat/#94-server-preference-foundation
Draft

[Feat] 서버 선택 기능의 로컬 우선 저장 기반 구현#95
MinHeokChoi wants to merge 1 commit into
feat/#92-account-lifecyclefrom
feat/#94-server-preference-foundation

Conversation

@MinHeokChoi

@MinHeokChoi MinHeokChoi commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

✨ PR 유형

어떤 변경 사항이 있나요??

  • 새로운 기능 추가
  • 버그 수정
  • 사용자 UI 디자인 변경 및 추가
  • 코드에 영향을 주지 않는 변경사항(오타 수정, 탭 사이즈 변경, 변수명 변경)
  • 코드 리팩토링
  • 주석 추가 및 수정
  • 문서 수정
  • 테스트 추가, 테스트 리팩토링
  • 빌드 부분 혹은 패키지 매니저 수정
  • 파일 혹은 폴더명 수정
  • 파일 혹은 폴더 삭제

🛠️ 작업내용

  • MoruSchemaV4와 명시적인 V3 → V4 lightweight migration stage를 추가했습니다.
  • 계정별 PersistedServerMutation, PersistedVoiceCatalogEntry와 SwiftData
    repository를 추가했습니다.
  • Outbox는 typed idempotent operation만 받고 account·operation key로 최신 값을
    coalescing합니다. 실행 중 새 값이 coalesce되어도 이전 응답이 새 mutation을
    삭제하거나 backoff하지 않도록 idempotency generation을 검증합니다.
  • transport, 408, 429, 5xx만 retryable로 분류하고 30초에서 최대 6시간까지
    exponential backoff합니다. 실패 mutation은 자동 폐기하지 않습니다.
  • app active, login success, manual retry만 SyncCoordinator trigger로 연결했습니다.
    P6에는 실제 서버 Target이 없으므로 runtime executor는 queue를 변경하지 않고
    deferred합니다.
  • P5 AccountScopedDataCleaning을 해당 계정 Outbox와 voice cache 삭제에 연결했습니다.
    다른 계정과 LocalProfile, Routine, AlarmSchedule, RoutineRun, snapshot, platform
    state는 유지합니다.
  • Routine/Run mapper, localOnly, hard delete 계약은 변경하지 않았습니다.

검증:

  • P6 관련 XCTest: 13 passed, 0 failed
  • 전체 XCTest: 364 passed, 0 failed, 0 skipped
  • 실제 V3 disk fixture → V4 migration, V4 저장과 재실행: 통과
  • Routine, AlarmSchedule, RoutineRun, step snapshot, weather, alarm platform/snooze
    state 보존: 통과
  • duplicate, corrupt, unknown raw value, 다른 계정 보존, stale coalescing completion:
    통과
  • iPhone 16 Simulator Debug build: 성공
  • generic iPhone Debug build: 성공
  • generic iPhone Release build: 성공
  • iPhone functional gate: 통과
  • exact V4 SwiftData boundary gate: 통과
  • Info.plist plutil: 통과
  • git diff --check: 통과

📋 추후 진행 상황

  • P7에서 실제 GET /tts, PATCH /members/me/tts Target과 executor, 음성 선택 UI를
    구현합니다.
  • 실제 서버 전송, airplane mode/timeout/5xx E2E와 실제 iPhone 재실행은 P7 이후 기기
    QA로 남깁니다.

📌 리뷰 포인트

  • V4가 정확히 V3 + Outbox/voice cache 두 모델인지 확인해 주세요.
  • retryable 분류와 30초~6시간 backoff, 자동 폐기 금지가 유지되는지 확인해 주세요.
  • 동일 account·operation key의 in-flight stale 응답이 최신 mutation을 손상하지 않는지
    확인해 주세요.
  • 회원 탈퇴 cleanup이 대상 계정 cache만 제거하고 기존 로컬 데이터와 다른 계정을
    보존하는지 확인해 주세요.
  • Routine/Run mapper와 localOnly/hard-delete 계약이 변경되지 않았는지 확인해 주세요.

✅ Checklist

PR이 다음 요구 사항을 충족하는지 확인해주세요!!!

  • 커밋 메시지 컨벤션에 맞게 작성했습니다
  • 유지-보수를 위해 필요한 계약 주석을 작성했습니다

Closes #94

DO NOT MERGE — v2 stacked PR 일괄 검토 대기

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8713bc06-0834-4768-99f2-5dd68f6d850a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#94-server-preference-foundation

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.

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