495 lines
14 KiB
Markdown
495 lines
14 KiB
Markdown
# 메일 관리 시스템 구현 계획서
|
|
|
|
## 📋 프로젝트 개요
|
|
|
|
**목적**: 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<string, string>;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 💾 데이터 저장 구조
|
|
|
|
### 파일 시스템 기반 (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": "<p>안녕하세요, {customer_name}님!</p>",
|
|
"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 착수 준비 완료
|
|
|