From 406c377d132767d6f3f5a7d1d3f22feb10c9e3fd Mon Sep 17 00:00:00 2001 From: klaus Date: Wed, 10 Jun 2026 18:11:59 +0900 Subject: [PATCH] =?UTF-8?q?docs(chat):=20DM=20=EC=B1=84=ED=8C=85=20Phase?= =?UTF-8?q?=202=20=EA=B2=80=EC=A6=9D=EC=9D=84=20=EA=B8=B0=EB=A1=9D?= =?UTF-8?q?=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/20260610_DM_채팅화면/plan-task.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/20260610_DM_채팅화면/plan-task.md b/docs/20260610_DM_채팅화면/plan-task.md index 864a0726..ae54f63f 100644 --- a/docs/20260610_DM_채팅화면/plan-task.md +++ b/docs/20260610_DM_채팅화면/plan-task.md @@ -113,7 +113,7 @@ ### Phase 2: Repository와 SSE 클라이언트 추가 -- [ ] **Task 2.1: Repository 추가** +- [x] **Task 2.1: Repository 추가** - Files: - Create: `app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/data/DmChatRepository.kt` - 작업: @@ -124,7 +124,7 @@ - Repository는 API 호출을 얇게 위임하고 별도 비즈니스 로직을 넣지 않는다. - 모든 REST API 호출은 동일한 bearer helper를 통해 생성된 auth header를 사용한다. -- [ ] **Task 2.2: OkHttp 기반 SSE 클라이언트 추가** +- [x] **Task 2.2: OkHttp 기반 SSE 클라이언트 추가** - Files: - Create: `app/src/main/java/kr/co/vividnext/sodalive/v2/main/chat/dm/data/DmChatEventClient.kt` - Create: `app/src/test/java/kr/co/vividnext/sodalive/v2/main/chat/dm/DmChatEventParserTest.kt` @@ -326,3 +326,8 @@ - 2026-06-10: Phase 1 범위로 `DmChatApi.kt`, `DmChatModels.kt`, `DmChatUiModels.kt`, `DmChatMappers.kt`, `DmChatMapperTest.kt`를 추가했다. DTO/API는 PRD 서버 필드를 `@SerializedName`으로 보존하고 `Single>` 반환 타입을 사용하도록 정의했다. - 2026-06-10: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.chat.dm.DmChatMapperTest"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`를 실행해 모두 PASS를 확인했다. `ktlintCheck`에서는 기존 `.editorconfig`의 `disabled_rules` deprecation warning이 출력됐지만 실패는 없었다. - 2026-06-10: `DmChatMappers.kt`와 `DmChatMapperTest.kt`를 보강해 `messageType` 대소문자 무시 `TEXT` 매핑, `TEXT` 외 타입 및 `textMessage == null` 미매핑, `createdAt` 동일 시 `messageId` 오름차순, 중복 `messageId` 선도착 우선 정책을 명시했다. `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.chat.dm.DmChatMapperTest"`와 `./gradlew :app:ktlintCheck` PASS를 확인했다. +- 2026-06-10: Phase 2 구현 전 `DmChatEventParserTest`를 먼저 추가하고 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.chat.dm.DmChatEventParserTest"`를 실행해 `DmChatEventParser` 심볼 부재로 실패하는 RED 상태를 확인했다. +- 2026-06-10: Phase 2 범위로 `DmChatRepository.kt`, `DmChatEventClient.kt`, `DmChatEventParserTest.kt`, `DmChatRepositoryTest.kt`를 추가했다. Repository는 `bearer(token)` helper를 통해 모든 REST API auth header를 생성하고 API 호출만 얇게 위임하도록 구현했다. SSE 클라이언트는 OkHttp `Call.enqueue()`와 streaming `ResponseBody`를 사용하고, `connected`/`message` event frame parser를 분리했다. +- 2026-06-10: `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.chat.dm.DmChatEventParserTest"`, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.chat.dm.*"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`를 실행해 모두 PASS를 확인했다. `ktlintCheck`에서는 기존 `.editorconfig`의 `disabled_rules` deprecation warning이 출력됐지만 실패는 없었다. +- 2026-06-10: Phase 2 리뷰에서 SSE stream read 중 `IOException`이 failure callback으로 전달되지 않는 문제가 발견되어, 취소되지 않은 call의 read 실패만 `listener.onFailure(e)`로 전달하도록 `DmChatEventClient`를 수정했다. 이후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.chat.dm.*"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck` PASS를 재확인했다. +- 2026-06-10: SSE 클라이언트 보강으로 비정상 HTTP 응답 failure callback 전달, trailing blank line 없는 마지막 frame dispatch, `data:` 뒤 단일 공백 제거 정책, listener `@Volatile` 가시성 보완을 반영했다. 보강 전 `DmChatEventClientTest`에서 HTTP 500 failure 누락과 마지막 frame 누락 RED를 확인했고, 이후 `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.chat.dm.DmChatEventClientTest"`, `./gradlew :app:testDebugUnitTest --tests "kr.co.vividnext.sodalive.v2.main.chat.dm.*"`, `./gradlew :app:compileDebugKotlin`, `./gradlew :app:ktlintCheck`, `git diff --check` PASS를 확인했다.