목적: Placement 결정(기존 노드 배치 vs 새 서버 생성) 로직을 검증·증명·테스트하기 위해, (1) 순서대로 들어오는 주문(Order) 형태의 테스트 데이터를 정의하고, (2) 해당 주문이 들어왔을 때 서버 생성·Frappe 설치·DB/Redis 설정·동적 적층 리소스 관리를 시뮬레이션하며 결과를 모니터링할 수 있는 페이지를 만드는 요건을 정리한다. 코드 생성 없음 — 기획·요건만.
create_new_server (true면 새 서버 생성), target_server_id (기존 노드에 배치 시 node_id).
현재 규칙 (R2)
region·status=Active·role(shared/dedicated) 일치, server_metrics 기준 memory_pct < 임계값, tenant_count < 임계값 인 노드만 후보. 후보 중 tenant_count·memory_pct 오름차순으로 1개 선택.
현재 규칙 (R4)
Enterprise → dedicated 노드만; Free/Basic/Professional → shared 또는 role NULL 노드.
검증 목표
다양한 플랜·리전·순서로 주문이 들어올 때, (1) 기대한 대로 기존 노드에 붙는지 / 새 서버가 생성되는지, (2) 이후 실제(또는 시뮬레이션) 프로비저닝 단계(서버·Frappe·DB·Redis·리소스 적층)가 로그/상태로 추적·모니터링 가능한지.
2. 테스트 데이터: Order 10건 (순서 보장)
아래는 Order를 “POST /v1/tenants 에 대응하는 한 건의 테넌트 생성 요청”으로 정의한다. 순서대로 1 → 10 적용 시 Placement·리소스 적층을 검증할 수 있도록 설계한다.
2.1 초기 상태 (시뮬레이션/테스트 전)
리소스
시나리오 A (빈 상태)
시나리오 B (1노드 존재)
nodes
0건
sg, Active, shared 1건 (예: node-sg-001), host 설정
server_metrics
없음
node-sg-001: memory_pct=20, tenant_count=0 (또는 원하는 값)
tenants_master / provision_jobs
비어 있음
비어 있음 (또는 기존 테스트 데이터 정리)
시나리오 A: 첫 주문부터 “노드 없음 → create_new_server” 가 나와야 함.
시나리오 B: 첫 주문은 “기존 노드에 배치”, 메트릭을 올려 가며 N번째부터 “create_new_server” 또는 “포화로 새 서버”가 나오는지 검증.
2.2 Order 10건 정의 (예시)
#
Order ID
plan_tier
region
subdomain_slug
기대 Placement (예시)
비고
1
order-01
free
sg
sim-acme
create_new_server (노드 0개) 또는 target_sg_001 (노드 1개)
첫 주문: 빈 상태면 새 서버, 있으면 기존 노드.
2
order-02
free
sg
sim-beta
use_existing (target_sg_001)
동일 region·shared, 용량 여유 있으면 기존 노드.
3
order-03
basic
sg
sim-gamma
use_existing (target_sg_001)
shared 노드 재사용.
4
order-04
professional
sg
sim-delta
use_existing (target_sg_001)
shared.
5
order-05
free
sg
sim-epsilon
use_existing 또는 create_new_server
tenant_count/memory_pct 임계값 근처에서 분기 검증.
6
order-06
enterprise
sg
sim-enterprise1
create_new_server (dedicated 없음) 또는 target_dedicated_001
R4: Enterprise는 dedicated만. dedicated 노드 없으면 새 서버.
7
order-07
free
us
sim-us-alpha
create_new_server (us 노드 없음)
리전 다름 → sg 노드 사용 불가 → 새 서버.
8
order-08
basic
us
sim-us-beta
use_existing (target_us_001)
7번으로 us 노드 생겼다면 재사용.
9
order-09
enterprise
eu
sim-eu-enterprise
create_new_server (eu dedicated 없음)
eu 전용 노드 없음 → 새 서버.
10
order-10
free
sg
sim-sg-omega
use_existing (target_sg_001 또는 target_sg_002)
sg shared 여유 노드 또는 포화 후 새 노드.
실제 기대값은 초기 상태(시나리오 A/B), PLACEMENT_MEMORY_PCT_MAX / PLACEMENT_MAX_TENANTS_PER_NODE, 그리고 각 Order 처리 후 server_metrics 갱신 여부에 따라 달라진다. 기획서에서는 “검증 포인트”만 정의하고, 테스트 데이터 스펙으로는 위 10건의 payload(JSON) 와 초기 nodes/server_metrics(선택) 를 명시한다.
2.3 Order Payload 스펙 (POST /v1/tenants body)
각 Order는 동일한 스키마를 따른다. 예시(Order 1):
{
"tier": "free",
"region": "sg",
"subdomain_slug": "sim-acme",
"subdomain_name": "sim-acme",
"company_name": "Sim Acme Corp",
"abbr": "SAC",
"admin_email": "admin@sim-acme.example.com",
"admin_name": "Admin One",
"admin_phone": "",
"additional_users": []
}
10건 전체: order-01 ~ order-10 에 대해 tier(free/basic/professional/enterprise), region(sg/us/eu), subdomain_slug(고유 값) 등만 위 표에 맞게 치환한 JSON 배열로 보관. (실제 파일은 기획서 외부에서 “테스트 데이터 세트”로 관리 가능.)
2.4 테스트 데이터 산출물 (요건)
산출물
설명
orders.json
위 10건 Order의 POST /v1/tenants body 배열. 순서 유지.
initial_state (선택)
시나리오 A/B용 nodes INSERT, server_metrics INSERT (SQL 또는 JSON). 테스트 전 D1 초기화 또는 시뮬레이션 입력으로 사용.
expected_placement (선택)
Order별 기대 결과(create_new_server, target_server_id) — 시나리오·임계값별로 “기대 매트릭스” 표 또는 파일. 자동 검증 시 비교용.
3. 시뮬레이션·검증 범위
Order가 들어왔을 때 실제로 어떻게 서버가 생성되고, Frappe가 설치되고, DB/Redis가 설정되고, 리소스가 적층되는지를 다음 두 가지 방식으로 검증할 수 있도록 기획한다.
3.1 방식 A: Placement 전용 시뮬레이션 (드라이 런)
항목
내용
입력
초기 상태(nodes, server_metrics) + Order 1~10 순차.
처리
실제 D1 쓰기 없이(또는 전용 테스트 DB에서) decidePlacement 만 호출하여 결과(create_new_server, target_server_id) 산출. 각 Order 후 가상 갱신: “이 노드에 배치됐다”고 가정하고 server_metrics.tenant_count +1, memory_pct 보정(선택).
목적
Placement 로직 단위 검증. R2(용량)·R4(shared/dedicated) 동작 확인.
산출
Order별 Placement 결과 + (선택) “가상 노드 상태 변화” 타임라인.
3.2 방식 B: E2E 시뮬레이션 또는 실제 파이프라인 연동
항목
내용
입력
동일 Order 10건 (또는 subset). 실제 POST /v1/tenants 호출 또는 동일 로직으로 D1에 tenants_master·provision_jobs 삽입 후 workflow_dispatch.
처리
resolve-server → DNS → Ansible(Frappe, DB, Redis) → Zuplo Sync → provision-complete 콜백. (실제 인프라 사용 시 “실서버 생성” 발생; 시뮬레이션 모드가 있으면 Ansible/Pulumi를 mock 또는 skip하고 콜백만 시뮬레이션 가능.)
목적
서버 생성·Frappe 설치·DB/Redis 설정·동적 적층이 로그·상태로 추적 가능한지 검증.
노드별 “몇 테넌트가 올라와 있는지”, 포화 임계 초과 시 알림(R8)·다음 Placement에서 제외되는지.
로그·상태
trace_events, provision_jobs.updated_at, Cloudflare Workers 로그, GitHub Actions run
단계별 시각화·타임라인.
4. 모니터링 페이지 요건
Placement 및 (가능하면) 프로비저닝 단계까지 한 화면에서 시뮬레이션·검증·상태를 볼 수 있는 전용 페이지를 둔다.
4.1 페이지 목적
Placement 테스트 데이터(Order 10건) 를 로드하고, 순서대로 Placement를 실행(드라이 런 또는 실제 API 호출)한 결과를 표시.
현재 리소스 상태(nodes, server_metrics, provision_jobs, tenants_master 요약)를 동적으로 표시.
Order 처리 후 “어떤 노드에 붙었는지 / 새 서버가 생성됐는지”, “Frappe·DB·Redis·Zuplo·콜백” 단계가 로그/상태 기준으로 어떻게 적층되는지 타임라인 또는 테이블로 모니터링.
4.2 기능 요건 (우선순위)
#
기능
설명
F1
테스트 데이터 로드
orders.json(10건) 업로드 또는 프리셋 선택(시나리오 A/B). 초기 상태(initial_state) 선택적 적용.
F2
Placement 실행(시뮬레이션)
Order 1~10 순차로 decidePlacement 호출(또는 내부 API). 결과 테이블: Order #, plan_tier, region, create_new_server, target_server_id, 비고.
F3
현재 리소스 현황
nodes(region, status, role, host), server_metrics(tenant_count, memory_pct, disk_pct), saturated_node_ids. 기존 GET /internal/metrics/summary 재사용 또는 전용 API.
F4
프로비저닝 작업 목록
provision_jobs 최근 N건: job_id, tenant_id, status, plan_tier, infra_mode, created_at. 클릭 시 상세(trace_id, 단계별 로그 링크).
F5
Order → Job 매핑
테스트 Order와 실제 provision_jobs 매핑(동일 subdomain_slug 또는 job_id). “이 Order가 어떤 job으로 처리됐는지” 표시.
F6
타임라인/단계 뷰
단일 job 선택 시: resolve-server → DNS → Ansible → Zuplo → provision-complete 단계별 상태·로그 링크. trace_events 기반 또는 workflow run 링크.
F7
동적 적층 시각화
노드별 “현재 테넌트 수·메모리 %” 막대 또는 테이블. Order 처리 순서에 따라 어떻게 쌓였는지(히스토리)는 선택.
F8
시뮬레이션 모드 전환
“Placement만 시뮬레이션(드라이 런)” vs “실제 API 호출(POST /v1/tenants) 후 workflow 연동” 전환. 실제 호출 시 경고 표시.
4.3 비기능 요건
항목
내용
인증
기존 내부 API와 동일하게 Bearer INTERNAL_API_KEY.
위치
GET /internal/placement-simulation 또는 /internal/dashboard 아래 “Placement 시뮬레이션” 탭/섹션. 기존 dashboard-html 패턴 참고.
데이터 소스
Control Plane D1(nodes, server_metrics, provision_jobs, tenants_master), GET /internal/metrics/summary, GET /internal/trace/:trace_id. Placement 시뮬레이션 전용 엔드포인트(예: POST /internal/placement-simulation/run)는 구현 시 설계.
4.4 화면 구성 (초안)
상단: 테스트 데이터 선택(프리셋 10건) + “Placement 시뮬레이션 실행” 버튼 + (선택) 초기 상태 로드.