English {#english}
Scope: Unified operator dashboard under prego-control-plane (React admin + internal APIs) for m.pregoi.com funnel: visits, auth attempts, OTP/email outcomes, checkout, webhooks, provision failures — tables + daily charts + drill-down by trace_id / email (policy-aware).
Correlation today: Zuplo forwards x-trace-id to upstreams only when it matches the platform shape (trimmed, trace_* prefix, max 128 characters): modules/append-incoming-trace-header.ts (appendIncomingTraceId) and gateway runtime logs (gatewayRuntimeLogFields) drop anything else at the edge. The control plane and prego_ai apply the same acceptance rules before D1 writes, list filters, or JSON trace_id echo. The control plane records D1 funnel_events for several flows (for example m_auth_user_upserted, m_auth_session_created, m_auth_user_tenant_linked, and m_auth_get_user when a trace header is present on GET /internal/auth/get-user, plus m_onboarding_subdomain_check when a valid trace header is present on GET /v1/subdomain/check). Marketing www appends trace_id to admin signup/login URLs when the page query carries a valid trace_* value: Next code uses @platform/platform-trust (sanitizeTraceIdValue); static index.html / plan-redirect.js mirror the same rules without a bundler.
Related plans: Plan A — Stripe Pay · Plan C — logpath · Plan D — Activate · Onboarding, provisioning, logpath, admin console
한국어 {#korean}
1. 사용자 스토리
- 운영자: “어제 로그인 실패가 왜 늘었는지, 어떤 이메일·에러인지 본다.”
- 운영자: “결제 시작 대비 완료 비율, OTP 발송 실패율을 일별 그래프로 본다.”
- 지원:
trace_id로 한 사용자의 타임라인을 연다.
2. 화면 IA
- 요약: 기간 선택, KPI 카드(세션·로그인 시도/성공·OTP 발송/실패·checkout 시작/완료·프로비전 실패 등).
- 트렌드: 일별 멀티 시리즈 차트.
- 이벤트 피드: 테이블 — 시각, 유형, 이메일(마스킹 정책),
trace_id,tenant_id, 결과,error_code, 상세. - 드릴다운: 행 클릭 → 기존
/cp/onboarding,GET /internal/trace/..., Stripe Dashboard.
라우트 제안: /cp/auth-commerce-funnel (명칭은 팀 합의).
3. 이벤트 사전 (초안)
| event_type | 발생 시점 | 필수 식별자 |
|---|---|---|
m_page_view | (선택) 랜딩/스텝 | anonymous_id 또는 세션 |
m_auth_login_start | OAuth/OTP 시작 | email 또는 sub |
m_auth_login_success | 세션 확립 | email, trace_id(있으면) |
m_auth_login_fail | 실패 응답 | email, error_code |
m_auth_get_user | CP GET /internal/auth/get-user 성공, Zuplo가 x-trace-id 전달 시 | trace_id, user_id(payload) |
m_otp_send | OTP 요청 | |
m_otp_send_result | 메일 게이트웨이 응답 | email, ok/fail |
m_checkout_click | Pay 클릭 | trace_id, plan_tier |
m_checkout_session_created | CP가 session url 반환 | stripe_session_id, trace_id |
m_stripe_webhook_checkout_complete | 웹훅 처리 완료 | stripe_event_id, trace_id |
m_onboarding_subdomain_check | CP GET /v1/subdomain/check 응답 시, x-trace-id가 유효할 때 | trace_id, slug(payload), success |
m_provision_job_created | POST /v1/tenants 등 | job_id, trace_id |
m_provision_failed | 실패 콜백 | job_id, failure_stage |
PII: 원문 이메일 저장 최소화 — 해시 + 도메인만 등 옵션을 보안 정책에 문서화.
4. D1 테이블 초안: funnel_events
| 컬럼 | 설명 |
|---|---|
| id | INTEGER PK |
| ts | ISO8601 서버 수신 시각 |
| event_type | 위 사전 |
| trace_id | NULL 허용 |
| tenant_id | NULL 허용 |
| job_id | NULL 허용 |
| email_fingerprint | 해시 등 |
| success | 0/1 NULL |
| error_code, error_message | NULL, 메시지 길이 제한 권장 |
| source | admin-web, zuplo, cp, stripe_webhook |
| payload_json | NULL, 축약 JSON |
인덱스: (ts), (event_type, ts), (trace_id), (email_fingerprint, ts).
5. API 초안 (내부, Bearer INTERNAL_API_KEY)
GET /internal/funnel-events/summary?from=&to=— KPI + 일별 버킷.GET /internal/funnel-events?from=&to=&type=&q_email=&trace_id=&cursor=— 페이지네이션.POST /internal/funnel-events/ingest— (선택) Zuplo/edge에서 HMAC 또는 내부 시크릿.
6. 수집 연결
| 소스 | 수단 |
|---|---|
| admin-web | Pay 클릭 등 → ingest 또는 CP INSERT |
| Zuplo | auth/OTP 라우트 끝에서 ingest |
| CP | checkout, tenants, webhook 핸들러 내부 INSERT |
| Stripe | 웹훅만(직접 클라이언트 없음) |
7. 페이즈
- Phase 0: 이벤트 사전 확정 + PII 정책.
- Phase 1: 마이그레이션 + ingest + 단순 GET 테이블.
- Phase 2: summary API + admin 차트.
- Phase 3: Zuplo·admin-web 점진 계측.
8. DoD
- 스테이징에서 하루 치 더미 이벤트로 summary·테이블·차트 일치.
- 프로덕션에서
trace_id하나로 필터 시 체인 가시.