Skip to content

www.pregoi.com 가입·패키지·결제·리소스 할당 플로우 기획서

목적: 클라이언트가 **www.pregoi.com**에 접속해 Gmail SSO 또는 이메일로 가입하고, 패키지(무료/유료)를 선택·결제한 뒤 리소스가 할당되기까지의 구체적인 로직, 초기 인프라 설정 자동화를 단계별로 정리한다.
코드 생성 없음 — 플로우·요건·현재 구현 상태만 기술.

참조: tenant-provisioning-flow.md, provision-tenant-workflow-design.md, api-control-plane-implementation-plan.md, prego-saas-app-implementation-plan.md.


1. 개요

항목내용
진입 URLhttps://www.pregoi.com (마케팅·가입·패키지 선택·결제 포털)
가입 방식Gmail SSO 또는 이메일 계정 생성
패키지무료(Free), 유료(Basic / Professional / Enterprise 등)
결제유료 선택 시 Stripe Checkout 또는 Subscription
리소스 할당Control Plane이 큐(provision_jobs) 적재 → 배치 결정 → Pulumi/Ansible/Zuplo 순차 실행
초기 인프라Hetzner 서버(필요 시), Docker·Frappe·테넌트 사이트, API Key, Zuplo·KV·DNS

2. 전체 플로우 요약

[1] www.pregoi.com 접속
[2] 회원가입 (Gmail SSO 또는 이메일)
[3] 패키지 선택 (무료 / 유료)
[4] 결제 (유료 시 Stripe)
[5] 리소스 할당 결정 (배치·큐)
[6] 초기 인프라 자동화 (Pulumi → Ansible → Zuplo → 콜백)
[7] 테넌트 활성화 (사용자 URL 안내)

3. 단계별 플로우 및 현재 구현 상태


3.1 1단계: www.pregoi.com 접속 및 랜딩

목표

  • 사용자가 **www.pregoi.com**에 접속했을 때 랜딩/마케팅 페이지 또는 로그인·가입 진입점을 제공한다.
  • (선택) 테넌트 서비스 접속은 {subdomain}.pregoi.com (예: acme.pregoi.com)으로 구분한다. 랜딩·가입은 www 또는 app.pregoi.com 등으로 분리할 수 있다.

구체적 로직

순서동작비고
1DNS: www.pregoi.com → Cloudflare Proxy 또는 정적 호스팅/SPAPages, Workers, 또는 외부 호스팅
2HTTPS 제공 (Edge SSL 또는 Origin 인증서)Cloudflare 기본
3랜딩: 제품 소개, 가격(무료/유료), CTA(시작하기·가입)프론트엔드 구현
4”시작하기” 클릭 시 → 로그인/가입 선택 (Gmail SSO 또는 이메일)2단계로 진입

현재 구현 상태

항목상태비고
www.pregoi.com 도메인·DNS기획/설정 의존pregoi.com·테넌트 서브도메인(subdomain.pregoi.com) 설계는 tenant-subdomain-dns-design.md에 있음. www 전용 랜딩은 별도 문서화·구현 여부 불명.
랜딩·마케팅 페이지미구현client-web 또는 마케팅 사이트는 기획서에서 “웹에서 가입”으로만 언급. 코드베이스에 별도 client-web 레포/경로 미확인.
테넌트 접속 URL설계 완료사용자용 {subdomain_slug}.pregoi.com CNAME → 내부 canonical tenant-{short_id}.pregoi.com.

3.2 2단계: 회원가입 (Gmail SSO 또는 이메일)

목표

  • Gmail SSO: Google OAuth 2.0으로 로그인/가입 한 번에 처리.
  • 이메일 계정: 이메일·비밀번호로 계정 생성, (선택) 이메일 검증 링크.

구체적 로직

순서동작비고
1”Google로 시작하기” 선택 시 → Google OAuth consent 화면 → redirect_uri로 복귀client_id, client_secret, redirect_uri 설정 필요
2OAuth 성공 시 백엔드에서 사용자 식별자(Google sub 또는 email) 저장. 신규면 “회원” 생성, 기존이면 로그인 처리사용자 DB/테이블 설계 필요
3”이메일로 가입” 선택 시 → 이메일·비밀번호 입력 → 유효성 검사 → 계정 생성이메일 중복 검사, 비밀번호 정책
4(선택) 이메일 인증: 가입 후 검증 링크 발송, 클릭 시 계정 활성화발송 서비스(SendGrid 등) 연동
5가입 완료 후 → “패키지 선택” 화면으로 이동(또는 대시보드)세션·JWT 등 인증 유지

