2026-08-29 · 최종 설계

Front / Backend 와이어프레임

화면 · DB · API · 견적 엔진 · 배포까지

🏗️ 시스템 전체도

FRONT (공개)
정적 HTML · 랜딩 · 견적기 · 가이드
ADMIN (비공개)
Basic Auth
↕
Workers + Hono
라우트 13개 · 견적 엔진
↕
D1 (SQLite)
테이블 5개
외부
텔레그램 알림 · Claude API
구성기술비용왜
정적 + APICloudflare Workers + Static Assets + Hono무료CF 공식 권고 · 이미 쓰는 스택
DBD1무료테이블 5개면 충분
알림Telegram Bot API무료라인보다 설정이 빠름
AIClaude API종량성분 대조 · 라벨 생성
PDF없음 (브라우저 인쇄)0라이브러리 불필요
로그인 · 결제 · 회원가입 없음. 서버 상태가 거의 없어서 장애 지점이 적습니다.

📱 FRONT — 7화면

① 랜딩 /
thai-permit.kr≡
태국 바이어가
등록증 달라는데
없으신가요
서류 뭐가 없는지
5분이면 나옵니다
▶ 내 견적 뽑아보기
✓ 화장품 3영업일
✓ 정부수수료 제품당 1,000밧
✓ 바우처로 70% 결제 가능
📖 태국 인허가 완전 가이드 →
훅은 ?h=1~5 로 교체 (A/B)
회사 소개·메뉴 없음
② 견적 1/3 /quote
← 뒤로1 / 3
━━━━━━━░░░░░░░░ 33%
어떤 제품인가요?
🧴 화장품 · 기초/색조
🍜 식품 · 가공식품
💊 건강기능식품
🩹 의료기기 · 헬스기구
📦 일반 공산품
잘 모르겠어요 →
선택 즉시 POST /api/lead (step=1)
"모르겠어요" = 최고 품질 리드
③ 견적 2/3
← 뒤로2 / 3
━━━━━━━━━━━━━░ 66%
몇 개 품목을
등록하시나요?
1~5
6~10
11~30
30+
수출바우처 상태는?
✅ 선정됨 · 예산 남음
🕐 신청 예정
❌ 아직 모름
"선정됨" → ADMIN에서 즉시 상담 대상
④ 견적 결과 /quote/:id 💰
견적서⤓ 인쇄
화장품 · 10품목 · 태국
실부담
1,350만원
총 비용3,800만원
바우처(70%)−2,450만
일정 서류 완비 후 3영업일
서류 준비 포함 약 6주
필요 서류
전성분표CFSLOA 제조증명라벨
⚠️ 태국은 등록 명의 이전 절차가 없습니다
📞 30분 무료 상담
실부담이 제일 크게 = 놀라움 지점
명의 경고가 차별화 메시지
⑤ 상담 신청 /consult
← 견적
30분이면
다음 단계가 정해집니다
· 우리 제품이 어느 분류인지
· 서류 중 뭐가 없는지
· 바우처를 어떻게 쓰는지
회사명 *
연락처 *
희망 시간대
신청하기
필수 2개만. 제출 → 텔레그램 즉시 알림
⑥ 가이드 /guide — SEO 핵심
태국 인허가 완전 가이드
태국 인허가
카테고리별 전부 공개
1. 화장품 — 3영업일, 1,000밧
2. 식품 — 수입면허 5영업일
3. 건기식
4. 의료기기 — CSDT·ISO13485
5. 일반공산품 — 인증 불필요
6. TISI 대상 — 10,000밧
· 명의는 누가 갖나
· 라벨 태국어 11항목
· 반려 사유 TOP
· 바우처로 70% 처리
▶ 내 견적 뽑기
검색 유입의 착륙 지점
협회 배포물·세일즈 자료로 동시 사용
⑦ 인쇄용 견적서 /quote/:id/print
흰 배경 · A4 1장
· 상단 로고/연락처
· 견적 요약 표
· 필요 서류 체크리스트
· 일정 · 유효기간
· 하단 "이 견적은 개요이며 확정은 상담 후"

