이메일 템플릿 기능 전수분석

app.rinda.ai/knowledge-base?tab=email-templates 화면에 적용된 기능의 코드 기반 분석

Frontend · React 19 + TanStack Query Backend · Elysia + Bun DB · Postgres (email_templates) AI · gemini-3-flash

시퀀스 다이어그램

진입·목록 조회 → 빌더/AI 스텝 생성 → 일괄 저장 → 그룹 삭제까지의 4개 핵심 흐름.

이메일 템플릿 기능 시퀀스 다이어그램

1네 가지 핵심 흐름

① 페이지 진입 · 목록 조회 KnowledgeBasePage lazy load → useWorkspaceEmailTemplatesGroupedGET /api/v1/email-templates/workspace/:id/groupedassertWorkspaceMatch(cross-workspace 차단) → 국가/소스별 그룹화 후 카드 렌더. 템플릿이 없으면 빈 상태 + "새 템플릿 만들기".
② 빌더 · 프리셋 선택 & 스텝 AI 생성 PresetGallery(4/6/8 스텝) + PresetPreviewDrawer → 각 스텝 BuilderStepEditor에서 "AI 생성" → POST /generate-step → AI가 { subject, bodyHtml, bodyText } 반환 → 필드 자동 채움.
③ 저장 · 다중 스텝 일괄 생성 useCreateBulkEmailTemplatesPOST /bulk-create → 서버가 stepOrder=i+1, totalSteps=len, createdBy 부여 → 다중 행 INSERT → 캐시 invalidate → 목록 자동 refetch + 성공 토스트.
④ 그룹 삭제 useDeleteEmailTemplateGroupDELETE /api/v1/email-templates/bulkDELETE WHERE id IN (...) → 캐시 invalidate → refetch + 삭제 토스트.

2백엔드 API 엔드포인트

전부 inline macro workspaceAuth: true (default-deny IAM · ADR-0001).

MethodPath역할
POST/generate시장별 AI 템플릿 일괄 생성 (productId·targetCountry·language·stepCount)
POST/generate-step단일 스텝 AI 콘텐츠 생성
POST/bulk-create수동 다중 스텝 템플릿 일괄 생성
GET/workspace/:id/grouped국가/소스별 그룹화 조회
GET/search필터 검색 (헤더 workspace만 신뢰 · cross-workspace enum 방지)
POST / PUT / DELETE/ · /:id단건 생성·수정·삭제
DELETE/bulk그룹(다중 id) 일괄 삭제
PUT/admin/.../bulk/category·shared어드민 카테고리·공유 상태 일괄 변경

3코드 맵

Frontendadmin/src

파일역할
pages/knowledge-base/index.tsxknowledge-base 페이지 · 탭 라우팅 · prefetch
pages/settings/email-templates/EmailTemplateSettings.tsx탭 컨테이너 · 목록/생성/편집 모드 관리
.../EmailTemplateList.tsx그룹 카드 목록 · 빈 상태 · 편집/삭제 액션
.../EmailTemplateBuilder.tsx생성/편집 폼 · AI 스텝 생성
.../BuilderStepList · BuilderStepEditor.tsx스텝 목록/편집 (stepType·subject·body)
.../PresetGallery · PresetPreviewDrawer.tsx4/6/8 스텝 전략 프리셋
lib/api/hooks/email-templates.tsTanStack Query 후크 · 캐시 키
lib/api/services/email-templates.tsAPI 클라이언트
lib/api/types/email-template.ts타입 정의

Backendelysia-server/src

파일역할
routes/email-templates.routes.tsCRUD + AI 생성 라우트 (workspaceAuth)
services/email-template.service.ts비즈니스 로직 (그룹화·필터·bulk)
services/email-template-generation.service.tsAI 다중 스텝 생성
db/schema/email-templates.tsDrizzle 스키마

4DB 스키마 — email_templates

PostgresUUIDv7 PK · workspace cascade delete · 다중 스텝을 행 단위로 저장.

컬럼타입설명
iduuidPK (uuidv7)
workspaceIduuid워크스페이스 (cascade)
name / subjectvarchar템플릿명 / 제목
bodyText / bodyHtmltext평문 / HTML 본문
sourcevarchar(20)ai_generated · manual
targetCountry / languagevarchar대상 국가 / 언어
stepTypevarchar(50)스텝 전략 (initial_contact 등)
stepOrder / totalStepsinteger스텝 순서 / 총 스텝 수 (4·6·8)
category / isSharedvarchar / bool카테고리 / 공유 여부
variablesjsonb플레이스홀더

인덱스: workspaceId, createdBy, category, name, (workspaceId, targetCountry), (workspaceId, source)

요약

하나의 "템플릿"은 여러 스텝(행)의 묶음이며, 같은 name으로 그룹화된다. 생성은 프리셋(4/6/8 스텝) → 스텝별 AI 생성 → bulk-create 일괄 저장 흐름이고, 조회·삭제는 모두 그룹 단위로 동작한다. 모든 라우트가 workspaceAuth default-deny로 cross-workspace 접근을 차단한다. SSOT는 email_templates 테이블 한 곳.