Leads 화면 · 리드 업로드 아키텍처

send-grid-test 모노레포 — Admin(React 19) ↔ elysia-server(Elysia/Bun) 코드 흐름 분석

개인용 분석 문서 · noindex · 생성일 2026-06-11

0. 전체 구조

Monorepo: admin(React 19 + Vite + TanStack Query + Jotai) + elysia-server(Elysia + Bun) + e2e(Playwright). 백엔드는 routes → services → db(Drizzle) 3-layer.

Component Query/State Hook FE service (fetch)⇒ HTTP ⇒ routes services Postgres

1. Leads 목록 / 조회 화면 Frontend

컴포넌트 트리

  • LeadsPage — 조합 루트, 8개 뷰 조건부 렌더
    pages/leads/LeadsPage.tsx
  • LeadsTableWithPagination — 테이블 + 페이지네이션, 모바일 카드 전환
    pages/leads/LeadsTableWithPagination.tsx
  • LeadsTableHeader / Body / GroupGallery / SearchBar / TabNav

데이터 · 상태

  • useLeads() — TanStack Query, staleTime 30s
    lib/api/hooks/leads.ts
  • useLeadsPageState() — cursor stack · 필터 · 선택 · 페이지 중앙 관리
    pages/leads/hooks/useLeadsPageState.ts
  • keyword→debouncedKeyword (300ms), localStorage 그룹 persist

페이지네이션 분기 (CLAUDE.md: OFFSET 금지 원칙)

  • Keyset (기본·안전): 그룹 미선택 + sortField=createdAt + descORDER BY createdAt, id LIMIT n+1. 새 리드 추가 중에도 순서 보장, cursor stack push/pop.
  • Offset (fallback): 그룹별 조회 또는 fitScore 등 동적 정렬 시 offset = (page-1)·size.

2. 리드 업로드 (Smart Import) Frontend Backend

AddBuyersPage — 3단계 pages/leads/AddBuyersPage.tsx

① StepGroupSelect
그룹 선택/생성
② StepUpload
파일 드롭 + 자동 분석
③ StepMapping
컬럼 매핑 + 임포트
  • 분석: POST /smart-import/analyze (FormData) → AI가 suggestedMapping 제안
  • 매핑 검증: 식별자(companyName · websiteUrl · email) 최소 1개 필수, confidence < 0.75 강조
  • 임포트: POST /smart-import/start (SSE 스트림) — parse → dedup → verify → import 단계별 이벤트

백엔드 파이프라인 services/lead-import.service.ts · lead-ingestion.service.ts

  • 파싱: UTF-8 BOM 제거 → EUC-KR fallback, XLSX 시트 선택
  • 중복: URL host 정규화 · 이메일(파일내+WS DB) · 회사명 정규화 3중 dedup
  • 검증: MillionVerifier 배치(concurrency 50) — undeliverable / risky(score≤20) 거절
  • 적재: ingestLeadsIntoGroup() — leads(UUIDv7) + leadContacts/social/products/sectors + customerGroupMembers INSERT, BullMQ 검증 잡 enqueue
  • 컴플라이언스: GDPR Art.6/7 consent 컬럼 UPDATE + consent_given 감사 로그
레거시 직접 업로드 경로 POST /api/v1/admin/lead-import/upload 도 존재 — consent 근거(legalBasis·source·evidence) 필수, 동일 importLeadsBatch 코어 공유.

3. 시퀀스 다이어그램 — Leads 조회

Leads 목록 조회 시퀀스 다이어그램

4. 시퀀스 다이어그램 — 리드 업로드

리드 업로드 시퀀스 다이어그램

5. 주요 API 엔드포인트

Method경로인증용도
GET/api/v1/leads/searchworkspaceAuth LEADS:LIST목록 조회 (keyset/offset)
GET/api/v1/leads/{id}auth상세 조회
GET/api/v1/leads/{id}/full-detailauth상세 + 평가
POST/api/v1/smart-import/analyzeworkspaceAuth파일 분석 · 매핑 제안
POST/api/v1/smart-import/startworkspaceAuth · CSRF임포트 파이프라인 (SSE)
POST/api/v1/admin/lead-import/uploadworkspaceAuth레거시 직접 업로드 (SSE)
POST/api/v1/leads/bulkauthCSV 일괄 생성
PUT/api/v1/leads/{id}auth수정
DEL/api/v1/admin/leads/bulkadminAuth일괄 삭제

6. 핵심 파일

Admin

  • pages/leads/LeadsPage.tsx
  • pages/leads/LeadsTableWithPagination.tsx
  • pages/leads/hooks/useLeadsPageState.ts
  • pages/leads/AddBuyersPage.tsx
  • pages/leads/add-buyers/Step{Upload,Mapping}.tsx
  • lib/api/hooks/{leads,smart-import}.ts
  • lib/api/services/{leads,smart-import}.ts

elysia-server

  • routes/leads.routes.ts
  • routes/lead-import.routes.ts
  • services/lead-search.service.ts
  • services/lead-import.service.ts
  • services/lead-ingestion.service.ts
  • db/schema → leads, lead_contacts ...