브라우저 인쇄 → PDF. 라이브러리 0
사내 공유가 확산 경로입니다
화면 7개가 전부입니다.
회원가입·마이페이지·결제 없음.

🖥️ ADMIN — 5화면 (Basic Auth · 나만)

① 대시보드 /admin

태국 인허가 ADMIN · 대시보드 · 리드 · 제휴 · 진행 · 설정2026-08-29
오늘 견적7
이번달132
상담5
계약1
누적매출3,800만
🔔 지금 해야 할 것
㈜코스뷰티 — 상담 신청 2시간 전즉시 연락
㈜한림푸드 — 견적만 · 바우처 선정됨먼저 연락
대한관세법인 — 제휴 회신 대기 5일리마인드
㈜예린코스 — 선크림 라벨 반려대응
훅별 성적 (A/B)
h1 4.2% · h2 1.8% · h3 3.1% · h4 2.6% · h5 —
견적완료 → 상담 전환율
유입 경로
검색 52 · 관세사 38 · 수행기관 29 · 협회 13
훅별 성적이 있어야 무엇을 버릴지 정합니다

② 리드 /admin/leads

리드 132필터: 바우처 선정됨 · 상태 견적만
회사카테고리SKU바우처견적훅상태마지막
㈜코스뷰티화장품10선정3,800만h1상담대기2시간
㈜한림푸드가공식품6선정2,900만h3견적만어제
바이오셀건기식20예정5,200만h1견적만3일
㈜예린코스화장품12선정4,100만h4계약2주
(미입력)의료기기———h22단계 이탈오늘
이탈 리드도 어느 단계에서 나갔는지 저장 → 화면 개선 근거

③ 제휴 /admin/partners

제휴 — 접촉 50 / 성사 3+ 추가
리스트업 (32)
대한관세법인
관세사
글로벌디자인
수행기관·디자인
…
연락함 (12)
서울포워딩
회신대기 5일
대한번역
담당자 부재
대화중 (3)
케이마케팅
조건 협의
제휴 (3)
비즈트랜스
소개 4건
코스인사이트
소개 2건
유형: 관세사포워더수행기관협회매체

④ 진행 /admin/registrations

㈜예린코스 (12 SKU) — 명의: 피키타이진행률 33%
제품전성분CFS번역라벨제출상태
수분크림 50ml✅✅✅✅✅등록완료
토너 200ml✅✅✅✅✅심사중 2일
선크림 SPF50✅✅✅❌—라벨 재작업
에센스 30ml✅❌———CFS 요청중
…8개 더 · 전성분 대기
🤖 AI 처리 대기   전성분 태국기준 대조 4라벨 11항목 생성 2 금지성분 체크 8 ▶ 일괄 실행
고객이 물어보면 이 화면을 그대로 보여줌 = 신뢰

⑤ 설정 /admin/settings

설정
견적 규칙
카테고리별 단가·기간·서류 목록 수정
코드 배포 없이 바꿈
훅 문구
h1~h5 랜딩 카피 수정
A/B 테스트용
알림
텔레그램 chat_id · 알림 조건
환율
THB→KRW (견적 계산용)

🗄️ DB 스키마 — 테이블 5개

