2.5 KiB
2.5 KiB
구현 계획: 채팅 이미지 입력
기술 배경
- React 19 + TypeScript + Zustand 기반
features/snap - 기존 SSE 전송기
streamLLM과/chat/streamJSON 요청 - Tauri 화면 캡쳐가 만드는 PNG data URL
- 브라우저 Clipboard API가 제공하는 PNG/JPEG/WebP Blob
- Vitest + Testing Library
규칙 확인
CLAUDE.md를 유일한 작업 규칙으로 적용함- 기존
Composer,useSnapChat,snapStream을 재사용함 - 서버 DTO는
features/snap/contract/types.ts의 기존 계약 위치에 둠 - 테스트를 먼저 실패시킨 뒤 최소 구현함
- 새 라이브러리는 추가하지 않음
설계
SnapImageInput을mediaType과 data URLdata로 정의하고SnapStreamRequest.images에 연결한다.Composer가 캡쳐와 클립보드 이미지를 같은 첨부 목록으로 관리한다.- 첨부 시 형식, 개수, 개별 크기, 전체 크기를 검사한다.
onSend는 텍스트와 이미지 목록을 받아 새 대화와 기존 대화에서 같은 전송 경로를 쓴다.- 새 대화는 세션 생성 뒤 route state로 텍스트와 이미지를 넘기고, 세션 화면이 한 번 소비한다.
useSnapChat은 로컬 user 메시지를 만든 뒤 백엔드 요청에images를 포함한다.- 과거 메시지 DTO에는 이미지 정보를 추가하지 않는다. 원본이 저장되지 않는 백엔드 계약을 따른다.
변경 파일
2_frontend/src/features/snap/contract/types.ts2_frontend/src/features/snap/components/Composer.tsx2_frontend/src/features/snap/components/Composer.test.tsx2_frontend/src/features/snap/hooks/useSnapChat.ts2_frontend/src/features/snap/hooks/useSnapChat.test.tsx2_frontend/src/features/snap/pages/NewChatPage.tsx2_frontend/src/features/snap/pages/SessionChatPage.tsx2_frontend/src/features/snap/api/snap.stream.test.ts
위험과 대응
- base64 크기를 문자열 길이로 잘못 계산할 수 있음 → data URL 본문을 디코딩한 byte 길이로 검사
- 새 대화 이동 중 이미지가 사라질 수 있음 → 텍스트와 이미지 모두 route state 한 묶음으로 전달
- 요청 실패 때 작성 내용이 사라질 수 있음 → 전송이 시작되기 전 검증 실패에는 입력과 첨부를 보존함
검증
- 단위 테스트: 이미지 계약, 캡쳐 수신, 클립보드 첨부, 이미지-only, 제한 차단, 요청 body
- 전체:
npm run format,npm run lint,npm run test,npm run build