# 메일 관리 시스템 구현 계획서 ## 📋 프로젝트 개요 **목적**: SMTP 기반 메일 계정 관리 및 드래그 앤 드롭 메일 템플릿 디자이너 구축 **방식**: 파일 시스템 기반 (DB 테이블 불필요) **저장 위치**: `uploads/mail-accounts/`, `uploads/mail-templates/` --- ## 🎯 핵심 기능 ### 1. 메일 계정 관리 - SMTP 계정 등록/수정/삭제 - 비밀번호 AES-256 암호화 저장 - 계정 상태 관리 (활성/비활성) - 일일 발송 제한 설정 ### 2. 메일 템플릿 관리 - 드래그 앤 드롭 에디터 - 컴포넌트 기반 디자인 - 텍스트 (HTML 편집) - 버튼 (링크, 색상 설정) - 이미지 - 여백 - 실시간 미리보기 - 템플릿 저장/불러오기 ### 3. SQL 쿼리 연동 - 쿼리 파라미터 자동 감지 (`$1`, `$2`, ...) - 동적 변수 치환 (`{customer_name}` → 실제 값) - 쿼리 결과로 수신자 자동 선택 - 이메일 필드 자동 감지 --- ## 🏗️ 시스템 아키텍처 ### 백엔드 (Node.js + TypeScript) #### **파일 구조** ``` backend-node/src/ ├── services/ │ ├── mailAccountFileService.ts # 메일 계정 관리 │ ├── mailTemplateFileService.ts # 템플릿 관리 │ ├── mailQueryService.ts # SQL 쿼리 빌더 │ └── encryptionService.ts # AES-256 암호화 ├── controllers/ │ ├── mailAccountFileController.ts # 계정 API │ ├── mailTemplateFileController.ts # 템플릿 API │ └── mailQueryController.ts # 쿼리 API └── routes/ ├── mailAccountFileRoutes.ts # /api/mail/accounts ├── mailTemplateFileRoutes.ts # /api/mail/templates-file └── mailQueryRoutes.ts # /api/mail/query ``` #### **API 엔드포인트** **메일 계정 API** (`/api/mail/accounts`) - `GET /` - 전체 계정 목록 - `GET /:id` - 특정 계정 조회 - `POST /` - 계정 생성 - `PUT /:id` - 계정 수정 - `DELETE /:id` - 계정 삭제 - `POST /:id/test-connection` - SMTP 연결 테스트 **메일 템플릿 API** (`/api/mail/templates-file`) - `GET /` - 전체 템플릿 목록 - `GET /:id` - 특정 템플릿 조회 - `POST /` - 템플릿 생성 - `PUT /:id` - 템플릿 수정 - `DELETE /:id` - 템플릿 삭제 - `POST /:id/preview` - 미리보기 (샘플 데이터) - `POST /:id/preview-with-query` - 쿼리 결과 미리보기 **SQL 쿼리 API** (`/api/mail/query`) - `POST /detect-parameters` - 쿼리 파라미터 자동 감지 - `POST /test` - 쿼리 테스트 실행 - `POST /execute` - 쿼리 실행 - `POST /extract-variables` - 템플릿 변수 추출 - `POST /validate-mapping` - 변수 매핑 검증 - `POST /process-mail-data` - 대량 메일 데이터 처리 --- ### 프론트엔드 (Next.js 14) #### **페이지 구조** ``` frontend/app/(main)/mail/ ├── accounts/page.tsx # 메일 계정 관리 ├── templates/page.tsx # 메일 템플릿 관리 ├── send/page.tsx # 메일 발송 └── receive/page.tsx # 메일 수신함 frontend/components/mail/ └── MailDesigner.tsx # 드래그 앤 드롭 에디터 ``` #### **주요 컴포넌트** **MailDesigner** - 드래그 앤 드롭 메일 에디터 - **왼쪽 패널**: 컴포넌트 팔레트, 템플릿 정보, 액션 버튼 - **중앙 캔버스**: 실시간 미리보기, 컴포넌트 선택/삭제 - **오른쪽 패널**: 속성 편집 (선택된 컴포넌트) **컴포넌트 타입** ```typescript interface MailComponent { id: string; type: "text" | "button" | "image" | "spacer"; content?: string; // 텍스트 HTML text?: string; // 버튼 텍스트 url?: string; // 링크/이미지 URL src?: string; // 이미지 소스 height?: number; // 여백 높이 styles?: Record; } ``` --- ## 💾 데이터 저장 구조 ### 파일 시스템 기반 (JSON) #### **메일 계정** (`uploads/mail-accounts/{account-id}.json`) ```json { "id": "account-1735970000000", "name": "회사 공식 메일", "email": "info@company.com", "smtpHost": "smtp.gmail.com", "smtpPort": 587, "smtpSecure": false, "smtpUsername": "info@company.com", "smtpPassword": "암호화된_비밀번호", "dailyLimit": 1000, "status": "active", "createdAt": "2025-01-04T12:00:00Z", "updatedAt": "2025-01-04T12:00:00Z" } ``` #### **메일 템플릿** (`uploads/mail-templates/{template-id}.json`) ```json { "id": "template-1735970100000", "name": "고객 환영 메일", "subject": "{customer_name}님 환영합니다!", "components": [ { "id": "comp-1", "type": "text", "content": "