-- ① 리드: 견적기에 들어온 모든 흔적 (중도이탈 포함)
CREATE TABLE leads (
  id            TEXT PRIMARY KEY,        -- uuid
  created_at    INTEGER NOT NULL,
  updated_at    INTEGER NOT NULL,
  hook          TEXT,                    -- 'h1'~'h5'  A/B 추적
  source        TEXT,                    -- search|customs|agency|assoc|direct
  referrer      TEXT,
  category      TEXT,                    -- cosmetic|food|supplement|device|goods|unknown
  sku_bucket    TEXT,                    -- '1-5'|'6-10'|'11-30'|'30+'
  voucher       TEXT,                    -- selected|planned|unknown
  step          INTEGER DEFAULT 1,       -- 1|2|3|4(완료)  ← 이탈 분석의 핵심
  company       TEXT,
  phone         TEXT,
  email         TEXT,
  memo          TEXT,
  status        TEXT DEFAULT 'new'       -- new|contacted|quoted|won|lost
);
CREATE INDEX idx_leads_status ON leads(status, updated_at);
CREATE INDEX idx_leads_voucher ON leads(voucher, step);

-- ② 견적: 계산 결과 스냅샷 (규칙이 바뀌어도 과거 견적은 그대로)
CREATE TABLE quotes (
  id            TEXT PRIMARY KEY,
  lead_id       TEXT NOT NULL REFERENCES leads(id),
  created_at    INTEGER NOT NULL,
  category      TEXT, sku_count INTEGER,
  total_krw     INTEGER,                 -- 총 비용
  voucher_krw   INTEGER,                 -- 정부 70% 부담분
  self_krw      INTEGER,                 -- 고객 실부담
  days_min      INTEGER, days_max INTEGER,
  rules_json    TEXT                     -- 계산 당시 규칙 원본 (재현용)
);

-- ③ 제휴처
CREATE TABLE partners (
  id            TEXT PRIMARY KEY,
  name          TEXT NOT NULL,
  type          TEXT,                    -- customs|forwarder|agency|assoc|media
  field         TEXT,                    -- 수행기관 분야 (겹침 판정용)
  contact       TEXT, phone TEXT, email TEXT,
  stage         TEXT DEFAULT 'listed',   -- listed|contacted|talking|partnered|dead
  intro_count   INTEGER DEFAULT 0,       -- 이 곳이 소개해준 건수 = 성과
  last_touch_at INTEGER, memo TEXT
);

-- ④ 계약 고객
CREATE TABLE clients (
  id            TEXT PRIMARY KEY,
  lead_id       TEXT REFERENCES leads(id),
  company       TEXT NOT NULL, biz_no TEXT,
  contract_at   INTEGER,
  amount_krw    INTEGER,
  channel       TEXT,                    -- direct|voucher  ← 수임한도 집계에 필수
  thai_holder   TEXT,                    -- 태국 등록 명의 보유처
  partner_id    TEXT REFERENCES partners(id)  -- 소개처
);

-- ⑤ 인허가 진행 (SKU 단위)
CREATE TABLE registrations (
  id            TEXT PRIMARY KEY,
  client_id     TEXT NOT NULL REFERENCES clients(id),
  product_name  TEXT NOT NULL, sku_code TEXT,
  doc_ingredients INTEGER DEFAULT 0,     -- 전성분표
  doc_cfs         INTEGER DEFAULT 0,     -- 판매증명서
  doc_translation INTEGER DEFAULT 0,
  doc_label       INTEGER DEFAULT 0,     -- 태국어 11항목
  doc_submitted   INTEGER DEFAULT 0,
  status        TEXT DEFAULT 'preparing',-- preparing|submitted|review|approved|rejected
  submitted_at  INTEGER, approved_at INTEGER,
  reject_reason TEXT
);
설계 포인트 3개
· leads.step — 중도이탈을 저장해야 어느 화면이 문제인지 압니다
· quotes.rules_json — 규칙이 바뀌어도 과거 견적을 재현합니다
· clients.channel — direct/voucher를 나눠야 수임한도 집계가 됩니다