현재 구현 상태

항목상태비고
Gmail SSO미구현기획서·Control Plane·prego-saas-app에 OAuth/Google 로그인 구현 없음. 랜딩·가입 담당 클라이언트 앱(client-web)이 별도일 경우 해당 앱에서 구현 대상.
이메일 가입미구현동일. Frappe 쪽은 테넌트 사이트별 User/Administrator가 있으며, 포털(www) 사용자와 테넌트 사용자는 레이어가 다를 수 있음(포털 = 계정·결제·테넌트 목록, 테넌트 = ERPNext 사용).
사용자·계정 저장소기획 수준Control Plane D1에는 tenants_master, billing_customers, provision_jobs 등이 있으나 포털 사용자(이메일·Google id) 저장 스키마는 명시되지 않음. 별도 B2C User DB 또는 Auth0/Clerk 등 IdP 연동 시 정의 필요.

3.3 3단계: 패키지 선택 (무료 / 유료)

목표

  • 사용자가 무료(Free) 또는 유료(Basic / Professional / Enterprise) 패키지 중 하나를 선택한다.
  • 선택 결과는 다음 단계(결제 또는 바로 프로비저닝)로 전달된다.

구체적 로직

순서동작비고
1화면에 플랜 목록 표시: Free, Basic, Professional, Enterprise 등. 가격·기능·리전(Enterprise 시 us/eu 등) 안내플랜 메타는 Control Plane PLAN_TIERS 또는 별도 설정에서 관리
2사용자가 플랜 선택 후 “다음” 또는 “결제하기” 클릭Free 선택 시 결제 단계 스킵 가능
3(유료) 결제 단계로 이동; (무료) 즉시 테넌트 생성 요청으로 진행 가능4단계와 연동
4선택값 정리: plan_tier, requested_region(선택), tenant_name(회사/서브도메인 slug)Stripe Checkout metadata 및 Control Plane API body와 동일 필드로 매핑

현재 구현 상태

항목상태비고
플랜 정의부분 구현prego-control-plane: PLAN_TIERS env, tenants.ts에서 basic | professional | enterprise 검증. 무료(Free) tier는 코드에 명시적 없을 수 있음.
패키지 선택 UI미구현www/client-web 쪽 화면. 기획서에는 “패키지(플랜) 선택” 단계만 기술.
plan_tier·region 전달구현됨Stripe metadata(plan_tier, requested_region) 및 POST /v1/tenants body(tier, region)로 전달 구조 있음.

3.4 4단계: 결제

목표

  • 유료 패키지 선택 시 Stripe Checkout 또는 Stripe Customer + Subscription으로 결제를 완료한다.
  • 무료 선택 시 결제 없이 테넌트 생성 요청만 수행한다.

구체적 로직

순서동작비고
1유료 선택 시: 백엔드 또는 클라이언트에서 Stripe Checkout Session 생성. metadata에 tenant_id(선택), plan_tier, requested_region 포함Stripe API 호출 주체는 포털 백엔드 또는 Control Plane 연동 API
2사용자를 Stripe Checkout 페이지로 리다이렉트 → 결제 완료 후 success_url으로 복귀success_url/cancel_url 설정
3결제 완료 시 Stripe가 Webhook 발송: checkout.session.completed (및 구독 시 customer.subscription.created 등)Control Plane이 수신
4무료 선택 시: Stripe 없이 Control Plane POST /v1/tenants 직접 호출. body: tenant_name, tier=free(또는 basic), region202 + job_id 반환 후 5단계로 진행

현재 구현 상태

