---
name: IMX[계획] IMAP 메일 기능 확장
description: 메일 삭제, SMTP 발송, 폴더 전환, 첨부파일 다운로드, 이동, 답장/전달 구현
type: plan
---

# IMX 계획 — IMAP 메일 기능 확장

## 개요

기존 메일 조회/읽음처리만 되던 IMAP 페이지에 전체 메일 클라이언트 기능 추가.
nodemailer(이미 설치), imapflow(이미 설치), TipTap v2(신규 설치) 기반.

## 현재 동작

- 계정 목록 조회
- 메일 스트리밍 목록
- 메일 상세 보기
- 읽음 처리
- 메일 삭제 (백엔드만, UI 버튼 있으나 실제 연동 확인 필요)

## 변경 후 동작

- 좌측 패널: 폴더 목록 (INBOX, Sent, Trash, Spam 등) + 미읽음 수
- 메일 상세 우측 버튼: 답장 / 전달 / 이동 / 삭제(→Trash)
- 하단 첨부파일 목록 + 다운로드 버튼
- 우상단 `작성` 버튼 → Dialog (TipTap 에디터, to/cc/subject)
- 답장/전달 시 원문 인용 자동 삽입

## 시각적 예시

```
┌──────────────────────────────────────────────────────────────────┐
│ 메일 관리 (IMAP)                              [작성] [계정추가]  │
├──────────────┬───────────────────┬───────────────────────────────┤
│ [계정목록]   │ [검색창]          │ 제목: 보안 알림               │
│              │                   │ From: Google                  │
│ Gmail        │ ● Google 오후1:51 │ To: yechul@gmail.com          │
│ Wace         │   보안 알림       │ Date: 2026-03-27              │
│              │ ● GitHub 오전9:48 │ [답장][전달][이동▼][삭제]    │
│ ─────────    │   Sudo code       │ ─────────────────────────────  │
│ [폴더목록]   │                   │ <HTML 본문>                   │
│ INBOX  (3)   │                   │                               │
│ Sent         │                   │ 📎 첨부파일                   │
│ Trash        │                   │  file.pdf (120KB) [다운로드]  │
│ Spam         │                   │                               │
└──────────────┴───────────────────┴───────────────────────────────┘
```

## 아키텍처

```mermaid
graph TD
  FE[page.tsx] -->|GET /folders| BE_CTRL[userMailController]
  FE -->|POST /send| BE_CTRL
  FE -->|POST /move| BE_CTRL
  FE -->|GET /attachment| BE_CTRL
  BE_CTRL --> IMAP[userMailImapService]
  BE_CTRL --> SMTP[userMailSmtpService - 신규]
  IMAP --> Pool[imapConnectionPool]
  SMTP --> Nodemailer[nodemailer]
```

## 변경 파일

### 신규
- `backend-node/src/services/userMailSmtpService.ts` — SMTP 발송 전용

### 수정
- `backend-node/src/services/userMailImapService.ts` — 폴더목록, 이동, 첨부파일 추가
- `backend-node/src/controllers/userMailController.ts` — 신규 엔드포인트 핸들러
- `backend-node/src/routes/userMailRoutes.ts` — 신규 라우트 등록
- `frontend/lib/api/userMail.ts` — 신규 API 함수
- `frontend/app/(main)/mail/imap/page.tsx` — UI 전면 확장

## 신규 API 엔드포인트

| Method | Path | 설명 |
|--------|------|------|
| GET | `/user-mail/accounts/:id/folders` | 폴더 목록 + 미읽음 수 |
| GET | `/user-mail/accounts/:id/folders/:folder/mails/stream` | 폴더별 메일 스트리밍 |
| POST | `/user-mail/accounts/:id/mails/:seqno/move` | 메일 이동 `{ targetFolder }` |
| GET | `/user-mail/accounts/:id/mails/:seqno/attachment/:partId` | 첨부파일 다운로드 (스트리밍) |
| POST | `/user-mail/accounts/:id/send` | 메일 발송 `{ to, cc, subject, html, text, inReplyTo?, references? }` |

## 코드 설계

### userMailSmtpService.ts
```typescript
// SMTP 포트 추론: useTls true → 465, false → 587
// Gmail: smtp.gmail.com, wace.me: mail.wace.me 또는 host 에서 도메인 추출
// nodemailer createTransport + sendMail
// 답장: inReplyTo, references 헤더 설정
```

### userMailImapService.ts 추가 메서드
```typescript
listFolders(account): Promise<{ path, name, unseen }[]>  // client.list({ statusQuery })
moveMail(account, seqno, targetFolder): Promise<Result>   // messageMove
downloadAttachment(account, seqno, partId, res): Promise<void>  // download() + pipeline(res)
```

### page.tsx 추가 UI
- `folders` state: 폴더 목록
- `currentFolder` state: 현재 폴더 (기본 INBOX)
- `ComposeDialog`: TipTap 에디터 + to/cc/subject 필드
- `composeMode`: 'new' | 'reply' | 'forward'
- 메일 상세 버튼: 답장, 전달, 이동(DropdownMenu), 삭제

## 예상 문제

1. **Gmail SMTP 포트**: Gmail은 587(STARTTLS) 또는 465(SSL). host에서 자동 추론.
2. **폴더명 인코딩**: 한글 폴더 등 UTF-7/UTF-8 혼용 → imapflow가 자동 처리
3. **첨부파일 partId**: bodyStructure 파싱이 복잡 → `client.download(seqno, partId)` 직접 사용
4. **TipTap SSR**: Next.js에서 dynamic import 필요 (`ssr: false`)

## 설계 원칙

- SMTP 서비스는 IMAP 서비스와 완전 분리 (파일 분리)
- 첨부파일은 서버에 저장하지 않고 스트리밍으로 직접 응답
- 답장/전달 인용: `<blockquote>` + RFC 2822 헤더 표준 준수
- TipTap은 dynamic import로 SSR 방지
