Files
CODE_ASSISTANT/docs/troubleshootings/2026-07-26-snap-reentry-blank-chat.md
T
2026-09-16 17:22:14 +09:00

49 lines
3.4 KiB
Markdown

# snap 채팅 재진입 시 대화 안 보임 (됐다 안 됐다)
## 증상
- 답변 스트리밍 중 목록 갔다 오면 대화가 비어 보이고, 새로고침해야 나타남
- 재진입 시 답변을 처음부터 타자기로 다시 뿌림
- "되묻기(의도 애매)" 답변에서 유독 자주 아무것도 안 보임
- 재현이 타이밍 따라 들쭉날쭉 (됐다 안 됐다)
## 원인 (겹친 층 4개)
1. **전역 `staleTime: 30_000` (진짜 뿌리)** — 세션 detail 캐시가 30초간 refetch 안 됨.
빈/부분 스냅샷이 캐시에 박히면 재진입해도 그대로 나옴. 테스트 들락날락이 다 30초 창
안이라 "새로고침해야 나타남"으로 체감. 아래 3개 수정이 다 "새 데이터 오면" 작동하는
구조였는데 새 데이터 자체가 안 오고 있었음.
2. **remount 시 무조건 재seed** — per-instance `initedRef` 가드는 remount 마다 리셋 →
stale DB 스냅샷이 라이브 store 를 덮고 스트림도 abort(seed 가 abort 함).
3. **타자기 진행도가 컴포넌트 로컬**`useSmoothedText` 의 displayed 가 `""` 시작이라
remount 마다 처음부터 재생.
4. **재진입 시 "생성 중" 표시 없음** — 생성 중 재진입하면 DB 엔 user 만 있어서 시머 없이
백지. 되묻기 경로는 응답이 느려서(관측치 43초) 이 백지 창이 유독 길었음 → "되묻는
부분에서 안 보임"으로 체감.
## 확정 근거
- dev DB 직접 조회(asyncpg): 되묻기 포함 모든 메시지 정상 저장돼 있었음 → 백엔드 무죄.
세션 34b5b639: user 06:59:57 → 되묻기 assistant 07:00:40 (len=302, **43초**) → 후속
user 07:00:49 → 본답변 07:01:00 (len=1347).
- 백엔드 streaming.py: persist → usage → done 순서. 클라 끊겨도 producer 가 끝까지 저장
→ DB 가 신뢰 가능한 복구원.
## 수정 (전부 2_frontend/src/features/snap + lib/streaming)
| 파일 | 내용 |
|---|---|
| `api/snap.api.ts` | detail 쿼리 `staleTime: 0` (재진입마다 refetch) + `isGenerating` 이면 1.5s 폴링 |
| `pages/SessionChatPage.tsx` | seed 가드: 라이브면 보존, 아니면 "내용량 많은 쪽으로 단조 수렴"(DB > store 일 때만 seed). 재진입+백엔드 생성 중이면 시머 표시 + Composer 잠금(409 방지) |
| `lib/streaming/useSmoothedText.ts` | displayed 초기값 `""``full` (remount 시 기존 내용 즉시, 새 토큰만 타자기) |
| `hooks/useSnapChat.ts` | `onDone` 에서 detail 캐시 invalidate |
## 교훈
- "됐다 안 됐다" = 레이스. 코드 추리로 5번 고치다 실패 → DB 직접 조회 한 방에 백엔드
무죄 확정 + 프론트로 범위 좁힘. **증거 수집을 먼저 했어야 함.**
- 전역 캐시 정책(staleTime)은 실시간성 데이터(스트리밍 대화)에 그대로 두면 안 됨 —
쿼리별 override 필수.
- 하위 층을 아무리 고쳐도 최상층(캐시)이 데이터를 안 내려주면 전부 무력화됨. 층이 겹친
버그는 층별로 분리해서 검증할 것.
## 남은 한계 (알고 수용)
- STOP 으로 얼린 부분 답변은 재진입 시 DB 완성본으로 교체됨(백엔드 cancel 미구현이라
어차피 끝까지 생성·저장). "정지 자리 유지"가 필요하면 백엔드 cancel 이 선행.
- 멀티탭 동시 스트림은 백엔드 단일 프로세스 전제(레지스트리)라 이번 범위 밖.