Files
vexplor_dev/docs/yc/IMX[맥락]-imap-메일기능확장.md

2.4 KiB

name, description, type
name description type
IMX[맥락] IMAP 메일 기능 확장 왜 이 기능들을 추가하는가, 핵심 결정 근거 context

IMX 맥락 — IMAP 메일 기능 확장

왜 하는가

ERP 시스템에서 메일 확인만 되면 의미가 없음. 거래처 메일 수신 후 바로 답장, 견적서 첨부파일 저장, 담당자 전달까지 워크플로우가 연결되어야 실용적.

핵심 결정 + 근거

SMTP 서비스 분리 (userMailSmtpService.ts)

  • IMAP(수신)과 SMTP(송신)은 프로토콜 자체가 다름
  • 파일 분리로 각각 독립적으로 교체/테스트 가능
  • nodemailer는 이미 설치됨 (추가 의존성 없음)

TipTap v2 선택 (메일 에디터)

  • ProseMirror 기반 → 안정적, 확장 용이
  • @tiptap/react 공식 패키지 → Next.js 15 호환
  • Quill보다 번들 크기 작음 (~100KB vs ~200KB)
  • dynamic import (ssr: false)로 SSR 문제 회피

첨부파일 스트리밍

  • 서버에 임시 저장하지 않음 → 디스크 절약, 보안
  • imapflow client.download()stream/promises pipeline() → HTTP 응답
  • 대용량 파일도 메모리 부담 없음

메일 삭제 = Trash 이동

  • 즉시 삭제(messageDelete) 대신 Trash 폴더 이동
  • 실수로 삭제 시 복구 가능
  • Gmail/wace.me 모두 Trash 폴더 표준 지원

폴더 구조 표시

  • client.list({ statusQuery: { unseen: true } }) 로 미읽음 수 포함
  • 폴더 클릭 시 기존 스트리밍 로직 재활용 (folder 파라미터 추가)

답장/전달 RFC 준수

  • inReplyTo, references 헤더 → 메일 클라이언트에서 스레드로 묶임
  • <blockquote> 인용 → Gmail/Outlook 모두 올바르게 렌더링

관련 파일

  • backend-node/src/services/userMailImapService.ts — IMAP 수신 로직
  • backend-node/src/services/imapConnectionPool.ts — 커넥션 풀 (건드리지 않음)
  • backend-node/src/services/mailCache.ts — TTL 캐시 (건드리지 않음)
  • frontend/app/(main)/mail/imap/page.tsx — 메인 UI

기술 참고

  • imapflow client.list() → statusQuery 옵션으로 unseen 포함
  • imapflow client.messageMove(seqno, folder) → UID 기반 이동
  • imapflow client.download(seqno, partId) → ReadableStream 반환
  • nodemailer createTransport({ host, port, secure, auth })sendMail()
  • RFC 2822 §3.6.4: In-Reply-To, References 헤더
  • W3C HTML Threading: <blockquote cite="mid:..."> 권장