# 20260327 콘텐츠 설정 PATCH 변경 필드 옵셔널 전송 ## 개요 - `userApi.updateContentPreference` 요청 시 `contentType`, `isAdultContentVisible`를 항상 같이 보내지 않고, 실제 변경된 필드만 PATCH payload에 포함되도록 수정한다. - 요청 모델을 optional 파라미터로 변경하고, 기존 UI/동기화 동작은 유지한다. ## 요구사항 요약 - 대상 API: `PATCH /member/content-preference` - 변경 사항: - 요청 DTO의 `contentType`, `isAdultContentVisible`를 optional로 전환 - 토글 변경 시에는 `isAdultContentVisible`만 전송 - 콘텐츠 타입 변경 시에는 `contentType`만 전송 ## 완료 기준 (Acceptance Criteria) - [x] AC1: `UpdateContentPreferenceRequest`가 optional 필드를 사용한다. - [x] AC2: 토글 변경 요청 payload에 `isAdultContentVisible`만 포함된다. - [x] AC3: 콘텐츠 타입 변경 요청 payload에 `contentType`만 포함된다. - [x] AC4: 기존 debounce/로딩/에러 처리 흐름이 유지된다. - [x] AC5: 빌드/진단 검증 결과가 문서에 기록된다. ## 구현 체크리스트 - [x] `UpdateContentPreferenceRequest` optional 필드 전환 - [x] `ContentSettingsViewModel` 요청 생성 로직을 변경 필드 기반으로 분기 - [x] `UserApi`/`UserRepository` 호출부 영향 점검 - [x] 수정 파일 진단 및 워크스페이스 빌드/테스트 실행 - [x] 검증 결과 문서화 ## 검증 계획 - [x] 정적 진단: - `lsp_diagnostics("SodaLive/Sources/Settings/Content/UpdateContentPreferenceRequest.swift")` - `lsp_diagnostics("SodaLive/Sources/Settings/Content/ContentSettingsViewModel.swift")` - [x] 빌드: - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` - [x] 테스트 시도: - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test` - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test` ## 검증 기록 - 일시: 2026-03-27 - 무엇: 콘텐츠 설정 PATCH 변경 필드 옵셔널 전송 작업 계획 문서 작성 - 왜: 구현 범위와 검증 절차를 선행 고정하여 요청사항을 정확히 반영하기 위함 - 어떻게: 기존 docs 포맷 기준으로 완료 기준/체크리스트/검증 계획 수립 - 실행 명령/도구: `apply_patch(문서 생성)` - 결과: 구현 계획 문서 생성 완료 - 일시: 2026-03-27 - 무엇: `updateContentPreference`를 변경 필드만 전송하도록 optional request + diff 기반 전송 로직 적용 - 왜: PATCH 호출 시 `contentType`/`isAdultContentVisible`를 항상 함께 보내지 않고 실제 변경 필드만 서버에 전달하기 위함 - 어떻게: - `UpdateContentPreferenceRequest`를 `Bool?`/`ContentType?`로 변경하고 `isEmpty` 계산 프로퍼티 추가 - `ContentSettingsViewModel`에 `lastSyncedState`를 추가해 이전 동기화 상태 대비 변경 필드를 계산 - `makeUpdateContentPreferenceRequest(from:to:)`에서 변경된 값만 request에 채우고, 빈 요청은 API 호출 생략 - 서버 성공 응답 시 `applyServerState`에서 `lastSyncedState`를 갱신해 후속 diff 기준 일관성 유지 - search-mode 준수를 위해 explore 에이전트 2개 병렬 실행으로 호출 흐름/optional 패턴 교차 확인 - 실행 명령/도구: - Background agents: - `task(subagent_type="explore", description="Trace content-preference flow")` - `task(subagent_type="explore", description="Find optional PATCH patterns")` - 코드/진단: - `lsp_diagnostics("SodaLive/Sources/Settings/Content/UpdateContentPreferenceRequest.swift")` - `lsp_diagnostics("SodaLive/Sources/Settings/Content/ContentSettingsViewModel.swift")` - 빌드/테스트: - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test` - `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test` - 결과: - `SodaLive`/`SodaLive-dev` Debug 빌드 모두 `BUILD SUCCEEDED` - 테스트는 두 스킴 모두 `Scheme ... is not currently configured for the test action`으로 실행 불가(테스트 액션 미구성) - `lsp_diagnostics`는 SourceKit 모듈 해석 한계로 다수 에러를 반환했으나, 실제 xcodebuild 통과로 컴파일 정상 확인 - 코드상으로 토글 변경 시 `isAdultContentVisible`만, 타입 변경 시 `contentType`만 request에 포함되도록 반영 완료