[BE-10] 재연결 backfill (FR-10)
작업 내용 (설계 의도)
변경 사항
근거 TDD: 20260704-채팅시스템고도화-tdd.md (FR-10, WebSocket 연결 끊김 실패 경로). 2단계(Milestone 2).
WebSocket 재연결 후 끊긴 구간의 메시지를 REST로 채운다. 클라이언트는 지수 백오프 재시도, 3회 실패 시 REST 폴링으로 전환하고 재연결 성공 시 backfill 호출.
domain/message/repository/MessageCustomRepository.kt+ Impl:findAfter(roomId, afterMessageId, pageSize): List<Message>추가 (id > afterMessageId 오름차순).domain/message/service/MessageDomainService.kt또는 신규MessageBackfillDomainService.kt:backfill(roomId, userId, afterMessageId)— 참여자·만료 가드 후findAfter.application/message/usecase/BackfillMessagesUseCase.kt(신규).presentation/message/controller/MessageApiController.kt:GET /rooms/{roomId}/messages/backfill?afterMessageId=추가 — wave4에서 본 티켓만 MessageApiController 수정.- at-least-once 전제: 중복은 클라이언트가 messageId로 dedup(멱등).
- 롤백: 조회 전용 additive 엔드포인트. 제거해도 실시간·기존 조회 무영향.
의존
- BE-05 (MessageCustomRepository 확장 — 같은 파일이므로 BE-05 완료 후 순차)
- BE-03a (컨텍스트 방 무관하나 Room 확장 이후)
다이어그램
처리 흐름
sequenceDiagram participant C as Client participant Ctl as MessageApiController participant UC as BackfillMessagesUseCase participant DS as MessageDomainService C->>Ctl: GET /rooms/1/messages/backfill?afterMessageId=120 Ctl->>UC: execute(roomId,userId,120) UC->>DS: backfill → findAfter(1,120,pageSize) DS-->>C: messages id>120
테스트 케이스
- afterMessageId=120 요청 시 id 121 이상의 메시지만 오름차순으로 반환된다.
- 끊긴 구간이 없으면(최신까지 읽음) 빈 목록을 반환한다.
- 방 비참여자의 backfill 요청은 거부된다.
- 만료된 게스트의 backfill 요청은 거부된다.
- 동일 afterMessageId로 재요청해도 동일 결과를 반환한다 (멱등).