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.senderEmail | AWS_SES_SENDER_EMAIL def no-reply@hi.rinda.ai | 발송 8곳+ | 유지 (핵심 SSOT) |
cs.replyToEmail | CS_REPLY_TO_EMAIL def 없음(부팅강제) | 답장 10곳+ | 유지 (핵심 SSOT) |
sendgrid.apiKey | SENDGRID_API_KEY | weekly-digest·suppression·partners 등 광범위 | 유지 (필수) |
sendgrid.fromEmail | SENDGRID_FROM_EMAIL def rinda@send.grinda.ai | weekly-digest fallback | 유지(별개 범위)·default는 누수 패턴 |
sendgrid.fromName | SENDGRID_FROM_NAME | weekly-digest | 유지 |
ses.fromEmail | AWS_SES_FROM_EMAIL def mail.rinda.ai | admin-ses-identity 도메인 추출 1곳 (발송 아님) | 제거 가능 |
ses.fromName | AWS_SES_FROM_NAME | 참조 0 | 제거 완료 ✓ (#8682/8683) |
emailProvider.default | EMAIL_PROVIDER_DEFAULT def "sendgrid" (레거시) | email.service.ts:710 | default를 "ses"로 변경 권장 |
3. 환경변수 3환경 현황
| 키 | local | alpha | beta |
|---|---|---|---|
AWS_SES_SENDER_EMAIL | no-reply@hi.rinda.ai | 동일 | 동일 |
CS_REPLY_TO_EMAIL | admin@grinda.ai | 동일 | 동일 |
AWS_SES_FROM_EMAIL | (def mail.rinda.ai) | mail.rinda.ai | mail.rinda.ai |
AWS_SES_FROM_NAME | — | 제거됨 | 제거됨 |
EMAIL_PROVIDER_DEFAULT | 없음 → sendgrid 폴백 | ses | ses |
local만 SendGrid 경로:
EMAIL_PROVIDER_DEFAULT가 local에 없어 코드 default(sendgrid)로 폴백 →
로컬 발송 디버깅이 운영(ses)과 달라집니다. 코드 default를 ses로 바꾸면 모든 환경이 일치하고 이 함정도 사라집니다.
4. 정리 계획 (정정판)
1
코드 —
발송 미사용, 도메인 추출 1곳만 SSOT 상수로 대체 → 동작 무변경
config.ses.fromEmail 정의 제거 + admin-ses-identity:76을 RINDA_MAIL_DOMAIN 상수로 교체발송 미사용, 도메인 추출 1곳만 SSOT 상수로 대체 → 동작 무변경
2
코드 —
레거시 default 제거. 모든 환경 ses 기본 → local env 불필요
config.ts:290 emailProvider.default "sendgrid" → "ses"레거시 default 제거. 모든 환경 ses 기본 → local env 불필요
3
env —
①②머지·재배포로 코드 미참조 확정 후 삭제
AWS_SES_FROM_EMAIL 제거 (alpha·beta)①②머지·재배포로 코드 미참조 확정 후 삭제
4
env —
②로 코드 default가 ses → env 중복. (명시 유지를 원하면 생략 가능)
EMAIL_PROVIDER_DEFAULT 제거 (alpha·beta)②로 코드 default가 ses → env 중복. (명시 유지를 원하면 생략 가능)
5
코드 —
DB·발송·SES identity 3곳 모두 0건 (아래 §7). fallback을 실제 운영(
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도메인 + DBrinda_managed_sending_domains(운영 21개 도메인) — 캠페인 발신 핵심 (실사용 SSOT) - ✗
SENDGRID_API_KEY— weekly-digest·suppression-sync 실사용 - △
SENDGRID_FROM_EMAILdefaultsend.grinda.ai— weekly-digest fallback에 남은 동일 누수 패턴(이번 범위 밖, 후속 검토)
주의 구분: 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.ai | mail01 ~ 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.ai | 44,305 | 캠페인 워밍업 풀 |
mail.rinda.ai | 33,765 | 캠페인 (Rinda Mail 기본) |
send.grinda.ai | 14,492 | 레거시 (최근 7일 9건으로 급감) |
ask / intro / memo / say.rinda.ai | 각 6~11k | 캠페인 워밍업 풀 |
hi.rinda.ai | 5,938 | 시스템 메일 |
→ 캠페인은 mail.rinda.ai 단일이 아니라 다수 워밍업 도메인 풀로 분산 발송. 모두 user_email_accounts 기반.