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

7.2 KiB

name description
zioinfo-mail-orchestrator 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 에이전트 실행 (읽기 전용 검증):

# 검증 항목
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 빌드

cd workspace/zioinfo-mail/frontend && npm run build
# dist/ → workspace/zioinfo-mail/dist/

3-2. 서버 업로드 (mail-infra-setup 담당)

# Backend: paramiko sftp → /opt/mail/backend/
# Frontend dist: bundle → /var/www/mail/
# Python venv: pip install requirements.txt

3-3. systemd + nginx 설정

# /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

# Gitea API로 zio/zioinfo-mail repo 생성
# repos/zioinfo-mail/ 로컬 git init
# bundle → server → push

3-5. deploy_server.py에 zioinfo-mail 추가

# /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: 검증

# 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