zioinfo-mail/.claude/skills/zioinfo-mail-orchestrator/SKILL.md
DESKTOP-TKLFCPR\ython 60be2f9375 feat(harness): zioinfo-mail webmail harness — backend/frontend/infra agents + orchestrator
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 21:19:51 +09:00

248 lines
7.2 KiB
Markdown

---
name: zioinfo-mail-orchestrator
description: >
zioinfo-mail 웹메일 시스템 구축 오케스트레이터.
지오정보기술 SMTP 서버(Postfix + Dovecot)를 활용한 React+FastAPI 웹메일 클라이언트를
workspace/zioinfo-mail/ 에 구축하고 서버(mail.zioinfo.co.kr:8025)에 배포한다.
FastAPI IMAP/SMTP 프록시 백엔드, React 3-패널 메일 UI 프론트엔드, nginx+systemd 인프라를
에이전트 팀으로 병렬 구현한다.
다음 상황에서 반드시 사용:
(1) 'webmail', '웹메일', 'zioinfo-mail', '메일 시스템 구축';
(2) '메일 클라이언트', '이메일 UI', 'IMAP 연동', 'SMTP 연동';
(3) mail.zioinfo.co.kr 관련 작업;
(4) 다시 실행, 업데이트, 수정, 보완.
---
# zioinfo-mail 웹메일 시스템 오케스트레이터
**실행 모드:** 하이브리드
- Phase 1 (인프라 검증): 서브 에이전트 (mail-infra-setup)
- Phase 2 (Backend + Frontend 구현): **병렬 서브 에이전트**
- Phase 3 (통합 배포): 에이전트 팀 (3명 협업)
---
## 시스템 개요
```
사용자 브라우저
↓ HTTPS:8025
nginx (/var/www/mail) → React SPA
↓ /api/
FastAPI (127.0.0.1:8026)
↓ IMAP:993 (SSL) ↓ SMTP:587 (STARTTLS)
Dovecot Postfix
(읽기) (발송)
```
**기존 인프라:**
| 항목 | 값 |
|------|-----|
| Postfix | active, `mail.zioinfo.co.kr` |
| Dovecot | active, IMAP/POP3, maildir:~/Maildir |
| TLS cert | `/etc/ssl/guardia/server.crt` |
| 계정 | ythong / info / admin @zioinfo.co.kr |
| 웹메일 URL | `https://mail.zioinfo.co.kr:8025` |
---
## Phase 0: 컨텍스트 확인
```
workspace/zioinfo-mail/ 존재 여부:
- 없음 → 초기 구현 (Phase 1부터 전체)
- 있음 + backend/만 요청 → mail-backend-dev만 재실행
- 있음 + frontend/만 요청 → mail-frontend-dev만 재실행
- 있음 + 배포 요청 → Phase 3만 실행
```
---
## Phase 1: 인프라 사전 검증 (서브 에이전트)
**mail-infra-setup** 에이전트 실행 (읽기 전용 검증):
```python
# 검증 항목
1. IMAP localhost:993 접속 테스트
2. SMTP localhost:587 접속 테스트
3. 포트 8025/8026 사용 가능 여부
4. /opt/mail/, /var/www/mail/ 생성 가능 여부
5. Gitea zio/zioinfo-mail 저장소 존재 여부
```
결과를 `_workspace/infra-check.json`에 저장.
IMAP/SMTP 접속 실패 시 → Postfix/Dovecot 설정 점검 후 재시도.
---
## Phase 2: Backend + Frontend 병렬 구현 (서브 에이전트)
**mail-backend-dev** + **mail-frontend-dev** 동시 실행:
### mail-backend-dev 작업 목록
```
workspace/zioinfo-mail/backend/
├── main.py ← FastAPI 앱 (포트 8026)
├── auth.py ← IMAP 로그인 → JWT 발급
├── imap_client.py ← aioimaplib 연결 풀
├── smtp_client.py ← aiosmtplib 발송
├── mail_parser.py ← 메일 파싱 (한글, 첨부파일)
├── models.py ← Pydantic 스키마
└── requirements.txt
```
**핵심 구현 포인트:**
- JWT 페이로드에 IMAP 자격증명 AES 암호화 포함
- IMAP 연결 풀: 사용자당 1개 재사용
- 한글 제목/본문 인코딩: `chardet` + `email.header.decode_header`
- 첨부파일: `/tmp/mail_attach_{uid}/` 임시 저장 후 스트리밍
### mail-frontend-dev 작업 목록
```
workspace/zioinfo-mail/frontend/
├── package.json ← react, typescript, vite, axios, zustand, dompurify
├── vite.config.ts ← outDir: '../dist', proxy: /api → :8026
├── src/
│ ├── App.tsx
│ ├── pages/Login.tsx ← 로그인
│ ├── pages/Mail.tsx ← 3-패널 메인
│ ├── components/
│ │ ├── FolderTree.tsx ← 좌측 폴더 트리
│ │ ├── MailList.tsx ← 중앙 목록
│ │ ├── MailView.tsx ← 우측 본문
│ │ └── Compose.tsx ← 작성 모달
│ ├── api/mailApi.ts ← axios 클라이언트
│ └── store/mailStore.ts ← zustand
```
**Backend API 스펙** (`_workspace/api-spec.md` 참조):
- Backend 완료 후 API 스펙 파일 생성 → Frontend에서 읽어 구현
---
## Phase 3: 통합 배포 (에이전트 팀)
3명 팀 구성: mail-backend-dev + mail-frontend-dev + mail-infra-setup
### 3-1. Frontend 빌드
```bash
cd workspace/zioinfo-mail/frontend && npm run build
# dist/ → workspace/zioinfo-mail/dist/
```
### 3-2. 서버 업로드 (mail-infra-setup 담당)
```bash
# Backend: paramiko sftp → /opt/mail/backend/
# Frontend dist: bundle → /var/www/mail/
# Python venv: pip install requirements.txt
```
### 3-3. systemd + nginx 설정
```bash
# /etc/systemd/system/zioinfo-mail.service 작성
# /etc/nginx/sites-available/zioinfo-mail 작성
# systemctl enable + start zioinfo-mail
# nginx -t && systemctl reload nginx
# ufw allow 8025/tcp
```
### 3-4. Gitea repo 생성 + push
```bash
# Gitea API로 zio/zioinfo-mail repo 생성
# repos/zioinfo-mail/ 로컬 git init
# bundle → server → push
```
### 3-5. deploy_server.py에 zioinfo-mail 추가
```python
# /opt/zioinfo/deploy_server.py에 zioinfo-mail 배포 함수 추가
elif repo == "zioinfo-mail":
steps = [
("git pull", [...]),
("npm build", [...]),
("copy dist", ["bash", "-c", "cp -r {SRC}/dist/. /var/www/mail/"]),
("pip install", [...]),
("restart", ["systemctl", "restart", "zioinfo-mail"]),
("health check", [...]),
]
```
---
## Phase 4: 검증
```bash
# 1. 서비스 상태
systemctl is-active zioinfo-mail
curl -f http://localhost:8026/health
# 2. IMAP 로그인 테스트
curl -X POST http://localhost:8026/auth/login \
-d '{"username":"ythong@zioinfo.co.kr","password":"1q2w3e!Q"}'
# 3. 메일 목록 조회
curl http://localhost:8026/mail/messages \
-H "Authorization: Bearer {token}"
# 4. nginx 응답
curl -f http://localhost:8025/
```
---
## 데이터 흐름
```
_workspace/
├── infra-check.json ← Phase 1 결과
├── api-spec.md ← Backend → Frontend 전달
└── deploy-result.json ← Phase 3 결과
```
---
## 에러 핸들링
| 에러 | 원인 | 처리 |
|------|------|------|
| IMAP 연결 실패 | Dovecot SSL 설정 | `/etc/ssl/guardia/server.crt` 확인 |
| SMTP 인증 실패 | SASL 설정 | `postconf smtpd_sasl_*` 확인 |
| npm build 실패 | node_modules 없음 | `npm ci` 재시도 |
| 포트 충돌 | 8026 이미 사용 | 8027로 변경 |
| HTML 메일 XSS | DOMPurify 미적용 | iframe sandbox 사용 |
---
## 테스트 시나리오
**정상 흐름:**
1. `https://mail.zioinfo.co.kr:8025` 접속
2. `ythong@zioinfo.co.kr` / `1q2w3e!Q` 로그인
3. 받은메함 목록 표시
4. 메일 클릭 → 본문 조회
5. 작성 → To: `info@zioinfo.co.kr` → 발송
6. 발신 계정 받은메함에서 수신 확인
**에러 흐름:**
- 잘못된 비밀번호 → 401 응답 + "인증 실패" 메시지
---
## should-trigger
- "웹메일 만들어줘"
- "zioinfo-mail 구축"
- "메일 클라이언트 개발"
- "mail.zioinfo.co.kr 배포"
- "IMAP 연동 웹메일"
- "다시 실행", "수정", "보완"
## should-NOT-trigger
- "GUARDiA에서 메일 알림 보내줘" → guardia-orchestrator (ITSM 알림)
- "메일 서버 설정해줘" → Postfix/Dovecot 직접 설정 (인프라 작업)
- "홈페이지 문의 메일 연동" → homepage-cms-orchestrator