안녕하세요, {customer_name}님!

", "styles": { "fontSize": "16px", "color": "#333" } }, { "id": "comp-2", "type": "button", "text": "시작하기", "url": "https://example.com/start", "styles": { "backgroundColor": "#007bff", "color": "#fff" } } ], "queryConfig": { "queries": [ { "id": "q-1", "name": "고객 목록", "sql": "SELECT name AS customer_name, email FROM customers WHERE active = $1", "parameters": [ { "name": "$1", "type": "boolean", "value": true } ] } ] }, "recipientConfig": { "type": "query", "emailField": "email", "nameField": "customer_name", "queryId": "q-1" }, "category": "welcome", "createdAt": "2025-01-04T12:00:00Z", "updatedAt": "2025-01-04T12:00:00Z" } ``` --- ## 🔒 보안 고려사항 ### 1. 비밀번호 암호화 - **알고리즘**: AES-256-CBC - **키 관리**: 환경변수 (`ENCRYPTION_KEY`) - **저장**: 암호화된 상태로 JSON 파일에 저장 ### 2. API 보안 - JWT 기반 인증 (기존 시스템 활용) - 비밀번호 반환 시 마스킹 처리 (`••••••••`) - 입력값 검증 및 Sanitization ### 3. 파일 시스템 보안 - 저장 디렉토리 권한 제한 - 파일명 검증 (Path Traversal 방지) --- ## 📈 성능 최적화 ### 1. 파일 I/O 최적화 - 비동기 파일 읽기/쓰기 (`fs.promises`) - 목록 조회 시 병렬 처리 (`Promise.all`) ### 2. 캐싱 전략 - 프론트엔드: React Query로 API 응답 캐싱 - 백엔드: 필요 시 메모리 캐시 추가 가능 ### 3. 대량 메일 처리 - 쿼리 결과를 스트림으로 처리 - 배치 단위 메일 발송 (추후 구현) --- ## 🚀 구현 단계 ### ✅ Phase 1: 파일 기반 저장 시스템 (완료) - [x] mailAccountFileService - [x] mailTemplateFileService - [x] encryptionService ### ✅ Phase 2: SQL 쿼리 빌더 (완료) - [x] mailQueryService - [x] 쿼리 파라미터 감지 - [x] 동적 변수 치환 - [x] 쿼리 실행 및 결과 처리 ### ✅ Phase 3: 백엔드 API (완료) - [x] Controllers - [x] Routes - [x] app.ts 통합 ### ✅ Phase 4: 프론트엔드 UI (완료) - [x] 메일 계정 관리 페이지 - [x] 메일 템플릿 관리 페이지 - [x] MailDesigner 컴포넌트 - [x] 드래그 앤 드롭 에디터 - [x] 메일 대시보드 페이지 - [x] URL 구조 변경 (`/admin/mail/*`) ### 🔜 Phase 5: 세부 기능 구현 (진행 예정) #### 5-1. 메일 계정 관리 (우선순위 ⭐⭐⭐) - [ ] 계정 추가 모달 구현 - [ ] 계정 수정 모달 구현 - [ ] 계정 삭제 확인 모달 - [ ] SMTP 연결 테스트 기능 - [ ] 계정 목록 테이블 (정렬, 검색) - [ ] 계정 상태 토글 (활성/비활성) - [ ] 일일 발송 제한 표시/수정 #### 5-2. 메일 템플릿 관리 (우선순위 ⭐⭐⭐) - [ ] 템플릿 목록 카드/테이블 뷰 - [ ] MailDesigner 통합 (생성/수정 모드) - [ ] 템플릿 미리보기 모달 - [ ] 템플릿 삭제 확인 - [ ] 템플릿 카테고리 관리 - [ ] 템플릿 검색/필터링 - [ ] 템플릿 복사 기능 #### 5-3. SQL 쿼리 빌더 (우선순위 ⭐⭐) - [ ] 쿼리 에디터 컴포넌트 - [ ] 파라미터 자동 감지 UI - [ ] 쿼리 테스트 실행 버튼 - [ ] 결과 테이블 표시 - [ ] 변수 매핑 UI (템플릿 변수 ↔ 쿼리 결과) - [ ] 이메일 필드 자동 감지 - [ ] 수신자 미리보기 #### 5-4. 메일 발송 시스템 (우선순위 ⭐⭐) - [ ] 발송 폼 UI (계정 선택, 템플릿 선택) - [ ] 수신자 입력 방식 선택 (직접 입력 / SQL 쿼리) - [ ] 발송 전 미리보기 - [ ] 실제 메일 발송 API 구현 (Nodemailer) - [ ] 발송 큐 관리 - [ ] 발송 이력 저장 (파일 or DB) - [ ] 발송 진행 상태 표시 - [ ] 실패 시 재시도 로직 #### 5-5. 대시보드 통계 (우선순위 ⭐) - [ ] 실제 발송 건수 집계 - [ ] 성공률 계산 - [ ] 최근 발송 이력 표시 - [ ] 계정별 발송 통계 - [ ] 일별/주별/월별 차트 #### 5-6. 메일 수신함 (우선순위 낮음, 보류) - [ ] IMAP/POP3 연동 - [ ] 메일 파싱 - [ ] 첨부파일 처리 - [ ] 수신함 UI --- --- ## 🎯 구현 우선순위 및 순서 ### 📅 **추천 구현 순서** #### **1단계: 메일 계정 관리** (2-3일 예상) 메일 발송의 기반이 되므로 최우선 구현 필요 - 계정 CRUD 모달 - SMTP 연결 테스트 - 목록 조회/검색 #### **2단계: 메일 템플릿 관리** (3-4일 예상) MailDesigner 통합 및 템플릿 저장/불러오기 - 템플릿 CRUD - MailDesigner 통합 - 미리보기 기능 #### **3단계: 메일 발송 시스템** (4-5일 예상) 실제 메일 발송 기능 구현 - Nodemailer 연동 - 발송 폼 및 미리보기 - 발송 이력 관리 #### **4단계: SQL 쿼리 빌더** (3-4일 예상) 대량 발송을 위한 쿼리 연동 - 쿼리 에디터 - 변수 매핑 - 결과 미리보기 #### **5단계: 대시보드 통계** (2-3일 예상) 실제 데이터 기반 통계 표시 - 발송 건수 집계 - 차트 및 통계 --- ## 📝 사용 방법 (구현 후) ### 1. 메일 계정 등록 1. 메뉴: "메일 관리" → "메일 계정 관리" (`/admin/mail/accounts`) 2. "새 계정 추가" 버튼 클릭 3. SMTP 정보 입력 (호스트, 포트, 인증 정보) 4. 연결 테스트 → 성공 시 저장 5. → `uploads/mail-accounts/account-{timestamp}.json` 생성 ### 2. 메일 템플릿 디자인 1. 메뉴: "메일 관리" → "메일 템플릿 관리" (`/admin/mail/templates`) 2. "새 템플릿 만들기" 버튼 클릭 3. 드래그 앤 드롭 에디터(MailDesigner) 사용: - **왼쪽**: 컴포넌트 팔레트 (텍스트, 버튼, 이미지, 여백) - **중앙**: 실시간 미리보기 캔버스 - **오른쪽**: 선택된 컴포넌트 속성 편집 4. SQL 쿼리 설정 (선택 사항): - 쿼리 작성 → 파라미터 자동 감지 - 결과 변수를 템플릿 변수에 매핑 5. 저장 → `uploads/mail-templates/template-{timestamp}.json` 생성 ### 3. 메일 발송 1. 메뉴: "메일 관리" → "메일 발송" (`/admin/mail/send`) 2. 발송 계정 선택 (등록된 SMTP 계정) 3. 템플릿 선택 (또는 직접 작성) 4. 수신자 설정: - **직접 입력**: 이메일 주소 입력 - **SQL 쿼리**: 템플릿의 쿼리 사용 또는 새 쿼리 작성 5. 미리보기 확인 (샘플 데이터로 렌더링) 6. 발송 실행 → 발송 큐에 추가 → 순차 발송 7. 발송 이력 확인 ### 4. 대시보드 확인 1. 메뉴: "메일 관리" → "메일 대시보드" (`/admin/mail/dashboard`) 2. 통계 카드: - 총 발송 건수 - 성공/실패 건수 및 성공률 - 오늘/이번 주/이번 달 발송 건수 3. 차트: - 일별/주별 발송 추이 - 계정별 발송 통계 4. 최근 발송 이력 테이블 --- ## 🛠️ 개발 환경 설정 ### 필수 환경변수 ```bash # docker/dev/docker-compose.backend.mac.yml ENCRYPTION_KEY=ilshin-plm-mail-encryption-key-32characters-2024-secure ``` ### 저장 디렉토리 생성 ```bash mkdir -p uploads/mail-accounts mkdir -p uploads/mail-templates ``` --- ## 📚 참고 문서 - [Nodemailer Documentation](https://nodemailer.com/) - [Node.js Crypto Module](https://nodejs.org/api/crypto.html) - [Next.js File System Routing](https://nextjs.org/docs/app/building-your-application/routing) --- ## 📌 주의사항 1. **DB 테이블 불필요**: 모든 데이터는 파일 시스템에 JSON으로 저장 2. **메뉴 연결**: 메뉴 관리 UI에서 각 메뉴의 URL만 설정 (✅ 완료) - 메일 대시보드: `/admin/mail/dashboard` - 메일 계정: `/admin/mail/accounts` - 메일 템플릿: `/admin/mail/templates` - 메일 발송: `/admin/mail/send` - 메일 수신함: `/admin/mail/receive` 3. **보안**: 비밀번호는 항상 암호화되어 저장됨 4. **백업**: `uploads/` 폴더를 정기적으로 백업 권장 --- --- ## 🔍 다음 단계: Phase 5-1 메일 계정 관리 상세 구현 계획 ### 📋 **필요한 컴포넌트** 1. **MailAccountModal.tsx** (계정 추가/수정 모달) - Form 필드: 계정명, 이메일, SMTP 호스트/포트, 인증정보, 일일 제한 - SMTP 연결 테스트 버튼 - 저장/취소 버튼 2. **MailAccountTable.tsx** (계정 목록 테이블) - 컬럼: 계정명, 이메일, 상태, 일일 제한, 생성일, 액션 - 정렬/검색 기능 - 상태 토글 (활성/비활성) - 수정/삭제 버튼 3. **ConfirmDeleteModal.tsx** (삭제 확인 모달) - 재사용 가능한 확인 모달 컴포넌트 ### 🔌 **필요한 API 클라이언트** `frontend/lib/api/mail.ts` 생성 예정: ```typescript // GET /api/mail/accounts export const getMailAccounts = async () => { ... } // GET /api/mail/accounts/:id export const getMailAccount = async (id: string) => { ... } // POST /api/mail/accounts export const createMailAccount = async (data) => { ... } // PUT /api/mail/accounts/:id export const updateMailAccount = async (id, data) => { ... } // DELETE /api/mail/accounts/:id export const deleteMailAccount = async (id) => { ... } // POST /api/mail/accounts/:id/test-connection export const testMailConnection = async (id) => { ... } ``` ### 📦 **상태 관리** React Query 사용 권장: - `useQuery(['mailAccounts'])` - 계정 목록 조회 - `useMutation(createMailAccount)` - 계정 생성 - `useMutation(updateMailAccount)` - 계정 수정 - `useMutation(deleteMailAccount)` - 계정 삭제 - `useMutation(testMailConnection)` - 연결 테스트 --- **작성일**: 2025-01-04 **최종 수정**: 2025-01-04 **상태**: ✅ Phase 1-4 완료, 🔜 Phase 5-1 착수 준비 완료