Rinda 이메일 발신 설정 분석 & 정리 계획

대상: elysia-server/src/config.ts · 데이터 출처: beta DB 실측(최근 30일) · 2026-06-15

1. 발신 체계는 3계층 — 섞으면 안 된다

계층발신 주소SSOT 위치제어
시스템 메일
인증·넛지·알림·상담·후속·공지
no-reply@hi.rinda.ai config.ses.senderEmail
= env AWS_SES_SENDER_EMAIL
SSOT 통일 완료 ✓
답장 수신
Reply-To
admin@grinda.ai config.cs.replyToEmail
= env CS_REPLY_TO_EMAIL
SSOT 통일 완료 ✓
캠페인/시퀀스 발송
유저가 보내는 콜드메일
xxx@mail.rinda.ai
워밍업 풀 도메인
DB user_email_accounts +
rinda_managed_sending_domains
(코드 fallback RINDA_MAIL_DOMAINS)
config.ts env 무관
중요 교정: 캠페인 발송은 별도 테이블(user_email_accounts)의 유저 계정으로 나갑니다. 발신 도메인 SSOT는 DB(rinda_managed_sending_domains) + 코드 상수 RINDA_MAIL_DOMAINS(mail.rinda.ai~mail10)이며, AWS_SES_FROM_EMAIL 환경변수와는 무관합니다. 따라서 이 env를 지워도 캠페인 발송은 깨지지 않습니다.

2. config.ts 메일 설정 — 항목별 현황

config 경로env / default코드 참조판정
ses.senderEmailAWS_SES_SENDER_EMAIL
def no-reply@hi.rinda.ai
발송 8곳+유지 (핵심 SSOT)
cs.replyToEmailCS_REPLY_TO_EMAIL
def 없음(부팅강제)
답장 10곳+유지 (핵심 SSOT)
sendgrid.apiKeySENDGRID_API_KEYweekly-digest·suppression·partners 등 광범위유지 (필수)
sendgrid.fromEmailSENDGRID_FROM_EMAIL
def rinda@send.grinda.ai
weekly-digest fallback유지(별개 범위)·default는 누수 패턴
sendgrid.fromNameSENDGRID_FROM_NAMEweekly-digest유지
ses.fromEmailAWS_SES_FROM_EMAIL
def mail.rinda.ai
admin-ses-identity 도메인 추출 1곳 (발송 아님)제거 가능
ses.fromNameAWS_SES_FROM_NAME참조 0제거 완료 ✓ (#8682/8683)
emailProvider.defaultEMAIL_PROVIDER_DEFAULT
def "sendgrid" (레거시)
email.service.ts:710default를 "ses"로 변경 권장

3. 환경변수 3환경 현황

localalphabeta
AWS_SES_SENDER_EMAILno-reply@hi.rinda.ai동일동일
CS_REPLY_TO_EMAILadmin@grinda.ai동일동일
AWS_SES_FROM_EMAIL(def mail.rinda.ai)mail.rinda.aimail.rinda.ai
AWS_SES_FROM_NAME제거됨제거됨
EMAIL_PROVIDER_DEFAULT없음 → sendgrid 폴백sesses
local만 SendGrid 경로: EMAIL_PROVIDER_DEFAULT가 local에 없어 코드 default(sendgrid)로 폴백 → 로컬 발송 디버깅이 운영(ses)과 달라집니다. 코드 default를 ses로 바꾸면 모든 환경이 일치하고 이 함정도 사라집니다.

4. 정리 계획 (정정판)

1
코드config.ses.fromEmail 정의 제거 + admin-ses-identity:76RINDA_MAIL_DOMAIN 상수로 교체
발송 미사용, 도메인 추출 1곳만 SSOT 상수로 대체 → 동작 무변경
2
코드config.ts:290 emailProvider.default "sendgrid""ses"
레거시 default 제거. 모든 환경 ses 기본 → local env 불필요
3
envAWS_SES_FROM_EMAIL 제거 (alpha·beta)
①②머지·재배포로 코드 미참조 확정 후 삭제
4
envEMAIL_PROVIDER_DEFAULT 제거 (alpha·beta)
②로 코드 default가 ses → env 중복. (명시 유지를 원하면 생략 가능)
5
코드RINDA_MAIL_DOMAINS / FALLBACK_DOMAINS에서 mail01~mail10 제거
DB·발송·SES identity 3곳 모두 0건 (아래 §7). fallback을 실제 운영(mail.rinda.ai 1개 또는 DB와 동기화)으로 정정
6
코드 — 외부 미참조 export(RINDA_MAIL_DOMAINS·isRindaMailDomain·RINDA_MAIL_DOMAIN_SET) 정리
검증 로직에서 안 쓰임. RINDA_RESERVED(유저 등록 차단)만 유지 — mail01~10은 SES에 없으니 예약에서도 제거 가능

순서: 코드 머지(①②⑤⑥) → 재배포 확인 → env 제거(③④) 가 안전 (미참조 확정 후 삭제).

5. 절대 건드리지 말 것

주의 구분: mail.rinda.ai(실사용, 유지) ≠ mail01~mail10(미사용, 제거 대상). DB SSOT는 mail.rinda.ai만 등록돼 있고 mail01~10은 어디에도 없음.

7. RINDA_MAIL_DOMAINS & mail01~mail10 — 제거 가능 (죽은 항목)

코드 상수 RINDA_MAIL_DOMAINS = [mail.rinda.ai, mail01~mail10]mail01~mail10은 3중 검증 결과 완전 미사용입니다:

검증 항목mail.rinda.aimail01 ~ mail10.rinda.ai
DB rinda_managed_sending_domains등록됨없음
beta 발송(emails, 30일)35,042건0건
SES verified identity(별도 경로)없음
코드 외부 참조RINDA_MAIL_DOMAINS export 자체가 외부 참조 0 (RINDA_RESERVED 내부 spread만)
실제 SSOT 불일치: 운영 발신 도메인은 DB의 21개(ask·brief·chat·hello·hey·hi·intro·knock·letter·mail·meet·memo·note·ping·post·reach·say·share·sync·talk·voice). 코드 fallback은 [mail, mail01~10]으로 실제와 완전히 다릅니다 → DB 장애 시 fallback이 작동하면 SES에 없는 mail01~10으로 발송 시도 → 전부 실패. 현재 fallback은 안전망 역할을 못 합니다.

권장:mail01~mail10 코드에서 제거 ② fallback을 mail.rinda.ai 1개(또는 DB 21개와 동기화)로 정정 ③ 미참조 export 정리. DB가 진짜 SSOT이므로 fallback은 최소 안전망만 남기면 충분.

6. beta 실측 — 발송 도메인 분포 (최근 30일)

발신 도메인발송 건수성격
chat.rinda.ai44,305캠페인 워밍업 풀
mail.rinda.ai33,765캠페인 (Rinda Mail 기본)
send.grinda.ai14,492레거시 (최근 7일 9건으로 급감)
ask / intro / memo / say.rinda.ai각 6~11k캠페인 워밍업 풀
hi.rinda.ai5,938시스템 메일

→ 캠페인은 mail.rinda.ai 단일이 아니라 다수 워밍업 도메인 풀로 분산 발송. 모두 user_email_accounts 기반.