Skip to content

English {#english}

Prego SaaS Control Platform v4.0 — Implementation Plan

Purpose: Stepwise implementation plan for the v4.0 technical specification (Enterprise-Grade Architecture, Multi-Region, GitHub Actions Pulumi Preview/Up separation). No code generation — scope, dependencies, completion criteria, and risk decisions only.

Reference: (separate) PREGO SaaS Control Platform technical specification v4.0
Date: February 2026

Contents: §0 Overview · §1 Three immediate decisions · §2 Phase roadmap (E2E, Trace Stage, kickoff, state machines, blockers) · §3 Phase 1 — SG + CI/CD · §4 Phase 2 — Usage Billing · §5 Phase 3 — LogPath, PDPA, D1 0006 · §6 Phase 4 — US + Autoscaler · §7 Phase 5 — EU + GDPR · §8 Cross-phase (Fail Sanely, security, alerts, retry) · §9 Dependencies & schedule · §10–§18 (codebase, risks, decision log, D1 schema, Runbook, glossary, v4.0 mapping, changelog).


0. Document Overview

  • Scope: SG single region → Multi-Region (SG/US/EU), CI/CD (Preview/Up), Billing, LogPath, PDPA, Autoscaler. Deliverables: Phase task lists, dependencies, completion criteria, three immediate decisions (§1).
  • Completeness: §0.1 maps v4.0 items (Multi-Region, Pulumi split, Atomic Workflow, D1 0001–0006, Usage R2→Aggregator→Stripe, LogPath, PDPA Purge, Autoscaler, Fail Sanely) to sections.
  • Quick ref: §0.2 table — E2E/Trace (§2.1, §2.2), kickoff (§2.3), Phase 1–5 tasks and checks (§3–§7), D1/Queue (§13), Runbook (§8, §14), implementation order (§9.10), release checklist (§9.11).
  • Maintenance: §0.3 — update §18 changelog, TOC, §16 v4.0 mapping when editing.
  • Exclusions: §0.4 — Frappe/HRMS app code, client-web UI detail, third-party SLA/pricing, dev/staging pipeline, code/config generation (on request).
  • Executive summary: §0.5 — Goal: tenant lifecycle, Usage Billing, infra automation, PDPA, LogPath, multi-region. Phases 1–5 summary. Three immediate decisions: ① Provision executor (recommended: GitHub Actions workflow_dispatch callback) ② Zuplo Soft Quota KV backend ③ trace_events high-frequency storage (R2 offload etc.). Next: §1 agreement → §2.3 kickoff → Phase 1 (P1-1…P1-13) → Phases 2–5.
  • Can do / Cannot do: §0.6 — Define scope, tasks, dependencies, criteria, decisions; cannot generate code or replace v4.0 spec body.

1. Three Immediate Decisions

Three items must be decided before Phase 1–2 scope is fixed.

#RiskDecision neededRecommendationStatus
1Provision executorWho runs provision jobs from the queue (GitHub Actions callback vs separate Worker vs manual)GitHub Actions callback — Queue consumer calls workflow_dispatch so only that region stack runs pulumi up[ ] Open
2Zuplo Soft Quota backendWhen to move from in-memory to KV; KV schema (key, TTL, per-region)KV backend required — key e.g. usage:{tenant_id}:{meter_key}:{cycle_start}[ ] Open
3trace_events high-frequency appendD1 write load and R2 offload (sync D1 vs async R2 batch vs hybrid)Define R2 offload — batch interval and index (e.g. by trace_id, by time) without breaking SEV1 analysis <1s[ ] Open

Next: Stakeholder agreement → update “Status” and §1 with decision summary.


2. Phase Roadmap Summary

PhasePeriodFocusDone when
1M1–M2SG single region, Pulumi(SG)+Ansible+D1 0001–0005, GitHub Actions Preview/UpSG tenant auto-provisioning success
2M3–M4Billing — Stripe Webhook, R2 Raw, Aggregator, usage_rollupsUsage → Stripe E2E success
3M5–M6LogPath, Audit, PDPA Purge, D1 0006 multiregionPDPA + LogPath SEV1 analysis
4M7–M8US (Ashburn), Autoscaler, SLA, Enterprise tierUS tenant provisioning success
5M9+EU (Falkenstein), GDPR, Predictive Scaling, admin dashboardEU customer readiness

E2E (Atomic Workflow, §2.1): (1) Stripe Webhook → (2) D1 tenants_master/provision_jobs → (3) Queue enqueue → (4) GitHub Actions Pulumi up → (5) Ansible (Docker+Frappe+bench) → (6) Zuplo Sync → (7) Control Plane COMPLETED.
LogPath stages (§2.2): STRIPE_WEBHOOK_RECEIVED, BILLING_STATUS_UPDATED, PROVISION_JOB_CREATED, INFRA_RUNNING, SITE_CREATED, GATEWAY_REGISTERED, COMPLETED — mapped to Phase 1 tasks.
Kickoff (§2.3): Decisions ①–③, Stripe/Hetzner/CF/Pulumi/GitHub accounts and secrets, D1 migrations 0001–0005, Queue (or alternative) and consumer.
State machines: tenants_master.status (§2.4), provision_jobs (§2.5), purge_jobs (§2.6). Dependencies (§2.7): Decisions → Kickoff → Phase 1 → Phase 2 → Phase 3 → Phase 4 → Phase 5. Blockers (§2.8): Per-phase prerequisites (e.g. Phase 1: decision ①, kickoff complete).

§§3–§18 (Phase 1–5 task breakdown, Stripe mapping, first-deploy checklists, Billing Cycle, LogPath/trace_events, Hard Purge order, US/EU checks, Cross-Phase Fail Sanely/security/alerts/retry, dependencies §9, codebase §10, risks §11, decision log §12, D1 schema §13, Runbook §14, glossary §15, v4.0 mapping §16, links §17, changelog §18) — full tables, task IDs, completion criteria, and runbook index are in the Korean section below.


한국어 {#korean}

Prego SaaS Control Platform v4.0 — 구현 기획서

문서 목적: 기술개발기획서 v4.0(Enterprise-Grade Architecture, Multi-Region, GitHub Actions Pulumi Preview/Up 분리)의 구현을 위한 단계별 기획서. 코드 생성은 포함하지 않으며, 작업 범위·의존성·완료 기준·리스크 결정만 정의.

참조 문서: (별도) PREGO SaaS Control Platform 기술개발기획서 v4.0
작성일: 2026년 2월


목차

제목
0문서 개요 · 0.1 완성도 · 0.2 빠른 참조 · 0.3 유지보수 · 0.4 제외 범위 · 0.5 Executive Summary · 0.6 할 수 있는 것/없는 것
1즉시 결정 필요 사항 (최우선 3가지)
2Phase별 로드맵 · 2.1~2.8 (E2E, Trace Stage, 킥오프, 상태 전이, Phase 간 의존성, 블로커)
3Phase 1 — SG 단일 리전 및 CI/CD · 3.6~3.9 (세부 체크, Stripe 매핑, Webhook 이벤트, 첫 배포 전 점검)
4Phase 2 — Usage-Based Billing · 4.7 Billing Cycle · 4.8 첫 Cycle Close 전 점검
5Phase 3 — Governance: LogPath, PDPA, D1 0006 · 5.7 trace_events · 5.8 Hard Purge 순서 · 5.9 첫 Purge 전 점검
6Phase 4 — US 리전 및 Autoscaler · 6.6~6.9 (세부 체크, 메트릭, nodes.status, 첫 US 전 점검)
7Phase 5 — EU 리전 및 GDPR · 7.5 태스크별 세부 체크 · 7.6 첫 EU 전 점검
8Cross-Phase · 8.1 Fail Sanely · 8.2 보안 · 8.3 Slack·Alert · 8.4 재시도·에러 · 8.5 역할·에스컬레이션 · 8.6 에러 시나리오
9의존성 및 일정 · 9.1~9.16 (Actions, 산출물, 인수테스트, 리전매트릭스, plan_tier, R2, Health Score, 태스크 인덱스, CF LB, 구현 순서, 릴리스 검수, 5-Layer↔Phase, scaling_events, Phase별 산출물 한 줄, 데이터 흐름, 시그니오프 템플릿)
10기존 코드베이스 연계
11리스크·가정·제약 · 11.4 다음 문서·산출물
12결정 로그 템플릿
13D1 마이그레이션 스키마 요약 · 13.1 핵심 컬럼 · 13.2 Provision Queue 메시지 스키마
14운영 Runbook 요약 · 14.1 Phase별 Runbook·문서 갱신
15용어·약어 정리 · 15.1 기술개발기획서 v4.0 인용 문구
16기술개발기획서 v4.0 절 대응표 · 16.1 역방향(본→v4.0)
17외부 참조 링크
18변경 이력

0. 문서 개요

항목내용
문서 버전본 기획서 §18 변경 이력 참조. 참조: 기술개발기획서 v4.0
대상Prego SaaS Control Platform v4.0 전 영역 (Control / Data / Infrastructure / Gateway / Event Plane)
범위SG 단일 리전 → Multi-Region(SG/US/EU), CI/CD(Preview/Up 분리), Billing, LogPath, PDPA, Autoscaler
산출물Phase별 태스크 목록, 의존성, 완료 기준, 즉시 결정 필요 사항
코드 생성본 문서는 기획만 포함. 코드/설정 파일 생성은 별도 요청 시 진행

0.1 기획서 완성도·반영 체크 (기술개발기획서 v4.0 대비)

본 구현 기획서가 기술개발기획서 v4.0 주요 항목을 반영했는지 점검용.

v4.0 항목본 기획서 반영
Multi-Region (SG→US→EU)§2, §3~§7, §9.4, §9.5
Pulumi Preview/Up 분리§3.3~3.5, §9.1
Atomic Workflow (7단계)§2.1, §2.2, §3
D1 0001~0006 스키마§13, §3.2, P1-8
Usage R2→Aggregator→Stripe§4, §9.6
LogPath Trace/Stage§2.1, §2.2, §5
PDPA Soft Delete 30일→Purge§5, §8.1, §2.4
Autoscaler Health Score§9.7, §6, §6.7
Fail Sanely·보안§8.1, §8.2, §8.4
최우선 리스크 3가지§1

0.2 빠른 참조: 주제별 절 안내

찾는 내용
결정 3건·권장안§1
E2E 7단계·Trace Stage§2.1, §2.2
킥오프·사전 준비§2.3
테넌트·provision_jobs 상태 전이§2.4, §2.5
Phase 1 태스크·세부 체크·Stripe 매핑§3.3, §3.6, §3.7
Billing·R2·Aggregator·Cycle Close§4, §9.6
LogPath·Audit·PDPA Purge·0006§5
US/EU 리전·Autoscaler·메트릭§6, §6.7, §9.7
GitHub Actions·리전·스택·Secrets§9.1, §9.4
D1 스키마·Queue 메시지§13, §13.1, §13.2
Runbook·Fail Sanely·보안§8, §14
구현 순서·릴리스 전 검수§9.10, §9.11
주요 에러 시나리오·대응§8.6
Phase 1 첫 배포 전 최종 점검§3.9
Phase 2 첫 Cycle Close 전 점검§4.8
Phase 3 첫 Hard Purge 전 점검§5.9
Phase 4 첫 US 프로비저닝 전 점검§6.9
Phase 5 첫 EU 프로비저닝 전 점검§7.6

0.3 문서 유지보수 체크리스트

본 기획서를 수정할 때 확인할 항목.

항목확인
버전§18 변경 이력에 새 버전·변경 내용·작성일 추가
목차상단 목차표에 신규·변경 절 반영
절 번호새 절 추가 시 기존 절 번호 밀림 여부 확인 (목차·본문·상호 참조)
§16 대응표기술개발기획서 v4.0 절과 매핑 변경 시 §16 갱신
§0.1 완성도v4.0 신규 항목 반영 시 §0.1 표에 행 추가

0.4 제외 범위·Known Gaps

본 기획서에서 의도적으로 다루지 않는 항목.

항목설명
Frappe/HRMS 앱 코드bench new-site·API Key 생성까지만 범위, Frappe 커스텀 모듈·앱 로직은 별도
client-web UI 상세플랜/리전 선택 UI(Phase 4+), 온보딩 플로우 상세는 별도 기획·디자인
제3자 SLA·가격Stripe·Hetzner·Cloudflare·Pulumi의 구체적 SLA·가격 정책은 해당 업체 문서 참조
개발 환경(dev/staging)본 문서는 prod(sg→us→eu) 중심; dev/staging 파이프라인은 필요 시 별도
코드·설정 파일 본문기획·태스크·완료 기준만 정의, 실제 코드 생성은 별도 요청 시

0.5 Executive Summary (한 페이지)

목표: Prego를 테넌트 라이프사이클·Usage Billing·인프라 자동화·PDPA·LogPath·멀티리전을 갖춘 SaaS Control Platform으로 구현. 기술개발기획서 v4.0 기준.

Phase 요약: (1) SG 단일 리전 + Pulumi Preview/Up 분리 + 테넌트 자동 프로비저닝 (2) Usage→R2→Aggregator→Stripe 청구 (3) LogPath·Audit·PDPA Purge·D1 0006 (4) US(Ashburn) 리전·Autoscaler (5) EU(Falkenstein)·GDPR·대시보드.

즉시 결정 3건: ① Provision 실행 주체(권장: GitHub Actions workflow_dispatch 콜백) ② Zuplo Soft Quota KV 백엔드 ③ trace_events 고빈도 저장(R2 오프로드 등). §1.

다음 단계: §1 결정 합의 → §2.3 킥오프 → Phase 1(P1-1…P1-13) → Phase 2~5. 상세는 §2·§9.10·§9.11.

0.6 이 문서로 할 수 있는 것·할 수 없는 것

할 수 있는 것할 수 없는 것
구현 범위·태스크·의존성·완료 기준 정의실제 코드·설정 파일 생성 (별도 요청 시)
결정 ①·②·③ 및 킥오프·블로커 정리Frappe/HRMS·client-web UI 상세 설계 (§0.4)
Phase별 산출물·Runbook 갱신 포인트·시그니오프제3자 SLA·가격·dev/staging 파이프라인
v4.0 대비 반영 여부·역방향 절 참조 (§0.1, §16, §16.1)기술개발기획서 본문 대체 (상세 수식·코드는 v4.0 §X)

1. 즉시 결정 필요 사항 (최우선 3가지)

기술개발기획서 v4.0 최종 결론에서 명시한 최우선 구현 리스크 3가지에 대한 결정이 선행되어야 Phase 1~2 구현 범위가 확정됩니다.

#리스크 항목결정 필요 내용권장안 (기술개발기획서 기준)결정 상태
1Provision 실행 주체Queue에 쌓인 프로비저닝 작업을 누가 실행할지 (GitHub Actions 콜백 vs 별도 Worker vs 수동 트리거)GitHub Actions 콜백 방식 권장 — main 병합 시가 아닌 Queue Consumer가 GitHub Actions workflow_dispatch 호출하여 해당 리전 스택에만 pulumi up 실행[ ] 미결정
2Zuplo Soft Quota 백엔드In-memory에서 KV 백엔드로 전환 시점 및 KV 스키마(키 구조, TTL, 리전별 분리 여부)KV 백엔드 전환 필수 — 영속성·재시작 시 카운트 유지. 키: usage:{tenant_id}:{meter_key}:{cycle_start}[ ] 미결정
3trace_events 고빈도 appendD1 write 부하 및 R2 오프로드 전략 (동기 D1 vs 비동기 R2 배치 vs 하이브리드)R2 오프로드 전략 결정 — SEV1 분석 1초 이내 요구사항과 충돌하지 않도록 배치 주기·인덱스(예: by trace_id, by time) 정의[ ] 미결정

다음 단계: 위 3건에 대해 이해관계자(SRE/Lead/Product) 합의 후 “결정 상태” 체크 및 본 기획서 1절에 결정 요약을 반영할 것.


2. Phase별 구현 로드맵 요약

Phase기간예상 소요(참고)핵심 목표완료 기준 (기술개발기획서 §14)
Phase 1M1–M2약 8주 (변동 가능)SG 단일 리전, Pulumi(SG) + Ansible + D1 0001~0005, GitHub Actions Preview/UpSG 테넌트 자동 프로비저닝 성공
Phase 2M3–M4약 8주Billing — Stripe Webhook, R2 Raw, Aggregator, usage_rollupsUsage 집계 → Stripe 청구 E2E 성공
Phase 3M5–M6약 8주Governance — LogPath, Audit Dashboard, PDPA Purge 자동화, D1 0006 multiregionPDPA 감사 대응 + LogPath SEV1 분석 가능
Phase 4M7–M8약 8주Ashburn(US) 리전 활성화, Autoscaler, SLA 모니터링, Enterprise Tier 분리US 리전 테넌트 프로비저닝 성공
Phase 5M9+조건부Falkenstein(EU) 리전, GDPR 대응, Predictive Scaling, 관리자 대시보드 고도화EU 고객 대응 완료

예상 소요(참고)는 팀·리소스·결정 일정에 따라 변동 가능.

2.1 신규 테넌트 생성 E2E 시퀀스 (Atomic Workflow)

기술개발기획서 §6.1 기준. 단계별 실행 주체·산출·LogPath Stage 요약.

단계실행 주체동작LogPath Stage
1Stripe Webhook결제 완료 이벤트 수신, 멱등성 체크STRIPE_WEBHOOK_RECEIVED
2Control Plane (D1)tenants_master status=Active, provision_jobs 등록BILLING_STATUS_UPDATED
3CF Queueprovision job enqueue (tenant_id, trace_id, region)PROVISION_JOB_CREATED
4GitHub Actions (결정 ①)pulumi up 실행 (해당 리전 스택)INFRA_RUNNING
5AnsibleDocker + Frappe + HRMS + bench new-siteSITE_CREATED
6Zuplo SyncAPI Key 등록, Rate Limit 정책 적용GATEWAY_REGISTERED
7Control Planestatus=Completed, 테넌트 알림 발송COMPLETED

2.2 LogPath Trace Stage ↔ 구현 태스크 매핑

Stage구현 Phase대응 태스크
STRIPE_WEBHOOK_RECEIVEDPhase 1P1-9 (Stripe Webhook → D1)
BILLING_STATUS_UPDATEDPhase 1P1-9
PROVISION_JOB_CREATEDPhase 1P1-9, P1-10 (Queue enqueue)
INFRA_RUNNINGPhase 1P1-10 (Pulumi up 트리거), P1-4
SITE_CREATEDPhase 1P1-11 (Ansible)
GATEWAY_REGISTEREDPhase 1P1-12 (Zuplo Sync)
COMPLETEDPhase 1P1-9 (status 갱신), P1-13 (E2E 검증)

Phase 3에서 trace_events에 region, pulumi_stack, gh_run_id 추가 시 동일 Stage를 리전별로 구분 추적.

2.3 킥오프·사전 준비 체크리스트

Phase 1 착수 전에 완료할 결정·환경 준비.

구분항목완료
결정§1 결정 ① Provision 실행 주체 (권장: GitHub Actions workflow_dispatch 콜백)[ ]
결정§1 결정 ② Zuplo Soft Quota KV 스키마·TTL[ ]
결정§1 결정 ③ trace_events 고빈도 저장 전략 (R2 오프로드 등)[ ]
계정·토큰Stripe 계정, Webhook 엔드포인트 URL[ ]
계정·토큰Hetzner API 토큰 (SG), Cloudflare API 토큰, Pulumi Cloud 계정[ ]
계정·토큰GitHub repo, Environments (production-sg, production-destroy), Secrets 등록[ ]
환경D1 데이터베이스 생성, 마이그레이션 0001~0005 적용 가능 상태[ ]
환경CF Queue(또는 선택 Queue) 생성, Consumer 연동 방식 확정[ ]

2.4 테넌트 상태 전이 (tenants_master.status)

상태설명다음 상태
Pending구독 생성 직후, 프로비저닝 대기Active (프로비저닝 완료), Failed (실패·재시도 소진)
Active서비스 이용 가능Pending_Deletion (삭제 요청), Suspended (Fraud 등)
Pending_DeletionSoft Delete, 30일 유예, 접근 차단— (30일 후 Hard Purge → row 삭제)
Suspended수동·자동 정지 (Fraud 등)Active (검토 후 복구)
Failed프로비저닝 실패 (재시도 소진)수동 재시도 또는 보류

Purge 완료 시 tenants_master row 삭제. audit_logs는 삭제하지 않음.

2.5 provision_jobs 상태 전이

상태설명다음 상태
PendingQueue enqueue 직후, 실행 대기Running (Consumer가 작업 수락)
RunningPulumi/Ansible/Zuplo 실행 중Completed, Failed (에러·타임아웃)
Completed프로비저닝 성공, tenants_master.status=Active 반영
Failed재시도 소진 또는 치명 오류, Slack Alert수동 재시도 시 새 job 또는 status 갱신

재시도: 지수 백오프, max 5회 (§8.1). Failed 시 trace_id로 LogPath 추적.

2.6 purge_jobs 상태 전이

상태설명다음 상태
Pending30일 경과 후 Hard Purge 예약 또는 수동 등록Running (Purge Job 시작)
RunningHetzner·R2·D1 삭제 실행 중 (§5.8)Completed, Failed
CompletedPurge 완료, tenants_master row 삭제 반영
Failed오류 시 재시도 또는 수동 개입Pending (재실행)

audit_logs는 어떤 상태에서도 삭제하지 않음.

2.7 Phase 간 의존성 다이어그램

[결정 ①·②·③] ──┬── [킥오프 §2.3]
└── Phase 1 (P1-1…P1-13) ──► Phase 2 (P2-1…P2-6)
Phase 3 (P3-1…P3-9) ◄── (P1-8, P1-9)
Phase 4 (P4-1…P4-7) ──► Phase 5 (P5-1…P5-8)

결정 ①·②는 Phase 1·2, 결정 ③은 Phase 3에 직접 영향. Phase 4·5는 P1-2(리전 분기)·P3-8(0006)에 의존.

2.8 Phase별 블로커 요약

각 Phase 착수 전 해소해야 할 선행 조건. 미충족 시 해당 Phase 지연.

Phase블로커(선행 조건)
Phase 1§1 결정 ① 미합의(Provision 실행 주체), §2.3 킥오프 미완료(Stripe·Hetzner·CF·Pulumi·GitHub·D1·Queue)
Phase 2P1-8(D1 0001~0005) 미적용, 결정 ②(KV 스키마) 미합의
Phase 3P1-9(Control Plane·trace_id) 미구현, 결정 ③(trace_events 저장) 미합의, P1-8 미적용
Phase 4P1-2(REGION_CONFIG·resolveRegion) 미반영, P3-8(D1 0006) 미적용
Phase 5P4-1~P4-4(US 스택·CF LB) 미완료

3. Phase 1 — SG 단일 리전 및 CI/CD (M1–M2)

3.1 목표

  • Singapore 단일 리전으로 테넌트 자동 프로비저닝 E2E 동작
  • Pulumi Preview(PR) / Up(main) 분리 파이프라인 구축
  • D1 스키마 0001~0005 적용, Control Plane · Infra · Gateway 연동

3.2 산출물

산출물설명위치/형식
Pulumi SG 스택prego/sg, Hetzner nbg1-dc3(sin) + Cloudflare DNS/SSLinfra/, Pulumi.sg.yaml
리전 분기 로직REGION_CONFIG, resolveRegion() (Basic/Pro → sg, Enterprise → tenant 선택)infra/index.ts (설계 반영, Phase 4 전까지 sg만 사용)
GitHub Actionspulumi-preview.yml, pulumi-up.yml, pulumi-destroy.yml.github/workflows/
D1 마이그레이션0001~0005 (tenants_master, billing, jobs_runtime, logpath_audit, usage_metering)migrations/
Ansible 플레이북Docker + Frappe + HRMS + bench new-site, API Key 생성config/ (또는 기존 infra/ansible)
Zuplo 연동신규 테넌트 API Key 등록, Rate Limit 정책 (zuplo_sync)infra/zuplo_sync.ts 등

3.3 태스크 분해

ID태스크선행 조건담당 유형완료 기준
P1-1Pulumi 프로젝트 구조 정리 (infra/, providers/, modules/)Infraindex.ts, server/dns/firewall 모듈, Pulumi.sg.yaml 존재
P1-2REGION_CONFIG 및 resolveRegion() 반영 (sg만 활성)P1-1Infrasg 리전으로 서버·DNS 생성 가능
P1-3pulumi-preview.yml (PR 시 preview, matrix region: [sg])P1-1DevOpsPR 코멘트에 preview 결과 출력
P1-4pulumi-up.yml (main push + workflow_dispatch, environment: production-sg)P1-3DevOpsmain 병합 또는 수동 실행 시 prego/sg 스택에 up 적용
P1-5pulumi-destroy.yml (workflow_dispatch, confirm 입력, production-destroy)P1-4DevOps수동 트리거 시에만 destroy, 2단계 확인 동작
P1-6GitHub Secrets 정리 (HCLOUD_TOKEN_SG, CLOUDFLARE_API_TOKEN, PULUMI_*, SLACK_WEBHOOK_URL)DevOps문서화 및 저장
P1-7GitHub Environment Protection (production-sg, production-destroy, Required Reviewers)P1-4DevOps규칙 적용 완료
P1-8D1 마이그레이션 0001~0005 적용Backendtenants_master, billing, jobs_runtime, logpath_audit, usage_metering 테이블 사용 가능
P1-9Control Plane: Stripe Webhook 수신 → D1 tenants_master/provision_jobs 갱신P1-8BackendSTRIPE_WEBHOOK_RECEIVED → BILLING_STATUS_UPDATED → PROVISION_JOB_CREATED
P1-10Provision 실행 주체 연동 (결정 ① 반영) — Queue → Pulumi 실행 트리거P1-4, 결정①Backend/DevOps신규 구독 시 해당 리전 Pulumi up 트리거 (콜백 또는 동등 방식)
P1-11Ansible: Docker + Frappe + bench new-site + API Key 생성P1-2Infra프로비저닝된 서버에 사이트 생성 및 키 발급
P1-12Zuplo Sync: API Key 등록, Rate Limit 정책 적용P1-11GatewayGATEWAY_REGISTERED 단계까지 완료
P1-13테넌트 생성 E2E 검증 (Stripe → Provision → Site → Zuplo → COMPLETED)P1-9~P1-12QA/SRESG 테넌트 자동 프로비저닝 성공

3.4 의존성 다이어그램 (Phase 1)

P1-1 ─┬─ P1-2 ──────────────────────────────────────────── P1-11 ─┬─ P1-12 ─┬─ P1-13
│ │ │
├─ P1-3 ─ P1-4 ─ P1-5 │ │
│ │ │ │
│ └── P1-10 (결정①) ──────────────────────────────────┘ │
│ │
P1-6, P1-7 (병렬) │
P1-8 ─────── P1-9 ────────────────────────────────────────────────────────────┘

3.5 Phase 1 완료 기준 체크리스트

  • PR에서 prego-pulumi/** 변경 시 Pulumi Preview가 자동 실행되고 PR 코멘트에 결과 표시
  • main 브랜치 병합(또는 수동 트리거) 시 production-sg 승인 후 prego/sg 스택에만 pulumi up 적용
  • Destroy는 workflow_dispatch + “DESTROY” 확인 + production-destroy 환경으로만 실행
  • 신규 구독(Stripe Webhook) → D1 상태 갱신 → 프로비저닝 큐 → (결정①에 따른) Pulumi/Ansible → Zuplo 등록 → COMPLETED 까지 무중단 흐름
  • D1 스키마 0001~0005 적용 완료, tenants_master.region 기본값 ‘sg’ 사용

3.6 Phase 1 태스크별 세부 체크 항목

구현·검증 시 각 태스크별로 확인할 하위 항목.

태스크세부 체크
P1-1infra/index.ts 진입점 존재; providers/에 hetzner·cloudflare; modules/에 server, dns, firewall
P1-2REGION_CONFIG.sg 정의, resolveRegion() 반환 ‘sg’ (Phase 4 전), Pulumi.sg.yaml config
P1-3paths: prego-pulumi/**, pull-requests: write, comment-on-pr: true, stack-name prego/sg
P1-4push branches: main, workflow_dispatch inputs(region), environment production-sg
P1-5workflow_dispatch only, inputs: tenant_id, region, confirm; confirm=“DESTROY” Guard
P1-6HCLOUD_TOKEN_SG, CLOUDFLARE_API_TOKEN, PULUMI_ACCESS_TOKEN, PULUMI_PASSPHRASE, SLACK_WEBHOOK_URL 문서화
P1-7production-sg Required Reviewers 1인 이상; production-destroy 2인 권장
P1-80001~0005 순서 적용, tenants_master.region DEFAULT ‘sg’, 외래키·인덱스 확인
P1-9Webhook 멱등성(provider_events 또는 이벤트 ID), tenants_master.status·provision_jobs INSERT
P1-10Queue 메시지에 tenant_id, trace_id, region; 결정 ①에 따른 workflow_dispatch 또는 동등 호출
P1-11대상 서버 SSH·Docker·bench new-site·API Key 출력; 실패 시 재시도 정책
P1-12Zuplo API Key·Rate Limit 정책 반영; GATEWAY_REGISTERED trace 기록
P1-13E2E: 결제 → Webhook → D1 → Queue → Pulumi → Ansible → Zuplo → status=Completed, 알림

3.7 Stripe ↔ Control Plane 필드·이벤트 매핑 (Phase 1 Webhook 참조)

Stripe 측Control Plane (D1/Queue)비고
event.type (예: checkout.session.completed, customer.subscription.created)provider_events에 event_id 저장, 멱등 처리동일 event_id 재수신 시 스킵
customer.id, subscription.idbilling_customers, subscriptions 테이블Stripe ID ↔ tenant_id 매핑 유지
subscription.items[].price Lookupplan_tier, plan_entitlements 결정Basic/Pro/Enterprise 분기
metadata.tenant_id 또는 신규 생성tenants_master.tenant_id, provision_jobs.tenant_idtrace_id UUID 생성 후 전 구간 전달
tenants_master.status = Active, region = ‘sg’(기본)Phase 4+ 시 requested_region 반영
provision_jobs (tenant_id, trace_id, region, status) INSERT → Queue enqueuePROVISION_JOB_CREATED Stage

3.8 Stripe Webhook 처리 대상 이벤트 (P1-9 참조)

event.type용도Control Plane 동작
checkout.session.completed결제 완료, 신규 구독tenant 생성·provision_jobs 등록·Queue enqueue
customer.subscription.created구독 생성billing_customers·subscriptions 연동, plan_tier 결정
customer.subscription.updated플랜 변경·갱신plan_entitlements·region(Enterprise) 반영
customer.subscription.deleted구독 해지Pending_Deletion 전환 또는 30일 유예 시작
invoice.paid / invoice.payment_failed청구 결과provider_events·invoices 갱신 (Phase 2와 연동)

모든 이벤트는 provider_events에 event.id(또는 동등 키)로 멱등 저장 후 처리.

3.9 Phase 1 첫 배포 전 최종 점검

Production에서 첫 테넌트 프로비저닝을 돌리기 전 한 번만 할 점검. §2.3 킥오프·§3.5 완료 기준과 중복되는 항목은 통과한 것으로 간주.

구분항목
결정§1 결정 ① 반영 완료(Queue → Pulumi 트리거 방식 확정)
SecretsHCLOUD_TOKEN_SG, CLOUDFLARE_API_TOKEN, PULUMI_ACCESS_TOKEN, PULUMI_PASSPHRASE, SLACK_WEBHOOK_URL 저장·검증
Environmentproduction-sg Required Reviewers 지정, production-destroy(2인 권장) 설정
D10001~0005 마이그레이션 적용, tenants_master·provision_jobs·provider_events 사용 가능
StripeWebhook 엔드포인트 URL 등록·검증, 테스트 이벤트 수신 확인
QueueCF Queue(또는 선택 Queue) 생성, Consumer가 결정 ① 방식으로 Pulumi 트리거 가능한지 확인
Pulumiprego/sg 스택으로 수동 pulumi preview 성공, Pulumi Cloud State 접근 가능
Ansible대상 서버 SSH·Docker·bench 실행 가능, API Key 출력 검증

위 통과 후 테스트 구독 1건으로 E2E(P1-13) 검증 권장.


4. Phase 2 — Usage-Based Billing (M3–M4)

4.1 목표

  • Zuplo Soft Metering → R2 Raw Log → Aggregator → usage_rollups → Billing Cycle Close → Stripe 청구 E2E

4.2 산출물

산출물설명
Zuplo Soft Quota결정 ② 반영 — KV 백엔드, 키 구조, TTL (In-memory 제거)
R2 Raw 파티셔닝usage_raw/tenant_id=…/dt=…/hour=…/part-*.jsonl.gz
Aggregator WorkerCron: R2 파티션 집계 → D1 usage_rollups Upsert (5분~1시간 단위)
Billing Cycle Closeincluded 차감, overage 계산, Stripe 전송 (월말)

4.3 태스크 분해

ID태스크선행 조건완료 기준
P2-1Zuplo Soft Quota KV 백엔드 설계 및 적용 (결정 ②)KV에 요청 카운트 영속, 재시작 후에도 유지
P2-2R2 버킷 및 파티셔닝 구조 생성 (tenant_id, dt, hour)JSONL+gzip 적재 구조 확정 및 쓰기 권한 설정
P2-3Zuplo → R2 Raw 로그 적재 파이프라인 (로그 형식 명세 반영)P2-2ts, tenant_id, meter_key, qty, path, status 등 필드 저장
P2-4Aggregator Cron: R2 읽기 → usage_rollups UpsertP1-8, P2-25분/1시간 단위 집계, 멱등성 보장
P2-5Billing Cycle Close Job (included, overage, Stripe 전송)P2-4월말 실행, Stripe Invoice/Usage 연동
P2-6E2E 검증: API 호출 → R2 → Aggregator → usage_rollups → Cycle Close → StripeP2-1~P2-5Usage 집계 → Stripe 청구 E2E 성공

4.4 의존성 다이어그램 (Phase 2)

P2-1 (결정②) ──────────────────────────────────────────────────────────────┐
P2-2 ───────────────────┬─ P2-3 ────────────────────────────────────────── │
│ │
P1-8 ───────────────────┴─ P2-4 ── P2-5 ────────────────────────────────── │
├─ P2-6 (E2E)

4.5 Phase 2 완료 기준 체크리스트

  • Zuplo Soft Quota가 KV 기반으로 동작 (결정 ② 반영)
  • R2 Raw 로그 구조가 기술개발기획서 §8.2와 일치
  • Aggregator가 D1 write 부하를 유발하지 않도록 배치 주기·Upsert 전략 확정
  • Usage 집계 → Stripe 청구 E2E 성공

4.6 Phase 2 태스크별 세부 체크 항목

태스크세부 체크
P2-1KV 네임스페이스·키 구조(usage:{tenant_id}:{meter_key}:{cycle_start}), TTL, Zuplo 설정 반영
P2-2R2 버킷 생성, tenant_id/dt/hour 파티션 prefix, 쓰기 권한(Worker/엣지)
P2-3Zuplo 또는 엣지에서 요청 시 ts, tenant_id, meter_key, qty, path, status JSONL 적재
P2-4Cron 주기(5분/1시간), R2 List+Get, usage_rollups Upsert 멱등 키(tenant_id, meter_key, dt, hour 등)
P2-5Cycle Close 일정(월말), included 차감·overage 계산, Stripe Usage/Invoice API 호출
P2-6E2E: API 호출 → R2 → Aggregator → usage_rollups → Cycle Close → Stripe 청구서 생성 확인

4.7 Billing Cycle·included·overage 요약 (Phase 2)

항목설명
Billing Cycle월 단위 (예: 1일~말일). usage_cycle_totals·meter_rates와 연동
included플랜별 포함량 (plan_entitlements). Cycle 내 사용량이 included 이하면 추가 과금 없음
overage포함량 초과분. usage_rollups 합계 − included, meter_rates 적용 후 Stripe Usage Record·Invoice 항목 반영
Cycle Close월말(또는 설정일) 실행: included 차감, overage 계산, Stripe API 호출 (P2-5)

D1: meters, usage_rollups, usage_cycle_totals, meter_rates (§13).

4.8 Phase 2 첫 Cycle Close 전 점검

첫 월말 Cycle Close 실행 전 확인.

항목확인
§4.5 완료 기준KV·R2·Aggregator·usage_rollups·P2-6 E2E 통과
meter_rates·plan_entitlementsD1에 반영, included/overage 계산 로직 검증
Stripe APIUsage Record·Invoice 연동 권한·테스트 모드 해제(prod 시)
Cycle Close 일정Cron/스케줄러 월말 실행 시간·타임존 확정

5. Phase 3 — Governance: LogPath, PDPA, D1 0006 (M5–M6)

5.1 목표

  • LogPath Trace/Stage 전 구간 연결, SEV1 분석 1초 이내
  • Audit Log 영구 보존, PDPA Soft Delete 30일 → Hard Purge 자동화
  • D1 0006_multiregion (nodes, scaling_events, tenants_master preferred_region/failover_region) 적용

5.2 산출물

산출물설명
Trace Stage 정의STRIPE_WEBHOOK_RECEIVED ~ COMPLETED (기술개발기획서 §9.1)
trace_events 고빈도 전략결정 ③ 반영 — R2 오프로드/하이브리드, 인덱스(trace_id, time, region)
Audit Dashboardaudit_logs 조회·필터 (append-only, Delete 금지)
PDPA Purge 자동화Soft Delete 30일 → Hard Purge(Hetzner, R2, Snapshot) → D1 tenant 삭제
D1 0006_multiregionnodes, node_metrics_rollups, scaling_events, placement_history, tenants_master 컬럼 추가

5.3 태스크 분해

ID태스크선행 조건완료 기준
P3-1trace_events 고빈도 append 전략 확정 및 구현 (결정 ③)R2 오프로드 또는 하이브리드 적용, SEV1 분석 1초 요구 충족
P3-2전 구간 trace_id 주입 (Stripe Webhook, Control Plane, Queue, Pulumi/Ansible, Zuplo)P1-9동일 trace_id로 전체 Stage 추적 가능
P3-3trace_events에 region, pulumi_stack, gh_run_id 필드 추가 (멀티리전 대비)P3-1리전별 프로비저닝 경로 추적 가능
P3-4Audit Log 저장 정책 (write-only, Delete 금지) 및 CF Access 권한 분리audit_logs 영구 보존
P3-5Audit Dashboard (조회·필터, 리전/테넌트/시간)P3-4PDPA 감사 대응 가능
P3-6PDPA Soft Delete (status=Pending_Deletion, 30일 유예)P1-8접근 차단, 30일 후 Hard Purge 트리거
P3-7Hard Purge Job: Hetzner DB, R2, Snapshot 삭제 → D1 tenant row 삭제P3-630일 후 자동 실행, Audit Log는 유지
P3-8D1 0006_multiregion 마이그레이션 적용P1-8nodes, scaling_events, tenants_master preferred_region/failover_region 등 사용 가능
P3-9LogPath SEV1 분석 시나리오 검증 (trace_id 기준 1초 이내 조회)P3-1, P3-2PDPA 감사 대응 + LogPath SEV1 분석 완료

5.4 의존성 다이어그램 (Phase 3)

결정③ ── P3-1 ──┬─ P3-3 ────────────────────────────────────────────────────┐
│ │
P1-9 ────────────┴─ P3-2 ───────────────────────────────────────────────── │
├─ P3-9
P1-8 ──┬─ P3-6 ── P3-7 (Purge) │
└─ P3-8 (0006_multiregion) ────────────────────────────────────────────┘
P3-4 ── P3-5 (Audit Dashboard)

5.5 Phase 3 완료 기준 체크리스트

  • Trace Stage 전 구간 연결, trace_id 일관 유지
  • trace_events 고빈도 전략(결정 ③) 적용, SEV1 분석 1초 이내
  • Audit Log 영구 보존, Dashboard로 감사 대응
  • PDPA Soft Delete 30일 → Hard Purge 자동화 동작
  • D1 0006_multiregion 적용 완료

5.6 Phase 3 태스크별 세부 체크 항목

태스크세부 체크
P3-1결정 ③ 반영: R2 파티션 또는 D1 배치 쓰기, trace_id·time 인덱스, 1초 이내 조회 검증
P3-2Webhook·Control Plane·Queue·Ansible 콜백·Zuplo에서 동일 trace_id 전달·기록
P3-3trace_events 테이블 또는 R2 스키마에 region, pulumi_stack, gh_run_id 컬럼/필드
P3-4audit_logs write-only 정책, Delete 금지, CF Access로 쓰기 권한 분리
P3-5Dashboard에서 리전/테넌트/시간 범위 필터, export(선택)
P3-6tenants_master.status=Pending_Deletion 시 접근 차단, 30일 후 purge_jobs 또는 Cron 트리거
P3-7Hard Purge: Hetzner 서버/볼륨 삭제, R2 테넌트 prefix 삭제, Snapshot 삭제, D1 tenant row 삭제; audit_logs 유지
P3-80006 마이그레이션 적용, nodes·scaling_events·placement_history, tenants_master preferred_region/failover_region
P3-9trace_id로 전 Stage 1초 이내 조회 시나리오, PDPA 감사 요청 시 Audit 로그 제출 시나리오

5.7 trace_events 스키마 요약 (결정 ③ 구현 참조)

D1 또는 R2(결정 ③) 저장 시 참조. SEV1 조회: trace_id·time(또는 region) 인덱스 권장.

필드타입설명
trace_idstring (UUID)전 구간 동일, LogPath 추적 키
stagestringSTRIPE_WEBHOOK_RECEIVED, BILLING_STATUS_UPDATED, … COMPLETED (§2.1)
regionstringsg / us / eu (P3-3 멀티리전)
pulumi_stackstringprego/sg 등 (P3-3)
gh_run_idstringGitHub Actions Run ID (P3-3)
created_atISO8601이벤트 시각
payload_jsonstring (선택)추가 메타데이터

5.8 Hard Purge 실행 순서 (P3-7)

30일 경과 후 자동(또는 예외 수동) 실행 시 순서. audit_logs는 삭제하지 않음.

순서대상동작
1Hetzner해당 테넌트 서버·볼륨·Snapshot 삭제 (또는 Pulumi destroy 해당 리소스)
2R2테넌트 prefix (usage_raw/tenant_id=… 등) 삭제
3기타 스토리지해당 테넌트 Snapshot·백업 있으면 삭제
4D1tenants_master·provision_jobs 등 tenant_id 기준 row 삭제 (purge_jobs 완료 갱신)
audit_logs삭제 금지 (append-only, 감사 보존)

수동 트리거 시 §14 Runbook “Hard Purge 수동 트리거” 참조.

5.9 Phase 3 첫 Hard Purge 전 점검

첫 30일 경과 Hard Purge 실행 전 확인.

항목확인
§5.5 완료 기준P3-6·P3-7·Purge Job·0006 적용 완료
§5.8 순서Hetzner → R2 → Snapshot → D1, audit_logs 삭제 없음
purge_jobs 상태Pending → Running → Completed/Failed 전이·에러 시 재시도
테스트(선택) 테스트 테넌트로 Soft Delete 30일 시뮬레이션 후 Purge 1건 검증

6. Phase 4 — US 리전 및 Autoscaler (M7–M8)

6.1 목표

  • Hetzner Ashburn(US) 리전 활성화, Enterprise Tier US 전용 노드
  • Autoscaler (Health Score, Scale Out/In 트리거), SLA 모니터링

6.2 산출물

산출물설명
Pulumi prego/us 스택ash-dc3, HCLOUD_TOKEN_US, Pulumi.us.yaml
resolveRegion() 확장Enterprise + tenant_region=us → us 스택 사용
Cloudflare Load Balancingus-pool, Geo Steering (선택), Health Check
AutoscalerHealth Score 공식(기술개발기획서 §10.1), 10분 지속·2개 이상 시 Scale Out
scaling_events 기록ScaleOut/ScaleIn/Rebalance/Drain, D1 nodes 갱신

6.3 태스크 분해

ID태스크선행 조건완료 기준
P4-1Pulumi us 스택 및 REGION_CONFIG.us (ash-dc3) 추가P1-2prego/us 스택으로 Ashburn 서버 생성 가능
P4-2GitHub Actions matrix region: [sg, us], HCLOUD_TOKEN_US Secrets/EnvironmentP1-3, P1-4PR Preview / main Up 시 us 스택 포함
P4-3resolveRegion() — Enterprise + requestedRegion=us → usP4-1테넌트 프로비저닝 시 US 리전 선택 반영
P4-4Cloudflare Load Balancing: sg-pool, us-pool, Health Check 30초리전별 오리진 풀 구성
P4-5D1 0006 nodes 테이블 활용, 노드 상태(Active/Draining 등) 갱신P3-8nodes.region, status 반영
P4-6Autoscaler: Health Score 계산 (CPU/Mem/Disk/Latency/Err/Density), 10분 지속 + 2개 이상 시 Scale OutP4-5scaling_events 생성, 신규 노드 프로비저닝 트리거
P4-7US 리전 테넌트 E2E (Enterprise US 선택 → prego/us → Ansible → Zuplo)P4-1~P4-4US 리전 테넌트 프로비저닝 성공

6.4 의존성 다이어그램 (Phase 4)

P1-2 ── P4-1 ──┬─ P4-3 ────────────────────────────────────────────────────┐
│ │
P1-3,P1-4 ──────┴─ P4-2 (matrix sg,us) │
├─ P4-7 (E2E)
P3-8 ── P4-5 ── P4-6 (Autoscaler) ──────────────────────────────────────────┘
(선택) P4-4 (CF Load Balancing) — P4-4는 P4-7 전 완료 권장

6.5 Phase 4 완료 기준 체크리스트

  • prego/us 스택으로 Ashburn 서버 생성 및 DNS 연동
  • Enterprise Tier에서 US 리전 선택 시 us 스택 사용
  • Autoscaler Health Score 및 Scale Out/In 트리거 동작
  • US 리전 테넌트 프로비저닝 성공

6.6 Phase 4 태스크별 세부 체크 항목

태스크세부 체크
P4-1Pulumi.us.yaml, REGION_CONFIG.us (ash-dc3), HCLOUD_TOKEN_US 사용, prego/us 스택 생성·실행
P4-2matrix region: [sg, us], production-us Environment, HCLOUD_TOKEN_US Secrets
P4-3resolveRegion()에서 plan_tier=Enterprise && requestedRegion=us → ‘us’ 반환, 프로비저닝 플로우에 반영
P4-4CF Load Balancer, sg-pool·us-pool, Health Check 30초, (선택) Geo Steering
P4-5nodes 테이블 INSERT/UPDATE (node_id, region, status, hostname, ip_address, infra_mode), 메트릭 수집 연동
P4-6Health Score 공식 적용, 10분 윈도우·2개 이상 임계 초과 시 Scale Out, scaling_events INSERT
P4-7E2E: Enterprise US 선택 → provision_jobs region=us → prego/us up → Ansible → Zuplo → COMPLETED

6.7 Autoscaler 메트릭 수집 항목 (node_metrics_rollups)

Health Score(§9.7) 계산을 위해 수집·집계할 메트릭. D1 0006 node_metrics_rollups 또는 동등 저장소.

메트릭설명Health Score 용도
cpu_avg노드 CPU 사용률 평균 (%)CPU 패널티 (가중치 0.30)
mem_avg메모리 사용률 평균 (%)Memory 패널티 (0.25)
disk_pct디스크 사용률 (%)Disk 패널티 (0.15)
p95_latency_msAPI p95 지연 (ms)Latency 패널티 (0.15)
err_5xx_rate5xx 에러 비율Error 패널티 (0.10)
tenant_count해당 노드 테넌트 수Density 패널티 (0.05)
max_tenants노드 최대 테넌트 수 (nodes 테이블)Density 분모

수집 주기: 1~5분 단위 권장. 10분 윈도우로 2개 이상 임계 초과 시 Scale Out (§9.7).

6.8 nodes.status 전이 (D1 0006)

상태설명다음 상태
Active정상 배치·트래픽 수신Draining (Scale In·유지보수 전), Maintenance
Draining신규 테넌트 배치 중단, 기존 트래픽만 유지Active (복구), Disabled (정리 완료)
Maintenance수동 점검·업데이트Active
Disabled비활성·삭제 예정— (리소스 정리 후 제거)

Autoscaler Scale In 시 노드 → Draining 후 테넌트 이전 완료 시 Disabled 또는 삭제.

6.9 Phase 4 첫 US 프로비저닝 전 점검

첫 Enterprise US(Ashburn) 테넌트 프로비저닝 전 확인.

항목확인
§6.5 완료 기준P4-1~P4-4, prego/us 스택·HCLOUD_TOKEN_US·CF us-pool·Health Check
resolveRegion()plan_tier=Enterprise && requestedRegion=us → ‘us’ 반환, 프로비저닝 플로우 반영
Ansible·ZuploUS 리전 서버 대상 배포·API Key 등록 동작
(선택) 테스트Enterprise US 플랜으로 테스트 구독 1건 E2E

7. Phase 5 — EU 리전 및 GDPR (M9+)

7.1 목표

  • Hetzner Falkenstein(EU) 리전 활성화, GDPR 대응
  • D1 리전별 인스턴스 검토 (d1-prego-eu), Predictive Scaling, 관리자 대시보드 고도화

7.2 산출물

산출물설명
Pulumi prego/eu 스택fsn1-dc14, HCLOUD_TOKEN_EU
D1 리전별 인스턴스 (선택)d1-prego-eu, 데이터 주권
GDPR 대응EU 고객 데이터 처리 정책, Purge 시 EU 전용 플로우
Predictive Scaling (선택)예측 기반 Scale Out
관리자 대시보드멀티리전 현황, 노드/테넌트/청구 요약

7.3 태스크 분해

ID태스크선행 조건담당 유형완료 기준
P5-1Pulumi eu 스택, REGION_CONFIG.eu, resolveRegion() eu 분기P4-1Infraprego/eu 스택 Falkenstein 서버 생성
P5-2GitHub Actions matrix [sg, us, eu], production-eu EnvironmentP4-2DevOpsPR/Up 시 eu 포함
P5-3Cloudflare eu-pool, Geo Steering (EU 고객), Health CheckP4-4InfraEU 리전 라우팅
P5-4D1 리전별 인스턴스 검토 및 마이그레이션 (d1-prego-eu)P3-8Backend데이터 주권 정책 반영
P5-5GDPR Purge·접근 제어 정책 정리 및 구현 (EU 전용 Purge 플로우)P3-7Backend/ComplianceEU 고객 대응 완료
P5-6Predictive Scaling (선택): 메트릭 기반 예측 Scale OutP4-6Infra필요 시 도입
P5-7관리자 대시보드 (리전별 노드/테넌트/청구, Audit 링크)P4-5, P3-5Frontend/Backend운영 가시화
P5-8EU 리전 테넌트 E2E (Enterprise EU 선택 → prego/eu → COMPLETED)P5-1~P5-3QA/SREFalkenstein 테넌트 프로비저닝 성공

7.4 Phase 5 완료 기준 체크리스트

  • prego/eu 스택으로 Falkenstein 서버 생성 및 DNS 연동
  • Enterprise Tier에서 EU 리전 선택 시 eu 스택 사용
  • Falkenstein 리전 테넌트 E2E 프로비저닝 성공 (P5-8)
  • EU 고객 대응 완료 (GDPR 정책·Purge 반영)
  • 관리자 대시보드에서 리전별 현황·Audit 링크 확인 가능

7.5 Phase 5 태스크별 세부 체크 항목

태스크세부 체크
P5-1Pulumi.eu.yaml, REGION_CONFIG.eu (fsn1-dc14), resolveRegion() eu 분기
P5-2matrix region: [sg, us, eu], production-eu Environment, HCLOUD_TOKEN_EU Secrets
P5-3eu-pool 추가, Geo Steering(EU), Health Check, Failover 정책
P5-4d1-prego-eu 검토(데이터 주권), 필요 시 마이그레이션·라우팅 분리
P5-5GDPR Purge 플로우(EU 테넌트 전용), 접근 제어·동의 기록 정책
P5-6(선택) 메트릭 기반 예측 Scale Out 로직
P5-7대시보드: 리전별 노드/테넌트 수, 청구 요약, audit_logs 링크
P5-8E2E: Enterprise EU 선택 → prego/eu → Ansible → Zuplo → COMPLETED

7.6 Phase 5 첫 EU 프로비저닝 전 점검

첫 Enterprise EU(Falkenstein) 테넌트 프로비저닝 전 확인.

항목확인
§7.4 완료 기준P5-1~P5-3, prego/eu 스택·HCLOUD_TOKEN_EU·eu-pool·Geo Steering
resolveRegion()plan_tier=Enterprise && requestedRegion=eu → ‘eu’ 반환
GDPR·PurgeP5-5 EU 전용 Purge·접근 제어 정책 반영
(선택) d1-prego-eu데이터 주권 요구 시 P5-4 검토 완료
(선택) 테스트Enterprise EU 플랜으로 테스트 구독 1건 E2E

8. Cross-Phase 공통 작업

영역내용적용 Phase
보안API Key Vault/CF Secrets 참조, NRIC Zuplo 마스킹, Magic Link TTL 48h+ 2차 인증, Admin Cloudflare Access+MFA전 단계
Fail Sanely아래 §8.1 상세 표 참조Phase 1~5
문서GitHub Secrets 로테이션 주기(90/180일), Environment Protection Rules, Runbook (Pulumi rollback, Purge 수동 트리거)Phase 1 정리, 이후 유지

8.1 Fail Sanely 상세 (상황별 정책·자동화)

기술개발기획서 v4.0 §12 기준.

상황정책자동화
Stripe 일시 장애기존 Active 테넌트 7일 Grace 유지자동 — status 유지, Webhook 재전송 대비 멱등
Provision 실패Queue 재시도 (지수 백오프, max 5회)자동 + Slack Alert
Fraud 의심즉시 Suspend + 수동 검토자동 Suspend
Webhook 지연/중복provider_events 멱등성 처리자동
Pulumi 스택 에러GitHub Actions 실패 알림, 수동 rollbackAlert 자동, 복구 수동
D1 write 실패낙관적 락 + 재시도 3회자동
리전 장애 (Phase 4+)Cloudflare Failover → SG 리전 폴백자동 (Phase 1 기준 SG 단일)

8.2 보안 설계 체크리스트 (기술개발기획서 v4.0 §13)

영역항목적용
API Key실제 키는 Vault/CF Secrets에만 저장, D1에는 참조(secret_refs)만Phase 1
Magic LinkTTL 48시간 + 생년월일 등 2차 인증전 단계
NRIC/FINZuplo 미들웨어에서 API 레이어 마스킹, 저장 전 필터링Phase 1~2
Admin 접근Cloudflare Access (Zero Trust) + MFAPhase 1 정리
GitHub Secrets리전별 분리(HCLOUD_TOKEN_SG 등), 90일 로테이션§9.4
Pulumi StatePulumi Cloud 암호화, PULUMI_PASSPHRASE 관리Phase 1
audit_logsCF Access write-only 권한 분리, Delete 금지Phase 3

8.3 Slack·Alert 메시지 포맷 (참조)

이벤트메시지 요약비고
Pulumi Up 성공✅ Pulumi Up 완료 — Region: {region}§4.3 pulumi-up.yml
Pulumi Up 실패🚨 Pulumi Up 실패 — Region: {region} — 즉시 확인 필요SLACK_WEBHOOK_URL
Provision 실패Provision 재시도 소진 시 tenant_id, trace_id, region 포함 Alert 권장Queue Consumer 또는 Control Plane
리전 장애 (Phase 4+)Failover 발생 시 리전·풀 정보 포함 알림 (선택)CF Notification

8.4 재시도·에러 정책 요약

대상정책비고
Provision (Queue)지수 백오프, max 5회, 실패 시 Slack Alert§8.1
D1 write낙관적 락 + 재시도 3회동시성 제어
Stripe Webhookprovider_events 멱등성 키로 중복 스킵event.id 또는 동등 키
Pulumi UpGitHub Actions 실패 시 수동 rollback, Alert 자동Runbook §14
Aggregator → usage_rollupsUpsert 멱등 키(tenant_id, meter_key, dt, hour)Phase 2

8.5 역할·에스컬레이션 요약

역할주 담당에스컬레이션
Infra/SREPulumi·Ansible·GitHub Actions·리전·Autoscaler (P1-1~P1-5, P1-11, P4, P5)Pulumi 실패·리전 장애 시 수동 복구·Runbook 실행
BackendD1·Control Plane·Webhook·Queue·Purge·trace (P1-8~P1-10, P3, D1 마이그레이션)D1·Queue 이상 시 로그·trace_id 추적, Purge 예외 처리
DevOpsSecrets·Environment·워크플로우 설정 (P1-6, P1-7, P4-2, P5-2)Secrets 로테이션·Environment 승인 정책
GatewayZuplo·KV·Rate Limit·zuplo_sync (P1-12, P2-1)KV·Quota 이슈 시 Zuplo·R2 연동 확인
QA/SREE2E 검증·릴리스 전 검수 (P1-13, §9.11)실패 시 해당 Phase 담당으로 에스컬레이션

결정 ①·②·③ 및 정책 변경은 SRE/Lead·Product 합의.

8.6 주요 에러 시나리오·대응 한 줄

시나리오대응 한 줄
Stripe Webhook 실패·중복provider_events 멱등 스킵; 7일 Grace 유지 (§8.1)
Provision Queue 재시도 소진Slack Alert, trace_id로 LogPath 추적, 수동 재시도 또는 보류 (§2.5, §8.1)
Pulumi Up 실패GitHub Actions 로그 → refresh/수동 up, State lock 확인 (§14)
D1 write 실패낙관적 락 + 3회 재시도 (§8.4)
Aggregator·Cycle Close 지연멱등 Upsert·다음 Cycle 보정; Stripe 재전송 정책 확인
리전(US/EU) 장애CF Failover → SG 폴백 (§9.9, §8.1)
Hard Purge 오류§5.8 순서 확인, audit_logs 삭제 금지, 수동 재실행 (§14)

9. 의존성 및 일정 요약

  • Phase 1이 전체 기반: CI/CD, D1, Control Plane, Provision E2E. 결정 ①·②·③은 Phase 1~3 범위에 직접 영향.
  • Phase 2는 P1-8(D1 0001~0005) 및 결정 ②에 의존.
  • Phase 3은 P1-9(Control Plane trace_id), 결정 ③, P1-8 및 D1 0006에 의존.
  • Phase 4는 P1-2(리전 분기), P3-8(D1 0006)에 의존.
  • Phase 5는 P4(US 리전 및 Autoscaler) 경험을 재사용.

권장 순서: 결정 ①·②·③ 합의 → Phase 1 집중 → Phase 2 → Phase 3 → Phase 4 → Phase 5.

9.1 GitHub Actions 워크플로우 요약

워크플로우트리거Pulumi 명령Environment비고
pulumi-preview.ymlpull_request (branches: main, paths: prego-pulumi/**)pulumi previewPR 코멘트 출력, matrix region: [sg] (Phase 4+ 시 [sg,us,eu])
pulumi-up.ymlpush (main), workflow_dispatch (region, dry_run)pulumi up 또는 previewproduction-sg / production-us / production-eu승인자 게이트, dry_run 시 preview만
pulumi-destroy.ymlworkflow_dispatch (tenant_id, region, confirm)pulumi destroyproduction-destroyconfirm=“DESTROY” 필수, 2인 승인 권장

필요 Secrets: PULUMI_ACCESS_TOKEN, PULUMI_PASSPHRASE, CLOUDFLARE_API_TOKEN, 리전별 Hetzner 토큰(HCLOUD_TOKEN_SG, HCLOUD_TOKEN_US, HCLOUD_TOKEN_EU), SLACK_WEBHOOK_URL.

9.2 Phase별 산출물 체크리스트 (파일·리소스 관점)

Phase생성/수정 대상 (요약)
Phase 1infra/index.ts, infra/providers/.ts, infra/modules/.ts, Pulumi.sg.yaml, .github/workflows/pulumi-*.yml, migrations/0001~0005, Control Plane(Webhook+D1), config/ Ansible, infra/zuplo_sync.ts
Phase 2Zuplo KV 스키마·설정, R2 버킷·파티셔닝, Aggregator Worker, Billing Cycle Close Job
Phase 3trace_events 저장 전략(결정 ③), 전 구간 trace_id 주입, audit_logs 정책·Dashboard, PDPA Soft/Hard Purge Job, migrations/0006_multiregion
Phase 4Pulumi.us.yaml, REGION_CONFIG.us, GitHub matrix [sg,us], CF Load Balancing, nodes·scaling_events 활용, Autoscaler
Phase 5Pulumi.eu.yaml, REGION_CONFIG.eu, matrix [sg,us,eu], eu-pool, (선택) d1-prego-eu, GDPR Purge 플로우, 관리자 대시보드

9.3 Phase별 인수 테스트 시나리오 요약

Phase시나리오 (요약)완료 판정
Phase 1Given 신규 구독 결제 완료 When Webhook 수신 Then D1 갱신 → Queue → Pulumi(해당 리전) → Ansible → Zuplo 등록 → status=CompletedSG 테넌트 자동 프로비저닝 성공
Phase 1Given prego-pulumi/** 변경 PR When PR Open/Update Then Pulumi Preview 실행, PR 코멘트에 결과 표시Preview 자동 실행·코멘트 확인
Phase 2Given 테넌트 API 호출 When Aggregator Cron·Cycle Close 실행 Then usage_rollups 반영, Stripe 청구 생성Usage → Stripe E2E 성공
Phase 3Given trace_id When LogPath 조회 Then 1초 이내 전 Stage 조회 가능; Soft Delete 30일 후 Hard Purge 실행SEV1 분석·PDPA Purge 검증
Phase 4Given Enterprise + region=us When 프로비저닝 Then prego/us 스택으로 Ashburn 서버 생성, 테넌트 ReadyUS 리전 프로비저닝 성공
Phase 5Given Enterprise + region=eu When 프로비저닝 Then prego/eu 스택으로 Falkenstein 서버 생성, GDPR Purge 적용EU 리전·GDPR 대응 완료

9.4 리전·스택·환경·Secrets 매트릭스

정책: Hetzner는 리전별로 다른 토큰을 사용한다 (HCLOUD_TOKEN_SG / HCLOUD_TOKEN_US / HCLOUD_TOKEN_EU). 과금·계정·규제 분리 목적.

Phase 4·5 적용 시 리전별 Pulumi 스택·GitHub Environment·Hetzner 토큰 일람.

리전Pulumi 스택GitHub EnvironmentHetzner SecretHetzner 위치
sgprego/sgproduction-sgHCLOUD_TOKEN_SGnbg1-dc3 (또는 sin)
usprego/usproduction-usHCLOUD_TOKEN_USash-dc3 (Ashburn)
euprego/euproduction-euHCLOUD_TOKEN_EUfsn1-dc14 (Falkenstein)

Destroy 전용: Environment production-destroy (2인 승인 권장). 공통 Secrets: PULUMI_ACCESS_TOKEN, PULUMI_PASSPHRASE, CLOUDFLARE_API_TOKEN, SLACK_WEBHOOK_URL.

9.5 plan_tier ↔ 리전·인프라 모드 매트릭스

기술개발기획서 v4.0 §6.2 기준. 테넌트 생성 시 플랜에 따른 리전·인프라·Pulumi 스택.

Plan Tier리전인프라 모드Pulumi 스택
Basic / Professionalsg (고정)shared_node (Frappe Multi-site)prego/sg
Enterprise (SG)sgdedicated_node (전용 서버)prego/sg
Enterprise (US)usdedicated_nodeprego/us
Enterprise (EU)eudedicated_nodeprego/eu

resolveRegion(planTier, requestedRegion): Enterprise일 때만 requestedRegion 사용, 그 외는 'sg'.

9.6 R2 Raw 로그 스키마 요약 (Usage 파이프라인)

기술개발기획서 v4.0 §8.2. 경로: usage_raw/tenant_id=<uuid>/dt=YYYY-MM-DD/hour=HH/part-*.jsonl.gz.

필드타입설명
tsISO8601요청 시각
tenant_idstring테넌트 UUID
meter_keystring미터 키 (예: api_calls)
qtynumber수량 (예: 1)
pathstringAPI 경로 (예: /api/v1/employee)
statusnumberHTTP 상태 (예: 200)

Aggregator는 위 파티션을 읽어 D1 usage_rollups에 Upsert (5분~1시간 단위, 멱등).

9.7 Autoscaler Health Score 패널티 요약

기술개발기획서 v4.0 §10.1. Final Score = max(0, 100 - total_penalty). 스케일 아웃: 10분 지속 + 2개 이상 메트릭 임계 초과.

패널티조건가중치(weight)
CPUcpu_avg > 50 → (cpu_avg - 50) * 1.20.30
Memorymem_avg > 50 → (mem_avg - 50) * 1.00.25
Diskdisk_pct > 70 → (disk_pct - 70) * 0.80.15
Latencyp95 > 600ms → (p95 - 600) / 200.15
Error5xx > 0.5% → err_rate * 2000.10
Densitytenant_count / max_tenants * 150.05

9.8 태스크 ID → 절 참조 인덱스

태스크 IDPhase
P1-1 ~ P1-13Phase 1§3.3 (태스크 분해), §3.6 (세부 체크)
P2-1 ~ P2-6Phase 2§4.3
P3-1 ~ P3-9Phase 3§5.3
P4-1 ~ P4-7Phase 4§6.3
P5-1 ~ P5-8Phase 5§7.3

9.9 Cloudflare Load Balancing 요약 (Phase 4·5)

기술개발기획서 v4.0 §3.4. 리전 확장 시 적용.

구성 요소내용
Origin Poolsg-pool (Phase 1), us-pool (Phase 4), eu-pool (Phase 5) — 리전별 오리진 IP/호스트
Health CheckHTTP, 30초 간격, 각 리전 노드
라우팅테넌트 subdomain 또는 Geo Steering으로 리전 고정 (선택)
Failover주 리전 장애 시 SG 리전 폴백 (Phase 1 기준 단일 리전)
SSLCloudflare Full Strict, 리전별 오리진 인증서 별도 발급

9.10 구현 순서 한 페이지 요약

순서단계내용
0결정§1 결정 ①·②·③ 합의
1킥오프§2.3 체크리스트: Stripe·Hetzner·CF·Pulumi·GitHub·D1·Queue 준비
2Phase 1P1-1 → P1-2, P1-3→P1-5, P1-6·P1-7, P1-8 → P1-9 → P1-10 → P1-11 → P1-12 → P1-13 (§3.4 의존성 참조)
3Phase 2P2-1·P2-2 병렬 → P2-3 → P2-4 → P2-5 → P2-6
4Phase 3P3-1, P3-4, P3-8 병렬 가능 → P3-2·P3-3, P3-6→P3-7, P3-5, P3-9
5Phase 4P4-1 → P4-2·P4-3, P4-4·P4-5 → P4-6 → P4-7
6Phase 5P5-1 → P5-2·P5-3, P5-4·P5-5, P5-7 → P5-8 (P5-6 선택)

마일스톤: Phase 1 완료 = SG 테넌트 자동 프로비저닝 성공. Phase 2 = Usage→Stripe E2E. Phase 3 = LogPath SEV1·PDPA Purge. Phase 4 = US 리전 프로비저닝. Phase 5 = EU 리전·GDPR.

9.11 Phase별 릴리스 전 검수 체크리스트

각 Phase 완료 후 다음 Phase 착수 전 확인.

Phase검수 항목
Phase 1§3.5 완료 기준 전부 체크, 결정 ① 반영 동작, D1 0001~0005 정상, Runbook·Secrets 문서화
Phase 2§4.5 완료 기준, KV·R2·Aggregator·Cycle Close E2E, 결정 ② 반영
Phase 3§5.5 완료 기준, trace 전 구간·SEV1 1초, Audit·Purge 자동화, 0006 적용
Phase 4§6.5 완료 기준, US 스택·resolveRegion(us)·CF LB·Autoscaler 동작. 첫 US 프로비저닝 전 §6.9 점검
Phase 5§7.4 완료 기준, EU 스택·GDPR Purge·대시보드. 첫 EU 프로비저닝 전 §7.6 점검

9.12 5-Layer 아키텍처 ↔ Phase 매핑

기술개발기획서 v4.0 §2. Control / Data / Infrastructure / Gateway / Event Plane이 어느 Phase에서 구현되는지.

Layer구성 요소구현 Phase
Control PlaneCF Pages Functions, D1, Stripe Webhook, 테넌트 상태·Queue enqueuePhase 1 (P1-8, P1-9, P1-10)
Data PlaneR2 Raw Logs, Aggregator, Billing Engine, usage_rollupsPhase 2 (P2-2~P2-5)
Infrastructure PlanePulumi, Ansible, GitHub Actions (Preview/Up 분리)Phase 1 (P1-1~P1-5, P1-11), Phase 4·5 (us/eu 스택)
Gateway PlaneZuplo API Gateway, Rate Limit, API Key, Soft Quota(KV)Phase 1 (P1-12), Phase 2 (P2-1 KV)
Event PlaneLogPath Trace/Stage, audit_logs, trace_eventsPhase 1 (D1 0004), Phase 3 (P3-1~P3-9)

9.13 scaling_events 액션·상태 요약 (D1 0006)

필드설명
actionScaleOut신규 노드 추가 (Health Score 임계 초과)
actionScaleIn노드 감소, 해당 노드 Draining 후 제거
actionRebalance테넌트 재배치 (선택)
actionDrain특정 노드 Draining 전환
statusPending이벤트 생성, 실행 대기
statusRunning실행 중 (Pulumi/이전 작업 등)
statusCompleted / Failed완료 또는 실패, completed_at 기록

P4-6 Autoscaler에서 ScaleOut 시 scaling_events INSERT 후 해당 리전 Pulumi up 트리거.

9.14 Phase별 핵심 산출물 한 줄 요약

Phase한 줄 산출
Phase 1SG 리전에서 Stripe 결제 → Pulumi·Ansible·Zuplo까지 테넌트 자동 프로비저닝 E2E 동작
Phase 2API 호출 → R2 Raw → Aggregator → usage_rollups → Cycle Close → Stripe 청구서 생성
Phase 3trace_id로 전 구간 1초 조회, Audit Log 영구 보존, Soft Delete 30일 후 Hard Purge 자동, D1 0006 적용
Phase 4Enterprise US 선택 시 prego/us(Ashburn) 프로비저닝, Autoscaler Health Score·Scale Out/In
Phase 5Enterprise EU 선택 시 prego/eu(Falkenstein) 프로비저닝, GDPR Purge·관리자 대시보드

9.15 데이터 흐름 요약 (텍스트)

프로비저닝: Stripe Webhook → Control Plane (D1 tenants_master, provision_jobs) → CF Queue → (결정 ①) GitHub Actions Pulumi up → Ansible (서버·Frappe·API Key) → Zuplo Sync → Control Plane (status=Completed).

Usage·Billing: API 요청 → Zuplo (Soft Quota KV) → R2 Raw (tenant_id/dt/hour) → Aggregator Cron → D1 usage_rollups → Cycle Close → Stripe Usage/Invoice.

LogPath: trace_id는 Webhook·Control Plane·Queue·Pulumi/Ansible 콜백·Zuplo에서 동일 전달 → trace_events(D1 또는 R2, 결정 ③) → SEV1 조회(trace_id·time).

Purge: Pending_Deletion 30일 경과 → purge_jobs → Hetzner·R2·Snapshot 삭제 → D1 tenant row 삭제; audit_logs 유지.

9.16 Phase 완료 시그니오프 템플릿 (선택)

Phase 완료·다음 Phase 착수 전 승인 기록용. 팀 정책에 따라 사용.

Phase완료일검수 항목 통과승인자비고
Phase 1____§3.5 전부________SG 프로비저닝 E2E 확인
Phase 2____§4.5 전부________Usage→Stripe E2E 확인
Phase 3____§5.5 전부________LogPath SEV1·Purge 확인
Phase 4____§6.5 전부________US 리전·Autoscaler 확인
Phase 5____§7.4 전부________EU·GDPR·대시보드 확인

10. 기존 코드베이스 연계

구현 시 수정·참조할 저장소 및 경로 매핑입니다. (현재 구조 기준, 추후 폴더 정리 시 본 절 업데이트 권장.)

기획서 항목저장소경로/비고
Pulumi 인프라Pregoprego-pulumi/ — Cloudflare·Hetzner provider, 리전 분기(sg/us/eu)
AnsiblePregoconfig/ 또는 infra/ansible/ — Docker·Frappe·bench new-site·API Key 롤
GitHub ActionsPrego.github/workflows/ — pulumi-preview.yml, pulumi-up.yml, pulumi-destroy.yml 신규
Control Plane (Stripe Webhook, D1)PregoCF Pages Functions 또는 동등 엣지 — Stripe Webhook 핸들러, D1 tenants_master/provision_jobs 갱신
D1 마이그레이션Pregomigrations/ 또는 D1 프로젝트 내 — 0001~0006 SQL 파일
client-web (온보딩·앱 UI)Pregoapps/client-web/ — 플랜/리전 선택 UI는 Phase 4+ Enterprise 분기 시 확장
Zuplo Gateway, Soft Quota, NRIC 마스킹prego-zuploGateway 설정, KV 백엔드(결정 ②), 미들웨어
Zuplo Sync 스크립트Pregoinfra/zuplo_sync.ts — API Key 등록, Rate Limit 정책 반영
R2 Raw, Aggregator WorkerPrego 또는 별도R2 버킷·파티셔닝, Cron Worker (Cloudflare Worker 또는 동등)
LogPath / trace_eventsPregoControl Plane·Queue·Ansible 콜백에서 trace_id 전달; 저장소는 결정 ③에 따라 D1/R2/하이브리드
Audit DashboardPregoapps/ 내 관리자 대시보드 또는 별도 앱 — audit_logs 조회·필터

참고: saas-unified-architecture-hetzner-cloudflare-zuplo-plan.md의 목표 디렉터리 구조와 본 Phase 산출물 위치를 맞출 것.


11. 리스크·가정·제약

11.1 리스크 (요약)

리스크영향대응
Provision 실행 주체 미결정(결정 ①)Phase 1 E2E 지연§1 권장안(GitHub Actions 콜백)으로 조기 확정
Zuplo KV 미전환(결정 ②)Billing 정확성·재시작 시 카운트 손실Phase 2 전 KV 스키마·TTL 확정
trace_events D1 집중(결정 ③ 미반영)D1 write 병목, SEV1 조회 지연R2 오프로드 또는 배치 쓰기 설계
Hetzner 리전 가용성/레이턴시US/EU 확장 일정 변동Phase 1 SG 안정화 우선, Phase 4/5는 조건부 활성화
D1 리전별 인스턴스 비용·운영 복잡도Phase 5 EU 비용 증가d1-prego-eu는 “검토” 단계로 두고, 규제 요구 시 도입

11.2 가정

  • Stripe Webhook·D1·R2·Cloudflare·Hetzner API 가정상의 SLA 내 동작.
  • Frappe/HRMS·Ansible 롤은 기존 또는 별도 레포에서 유지·재사용.
  • “승인자 게이트”는 GitHub Environment Required Reviewers로 충족.
  • Phase 1~2 완료 시점에 실제 결제·프로비저닝 트래픽이 소규모로 존재한다고 가정.

11.3 제약

  • 코드 생성은 본 문서에 포함하지 않음 — 별도 요청 시 Phase/태스크 단위로 진행.
  • Pulumi State는 Pulumi Cloud 이외 외부 저장소 비사용 권장(기술개발기획서 정책).
  • audit_logs는 append-only, Delete 금지(감사 요구사항).

11.4 다음 문서·산출물

본 기획서를 기준으로 이후 작성·갱신할 문서. 구현 순서에 따라 단계별 작성 권장.

문서·산출물시점내용
Runbook 상세Phase 1 완료 후§14 요약을 절차별 상세화 (Pulumi Up/Destroy, Provision 재시도, Secrets 로테이션, Hard Purge 수동)
Stripe 연동 명세Phase 1·2Webhook 이벤트·필드 매핑, provider_events 스키마, Cycle Close→Stripe API 호출 순서
D1 마이그레이션 파일Phase 1~30001~0006 SQL (기술개발기획서 §7·본 §13 참조)
API·Queue 메시지 명세Phase 1§13.2 확장, Consumer 계약 (tenant_id, trace_id, region 등)
관리자 대시보드 요구사항Phase 5리전별 노드/테넌트/청구, Audit 링크, 권한 (§14.1)
첫 US/EU 프로비저닝 체크리스트Phase 4·5§6.9·§7.6 점검표를 Runbook 또는 운영 문서에 반영

12. 결정 로그 템플릿 (§1 외 추가 결정)

§1의 3건 외에 Phase 진행 중 발생하는 설계·운영 결정을 기록할 때 사용합니다. 아래는 §1 즉시 결정 3건을 로그에 반영한 예시.

일자결정 제목내용결정자
(예) 2026-02-xx결정 ① Provision 실행 주체GitHub Actions + workflow_dispatch 콜백 vs Control Plane 직접 호출 → 권장안 반영 후 기록SRE/Lead
(예) 2026-02-xx결정 ② Zuplo Soft Quota KV 백엔드Cloudflare KV vs 외부 KV → 권장안 반영 후 기록Backend/Lead
(예) 2026-02-xx결정 ③ trace_events 고빈도 저장R2 오프로드 vs 하이브리드 → 권장안 반영 후 기록SRE/Lead
(추가 결정)

13. D1 마이그레이션 스키마 요약

기술개발기획서 v4.0 §7 기준. 구현 시 마이그레이션 파일 순서·외래키 의존성 준수.

Migration테이블(주요)목적
0001_inittenants_master, plans, plan_entitlements테넌트 기본 상태, 플랜 정의
0002_billingbilling_customers, subscriptions, provider_events, invoicesStripe 연동, 청구 상태
0003_jobs_runtimetenant_runtime, secret_refs, provision_jobs, purge_jobs비동기 작업, 런타임 정보
0004_logpath_audittraces, trace_events, audit_logsLogPath 이벤트 추적, 감사 (append-only)
0005_usage_meteringmeters, usage_rollups, usage_cycle_totals, meter_ratesUsage 집계, 청구 계산
0006_multiregionnodes, node_metrics_rollups, scaling_events, placement_history; tenants_master.preferred_region, failover_region멀티리전 Node Pool, 오토스케일러

참고: tenants_master.region 기본값 'sg'. Phase 3에서 0006 적용 후 nodes·scaling_events 사용.

13.1 D1 tenants_master · provision_jobs 핵심 컬럼 (구현 참조)

Phase 1 Webhook·Queue 연동 시 참조. 마이그레이션 0001, 0003 정의와 일치시키면 됨.

테이블컬럼(핵심)용도
tenants_mastertenant_id (PK), status, region, plan_tier, preferred_region (0006), failover_region (0006)테넌트 상태·리전; status=Active/Pending_Deletion 등
tenants_mastercreated_at, updated_at감사
provision_jobsjob_id (PK), tenant_id, trace_id, region, status, created_atQueue enqueue 시 INSERT; status=Pending/Running/Completed/Failed
provision_jobsplan_tier, infra_mode (선택)resolveRegion·Pulumi 스택 분기
provider_events (0002)event_id (Stripe event.id 등), idempotencyWebhook 멱등 처리

13.2 Provision Queue 메시지 스키마

CF Queue(또는 결정 ①에 따른 Queue)에 넣는 프로비저닝 작업 페이로드. Consumer가 Pulumi 트리거 시 동일 필드 전달.

필드타입필수설명
tenant_idstring (UUID)테넌트 식별자
trace_idstring (UUID)LogPath 전 구간 동일 ID
regionstring‘sg’ / ‘us’ / ‘eu’ — Pulumi 스택 선택
plan_tierstring선택Basic / Professional / Enterprise
infra_modestring선택shared_node / dedicated_node
job_idstring선택provision_jobs.job_id (상태 갱신용)

14. 운영 Runbook 요약

Phase 1 정리 후 유지·보완. 상세 절차는 별도 Runbook 문서 권장.

상황조치 요약
Pulumi Up 실패GitHub Actions 로그 확인 → 필요 시 pulumi refresh / 수동 pulumi up (동일 스택). State 충돌 시 Pulumi Cloud에서 lock 확인 후 재시도.
Pulumi Destroy (테넌트/노드 제거).github/workflows/pulumi-destroy.yml workflow_dispatch 실행, tenant_id·region 입력, confirm에 “DESTROY” 입력. production-destroy 환경 2인 승인 후 실행.
Provision 재시도Queue 재처리(지수 백오프, max 5회). 실패 시 Slack Alert 확인, provision_jobs 상태·trace_id로 LogPath 추적.
Stripe Webhook 지연/중복provider_events 멱등성 키로 중복 무시. 7일 Grace 기간 동안 Active 유지.
Secrets 로테이션HCLOUD_TOKEN_* 90일, PULUMI_ACCESS_TOKEN 180일, CLOUDFLARE_API_TOKEN 90일. 로테이션 후 해당 Environment 사용 워크플로우 재실행 검증.
Hard Purge 수동 트리거30일 미만 테넌트는 정책상 수동 Purge 비권장. 예외 시 Purge Job 수동 실행 후 D1·R2·Hetzner 순서 확인.
리전 장애 (Phase 4+)Cloudflare Failover → SG 리전 폴백. Health Check 복구 후 수동으로 라우팅 복원 가능 여부 검토.

14.1 Phase별 Runbook·문서 갱신 포인트

각 Phase 완료 시 업데이트할 운영 문서·Runbook 항목.

Phase갱신 대상
Phase 1Runbook: Pulumi Up/Destroy 절차, Provision 재시도, Secrets 목록·로테이션 주기, Environment Protection Rules
Phase 2Runbook: R2 버킷·파티션, Aggregator Cron, Cycle Close 일정·Stripe 연동, KV 스키마
Phase 3Runbook: Hard Purge 순서(§5.8), trace 조회·SEV1 절차, Audit Dashboard 접근, 0006 스키마
Phase 4Runbook: US 스택·리전, CF Load Balancing·Failover, Autoscaler 메트릭·Scale Out/In 절차. 첫 US 전 §6.9 점검 절차 포함
Phase 5Runbook: EU 스택·GDPR Purge, 리전별 Secrets·Environment, 관리자 대시보드. 첫 EU 전 §7.6 점검 절차 포함

15. 용어·약어 정리

용어/약어의미
SGSingapore 리전 (Phase 1 기본)
US / IADAshburn, VA (미주) — Phase 4
EU / FSNFalkenstein (유럽) — Phase 5
D1Cloudflare D1 (SQLite 호환 State DB)
R2Cloudflare R2 (Raw Log, Usage 파티셔닝)
KVCloudflare Workers KV (Zuplo Soft Quota 백엔드)
Control PlaneCF Pages Functions + D1, Stripe Webhook, 테넌트 상태 관리
Data PlaneR2 Raw, Aggregator, Billing Engine
Gateway PlaneZuplo API Gateway, Rate Limit, API Key
Event PlaneLogPath Trace/Stage, audit_logs
PDPAPersonal Data Protection Act (Singapore)
GDPREU 일반 개인정보 보호 규칙 (Phase 5)
SEV1Severity 1 — LogPath 기준 1초 이내 분석 목표
plan_tierBasic / Professional / Enterprise (리전 선택은 Enterprise)
infra_modeshared_node(멀티사이트) / dedicated_node(전용 서버)
Cycle CloseBilling Cycle 월말 실행 — included 차감·overage 계산·Stripe 전송 (§4.7)
ScaleOut / ScaleInAutoscaler가 노드 추가/감소 시 scaling_events action (§9.13)
Drainingnodes.status — 신규 배치 중단, 기존 트래픽만 유지 후 제거 (§6.8)
workflow_dispatchGitHub Actions 수동 트리거; pulumi-up·pulumi-destroy에서 사용 (§9.1)

15.1 기술개발기획서 v4.0 인용 문구

구현 시 상세 수식·코드 예시·구문은 기술개발기획서 v4.0 해당 절 참조.

참조 내용v4.0 절
REGION_CONFIG·resolveRegion() 코드 예시§3.2
Pulumi preview/up/destroy 워크플로우 예시§4.2~4.4
0006_multiregion SQL 예시§7.2
R2 파티셔닝·JSONL 레코드 예시§8.2
Health Score 패널티 수식§10.1
Trace Stage 순서·멀티리전 trace 확장§9.1, §9.2

16. 기술개발기획서 v4.0 ↔ 본 기획서 절 대응표

참조 문서(기술개발기획서 v4.0) 섹션 번호와 본 구현 기획서 절 번호 매핑.

기술개발기획서 v4.0본 기획서
§0 문서 목적·버전
§1 프로젝트 목표§0, §2
§2 아키텍처 5-Layer§0, §10
§3 Multi-Region 전략§2, §3~§7, §9.4, §9.5
§4 GitHub Actions CI/CD (Preview/Up 분리)§3.3~3.5, §9.1, §9.4
§5 Pulumi 스택·디렉토리§3.2, §9.2, §10
§6 신규 테넌트 Atomic Workflow§2.1, §2.2, §3
§7 D1 State DB 스키마§13, §3.2 (P1-8)
§8 Usage-Based Billing§4, §9.6
§9 LogPath Trace/Stage§2.1, §2.2, §5
§10 Autoscaler & Node Pool§6, §9.7
§11 PDPA 데이터 보호§5, §8, §14
§12 Fail Sanely§8, §14
§13 보안 설계§8
§14 개발 단계 로드맵§2, §9.3
§15 확장성 평가§11
§16 최종 결론·최우선 리스크 3가지§1

16.1 본 기획서 절 → v4.0 절 (역방향)

구현 시 “이 절의 상세 수식·코드 예시는 v4.0 §X 참조”용 빠른 참조.

본 기획서 (주요 절)v4.0 참조
§2.1 E2E 시퀀스, §2.2 Trace Stage§6, §9.1
§3 (Phase 1, Pulumi·Ansible·Webhook)§4, §5, §6
§4 (Billing·R2·Aggregator)§8
§5 (LogPath·Purge·0006)§9, §11
§6 (US 리전·Autoscaler)§3, §10
§9.1 GitHub Actions§4.2~4.4
§9.7 Health Score§10.1
§13 D1 스키마§7
§1 결정 3건§16 최종 결론

17. 외부 참조 링크

구현 시 참조할 공식 문서·API (URL은 예시, 최신 문서로 확인 권장).

대상참조
StripeWebhooks (event types, idempotency), Billing (Usage, Invoice API)
HetznerCloud API (Servers, SSH Keys, Datacenters), ash-dc3 / fsn1-dc14 / nbg1-dc3
CloudflareD1 (SQLite, migrations), R2 (S3-compatible API), Workers KV, Load Balancing, Access
Pulumipulumi/actions (GitHub Actions), State (Pulumi Cloud), Hetzner/Cloudflare providers
ZuploAPI Key, Rate Limiting, Soft Quota, KV 백엔드(결정 ②)

18. 변경 이력

버전변경 내용작성일
0.1초안 — Phase 1~5 태스크 분해, 즉시 결정 3건, 완료 기준2026-02
0.2§10 기존 코드베이스 연계, §11 리스크·가정·제약, §12 결정 로그 템플릿, Phase 5 태스크 세부화(P5-1~P5-8)2026-02
0.3Phase 2·3·4 의존성 다이어그램(§4.4, §5.4, §6.4), §13 D1 스키마 요약, §14 운영 Runbook 요약, §15 용어·약어2026-02
0.4§2.1 신규 테넌트 E2E 시퀀스, §2.2 Trace Stage↔태스크 매핑, §9.1 GitHub Actions 요약, §9.2 Phase별 산출물 체크리스트2026-02
0.5목차 추가, §9.3 Phase별 인수 테스트 시나리오 요약, §9.4 리전·스택·환경·Secrets 매트릭스2026-02
0.6§9.5 plan_tier↔리전·인프라 매트릭스, §9.6 R2 Raw 로그 스키마, §9.7 Health Score 패널티, §16 기술개발기획서 절 대응표2026-02
0.7§3.6 Phase 1 태스크별 세부 체크 항목, §3.7 Stripe↔Control Plane 매핑, §8.1 Fail Sanely 상세 표2026-02
0.8§9.8 태스크 ID→절 참조 인덱스, §13.1 D1 tenants_master·provision_jobs 핵심 컬럼, §13.2 Provision Queue 메시지 스키마2026-02
0.9§2.3 킥오프·사전 준비 체크리스트, §4.6 Phase 2·§5.6 Phase 3 태스크별 세부 체크, §8.2 보안 설계 체크리스트, §9.9 CF Load Balancing 요약2026-02
0.10§6.6 Phase 4·§7.5 Phase 5 태스크별 세부 체크, §9.10 구현 순서 한 페이지 요약2026-02
0.11§2.4 테넌트 상태 전이, §8.3 Slack·Alert 메시지 포맷, §9.11 Phase별 릴리스 전 검수, §17 외부 참조 링크2026-02
0.12§2.5 provision_jobs 상태 전이, §8.4 재시도·에러 정책 요약, §9.12 5-Layer↔Phase 매핑2026-02
0.13§0.1 기획서 완성도·반영 체크, §6.7 Autoscaler 메트릭 수집 항목2026-02
0.14§0.2 빠른 참조(주제별 절), §4.7 Billing Cycle·included·overage, §5.7 trace_events 스키마, §6.8 nodes.status 전이2026-02
0.15§5.8 Hard Purge 실행 순서, §9.13 scaling_events 액션·상태, §14.1 Phase별 Runbook·문서 갱신 포인트2026-02
0.16§2.6 purge_jobs 상태 전이, §3.8 Stripe Webhook 처리 대상 이벤트, §9.14 Phase별 핵심 산출물 한 줄 요약2026-02
0.17§0.3 문서 유지보수 체크리스트, §8.5 역할·에스컬레이션 요약, §15.1 기술개발기획서 v4.0 인용 문구2026-02
0.18§0.4 제외 범위·Known Gaps, §2.7 Phase 간 의존성 다이어그램, §9.15 데이터 흐름 요약2026-02
0.19§9.16 Phase 완료 시그니오프 템플릿, §11.4 다음 문서·산출물2026-02
0.20§0.5 Executive Summary, §8.6 주요 에러 시나리오·대응 한 줄, §16.1 본 기획서→v4.0 역방향 대응표2026-02
0.21로드맵 표에 예상 소요(참고) 열, §0.2 빠른 참조에 에러 시나리오, §2.8 Phase별 블로커 요약2026-02
0.22§3.9 Phase 1 첫 배포 전 최종 점검, §15 용어 추가(Cycle Close, ScaleOut/ScaleIn, Draining, workflow_dispatch)2026-02
0.23§0.6 이 문서로 할 수 있는 것·할 수 없는 것, §0.2 빠른 참조에 Phase 1 첫 배포 전 점검(§3.9)2026-02
0.24로드맵 예상 소요 주석, §0 문서 개요에 문서 버전 행, §4.8 Phase 2 첫 Cycle Close 전 점검, §5.9 Phase 3 첫 Hard Purge 전 점검2026-02
0.25§0.2 빠른 참조에 Phase 2·3 적용 전 점검(§4.8·§5.9), §6.9 Phase 4 첫 US 프로비저닝 전 점검, §7.6 Phase 5 첫 EU 프로비저닝 전 점검2026-02
0.26§0.2 Phase 4·5 첫 점검(§6.9·§7.6) 참조 추가, §9.11 Phase 4·5에 §6.9·§7.6 언급, §14.1 Runbook에 첫 US/EU 점검 포함, §11.4 첫 US/EU 체크리스트 문서 행, §12 결정 로그에 §1 3건 예시 행2026-02

다음 단계: §1 최우선 3가지 결정 합의 후 Phase 1 태스크(P1-1~P1-13) 착수 및 본 기획서 “결정 상태” 업데이트.

Help