o2o-infinith-demo/docs/DESIGN_신청알림메일_v0.1.md
Haewon Kam 74c70d656e docs(design): 신청 접수 알림과 완료 안내 메일 설계 v0.1
랜딩 신청 모달은 남긴 연락처로 안내한다고 말하는데 보내는 코드가 없다.
운영자도 신청이 들어온 사실을 알 방법이 없다. discovery_leads 는 anon insert 만
열려 있고 폴러는 supporter_builds 만 본다.

메일을 셋으로 나눈다. 접수 확인(신청자)과 신규 신청 알림(운영자)은 insert 트리거로
자동 보내고, 완료 안내는 사람이 보낸다. 자동으로 보내면 사진 검토를 건너뛴 링크가
나간다. 발송은 Edge Function 에 두고 프런트에서 부르지 않는다(anon 키 스팸 경로).
email_log 로 중복 발송을 막고 안 갔다는 문의에 답할 근거를 남긴다.
연락처가 전화번호일 수 있어 contact_kind 를 함께 저장한다.

발송 서비스 계정·발신 도메인·"리포트"의 정의는 결정 대기로 8절에 적었다.

개인 업무 문서(주간보고)는 저장소에 올리지 않는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 16:22:28 +09:00

7.8 KiB

설계: 신청 접수 알림과 완료 안내 메일 v0.1

작성 2026-09-18 · 대상 AI Discovery 랜딩(/discovery) 신청 흐름


1. 지금 무엇이 비어 있나

랜딩 신청 모달은 이렇게 말합니다.

입력하신 URL을 실측 진단한 뒤, 남겨주신 연락처로 리포트를 안내드립니다.

보내는 코드가 없습니다. workers/, scripts/, supabase/functions/ 전체에 메일 발송이 없습니다. 유일한 mailto:는 저장 실패 시 사람이 직접 메일을 쓰라고 띄우는 폴백입니다(DiscoveryLeadModal.tsx:82).

그래서 지금은 이렇게 됩니다.

신청 → discovery_leads (status: new)
     → supporter_builds 큐 → 워커가 빌드 → preview
     → 여기서 끝. 신청자에게도, 운영자에게도 아무 연락이 없음

2026-09-18 JK성형외과 신청이 정상 접수되고 10분 만에 빌드까지 끝났지만, 신청자가 직접 확인하기 전까지 아무도 몰랐습니다.

문제는 두 갈래입니다.

문제
운영자 신청이 들어온 사실을 알 방법이 없습니다. discovery_leads는 anon insert만 열려 있고 조회는 service_role 전용이며, 폴러는 supporter_builds만 봅니다
신청자 화면이 약속한 안내를 받지 못합니다

2. 설계 원칙

원칙 1. 자동 발송은 접수 알림까지만 한다.

완료 안내를 자동으로 보내면 사람 검토를 건너뛴 결과물 링크가 나갑니다. 이번 JK 건에서 첫 화면 대표 사진이 사람 확인이 필요한 사진이었던 것을 생각하면, 자동 발송이 아니었던 것이 결과적으로 안전했습니다. 완료 안내는 사람이 보내기를 누를 때 나갑니다.

원칙 2. 화면의 약속과 코드를 맞춘다.

지금 모달 문구는 자동으로 갈 것처럼 읽힙니다. 실제 동작에 맞게 문구를 고치거나, 동작을 문구에 맞추거나 둘 중 하나를 해야 합니다. 이 설계는 후자에 가깝되 검토 단계를 명시하는 쪽입니다.

원칙 3. "리포트"라는 말을 정확히 쓴다.

현재 파이프라인이 만드는 것은 서포터즈 사이트입니다. 랜딩이 말하는 AEO/GEO 36항목 진단 리포트(/discovery/viewclinic 형태)는 이 빌드에서 생성되지 않습니다. 신청 한 건이 서로 다른 두 산출물로 갈라져 있어, 메일 문안에서 무엇을 보내는지 분명히 해야 합니다.


3. 보내는 메일 3종

3-1. 접수 확인 (신청자에게, 자동)

  • 시점: discovery_leads insert 직후
  • 받는 사람: 신청자가 남긴 연락처
  • 내용: 접수 사실, 어떤 URL로 접수됐는지, 언제쯤 연락이 가는지, 문의처(o2oteam@o2o.kr)
  • 보내지 않는 것: 결과 링크, 진행률

3-2. 신규 신청 알림 (운영자에게, 자동)

  • 시점: 3-1과 동시
  • 받는 사람: 운영 담당 주소 1개
  • 내용: 병원명·URL·연락처, 빌드 큐 등록 여부, 확인 화면 링크(/images/<clinic_id>, /supporters/<clinic_id>)
  • 목적: 신청을 놓치지 않는 최소 장치. 이것만 있어도 지금 상태보다 낫습니다