항목상태비고
Stripe Webhook 수신구현됨prego-control-plane: POST /webhooks/stripe. 서명 검증(STRIPE_WEBHOOK_SECRET), 멱등(provider_events), checkout.session.completed 처리.
Webhook 후처리구현됨D1: provider_events 삽입, tenants_master(Pending), provision_jobs(Pending), billing_customers, subscriptions. metadata에서 plan_tier, requested_region 파싱.
workflow_dispatch 트리거구현됨GITHUB_WORKFLOW_DISPATCH_URL + GITHUB_TOKEN 설정 시 Stripe Webhook 처리 후 GitHub Actions workflow_dispatch 호출(job_id, tenant_id, region, create_new_server, target_server_id).
무료 플로우(Stripe 없이)부분 구현POST /v1/tenants로 직접 job 적재 가능. “Free” tier가 PLAN_TIERS에 포함되어 있으면 동일 경로로 처리 가능.
Checkout Session 생성 UI/API미구현(포털)prego-saas-app 기획서에 create_checkout_session(plan, tenant_name) API 명세 있음(Phase 6). 실제 Stripe Session 생성은 포털 백엔드 또는 별도 Billing API에서 구현 대상.

3.5 5단계: 리소스 할당 로직 (배치·큐)

목표

  • 결제 완료(또는 무료 신청) 직후 어디에 테넌트를 올릴지 결정하고, 프로비저닝 작업을 큐에 넣는다.
  • 리소스 = 서버(노드) + DB·Frappe 사이트 + API Key·라우팅 등. “할당”은 “기존 서버에 배치” 또는 “신규 서버 생성” 결정까지 포함.

구체적 로직

순서동작비고
1큐 적재: D1 provision_jobs에 1행 삽입. status=Pending, tenant_id, job_id, trace_id, region, plan_tier, infra_mode(create_new_server | use_existing)Stripe Webhook 또는 POST /v1/tenants에서 수행
2배치 결정(Placement): 기존 서버에 넣을지, 신규 서버를 만들지 결정. 입력: tenant_id, plan_tier, requested_region. 출력: target_server_id(기존 노드) 또는 create_new_server=trueCPU/메모리/테넌트 수 등 server_metrics 기반 규칙 또는 AI 엔진
3region 결정: resolveRegion(plan_tier, requested_region) → sg | us | eu. Enterprise는 requested_region 존중webhooks-stripe.ts에 resolveRegion 있음
4트리거: workflow_dispatch(또는 Provision Worker) 호출 시 입력으로 job_id, tenant_id, region, target_server_id, create_new_server 전달다음 단계(6) 실행 주체가 사용

현재 구현 상태

항목상태비고
provision_jobs 큐구현됨D1 테이블, Stripe Webhook 및 POST /v1/tenants에서 삽입.
decidePlacement구현됨prego-control-plane placement.js: D1·server_metrics(또는 nodes) 조회, create_new_server 또는 target_server_id 반환.
workflow_dispatch 입력구현됨Stripe Webhook 처리 후 GitHub API로 job_id, tenant_id, region, create_new_server, target_server_id 전달.
Idempotency구현됨POST /v1/tenants 시 Idempotency-Key 헤더로 24시간 내 중복 요청 시 기존 job_id 반환.
Free tier 배치동일 로직무료도 동일 placement·큐 적재. plan_limits 등은 plan_tier에 따라 6단계 Ansible에서 적용.

3.6 6단계: 초기 인프라 설정 자동화

목표

  • 큐에 넣어진 한 건의 프로비저닝 job에 대해, Pulumi(필요 시) → Ansible → Zuplo Sync → Control Plane 콜백까지 사람 개입 없이 실행한다.
  • 초기 인프라 = 서버(VM), Docker·Frappe·테넌트 사이트, API Key, 게이트웨이·라우팅·DNS·상태 갱신.

구체적 로직

순서담당동작
6.1실행 주체job 입력 확보: workflow_dispatch inputs 또는 D1에서 Pending job 1건 조회.
6.2Pulumi(조건부)target_server_id 없고 create_new_server 시: region 스택 선택 → pulumi up → server_ip 획득. 있으면 D1 nodes에서 해당 서버 host 조회.
6.3Ansibleserver_ip, tenant_id, plan_tier·plan_limits 전달. Docker 설치, Frappe bench, bench new-site, API Key 발급. 결과: api_key 파일/변수.
6.4Cloudflare DNS테넌트 canonical tenant-{short_id}.pregoi.com 및 사용자 URL {subdomain_slug}.pregoi.com CNAME 등록.
6.5Zuplo Synctenant_id, api_key로 Zuplo Consumer·API Key 등록.
6.6Control Plane 콜백POST /internal/provision-complete. D1: provision_jobs.status=Completed, tenants_master.status=Active, tenant_runtime 갱신. TENANT_ORIGINS(KV) 갱신.

