Trial email (marketing web) and admin handoff
End-to-end flow:
- Marketing web (
/trial) — user enters work email; the browser calls the API gateway atNEXT_PUBLIC_ZUPLO_API_URLwithPOST /api/trial/*, which proxies to Control PlanePOST /v1/trial/email/check(and related paths). See API gateway & BFF governance. - Tenant admin web (deployed on
ADMIN_WEB_HOST/ admin Worker) —/signupor/loginfrom the trial funnel callsPOST /api/trial/onboarding-handoff-verify, which server-side forwards to CPPOST /internal/trial-email-onboarding-handoff-verifywithAuthorization: Bearer ….
Manual trial approval (separate path): When the gate does not allow auto-trial, the marketing site may continue on /trial/manual-approval/verify (work-email OTP via Resend where applicable, company/contact details, and submit-details; gateway POST /api/trial/manual-approval/* → Control Plane). Apply D1 migrations 0027 (continuation / legacy columns) and 0028 (draft + email OTP columns) as documented in the control-plane repository README.md. Optional OTP_PEPPER applies to stored OTP hashes. Email deep links use /trial/manual-approval/complete?token=, which redirects into the same verify flow.
Admin handoff calls POST /internal/trial-email-onboarding-handoff-verify on the same gateway host as NEXT_PUBLIC_PREGO_CONTROL_PLANE_URL. The gateway must forward that path to the Control Plane. The request uses a service-to-service Bearer that matches CP INTERNAL_API_KEY (see tenant trust boundaries in the operator AI documentation tree when cloned beside this monorepo).
Control Plane Worker (control-plane repository)
| Setting | Where | Purpose |
|---|---|---|
INTERNAL_API_KEY | Wrangler secret (wrangler secret put INTERNAL_API_KEY) | Bearer for /internal/* (including onboarding handoff). Same string must be known to admin (below). |
TRIAL_FORCE_BUSINESS_EMAILS | [vars] in wrangler.jsonc / wrangler.toml or dashboard Variables (plain text) | Staging / test only. Comma-separated emails forced to business auto-trial; handoff skips D1 trial_signup_attempts for listed addresses. Do not set in production for real users. |
TRIAL_GOKIRI_SCORE_OVERRIDE | Optional [vars] | Test-only synthetic score path for marco@gokiri.com when not using the force list. |
Admin Worker (admin web, OpenNext)
| Setting | Where | Purpose |
|---|---|---|
PREGO_CONTROL_PLANE_INTERNAL_API_KEY | Worker Secret | Must equal CP INTERNAL_API_KEY. If missing, users see Trial verification is not configured on this app (missing control plane credentials). |
NEXT_PUBLIC_PREGO_CONTROL_PLANE_URL | Build-time / CI / optional Worker Variable | Zuplo (or public gateway) base; server appends /internal/trial-email-onboarding-handoff-verify on this host. |
Local preview: apps/admin-web/.dev.vars (see .dev.vars.example).
Verification
- After setting secrets, open admin
/signup?…from the trial redirect and confirm handoff returns 200 (not 503 withMISSING_INTERNAL_KEY). - CP logs or the operator React page
/cp/trial-access(manual approval queue, pagination) can help confirm trial classification and review pending approvals. - Admin UI (free plan, after handoff):
/signup,/login, and email OTP verify (/signup/verify,/login/verify) show the same three-step onboarding rail as the root wizard (step 1 — Account Setup — active), not a separate “plan summary” line plus green verification banner. Seeapps/admin-web/components/onboarding/TrialFreeOnboardingStepRail.tsxand Playwrighte2e/*-from-trial.spec.ts.
Repositories
- Application code: monorepo
apps/admin-web(routeapp/api/trial/onboarding-handoff-verify). - CP logic: control-plane repository
src/trial-access/handlers.ts(handleTrialOnboardingHandoffVerify).
한국어 요약
- TRIAL_FORCE_BUSINESS_EMAILS는 Control Plane Worker 변수(스테이징/테스트 전용).
- PREGO_CONTROL_PLANE_INTERNAL_API_KEY는 admin Worker(
admin-web) Secret이며, CP의 INTERNAL_API_KEY와 동일한 값. - 수동 트라이얼 승인(이메일 OTP·회사 정보)은
/trial/manual-approval/verify및 CP D1 0027·0028 — 위 본문 “Manual trial approval” 절 참고. - Pages(www)나 GitHub 저장소에 비밀 값을 커밋하지 말 것.