3-3. 완료 안내 (신청자에게, 사람이 보냄)

  • 시점: 운영자가 이미지 검토와 결과 확인을 마치고 보내기를 눌렀을 때
  • 받는 사람: 신청자
  • 내용: 무엇을 만들었는지, 미리보기 링크(noindex), 병원이 확인해야 할 것 두 가지(/images/<id> 사진 확인, /supporters/<id> 확인 항목), 색인 전환은 법무 확인 뒤라는 안내
  • 전제: 발송 전에 사진 검토가 끝나 있어야 합니다

4. 무엇으로 보내나

4-1. 발송 수단

현재 메일 발송 키가 하나도 없습니다. .env에 Resend·SendGrid·SES·SMTP 어느 것도 없어 계정부터 필요합니다.

후보 장점 단점
Resend (추천) Edge Function에서 fetch 한 번. 도메인 인증이 단순. 무료 한도로 이 규모는 충분 계정·도메인 인증 필요
SendGrid 전달률 기록이 길다 설정 항목이 많다
AWS SES 단가가 가장 낮다 샌드박스 해제 심사가 필요

발신 도메인은 o2o.kr 계열을 쓰고, 신규 도메인은 초기 전달률이 낮으므로 SPF·DKIM·DMARC를 먼저 맞춥니다.

4-2. 발송 위치

Supabase Edge Function notify-lead 를 새로 만듭니다.

프런트에서 직접 부르지 않습니다. 프런트가 부르면 anon 키로 메일을 쏠 수 있게 되어 스팸 경로가 됩니다. DB 변경을 신호로 삼습니다.

discovery_leads INSERT
  → Postgres 트리거 (pg_net)
  → Edge Function notify-lead (service_role 검증)
  → Resend 호출 2건 (신청자 접수 확인 + 운영자 알림)
  → email_log 기록

완료 안내(3-3)는 같은 함수의 다른 진입점으로 두고, 운영자 화면의 버튼에서 호출합니다.


5. 필요한 DB 변경

5-1. email_log 신설

무엇을 언제 누구에게 보냈는지 남깁니다. 중복 발송을 막고, 안 갔다는 문의에 답할 근거가 됩니다.

용도
id
kind lead_ack · lead_notify · build_done
lead_id / clinic_id 대상
to_addr 받는 주소
status sent · failed
provider_id 발송 서비스가 준 id. 전달 추적용
error 실패 사유
created_at

중복 발송 방지는 (kind, lead_id) 유니크로 겁니다.

5-2. discovery_leads.status 를 실제로 쓴다

지금은 모든 행이 new로 고정입니다. 흐름을 담도록 값을 정합니다.

new → notified(접수 메일 발송) → building → review(사람 검토 중)
    → delivered(완료 안내 발송) → closed

5-3. 연락처가 이메일이 아닐 수 있다

모달은 "이메일 또는 전화번호"를 받습니다. 전화번호면 메일을 보낼 수 없습니다.

  • 저장 시 형식을 판별해 contact_kind(email · phone)를 같이 남깁니다
  • phone이면 접수 메일을 건너뛰고 운영자 알림에 전화로 연락 필요를 표시합니다

6. 화면에서 고칠 것

위치 지금 바꿀 안
신청 모달 완료 문구 "실측 진단한 뒤, 남겨주신 연락처로 리포트를 안내드립니다" "접수됐습니다. 확인 메일을 보내 드렸습니다. 결과가 준비되면 남겨주신 연락처로 안내드립니다"
운영자 화면 없음 완료 안내 발송 버튼. 사진 검토가 끝나지 않았으면 버튼을 잠그고 이유를 표시

7. 만들 순서

순서 할 일 비고
1 발송 서비스 계정과 도메인 인증 haewon 결정 필요. 이것 없이는 아무것도 못 보냅니다
2 email_log 테이블, contact_kind 열 추가
3 Edge Function notify-lead + 트리거 3-1·3-2 자동 발송
4 모달 문구 수정 1~3과 무관하게 지금 할 수 있습니다
5 완료 안내 발송 버튼 사진 검토 완료 조건과 묶습니다

1번이 없으면 2~3번이 무의미하므로, 4번을 먼저 넣어 화면과 코드의 어긋남부터 없애는 방법도 있습니다.


8. haewon 결정이 필요한 것

  1. 발송 서비스: Resend를 추천합니다. 계정과 발신 도메인(o2o.kr 하위 무엇으로 할지)이 필요합니다
  2. 운영자 알림 수신 주소: 개인 주소인지 공용 주소인지
  3. 완료 안내를 사람이 보내는 방식으로 할지: 자동 발송으로 하면 사진 검토를 건너뛴 링크가 나갈 수 있습니다. 이 설계는 사람이 보내는 쪽을 전제합니다
  4. "리포트"의 정의: 완료 안내로 보내는 것이 서포터즈 사이트인지, AEO/GEO 진단 리포트인지, 둘 다인지. 지금 파이프라인은 앞의 것만 만듭니다