현재 구현 상태

항목상태비고
provision-complete 콜백구현됨prego-control-plane: POST /internal/provision-complete. Bearer INTERNAL_API_KEY. D1 갱신, TENANT_ORIGINS KV 쓰기.
Pulumi구현됨prego-pulumi 레포, 스택(sg/us/eu), Hetzner 서버·방화벽·Cloudflare DNS(node-01.pregoi.com 등). workflow에서 호출 시 동작.
Ansible구현됨prego-ansible: Docker, Frappe, bench new-site, API Key. plan_tier·plan_limits 전달은 기획 반영 중(resource-optimization-safe-adoption-plan).
Zuplo Sync구현됨infra/zuplo_sync.ts 또는 동등. tenant_id, api_key 등록.
provision-tenant 워크플로기획/부분provision-tenant-workflow-design.md에 상세. 실제 .github/workflows/provision-tenant.yml 존재 여부·연동은 레포별 확인 필요.
테넌트 DNS 자동 등록기획tenant-provisioning-flow §5.1: 프로비저닝 단계에서 Cloudflare API로 canonical·CNAME. 구현은 워크플로 또는 Worker에서 수행.

3.7 7단계: 테넌트 활성화 및 사용자 안내

목표

  • 프로비저닝이 완료되면 사용자에게 테넌트 접속 URL(예: acme.pregoi.com) 및 (선택) 초대 메일·비밀번호 설정 링크를 안내한다.

구체적 로직

순서동작비고
1provision-complete 수신 시 tenant_runtime에 site_name, host, 사용자 URL 저장D1·KV에 이미 반영됨
2(선택) 웹훅 또는 이메일: “테넌트가 준비되었습니다. 접속 URL: https://{subdomain_slug}.pregoi.com”기획서에 선택 구현으로 명시
3포털(www) 대시보드에서 “내 테넌트” 목록·상태(job_id로 GET /v1/jobs/:id) 표시. Completed 시 “열기” 링크 제공client-web 구현 대상

현재 구현 상태

항목상태비고
job 상태 조회구현됨GET /v1/jobs/:id. job_id, tenant_id, status 등 반환.
완료 시 알림(이메일/웹훅)미구현api-control-plane-implementation-plan §2 ⑤ 선택 구현.
포털 “내 테넌트” UI미구현client-web·www 전제.

4. 단계별 구현 상태 요약표

단계내용구현 상태
1www.pregoi.com 접속·랜딩미구현(www/랜딩 페이지)
2Gmail SSO·이메일 가입미구현
3패키지 선택(무료/유료)플랜 정의·API 연동 부분 구현, UI 미구현
4결제(Stripe·무료)Stripe Webhook·큐 적재·workflow_dispatch 구현됨; Checkout 생성·무료 UI 미구현
5리소스 할당(배치·큐)구현됨(placement, provision_jobs, Idempotency)
6초기 인프라 자동화Pulumi·Ansible·Zuplo·provision-complete 구현됨; provision-tenant 워크플로·DNS 자동 등록은 기획/부분
7테넌트 활성화·안내GET /v1/jobs/:id 구현됨; 알림·포털 UI 미구현

5. 의존성 및 권장 구현 순서

  1. www.pregoi.com 랜딩·도메인: 랜딩 페이지 또는 SPA 배포, DNS 설정.
  2. 가입·인증: Gmail SSO + 이메일 가입, 사용자 저장소(또는 IdP) 결정 후 구현.
  3. 패키지 선택 UI: 플랜 목록·가격 노출, 선택 시 tier·region·tenant_name 수집.
  4. 결제 연동: 유료 시 Stripe Checkout Session 생성 API·success/cancel 리다이렉트; 무료 시 POST /v1/tenants 호출.
  5. 프로비저닝 파이프라인: provision-tenant 워크플로 또는 Provision Worker가 6단계 전 구간 실행·DNS·알림까지 연결.
  6. 사용자 안내: job 상태 폴링·완료 시 이메일/대시보드 “내 테넌트” 링크.

6. 참조 문서

Help