Files
CODE_ASSISTANT/specs/005-chat-image-input/plan.md
T
2026-09-16 17:22:14 +09:00

2.5 KiB

구현 계획: 채팅 이미지 입력

기술 배경

  • React 19 + TypeScript + Zustand 기반 features/snap
  • 기존 SSE 전송기 streamLLM/chat/stream JSON 요청
  • Tauri 화면 캡쳐가 만드는 PNG data URL
  • 브라우저 Clipboard API가 제공하는 PNG/JPEG/WebP Blob
  • Vitest + Testing Library

규칙 확인

  • CLAUDE.md를 유일한 작업 규칙으로 적용함
  • 기존 Composer, useSnapChat, snapStream을 재사용함
  • 서버 DTO는 features/snap/contract/types.ts의 기존 계약 위치에 둠
  • 테스트를 먼저 실패시킨 뒤 최소 구현함
  • 새 라이브러리는 추가하지 않음

설계

  1. SnapImageInputmediaType과 data URL data로 정의하고 SnapStreamRequest.images에 연결한다.
  2. Composer가 캡쳐와 클립보드 이미지를 같은 첨부 목록으로 관리한다.
  3. 첨부 시 형식, 개수, 개별 크기, 전체 크기를 검사한다.
  4. onSend는 텍스트와 이미지 목록을 받아 새 대화와 기존 대화에서 같은 전송 경로를 쓴다.
  5. 새 대화는 세션 생성 뒤 route state로 텍스트와 이미지를 넘기고, 세션 화면이 한 번 소비한다.
  6. useSnapChat은 로컬 user 메시지를 만든 뒤 백엔드 요청에 images를 포함한다.
  7. 과거 메시지 DTO에는 이미지 정보를 추가하지 않는다. 원본이 저장되지 않는 백엔드 계약을 따른다.

변경 파일

  • 2_frontend/src/features/snap/contract/types.ts
  • 2_frontend/src/features/snap/components/Composer.tsx
  • 2_frontend/src/features/snap/components/Composer.test.tsx
  • 2_frontend/src/features/snap/hooks/useSnapChat.ts
  • 2_frontend/src/features/snap/hooks/useSnapChat.test.tsx
  • 2_frontend/src/features/snap/pages/NewChatPage.tsx
  • 2_frontend/src/features/snap/pages/SessionChatPage.tsx
  • 2_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