# 20260312 알림 리스트 구현 ## 작업 목표 - 홈 탭 벨 아이콘 진입으로 알림 리스트 화면을 구현한다. - 알림 카테고리/리스트 API를 연동하고 무한 스크롤을 구현한다. - 알림 아이템 deepLink 실행과 경로형 deepLink 파싱을 보완한다. ## 구현 체크리스트 - [x] 기존 UI/네비게이션/딥링크 처리 패턴 탐색 - [x] 알림 리스트 라우트(AppStep) 및 진입 경로(HomeTabView) 연결 - [x] 알림 카테고리/리스트 API 모델, TargetType, Repository 추가 - [x] 알림 리스트 ViewModel(카테고리/페이지네이션/상대시간/딥링크 처리) 구현 - [x] 알림 리스트 View(UI: Title bar, Category List, Item List) 구현 - [x] 경로형(`voiceon://live/333`) + 기존 쿼리형 deepLink 파싱/실행 보완 - [x] `voiceon://community`처럼 id 없는 community 경로의 fallback(로그인 userId) 처리 보완 - [x] 알림 카테고리 리스트에서 앱 주입 `전체` 제거, 서버 조회 카테고리만 사용하도록 수정 - [x] LSP 진단 및 빌드/테스트 검증 ## 검증 기록 - 무엇/왜/어떻게: `lsp_diagnostics`를 변경 파일 전부(`AppStep`, `ContentView`, `HomeTabView`, `AppState`, `SodaLiveApp`, `SplashView`, `Notification/List/*`)에 수행해 정적 진단을 확인했다. - 실행 명령: `lsp_diagnostics` (복수 파일) - 결과: SourceKit 컨텍스트에서 외부 모듈(`Bootpay`, `Kingfisher`, `Moya`, `CombineMoya`, `FirebaseRemoteConfig`) 및 참조 타입 인식 오류가 다수 발생해 단독 진단으로는 신뢰도가 낮았고, 실제 컴파일 유효성은 빌드로 검증했다. - 무엇/왜/어떻게: 새 알림 페이지/딥링크/라우팅 변경의 컴파일 무결성을 `SodaLive` 스킴에서 검증했다. - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` - 결과: `** BUILD SUCCEEDED **`. - 무엇/왜/어떻게: 동일 변경 사항의 dev 스킴 회귀 여부를 확인했다. - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` - 결과: `** BUILD SUCCEEDED **`. - 무엇/왜/어떻게: 저장소의 테스트 액션 가용성 확인을 위해 두 스킴 테스트를 실행했다. - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test` - 결과: `Scheme SodaLive is not currently configured for the test action.` - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test` - 결과: `Scheme SodaLive-dev is not currently configured for the test action.` - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` - 결과: `** BUILD SUCCEEDED **`. - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` - 결과: 병렬 빌드 시 `build.db` lock으로 1회 실패 후 단독 재실행에서 `** BUILD SUCCEEDED **`. - 무엇/왜/어떻게: 알림 카테고리 리스트가 앱에서 `전체`를 주입하던 로직을 제거하고, 서버 응답 카테고리만 노출/선택/요청에 사용하도록 `PushNotificationListViewModel`을 수정했다. - 실행 명령: `lsp_diagnostics` (`SodaLive/Sources/Notification/List/PushNotificationListViewModel.swift`) - 결과: SourceKit 컨텍스트 한계로 모듈/타입 인식 오류가 보고되어 단독 신뢰는 낮고, 컴파일 유효성은 빌드 결과로 확인했다. - 무엇/왜/어떻게: `community` 경로의 id 누락 케이스 보완(`voiceon://community` 입력 시 로그인 사용자 `userId`를 fallback으로 사용) 이후 정적 진단/빌드/테스트 상태를 재검증했다. - 실행 명령: `lsp_diagnostics` (`SodaLive/Sources/App/AppDeepLinkHandler.swift`) - 결과: SourceKit 컨텍스트 한계로 `AppState`, `APPSCHEME`, `UserDefaults.int` 인식 오류가 계속 보고되어 단독 신뢰는 낮고, 컴파일 유효성은 빌드 결과로 확인했다. - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" -configuration Debug build` - 결과: `** BUILD SUCCEEDED **`. - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" -configuration Debug build` - 결과: `** BUILD SUCCEEDED **`. - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive" test` - 결과: `Scheme SodaLive is not currently configured for the test action.` - 실행 명령: `xcodebuild -workspace "SodaLive.xcworkspace" -scheme "SodaLive-dev" test` - 결과: `Scheme SodaLive-dev is not currently configured for the test action.` - 무엇/왜/어떻게: 초기 진입 시 카테고리 조회 후 기본 선택 과정에서 알림 리스트 API가 2회 호출되는지 여부를 search-mode(병렬 explore/librarian + grep/ast-grep)로 점검했다. - 실행 명령: `grep` (`getPushNotificationList`, `initialize`, `selectedCategory`, `onAppear`), `ast_grep_search` (`getPushNotificationList(reset: true)`), background `explore`/`librarian` 결과 수집 - 결과: `PushNotificationListView`의 최초 `onAppear`에서 `initialize()` 1회 진입, `PushNotificationListViewModel`의 `selectedCategory` didSet에서 리스트 호출 1회 발생, `initialize()` completion의 `trimmed.isEmpty` 가드로 추가 호출이 차단되어 카테고리 선택 과정에서의 중복 호출 버그는 확인되지 않았다.