7.2 KiB
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 사용 |
테스트 시나리오
정상 흐름:
https://mail.zioinfo.co.kr:8025접속ythong@zioinfo.co.kr/1q2w3e!Q로그인- 받은메함 목록 표시
- 메일 클릭 → 본문 조회
- 작성 → To:
info@zioinfo.co.kr→ 발송 - 발신 계정 받은메함에서 수신 확인
에러 흐름:
- 잘못된 비밀번호 → 401 응답 + "인증 실패" 메시지
should-trigger
- "웹메일 만들어줘"
- "zioinfo-mail 구축"
- "메일 클라이언트 개발"
- "mail.zioinfo.co.kr 배포"
- "IMAP 연동 웹메일"
- "다시 실행", "수정", "보완"
should-NOT-trigger
- "GUARDiA에서 메일 알림 보내줘" → guardia-orchestrator (ITSM 알림)
- "메일 서버 설정해줘" → Postfix/Dovecot 직접 설정 (인프라 작업)
- "홈페이지 문의 메일 연동" → homepage-cms-orchestrator