QA #19 · 코드 정독 분석

넛지 메일 발송 로직 구현 분석

72시간 활성화 넛지 · 자료실 넛지 · 일본 바이어 넛지 · 언어별 발송 · 발송율 페이싱

대상: elysia-server · 분석일 2026-06-25 · 정적 코드 분석 기반

TL;DR

1. QA 명세 ↔ 실제 구현 갭 가장 중요

QA #19 기대실제 코드평가
"발송 0건 체험(trial) 계정"에 72h 넛지 조건 = noBuyerSearchDays:3(바이어검색 0건). trial 한정 아님, "발송 0건"도 아님 조건 불일치 바이어검색만 안 한 유료·발송이력 계정도 대상 가능
자료실·일본바이어 넛지 전 로케일 정상발송 자료실 6개 입력 → ko/ja/en 3개만, id/zh-CN/th → 영어. 자동넛지 zh/th 템플릿 없음 → ko 폴백 모국어 누락 발송 자체는 됨
발송율 페이싱으로 부분발송 사고 없음 자동넛지=순차 for(페이싱 없음), 자료실=건당 1통. 페이싱 코드(14통/s)는 release-note 전용 페이싱 부재 SES adaptive 재시도에만 의존
#19를 코드 그대로 QA하면 "정상"이 나오지만, 명세가 의도한 동작과는 다릅니다. 명세를 코드에 맞추거나, 코드를 명세에 맞춰야 합니다.

2. 정정 — 시간 윈도우는 안전 오판 정정

bounds(): 윈도우 폭 delay + 2h, 워커는 55분 주기(auto-nudge.worker.ts:41). 직접 검산:

윈도우를 워커주기 대비 여유있게 둔 설계는 합리적입니다.

3. 실제 유효한 결함 (심각도순)

심각도위치내용
MEDrelease-note-nudge.service.ts:36페이싱 14통/s가 단일 인스턴스 가정. SES 25/s를 시퀀스·OTP·자동넛지와 공유 → 여러 발송원 동시 가동 시 합산 초과 → throttle. 시퀀스 워커의 throttleRedis 같은 전역 throttle 부재
MEDrelease-note-nudge.service.ts:432partial 시 실패 수신자 목록 미저장(failedCount 숫자만) → 재발송 시 전체 재발송=중복 위험. 자동 재시도 없음
MEDauto-nudge.service.ts:620-653SES 성공 후 DB insert 실패 시 failed++ 처리되나 메일은 이미 발송 → 통계 부정확 + (unique 덕에) 재발송 차단되어 영구 누락
MEDauto-nudge.service.ts:302trialOnly 쿼리는 정상이나 시드에 이 조건을 쓰는 넛지가 없음 → 명세갭 ①의 원인
LOWauto-nudge.service.ts:89-121모든 언어 템플릿 null이면 warn만 찍고 silent skip. seed엔 ko 있어 실제 발송은 되나 템플릿 관리 실수 시 침묵 누락

4. 잘 된 부분 GOOD

5. 결론 & 우선순위

런타임 크래시·치명 버그는 없음. "잘 구현"은 맞되, QA #19 명세와 코드 사이 정의 불일치(조건·페이싱·언어 커버리지)가 진짜 문제.