Skip to content

1. 목적

  • 현재 /trial에 구현된 비즈니스 이메일 검증·수동 승인 플로우를 문서로 고정한다.
  • 향후 client-web·admin-web·www 등 모든 공개 호출자가 동일한 패턴으로 Zuplo API를 경유하고, Cloudflare(Pages·Workers·Zone) 쪽 기능을 일관되게 적용할 수 있도록 변경 방향을 정의한다.
  • 본 문서는 기획·계약 순서만 다룬다. 구현은 How to add an APIprego-zuplo runbook을 따른다.

구현 업데이트 (www /trial): 브라우저는 NEXT_PUBLIC_ZUPLO_API_URL 로 Zuplo에 직접 POST /api/trial/* 합니다. 예전 Pages Functions → Zuplo 프록시 경로는 제거되었습니다. 거버넌스: API gateway & BFF governance.


2. 현재 구현 플로우 (요약)

2.1 사용자 여정

  1. 사용자가 www GET /trial 접속 (마케팅 헤더/푸터, 다크 모드 등 기존 셸).
  2. 회사 이메일 입력 후 Continue → 클라이언트가 trial 이메일 분류 API 호출.
  3. 응답에 따라:
    • 자동 트라이얼 허용admin-web signup으로 이동 (plan=free, region=sg, from_trial=1, 선택적 trace_* / 온보딩 상관 ID).
    • 수동 승인 필요 → 전면 모달 안내; Start Manual OnboardingPOST /api/trial/manual-approval/request/trial/manual-approval/verify 에서 업무 이메일 OTP(필요 시) 및 단계별 폼 → 회사 정보 제출 (submit-details). 이메일 딥링크 /trial/manual-approval/complete?token= 는 동일 verify 플로우로 리다이렉트.

2.2 시퀀스 (현재 프로덕션 기준)

sequenceDiagram
  participant U as Browser (www)
  participant Z as Zuplo
  participant CP as Control Plane Worker

  U->>Z: POST /api/trial/email/check
  Z->>CP: POST /v1/trial/email/check
  CP-->>Z: JSON
  Z-->>U: JSON

  U->>U: 허용 시 location → admin-web /signup?...

  opt manual approval (request, draft, email OTP, submit-details)
    U->>Z: POST /api/trial/manual-approval/request | GET/PATCH draft | email/send-otp | email/verify-otp | submit-details
    Z->>CP: /v1/trial/manual-approval/...
  end

2.3 저장소·계약 매핑

구간역할저장소 / 산출물
UI폼, 에러 매핑, x-trace-id 전달Prego apps/wwwTrialPageClient, TrialEmailGate, TrialBlockedModal, app/trial/manual-approval/verify, lib/trial-gateway.ts
브라우저 → ZuploNEXT_PUBLIC_ZUPLO_API_URL (trial CORS는 게이트웨이 trial-access 조각 15-trial-access-* …)apps/www/lib/trial-gateway.ts
공개 API 정의·라우트경로·CORS·핸들러prego-zuplo trial-access 조각 (15-trial-access-*19-trial-access-*, oas-manifest.json), modules/trial-access-handlers.ts
도메인 로직이메일 분류·수동 승인·업무 이메일 OTP·드래프트prego-control-plane v1/trial/*, D1 0027·0028, Resend / OTP_PEPPER (SMS OTP 제거됨 — remove-phone plan)
온보딩 이동admin-web 가입 URLapps/www ADMIN_BASE_URL, onboarding-trace

Zuplo 핸들러는 Control Plane URL(CONTROL_PLANE_URL)로 프록시만 수행한다. ERP 규칙은 Frappe(prego_saas)가 아니라 CP 쪽 계약을 따른다.


3. “이질적”인 지점 (통합 기획의 출발점)

항목현재리스크
브라우저 → API프로덕션은 www 동일 출처 → Functions → Zuplo. 로컬은 Zuplo 직접CORS·환경 변수 이중 관리, 문서화 부족 시 운영 혼선
Zuplo vs WorkerTrial은 Zuplo → CP가 이미 표준다른 흐름은 CP 직접 URL을 쓰는 경우가 있으면 Zuplo vs 직접 Worker와 불일치
Cloudflare “기능”Pages(정적·Functions)·Zone(WAF·Rocket Loader)·Workers(CP)가 각각 분산Rate limit, 로그, 추적 ID를 한 패턴으로 묶기 어려움

통합 목표는 “브라우저가 보는 공개 HTTP 엔드포인트의 첫 홉은 항상 Zuplo(또는 의도적으로 동일한 게이트)” 이고, Cloudflare는 그 앞·옆에서 정책을 적용하는 형태로 정리하는 것이다.


4. 목표 아키텍처 (Zuplo API + Cloudflare)

4.1 원칙

  1. 공개 브라우저 APIZuplo에 노출된 경로(config/*.oas.json → sync-oas → verify)만 사용한다. 도메인 규칙은 Zuplo에 넣지 않고 CP/Frappe에 둔다 (tenant trust).
  2. www는 가능한 한 동일 출처(/api/...)로 호출해 CORS를 원천 차단하고, 그 백엔드는 Zuplo로만 붙인다 (현재 Pages Functions 프록시와 동일한 방향).
  3. Cloudflare 기능은 아래처럼 역할을 분리해 기술한다.
Cloudflare 계층Trial 플로우에 쓸 수 있는 기능 (예시)
Pages정적 자산, functions/ 프록시, 빌드 시 NEXT_PUBLIC_*
Zone (www)WAF, Bot, Rocket Loader 끔, 캐시 규칙
Workers (CP 등)D1, 내부 시크릿, 비즈니스 API 구현체
Zuplo라우팅, CORS, rate limit, API 키, 관측, Stripe 등 다른 업스트림과 동일한 게이트

4.2 통합 후 “한 장” 흐름 (목표)

flowchart LR
  subgraph clients [Clients]
    WWW[www 브라우저]
    CW[client-web]
    AW[admin-web]
  end

  subgraph edge [Edge]
    P[Pages Functions 선택]
    Z[Zuplo API]
  end

  subgraph cf [Cloudflare Workers]
    CP[Control Plane]
    AI[prego_ai 등]
  end

  WWW -->|권장: same-origin /api| P
  P --> Z
  WWW -.->|개발만 직접| Z
  CW --> Z
  AW --> Z
  Z --> CP
  Z -.->|다른 라우트| AI
  • 목표: client-web·admin-web에서도 가능하면 Zuplo 베이스 URL 한 종류로 호출하고, www만 동일 출처 프록시 예외를 유지하거나, 장기적으로 Workers 라우트 하나로 통일하는 방안을 검토한다.

5. 구현 단계 (권장 순서)

계약 우선 순서는 플랫폼 허브의 How to add an API를 따른다.

단계작업산출물
ATrial 관련 경로를 OpenAPI·Zuplo에 단일 진실원으로 유지prego-zuplo OAS, pnpm run sync-oas / verify
BALLOWED_ORIGINS, x-trace-id — www·Pages preview·client-web 출처가 누락되지 않게 runbook 점검prego-zuplo runbook
CPages Functions ZUPLO_API_URL·프로덕션 빌드 NEXT_PUBLIC_* — 배포 체크리스트에 고정apps/www/README, Cloudflare 대시보드
D(선택) client-web·admin-web의 CP/Zuplo 직접 호출을 감사하고, Zuplo 경로로 수렴각 앱 ADR 또는 작은 설계 문서
E관측: Zuplo 대시보드 + CP Logpush에서 같은 trace로 상관x-trace-id / trace_*

6. 비기능·운영

  • 보안: 브라우저에 내부 Worker URL을 노출하지 않는다. Zuplo 또는 동일 출처 프록시만.
  • CORS: Zuplo 측 prego-web CORS와 trial allow-all 정책의 차이를 운영 문서에 명시; 장기적으로 혼선이 없게 정책 이름·출처 목록 정리.
  • Rocket Loader: www에서 클라이언트 스크립트가 깨지지 않도록 www README 배포 절차 유지.

7. 참고 문서


8. English summary {#english-summary}

Purpose: Document the current www /trial flow (email check → optional manual approval → redirect to admin-web signup with trace), and define a target where all public callers converge on the Zuplo API, with Cloudflare (Pages Functions for same-origin proxy, Zone policies, Workers behind Zuplo) applied consistently. Implementation follows OpenAPI-first in prego-zuplo and platform contract order; no code in this doc.


9. 구현 상태 (Prego 모노레포) {#implementation-status}

단계상태비고
A — Trial 경로 OpenAPI·Zuplo기존 유지prego-zuplo config/15-trial-access-*19-trial-access-*, trial-access-handlers.ts
B — CORS·x-trace-id운영 설정Zuplo ALLOWED_ORIGINS, runbook
C — Zuplo 직접 (NEXT_PUBLIC_ZUPLO_API_URL)브라우저 → Zuploapps/www/lib/trial-gateway.ts; 검증은 verify-www-pages-functions.mjs (/api/country 등만) + verify:trial-functions 별칭
D — client-web·admin-web Zuplo 수렴부분 적용client-web api-client는 이미 게이트웨이 베이스 사용. admin-web 레거시 PREGO_CONTROL_PLANE_URL은 온보딩 /v1/* 전용; trial과 무관. 전면 Zuplo화는 별도 마이그레이션.
E — 관측·trace기존x-trace-id / trace_*, trial-gateway에서 전달

CI: .github/workflows/deploy-pages.ymlverify:pages-functions 실행 (verify:trial-functions는 동일 스크립트 별칭).

Help