generated from ttipo/project-base
feat: 메일 15단계 — 읽기 화면 이동 · 끌어다 놓기 · 메일함 옮기기 · 차단할 때 받은편지함 정리 · 예약 메일 지금 보내기 #23
Reference in New Issue
Block a user
Delete Branch "feat/mail-handling"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
무엇을 · 왜
메일 15단계(메일 · 메일함 다루기)입니다. 옛 16단계를 당긴 것으로, 옛 15단계(수신 확인 · 사내 발송 취소)는 계획에서 빼 보류로 옮겼습니다(2026-11-09).
화면은 캔버스 보드로 먼저 확정했습니다(v71 —
Reader15·ListDrag15·Mailbox15).PATCH /api/mailboxes/{id}의parentId) · 하위 메일함까지 지우기(DELETE /api/mailboxes/{id}?withChildren=true).POST /api/mail-block-runs): 차단 규칙(Sieve)과 같은 판정으로 받은편지함의 그 보낸 사람 메일을 스팸메일함으로 옮깁니다(7단계 필터 적용과 같은 cursor · 잠금).엔진 검색은 비슷한 주소 · 표시 이름에 쓴 주소까지 잡아서 쓰지 않습니다 — 남의 메일이 옮겨지지 않습니다.
POST /api/scheduled-messages/{id}/release): 예약 제출을 취소하고 원래 envelope 으로 다시 제출합니다(보내기 취소 설정만큼 붙잡음).결과를 모르는 실패는 다시 내지 않고 503 — 같은 요청이 이어 냅니다(두 통이 나가지 않게). 화면은 503 뒤 그 메일을 다시 받아 가르고, 확인하지 못한 일은 단정하지 않습니다.
docs/roadmap.md를 더했습니다(16단계 첫 항목: 주소록 가져오기 · 내보내기).backend · frontend README 는 프레임워크가 만든 영어 안내 대신 이 저장소의 실행 · 검사 안내로 바꿨습니다.
엔진 실측(개발 Stalwart 0.16.27):
parentId바꾸기 · 고리 거절 · 같은 이름(대소문자 무시) 거절,destroy는 적은 차례대로,from검색은 넓게 잡힘, 예약 취소 뒤 다시 제출하면 받는 사람에게 한 통.리뷰는 세 번 받았습니다. 1차 중간 2 · 낮음 3 · 참고 2 → 재리뷰 중간 1 · 낮음 2 → 마지막 확인 낮음 1 — 모두 고쳤습니다.
확인 방법
시험 메일함은 지우고 시험 메일은 휴지통으로 옮겼습니다.
영향 범위
체크리스트
BusinessException/error.code분기)npm run sync:error-codes실행 후 생성 파일까지 커밋 — 바꾸지 않음*.example값은 placeholder)maskEmail), 메일 글 · 엔진 설명 글 없음🤖 Generated with Claude Code
- PATCH /api/mailboxes/{id} 에 parentId — 맨 위(null) · 자기 하위로는 VAL_001 · 새 상위에 같은 이름(대소문자 무시)은 MAIL_009 · 역할 메일함 막기 - DELETE /api/mailboxes/{id}?withChildren=true — 나무를 깊은 것부터 지금 지우기와 같은 차례로(휴지통으로 → destroy) - POST /api/mail-block-runs — 받은편지함에서 차단한 보낸 사람의 메일을 스팸메일함으로(Sieve 차단 규칙과 같은 판정, 필터 적용과 같은 cursor · 잠금, 도는 동안 스팸메일함 잠금) - POST /api/scheduled-messages/{id}/release — 예약 제출을 취소하고 원래 envelope 으로 다시 제출(보내기 취소 설정만큼 붙잡음). 결과를 모르는 실패면 다시 내지 않고 503 — 같은 요청이 이어 낸다(두 통이 나가지 않게), 엔진이 분명히 거절했을 때만 임시보관함으로 엔진 사실은 개발 엔진(Stalwart 0.16.27)으로 확인했다: parentId 바꾸기 · 고리 거절, destroy 는 적은 차례대로, from 검색은 비슷한 주소 · 표시 이름의 주소까지 넓게 잡힘, 취소 뒤 다시 제출하면 받는 사람에게 한 통. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>루트 README · CLAUDE.md · 점검 목록이 아직 "풀스택 모노레포 템플릿"으로 소개하고 있었다 — 사내 그룹웨어(메일 운영 중)에 맞게 지금 상태 · 구성(메일 엔진 · 리졸버 · ClamAV · 운영 스크립트 포함) · 문서 지도 · 디렉터리 구조로 다시 쓰고, 백엔드를 호스트에서 npm ci 하라던 옛 안내(컨테이너 안에서만 — 규칙과 반대)를 뺐다. docs/roadmap.md 에 메일 1~16단계 상태(16단계 첫 항목: 주소록 가져오기 · 내보내기) · 공통 기반 · 2부 · 앱 · 추후 후보 모음을 둔다. backend · frontend README 는 프레임워크가 만든 영어 안내 대신 이 저장소의 실행 · 검사 · 참고 문서로, 규칙 · 스킬 · 역할 문서의 "템플릿" 표현("템플릿 기본 제공 골격" 등)은 "기본 골격"으로 바꿨다(nginx 설정 템플릿은 그대로). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>- 폭 360 에서 검색 칸이 상단 바 밖으로 넘쳐 화면이 옆으로 밀렸다(14단계부터) — 메일 검색 칸 · 비활성 통합 검색 칸의 최소 폭을 0 으로 둔다 - 읽기 칸 도구 줄이 이름을 숨기는 폭을 570 · 595 에서 580 · 605 로 올린다 — 실측한 필요 폭(569.19 · 594.83)에 여유가 1px 도 없어 글자 · 여백이 조금만 늘어도 두 줄로 꺾였다 - 잘못 놓은 파일 무시를 메일 화면(MailLayout)에서 앱 틀(AppShell)로 옮긴다 — 주소록 · 설정에 놓은 파일은 브라우저가 열어 웹메일을 떠났다. 쓰기 화면 · 서명 설정은 지금처럼 받는다 - 받은편지함 정리를 켠 차단 뒤에는 다음 메일 대신 목록으로 간다 — 다음 메일이 같은 보낸 사람의 것이면 열자마자 읽음이 되고 곧 정리가 스팸메일함으로 옮겼다 - 모달 창의 제목 · 글은 낱말 가운데서 줄을 바꾸지 않고("지울까/요?") 띄어쓰기 없는 긴 글만 아무 데서나 끊는다 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>