메일 트리아지 · 2026
사람을 빼지 않고, 사람을 빠르게 만들기로 했다
쇼핑몰이나 예약 서비스를 운영하면 하루에 수십 통의 문의가 옵니다. 각각을 읽고, 급한 것을 골라내고, 답장을 쓰는 데 건당 10분 이상이 듭니다.
자동화의 목표를 '사람 없이 보내기'가 아니라 '사람이 빨리 판단하게 하기'로 잡았습니다. 고객 응대는 틀렸을 때 비용이 크기 때문에 최종 판단은 사람에게 남겼습니다.
0통
사람 없이 나가는 메일
초안까지만, 발송은 사람이
4단계
자동 처리 구간
수신·분류·기록·초안
0원
데모 운영 비용
API 키 없이 동작
API 키가 없어도 전부 동작해야 했다
포트폴리오 데모는 아무나 열어서 눌러볼 수 있어야 의미가 있습니다. 키를 넣어야 돌아가는 데모는 아무도 눌러보지 않습니다.
그래서 모델 호출이 불가능한 환경에서는 한국어 규칙 기반 분류기로 자동 폴백합니다. 키가 있으면 실제 모델을 쓰고, 없거나 호출이 실패하면 조용히 내려갑니다. 화면에는 현재 어느 쪽인지 표시됩니다.
시간이 9시간씩 두 번 어긋났다
새로 들어온 문의가 미래 시각으로 표시됐습니다. 타임존 없는 컬럼에 now()가 들어가면서 이중 변환된 것이 원인이었고, 스키마 전체를 timestamptz로 바꿔 해결했습니다.
배포한 뒤 같은 증상이 다시 나타났습니다. 이번엔 DB가 아니라 렌더링 쪽으로, 서버 런타임이 UTC였습니다. 표시 기준을 Asia/Seoul로 고정했습니다.
두 번째 버그는 로컬에서 재현되지 않습니다. 개발 머신이 KST이기 때문입니다. 배포하고 실제로 열어보지 않았으면 못 잡았을 문제였습니다.
공개 URL이 되는 순간 아무나 쓸 수 있었다
초기 구현은 수신 엔드포인트가 인증 없이 임의 JSON을 받아 DB에 저장했습니다. 로컬에서는 문제없지만 공개 주소가 되면 누구나 아무 내용이나 심을 수 있습니다.
데모용 경로는 본문을 아예 받지 않고 서버가 고정된 샘플을 고르도록 바꿨고, 실제 연동 자리는 시크릿 없이는 404를 반환합니다.
쿨타임도 넣었는데, 클라이언트 타이머만 두면 개발자 도구로 바로 우회됩니다. 판단 근거를 DB에 두어 서버가 강제합니다. 서버리스는 인스턴스가 여러 개라 메모리 상태로는 안 됩니다.
이 설계의 한계
- 실제 메일함에 연결되어 있지 않습니다. 수신 웹훅이 그 자리입니다
- 등장하는 고객과 문의는 전부 가상입니다
- 분류 정확도를 평가하는 파이프라인이 없습니다
- 규칙 기반 폴백은 한국어 전용입니다
역할
기획 · 설계 · 개발 · 배포
스택
Next.js 16 · Vercel AI SDK · Drizzle · Supabase · TypeScript