🔌 라우트 — 13개 (그중 /api/* 8개)

메서드경로용도인증
GET/랜딩 (훅 ?h= 반영)—
GET/guide태국 인허가 완전 가이드 (SEO)—
GET/quote견적 3스텝 화면—
POST/api/lead리드 생성/갱신 — 단계마다 호출 (upsert)—
POST/api/quote견적 계산 → quotes 저장 → id 반환—
GET/quote/:id견적 결과 화면—
GET/quote/:id/print인쇄용 A4—
POST/api/consult상담 신청 → 텔레그램 알림—
GET/api/admin/dashboard집계 (오늘/이번달/훅별/유입별)Basic
GET/PATCH/api/admin/leads목록·필터·상태 변경Basic
GET/POST/PATCH/api/admin/partners제휴 파이프라인Basic
GET/PATCH/api/admin/registrations인허가 진행 보드Basic
POST/api/admin/ai성분 대조 · 라벨 생성 · 금지성분 체크Basic

공개 API 5개는 인증 없음. 대신 레이트 리밋(IP당 분당 20회)만 겁니다.

⚙️ 견적 엔진 — 실제 조사값으로 만든 규칙표

이 표가 곧 코드입니다. ✓ 는 이 세션에서 확인한 값, ⚠ 는 설계값.

카테고리인허가정부수수료기간명의
화장품Thai FDA 신고 ✓1,000밧/제품 ✓3영업일 ✓태국 사업자 필수
이전 절차 없음 ✓
식품수입면허 + 품목등록 ✓분류별 상이면허 5영업일 ✓태국 사업자 필수
건강기능식품식품 체계 준용분류별—태국 사업자 필수
의료기기Establishment License(Orr.7)
+ CSDT + ISO 13485 ✓
—수개월 ✓태국 법인만
외국 제조사 직접수입 불가 ✓
일반 공산품불필요 (TISI 비대상) ✓관세 + VAT 7% ✓통관일—
└ TISI 대상TISI 인증 ✓10,000밧/건 ✓45~90일 ✓—

계산식

// 1밧 ≈ 42원 (설정에서 수정 가능)
const RULES = {
  cosmetic: {
    govFeeTHB: 1000,          // 제품당 ✓
    agencyTHB: 6000,          // SKU당 민간 대행 시세 ✓
    holderTHB: 18000,         // 명의 보유 연회비 ✓
    daysMin: 3, daysMax: 3,   // 서류 완비 후 영업일 ✓
    prepWeeks: 6,             // 서류 준비 포함 ⚠
    docs: ['전성분표','CFS','LOA','제조증명','라벨'],
    warn: '태국은 등록 명의 이전 절차가 없습니다'
  },
  device: { daysMin: 60, daysMax: 180, needs: ['ISO13485','CSDT(영문)'], hard: true },
  goods:  { govFeeTHB: 0, note: 'TISI 대상 아니면 인증 불필요 · 관세+VAT 7%' },
  // food, supplement …
}

function quote(category, skuCount) {
  const r = RULES[category]
  const cost   = (r.govFeeTHB + r.agencyTHB) * skuCount + r.holderTHB
  const service = SERVICE_FEE[category](skuCount)   // ⚠ 내 수수료 (설계값)
  const total   = (cost * THB_KRW) + service
  return {
    total,
    voucher: Math.round(total * 0.7),   // 중소기업 정부보조 70% ✓
    self:    Math.round(total * 0.3),
    daysMin: r.daysMin, daysMax: r.daysMax,
    docs: r.docs, warn: r.warn
  }
}
⚠️ 견적 화면에 반드시 넣을 문구
"본 견적은 개요이며, 제품의 실제 분류와 서류 상태에 따라 달라집니다. 확정 견적은 상담 후 제공합니다."
→ 분류 오판정으로 인한 분쟁을 막습니다. 특히 의료기기/화장품 경계가 위험합니다.

🚀 배포 구조 · 개발 순서

왜 이 스택인가 — 2026-08-29 결정

🔴 Pages가 아니라 Workers입니다.
Cloudflare 공식 입장이 바뀌었습니다 — "Pages로 시작하지 마세요." Workers가 정적 자산 + SSR을 모두 지원하고, 앞으로의 모든 투자는 Workers에 갑니다. (Pages는 유지만) → 초안의 Pages 설계를 Workers로 정정했습니다.
후보강점왜 지금은 아닌가
✅ 정적 HTML + Hono빌드 0 · SEO 최상 · 이미 쓰는 스택(fanjai 62라우트) · 되돌리기 비용 0— 채택
React SPA + HonoADMIN 화면에 최적SPA는 SEO가 약함. 채널 1번이 검색인데 치명적 → 혼합 구조가 됨
React Router v7 (SSR)loaders/actions가 폼에 강함 · 타입 안전 라우트가장 무거움 · SSR이 필요한 화면이 하나도 없음(가이드는 원래 정적) · v8 마이그레이션 예고
Astro마크다운 글 = 자동 라우팅. SEO 콘텐츠에 최강API·ADMIN은 결국 별도. 글 10개는 빌드 스크립트 20줄로 충분
판단 근거는 점수가 아니라 비대칭입니다.
잘 고르면 코드가 조금 깔끔해지고, 잘못 고르면 3주차 영업 시작이 밀립니다.
이 사업이 실패한다면 견적기를 못 만들어서가 아니라 고객이 안 와서입니다.

🔁 갈아타는 시점을 미리 정해둡니다 — 리드 100건을 넘고 ADMIN에서 하루 30분 이상 쓰게 되면, 그때 /admin만 React로 뗍니다. Hono API·D1·정적 프론트는 하나도 안 버립니다.

배포 구조

thai-permit.kr  (도메인 1개 · Workers 1개)

src/index.ts            ← Hono 앱 (라우트 13개)
public/                  ← 정적 자산 (Workers Assets)
  ├─ index.html          랜딩 (훅 ?h=1~5)
  ├─ quote.html          견적 3스텝 — 순수 JS
  └─ guide/*.html        ← 마크다운 빌드 스크립트 20줄

wrangler.jsonc
{
  "name": "thai-permit",
  "main": "src/index.ts",
  "compatibility_date": "2026-08-01",
  "assets": { "directory": "./public", "binding": "ASSETS" },
  "d1_databases": [{ "binding": "DB", "database_name": "thai-permit" }],
  "vars": { "THB_KRW": "42" }
}
// secrets (wrangler secret put)
//   TG_TOKEN, TG_CHAT       텔레그램 알림
//   ADMIN_USER, ADMIN_PASS  Basic Auth
//   ANTHROPIC_KEY           AI 처리

개발 순서 — 이 순서를 지켜야 낭비가 없습니다

#무엇소요왜 이 순서
1견적 규칙표 확정 (RULES 상수)0.5일이게 없으면 화면을 못 만듦
2D1 스키마 + Hono 앱 골격 + /api/lead, /api/quote0.5일데이터부터
3견적기 화면 4개 (랜딩·1·2·결과)1.5일훅을 참으로 만드는 최소
4상담 신청 + 텔레그램 알림0.5일리드를 놓치지 않으려면
5가이드 페이지 (SEO 자산)1일유입의 착륙 지점
6인쇄용 견적서0.5일확산 경로
7배포 · 도메인 · 모바일 확인0.5일—
▲ 여기까지 5일. 이 상태로 3주차 영업 시작합니다.
8ADMIN 대시보드 + 리드 (서버 렌더 표로 충분)1일리드가 실제로 들어온 뒤
9ADMIN 제휴 (칸반은 나중 · 표+필터로 시작)0.5일제휴 대화 시작 뒤
10ADMIN 진행 보드 + AI 처리1.5일첫 계약 뒤
11설정 화면0.5일규칙을 자주 바꾸게 되면
8번 이후는 전부 "~한 뒤"입니다.
ADMIN을 미리 만드는 게 런칭을 미루는 가장 흔한 방법입니다. 리드 0건일 때 리드 관리 화면은 아무 가치가 없습니다.