knowledge-base?tab=email-templates 템플릿을 실제 시퀀스 발송에 적용하는 최적 아키텍처
sequence_step_contents(발송 SSOT)로 복사해 시퀀스를 시드하고,
emailTemplateId는 provenance로만 유지한다. live-reference는 진행 중 캠페인 안정성을 깨므로 기각.
| 항목 | 상태 | 근거 |
|---|---|---|
sequenceSteps.emailTemplateId FK | 스텁 | sequences.ts:173 // add relation later |
| 발송 워커가 email_templates read | ✕ 없음 | workers/ grep 0건 |
| 발송 콘텐츠 SSOT | sequence_step_contents | email-content-resolver.service.ts:174 (stepId+leadId) |
| 템플릿 실제 용도 | AI 참고만 | campaign-email-streaming:776, sequence-proposal/…query.ts:30 |
→ 템플릿 저장소와 발송 파이프라인이 기능적으로 단절. emailTemplateId는 dangling 스텁.
| 기준 | A. Copy-on-apply | B. Live-reference |
|---|---|---|
| 진행 중 캠페인 안정성 | ✓ 템플릿 수정이 발송 중 코호트에 영향 없음 | ✕ 수정 시 in-flight 변조 |
| SSOT | ✓ 기존 sequence_step_contents 재사용 | ✕ 콘텐츠 모델 2개 → drift |
| 개인화 모델 (leadId NULL/UUID) | ✓ 그대로 동작 | ✕ 충돌 |
| 발송 hot-path 비용 | ✓ 추가 read 없음 | ✕ 템플릿 join 추가 |
| 템플릿 개선 전파 | ✕ 자동 안 됨 (→ 명시적 re-sync 보완) | ✓ 자동 |
템플릿 스텝을 그대로 복사 → sequence_step_contents(leadId=NULL). 정성 작성한 source=manual 템플릿 대상. 결정적·빠름.
템플릿을 참고로 AI가 리드별 재생성 (이미 부분 존재). source=ai_generated·개인화 강조 대상.
L0(병렬) L1 L2 ┌──────────────┐ ┌─────────────────────┐ ┌──────────────┐ │N0.1* S │═▶│N1.1* M apply API │═▶│N2.1* M 빌더 │ │apply preview │ │POST /sequences/ │ │"템플릿에서 │ │+ 변수커버리지 │ │ from-template (tx) │ │ 시작" picker │ └──────────────┘ └─────────────────────┘ └──────────────┘ ┌──────────────┐ ┌─────────────────────┐ │N0.2 S 도달율 │─▶│N1.2 S provenance │ │HTML→text 적용│ │emailTemplateId 기록 │ └──────────────┘ └─────────────────────┘
| 노드 | 내용 | verify |
|---|---|---|
N0.1* [S] | apply-preview: 템플릿 그룹→시퀀스 스텝 매핑 + 변수 커버리지(리드 스키마의 {{var}}) + country/lang 일치 리포트 | 미해결 변수 0건이면 green |
N0.2 [S] | 도달율 정규화: 적용 시 HTML-only→text/plain 자동생성(커밋 73397ca1b) 재사용 | text 대체본 존재 |
N1.1* [M] | apply API: POST /api/v1/sequences/from-template { templateIds[] }, 단일 tx로 N스텝+contents 시드, workspaceAuth+assertWorkspaceMatch | 부분실패 시 전체 rollback |
N1.2 [S] | provenance: sequenceSteps.emailTemplateId 채움(감사용, 발송엔 미사용) | FK 채워짐 |
N2.1* [M] | 빌더 UX: "템플릿에서 시작" → useWorkspaceEmailTemplatesGrouped 재사용 picker + PresetPreviewDrawer 패턴 미리보기 → Apply 후 편집 가능 | 적용 후 스텝 편집 정상 |
| 라운드 | 발견 갭 | 반영 |
|---|---|---|
| R1 | 변수 미스매치 / country 불일치 / 자동전파 위험 | preview에 변수커버리지·언어경고 추가, 전파는 명시적 opt-in |
| R2 | 부분실패 원자성 | apply 단일 tx (createSequenceStep 기존 tx 활용) |
| R3 | 잔여 트레이드오프(자동전파 없음) | 의도된 설계 — 콜드메일 안정성 우선, 기각 |
→ R3에서 신규 갭 0건. 설계 수렴 완료.
최적 적용법 = copy-on-apply 인스턴스화 + 2-모드(직접/AI-보조) + preview 변수검증 + tx 원자성 + 명시적 re-sync.
신규 SSOT·스키마 추가 없이 기존 sequence_step_contents·emailTemplateId 재사용으로 dangling 스텁을 실제 적용 경로로 승격.