Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed059d4884 | ||
|
|
3250502caa |
@@ -43,6 +43,22 @@
|
|||||||
### 테스트
|
### 테스트
|
||||||
- `test/hal-041.test.mjs` RED(모듈·스크립트·문서 없음) → GREEN 7/7: 실제 자체 서명 HTTPS 픽스처(hal.local.test)로 TLS 확인·핀·CA 경로·설치 명령, 이미 등록 409·재등록 허용·재인증, Agent CLI(별도 프로세스) 오류 문구·`--ca`·`status` 런타임 CA, 부트스트랩 완료·배너·hawkeye, CLI 3종, 스크립트·문서·버전. 기존 테스트 갱신: 배너 문구(`hal-ui`·`hal-reauth-banner`: "부트스트랩 미완료(…첫 Agent 미등록)" → "부트스트랩 진행 중(…HAL 서버의 Node Agent 미설치)"), 프로필 목록에 `hal`(`hal-0317`), 버전 0.4.1(`hal-ai`·`webmaker-visual-editor` 등). 전체 Suite 32파일 통과. 로컬 E2E(실제 HAL 프로세스 + 자체 서명 TLS 앞단, sudo/systemctl 셈): 핀 없는 curl → 60(WS2 재현), 핀 명령 → CA 받기·등록·유닛 `NODE_EXTRA_CA_CERTS`, 같은 명령 재실행 → "이미 등록된 서버"(종료 0), 새 토큰 → HAL 409 안내(종료 1), `hal-host-agent.sh` → 부트스트랩 완료·pending 4.
|
- `test/hal-041.test.mjs` RED(모듈·스크립트·문서 없음) → GREEN 7/7: 실제 자체 서명 HTTPS 픽스처(hal.local.test)로 TLS 확인·핀·CA 경로·설치 명령, 이미 등록 409·재등록 허용·재인증, Agent CLI(별도 프로세스) 오류 문구·`--ca`·`status` 런타임 CA, 부트스트랩 완료·배너·hawkeye, CLI 3종, 스크립트·문서·버전. 기존 테스트 갱신: 배너 문구(`hal-ui`·`hal-reauth-banner`: "부트스트랩 미완료(…첫 Agent 미등록)" → "부트스트랩 진행 중(…HAL 서버의 Node Agent 미설치)"), 프로필 목록에 `hal`(`hal-0317`), 버전 0.4.1(`hal-ai`·`webmaker-visual-editor` 등). 전체 Suite 32파일 통과. 로컬 E2E(실제 HAL 프로세스 + 자체 서명 TLS 앞단, sudo/systemctl 셈): 핀 없는 curl → 60(WS2 재현), 핀 명령 → CA 받기·등록·유닛 `NODE_EXTRA_CA_CERTS`, 같은 명령 재실행 → "이미 등록된 서버"(종료 0), 새 토큰 → HAL 409 안내(종료 1), `hal-host-agent.sh` → 부트스트랩 완료·pending 4.
|
||||||
|
|
||||||
|
### 배포(2026-11-06 UTC, bear `hal21.ariweb.net` HAL + HAL 서버 Agent + HAL 작업으로 agent)
|
||||||
|
- main ff `0f5e01a → 2b31543`, 깨끗한 main 빌드·verify(전체 32파일 통과, dirty=false, provenanceClean). artifact sha256: hal `3a9f93b02f0c13d6a6edd007a675016fab5f5ce672357c2258189fcf7ca0a1da` · agent `35a2a9ccf20204657a66c01e08b4053b265c3073a1e8f7e76bf9b4f012540d5a` · portal `323155f5f9402680c3cce1acc86b3ce885341f8c2c40235c3fa1439810c693e3` · webmaker `a1556587c884da74eefb9764f3ad26ebced4c198860294253d8315e8926798b6` · arimail `f9fc10858960ba9058e7fc7e68e64d42ea9d007db2f855ba0a6b27fb34bd0d7b`.
|
||||||
|
- HAL: 백업 `/srv/ariweb/hal/backups/pre-v0.4.1-20261106T084347Z` → stage(`hal/tls.mjs`·`deploy/hal-host-agent.sh` 확인) → `register-release --approve` → `bootstrap-release` → current `releases/0.4.1-2b31543` → 재시작 뒤 500ms 에 health ok(0.4.1). config·vault 보존 sha256 전=후. 운영 DB read-back: 마이그레이션 `hal_0011_token_replace`, 릴리스 0.4.1 approved. 기동 로그 "공개 주소 TLS: 신뢰됨"(Let's Encrypt → 설치 명령에 핀 없음), `GET /agent/v1/tls` trusted·`hal-ca.pem` 404(불필요). 배포 코드 read-back(메모리 DB, 사설 CA 흉내): 완료 전 배너 "부트스트랩 진행 중…", 완료 뒤 "부트스트랩 완료 · 기능 단위 서버 배포 대기: 고객 포털, Webmaker, AriMail, 백업", 핀 설치 명령, 두 번째 토큰 409 `server_already_registered`, `/agent/v1/hal-ca.pem` 200.
|
||||||
|
- HAL 서버 Agent(`deploy/hal-host-agent.sh --name hal21.ariweb.net --by claude-fable-5.1`): 서버 `srv_01a1b007b83b87fca6c9766a94`(control, 프로필 hal) · Agent `ag_01a1b007b9c088f15b3031db15` · `/srv/ariweb/agent`(유닛 `ariweb-agent`, loopback `http://127.0.0.1:8900`) · 승인 → bootstrapComplete true, pendingModules [](운영 HAL 은 기능 모듈이 모두 배치되어 배너 없음). `/api/health.deployment` = deployed portal·webmaker·arimail·backup, agents 3.
|
||||||
|
- HAL 작업(CLI `module-deploy`, 감사 `cli:claude-fable-5.1`, 한 대씩): agent 0.4.1 → srv1953374(`j_01a1b00816493ecf9b390fce32`) · jitsi(`j_01a1b0082beaaf45decd2fefa2`) 각 done 5초 안, 재시작 뒤 heartbeat 0.4.1. hawkeye 0.4.1 기록(3대, `j_01a1b008831e7c9bf45ca2a400`) · backup 0.4.1 기록(srv1953374, `j_01a1b0089874924f22df95de5f`). 실패 작업 0. read-back: 세 서버 모두 agent_version 0.4.1, `hawkeye` 행 last_check_at 08:45(0.3.17 잔여 결함 해소: 2026-10-29 에 멈춰 있던 값 갱신), `observability` 행 0. Webmaker·AriMail·포털은 코드 변경이 없어 배포하지 않음.
|
||||||
|
- **hal.local.test(WS1, 192.168.20.31 — 사설 루트 CA "Ariweb HAL Local Root CA", 지시의 오류 재현 환경) 배포(2026-11-06 09:17 UTC)**: `~/oz-deploy/ws-apply-0.4.1.sh`(bear-apply 와 같은 절차, vault.json 없는 데이터 디렉터리 허용) → 백업 `pre-v0.4.1-20261106T091745Z` → current `releases/0.4.1-2b31543` → health 0.4.1, config·vault.key 보존. 기동 로그 "공개 주소 TLS: 시스템 CA 로 신뢰되지 않음(SELF_SIGNED_CERT_IN_CHAIN) — 설치 명령에 핀을 붙입니다", `tls-probe` pin `sha256//ANF6p+gy…`, caSource chain(루트 1). `hal-host-agent.sh --name hal.local.test` → 서버 `srv_01a1b0268c70986dc77d7f8e76`(control, 프로필 hal) · Agent `ag_01a1b0268e2ef4aba63f88cae4` · bootstrapComplete true · pending portal·webmaker·arimail(backup 은 Agent 기능으로 배치됨). 실제 TLS 경로 검증(bear 에서 `--resolve`): 핀 없는 curl → 60(WS2 재현) / 핀 curl → install.sh 수신 / 틀린 핀 → 90 거부 / 핀으로 `hal-ca.pem` → 루트 CA → `--cacert` health ok / 받은 CA 로 Node fetch ok(ws1). 배포 코드 read-back 통과. 이전 WS2 서버 행(`srv_01a19f297b62971d5fc4d1edcc`, pending, Agent 없음)은 그대로 — 운영자가 새 토큰을 발급하면 핀 명령이 나온다.
|
||||||
|
- 되돌리기: HAL `ln -sfn /srv/ariweb/hal/releases/0.4.0-9f1e490 /srv/ariweb/hal/current && sudo systemctl restart ariweb-hal`(hal.local.test 는 `releases/0.4.0`). HAL 서버 Agent 제거는 RUNBOOK §11.1. 모듈은 HAL 작업 `module.rollback`(agent `releases/0.4.0` 보존).
|
||||||
|
- 운영자 조치: (1) 사설 CA 로 운영하는 HAL(예: hal.local.test)은 이 릴리스로 올린 뒤 운영자 콘솔에서 토큰을 다시 발급해 핀이 붙은 명령으로 설치한다(RUNBOOK §11.3). (2) hal21 서버 행의 `webmaker` 모듈은 bear 의 webmaker.ibit.kr(Suite 외 운영)을 Agent 가 발견해 보고한 것 — 배포 대상이 아니며 인벤토리 전송은 환경 변수 미지정으로 `inventory_incomplete` 로그만 남긴다(필요하면 서버 행에서 정리). (3) 0.4.0 이하 Agent 가 사설 CA HAL 에 이미 붙어 있는 서버는 RUNBOOK §11.3-4.
|
||||||
|
|
||||||
|
### 알려진 제한(0.4.1)
|
||||||
|
- 핀 설치 명령은 HAL 이 자기 공개 주소에 접속할 수 있어야 만들어진다(hairpin NAT 불가 등으로 접속이 안 되면 `trusted:null` → 핀 없는 명령 + 기동 로그 경고). 그때는 운영자가 `<data>/tls/hal-ca.pem` 을 두고 대상 서버에서 `--ca` 로 설치한다.
|
||||||
|
- 루트를 체인에 싣지 않는 사설 CA 는 `<data>/tls/hal-ca.pem` 이 있어야 CA 를 제공한다. 인증서 키 교체 뒤에는 10분(또는 `GET /agent/v1/tls?refresh=1`) 뒤 새 핀이 반영된다 — 그 사이 발급한 명령은 핀 불일치로 실패하므로 다시 발급한다.
|
||||||
|
- `tls.setDefaultCACertificates` 가 없는 Node(22.18 이하)는 유닛의 `NODE_EXTRA_CA_CERTS` 만으로 동작한다(설치 스크립트가 넣는다).
|
||||||
|
- HAL 서버 Agent 는 control 역할이라 web·backup 서버가 하나도 없을 때 사이트·백업 배치 후보가 된다(0.1.1 의 단일 서버 대체 규칙). 전용 서버가 생기면 그쪽이 우선한다.
|
||||||
|
|
||||||
|
|
||||||
## 0.4.0 (2026-10-29)
|
## 0.4.0 (2026-10-29)
|
||||||
|
|
||||||
- **작성자**: 개발 지시 — Oz(`Ariweb-Suitle_Dev-Order_v0.4.0.md`, 2026-10-29) · 구현 — Claude Opus 5.5(브랜치 `feature/hal-settings-v0.4.0`, 기준 main `54db663` = 0.3.17).
|
- **작성자**: 개발 지시 — Oz(`Ariweb-Suitle_Dev-Order_v0.4.0.md`, 2026-10-29) · 구현 — Claude Opus 5.5(브랜치 `feature/hal-settings-v0.4.0`, 기준 main `54db663` = 0.3.17).
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ cd /srv/ariweb/hal/current && bash deploy/hal-host-agent.sh --name hal21.ariweb.
|
|||||||
- 하는 일: 관리 서버 `hal21.ariweb.net`(역할 control, 프로필 `hal`) 생성 → 일회용 토큰(표시 안 함) → `agent-install.sh --hal http://127.0.0.1:8900 --role control`(agent artifact 는 HAL 릴리스 등록부에서, `/srv/ariweb/agent`, 유닛 `ariweb-agent`, sudoers 는 부트스트랩 때 둔 것과 같은 파일) → `server-approve`. 이미 `agent.json` 이 있으면 승인만 한다.
|
- 하는 일: 관리 서버 `hal21.ariweb.net`(역할 control, 프로필 `hal`) 생성 → 일회용 토큰(표시 안 함) → `agent-install.sh --hal http://127.0.0.1:8900 --role control`(agent artifact 는 HAL 릴리스 등록부에서, `/srv/ariweb/agent`, 유닛 `ariweb-agent`, sudoers 는 부트스트랩 때 둔 것과 같은 파일) → `server-approve`. 이미 `agent.json` 이 있으면 승인만 한다.
|
||||||
- 확인: `curl -fsS http://127.0.0.1:8900/api/health`(bootstrap.complete·deployment.pending), 운영자 콘솔 서버 목록에 HAL 서버(역할 control, Agent 0.4.1, HawkEye 지표), 배너 "부트스트랩 완료 · 기능 단위 서버 배포 대기…"(기능 모듈이 다 배치된 운영 HAL 은 배너 없음).
|
- 확인: `curl -fsS http://127.0.0.1:8900/api/health`(bootstrap.complete·deployment.pending), 운영자 콘솔 서버 목록에 HAL 서버(역할 control, Agent 0.4.1, HawkEye 지표), 배너 "부트스트랩 완료 · 기능 단위 서버 배포 대기…"(기능 모듈이 다 배치된 운영 HAL 은 배너 없음).
|
||||||
- 되돌리기: `sudo systemctl disable --now ariweb-agent && sudo rm /etc/systemd/system/ariweb-agent.service && sudo systemctl daemon-reload`, 운영자 콘솔에서 그 서버 삭제(Agent 해지). HAL 데이터는 서버·Agent 행만 추가된다.
|
- 되돌리기: `sudo systemctl disable --now ariweb-agent && sudo rm /etc/systemd/system/ariweb-agent.service && sudo systemctl daemon-reload`, 운영자 콘솔에서 그 서버 삭제(Agent 해지). HAL 데이터는 서버·Agent 행만 추가된다.
|
||||||
|
- 실행 기록(2026-11-06 08:44 UTC, HAL 0.4.1): 서버 `srv_01a1b007b83b87fca6c9766a94`(hal21.ariweb.net, control, 프로필 hal), Agent `ag_01a1b007b9c088f15b3031db15`, 유닛 active, bootstrapComplete true, pendingModules [].
|
||||||
|
|
||||||
### 11.2 새 HAL 부트스트랩(0.4.1)
|
### 11.2 새 HAL 부트스트랩(0.4.1)
|
||||||
`bootstrap-hal.sh` 가 6/7 단계에서 11.1 을 스스로 수행한다. `--no-agent` 를 주면 이전처럼 첫 Agent 승인 때 부트스트랩이 닫힌다.
|
`bootstrap-hal.sh` 가 6/7 단계에서 11.1 을 스스로 수행한다. `--no-agent` 를 주면 이전처럼 첫 Agent 승인 때 부트스트랩이 닫힌다.
|
||||||
@@ -162,4 +163,5 @@ cd /srv/ariweb/hal/current && bash deploy/hal-host-agent.sh --name hal21.ariweb.
|
|||||||
1. HAL 서버에서 상태 확인: `node hal/index.mjs tls-probe` → `trusted:false, reason:…, pin:"sha256//…", caCount:1`. `caCount:0` 이면(루트를 체인에 싣지 않는 사설 CA) `/srv/ariweb/hal/data/tls/hal-ca.pem` 에 루트 CA PEM 을 두고 HAL 을 재시작하거나 10분 기다린다(`GET /agent/v1/tls?refresh=1`).
|
1. HAL 서버에서 상태 확인: `node hal/index.mjs tls-probe` → `trusted:false, reason:…, pin:"sha256//…", caCount:1`. `caCount:0` 이면(루트를 체인에 싣지 않는 사설 CA) `/srv/ariweb/hal/data/tls/hal-ca.pem` 에 루트 CA PEM 을 두고 HAL 을 재시작하거나 10분 기다린다(`GET /agent/v1/tls?refresh=1`).
|
||||||
2. 운영자 콘솔 › 서버 › 등록 토큰: 핀이 붙은 명령이 나온다. 대상 서버에서 그대로 실행한다(`-k --pinnedpubkey` 로 스크립트를 받고 `--hal-pin` 으로 CA 를 받는다). CA 는 `/srv/ariweb/agent/data/hal-ca.pem`, 유닛에 `NODE_EXTRA_CA_CERTS`, `agent.json` 에 `caFile`.
|
2. 운영자 콘솔 › 서버 › 등록 토큰: 핀이 붙은 명령이 나온다. 대상 서버에서 그대로 실행한다(`-k --pinnedpubkey` 로 스크립트를 받고 `--hal-pin` 으로 CA 를 받는다). CA 는 `/srv/ariweb/agent/data/hal-ca.pem`, 유닛에 `NODE_EXTRA_CA_CERTS`, `agent.json` 에 `caFile`.
|
||||||
3. 이미 등록된 서버에서 같은 명령을 다시 실행하면 "이미 등록된 서버 … 코드·유닛만 갱신" 으로 끝난다. 새 Agent 로 바꾸려면 토큰 발급 때 "재등록 허용" 을 선택한다(재인증).
|
3. 이미 등록된 서버에서 같은 명령을 다시 실행하면 "이미 등록된 서버 … 코드·유닛만 갱신" 으로 끝난다. 새 Agent 로 바꾸려면 토큰 발급 때 "재등록 허용" 을 선택한다(재인증).
|
||||||
|
- 실행 기록(2026-11-06 09:17 UTC, hal.local.test = WS1 192.168.20.31, `ssh master@ws1`): HAL 0.4.0 → 0.4.1(`ws-apply-0.4.1.sh`), `hal-host-agent.sh` 로 서버 `srv_01a1b0268c70986dc77d7f8e76`·Agent `ag_01a1b0268e2ef4aba63f88cae4`, 부트스트랩 완료. 핀 `sha256//ANF6p+gy9SXw0D3TEJGBBDA3HQHRgp078yEuZJrj8uc=`(루트 CA 가 체인에 있어 `hal-ca.pem` 제공). WS2 등록은 운영자 콘솔 › 서버 ws2 › 등록 토큰(핀 명령) 또는 `node hal/index.mjs server-token --server srv_01a19f297b62971d5fc4d1edcc --by <who>`.
|
||||||
4. 0.4.0 Agent 가 이미 설치된 서버(인증서가 사설 CA 로 바뀐 경우): `curl -k --pinnedpubkey '<핀>' https://<HAL>/agent/v1/hal-ca.pem -o /srv/ariweb/agent/data/hal-ca.pem` 후 유닛에 `Environment=NODE_EXTRA_CA_CERTS=/srv/ariweb/agent/data/hal-ca.pem` 을 더하고 재시작, 또는 HAL 작업으로 agent 0.4.1 배포 뒤 설치 명령을 다시 실행(`--hal-pin`)해 `caFile` 을 보완한다.
|
4. 0.4.0 Agent 가 이미 설치된 서버(인증서가 사설 CA 로 바뀐 경우): `curl -k --pinnedpubkey '<핀>' https://<HAL>/agent/v1/hal-ca.pem -o /srv/ariweb/agent/data/hal-ca.pem` 후 유닛에 `Environment=NODE_EXTRA_CA_CERTS=/srv/ariweb/agent/data/hal-ca.pem` 을 더하고 재시작, 또는 HAL 작업으로 agent 0.4.1 배포 뒤 설치 명령을 다시 실행(`--hal-pin`)해 `caFile` 을 보완한다.
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"generatedAt": "2026-11-06T08:39:15.596Z",
|
"generatedAt": "2026-11-06T08:42:57.005Z",
|
||||||
"startedAt": "2026-11-06T08:36:56.328Z",
|
"startedAt": "2026-11-06T08:40:37.605Z",
|
||||||
"env": {
|
"env": {
|
||||||
"agents": 4,
|
"agents": 4,
|
||||||
"ports": {
|
"ports": {
|
||||||
"hal": 46137,
|
"hal": 42077,
|
||||||
"portal": 33827,
|
"portal": 35717,
|
||||||
"wm": 44585,
|
"wm": 38791,
|
||||||
"am": 46243,
|
"am": 37901,
|
||||||
"mail": 33749
|
"mail": 36549
|
||||||
},
|
},
|
||||||
"mailServerRegistered": true,
|
"mailServerRegistered": true,
|
||||||
"node": "v24.22.1"
|
"node": "v24.22.1"
|
||||||
@@ -99,12 +99,12 @@
|
|||||||
{
|
{
|
||||||
"name": "팀 그룹 만들기 → 현재 그룹 전환",
|
"name": "팀 그룹 만들기 → 현재 그룹 전환",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": "g_01a1b001050da5f0aac64cb28b"
|
"detail": "g_01a1b004656a3fd8bdbc431252"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "이메일 초대(7일) → 초대 메일 링크",
|
"name": "이메일 초대(7일) → 초대 메일 링크",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": "CuKQ5wejxWQRySeHUeXtDHc6UV_gtoBe"
|
"detail": "gDQeFdZYzURAfDUw-yHeUH762uhAoRwS"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "초대 수락(1회용) → 별칭 user-02 · 역할 member",
|
"name": "초대 수락(1회용) → 별칭 user-02 · 역할 member",
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
"detail": {
|
"detail": {
|
||||||
"count": 2,
|
"count": 2,
|
||||||
"team": {
|
"team": {
|
||||||
"id": "pv_01a1b001033bcca913e287fd2e",
|
"id": "pv_01a1b004639c49d0dc8ae615b6",
|
||||||
"price": 49000,
|
"price": 49000,
|
||||||
"sites": 3
|
"sites": 3
|
||||||
},
|
},
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
"orderNo": "AW-20261106-0001",
|
"orderNo": "AW-20261106-0001",
|
||||||
"status": "awaiting_payment",
|
"status": "awaiting_payment",
|
||||||
"total": 63800,
|
"total": 63800,
|
||||||
"dueAt": "2026-11-13T08:36:59.371Z",
|
"dueAt": "2026-11-13T08:40:40.667Z",
|
||||||
"hasInstructions": true
|
"hasInstructions": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -221,7 +221,7 @@
|
|||||||
"detail": {
|
"detail": {
|
||||||
"sites": 3,
|
"sites": 3,
|
||||||
"subs": 1,
|
"subs": 1,
|
||||||
"nextBilling": "2026-12-06T08:36:59.420Z"
|
"nextBilling": "2026-12-06T08:40:40.718Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -233,7 +233,7 @@
|
|||||||
"bill": {
|
"bill": {
|
||||||
"sites": 3,
|
"sites": 3,
|
||||||
"subs": 1,
|
"subs": 1,
|
||||||
"nextBilling": "2026-12-06T08:36:59.420Z"
|
"nextBilling": "2026-12-06T08:40:40.718Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -248,7 +248,7 @@
|
|||||||
"name": "사이트 생성(새 Webmaker 프로젝트·배포 방식 관리형) → 초안·사이트 수 미소비·다음 단계 안내",
|
"name": "사이트 생성(새 Webmaker 프로젝트·배포 방식 관리형) → 초안·사이트 수 미소비·다음 단계 안내",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"id": "s_01a1b00105c6ccdc2e6bed72ab",
|
"id": "s_01a1b004663ab3d2ed1c59d189",
|
||||||
"lifecycle": "draft",
|
"lifecycle": "draft",
|
||||||
"projectId": "00000000000000000000000000000001",
|
"projectId": "00000000000000000000000000000001",
|
||||||
"nextSteps": [
|
"nextSteps": [
|
||||||
@@ -283,7 +283,7 @@
|
|||||||
"name": "제작 화면 열기: 포털 SSO 티켓 → Webmaker /api/auth/sso 302(1회용)",
|
"name": "제작 화면 열기: 포털 SSO 티켓 → Webmaker /api/auth/sso 302(1회용)",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"portalRedirect": "http://127.0.0.1:44585/api/auth/sso?ticket=…",
|
"portalRedirect": "http://127.0.0.1:38791/api/auth/sso?ticket=…",
|
||||||
"webmaker": 302,
|
"webmaker": 302,
|
||||||
"reuse": 401
|
"reuse": 401
|
||||||
}
|
}
|
||||||
@@ -299,7 +299,7 @@
|
|||||||
],
|
],
|
||||||
"evidence": {
|
"evidence": {
|
||||||
"sso": {
|
"sso": {
|
||||||
"portalRedirect": "http://127.0.0.1:44585/api/auth/sso?ticket=…",
|
"portalRedirect": "http://127.0.0.1:38791/api/auth/sso?ticket=…",
|
||||||
"webmaker": 302,
|
"webmaker": 302,
|
||||||
"reuse": 401
|
"reuse": 401
|
||||||
},
|
},
|
||||||
@@ -320,7 +320,7 @@
|
|||||||
"name": "배포 요청 → 10단계 작업·사이트 수 예약·같은 요청 재제출은 하나",
|
"name": "배포 요청 → 10단계 작업·사이트 수 예약·같은 요청 재제출은 하나",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"jobId": "j_01a1b00105ee38a83dc81ee219",
|
"jobId": "j_01a1b004666d3964ce5450810c",
|
||||||
"steps": 10,
|
"steps": 10,
|
||||||
"again": false,
|
"again": false,
|
||||||
"siteCount": "reserved",
|
"siteCount": "reserved",
|
||||||
@@ -351,7 +351,7 @@
|
|||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"lifecycle": "needs_domain",
|
"lifecycle": "needs_domain",
|
||||||
"version": "20261106083700-rev-c1-000000",
|
"version": "20261106084041-rev-c1-000000",
|
||||||
"verify": "needs_domain",
|
"verify": "needs_domain",
|
||||||
"health": "ok",
|
"health": "ok",
|
||||||
"agentHasSite": true
|
"agentHasSite": true
|
||||||
@@ -360,7 +360,7 @@
|
|||||||
],
|
],
|
||||||
"evidence": {
|
"evidence": {
|
||||||
"d": {
|
"d": {
|
||||||
"jobId": "j_01a1b00105ee38a83dc81ee219",
|
"jobId": "j_01a1b004666d3964ce5450810c",
|
||||||
"steps": 10,
|
"steps": 10,
|
||||||
"again": false,
|
"again": false,
|
||||||
"siteCount": "reserved",
|
"siteCount": "reserved",
|
||||||
@@ -383,7 +383,7 @@
|
|||||||
},
|
},
|
||||||
"after": {
|
"after": {
|
||||||
"lifecycle": "needs_domain",
|
"lifecycle": "needs_domain",
|
||||||
"version": "20261106083700-rev-c1-000000",
|
"version": "20261106084041-rev-c1-000000",
|
||||||
"verify": "needs_domain",
|
"verify": "needs_domain",
|
||||||
"health": "ok",
|
"health": "ok",
|
||||||
"agentHasSite": true
|
"agentHasSite": true
|
||||||
@@ -401,7 +401,7 @@
|
|||||||
"name": "도메인 추가(웹·대표 지정) → 소유 확인 TXT 값 안내 → 작업이 외부 대기(TXT)",
|
"name": "도메인 추가(웹·대표 지정) → 소유 확인 TXT 값 안내 → 작업이 외부 대기(TXT)",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"domainId": "d_01a1b00119adec1932fea26a6e",
|
"domainId": "d_01a1b0047a331aa3d1923d51a8",
|
||||||
"txtName": "_ariweb-verify.aw-e2e.localhost",
|
"txtName": "_ariweb-verify.aw-e2e.localhost",
|
||||||
"txtValueShape": "ariweb-verify=…",
|
"txtValueShape": "ariweb-verify=…",
|
||||||
"copyable": true
|
"copyable": true
|
||||||
@@ -422,7 +422,7 @@
|
|||||||
],
|
],
|
||||||
"evidence": {
|
"evidence": {
|
||||||
"dm": {
|
"dm": {
|
||||||
"domainId": "d_01a1b00119adec1932fea26a6e",
|
"domainId": "d_01a1b0047a331aa3d1923d51a8",
|
||||||
"txtName": "_ariweb-verify.aw-e2e.localhost",
|
"txtName": "_ariweb-verify.aw-e2e.localhost",
|
||||||
"txtValueShape": "ariweb-verify=…",
|
"txtValueShape": "ariweb-verify=…",
|
||||||
"copyable": true
|
"copyable": true
|
||||||
@@ -500,7 +500,7 @@
|
|||||||
"name": "사이트 대표 메일 생성(사이트 연결 도메인·배정) → AriMail 테넌트 준비·도메인별 보장량·ariweb 표시",
|
"name": "사이트 대표 메일 생성(사이트 연결 도메인·배정) → AriMail 테넌트 준비·도메인별 보장량·ariweb 표시",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"id": "msv_01a1b001a21edb1db0b90caa39",
|
"id": "msv_01a1b00502c0755b9fe965ba46",
|
||||||
"status": "needs_setup",
|
"status": "needs_setup",
|
||||||
"tenant": true,
|
"tenant": true,
|
||||||
"ariwebKind": "site_bound",
|
"ariwebKind": "site_bound",
|
||||||
@@ -517,7 +517,7 @@
|
|||||||
"name": "메일함 생성: 초기 비밀번호 1회 표시·접속 안내 → 재조회에는 비밀번호 없음",
|
"name": "메일함 생성: 초기 비밀번호 1회 표시·접속 안내 → 재조회에는 비밀번호 없음",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"id": "mb_01a1b001a23523c0be408a7704",
|
"id": "mb_01a1b00502e82fb99c6a1d925b",
|
||||||
"address": "kim@aw-e2e.localhost",
|
"address": "kim@aw-e2e.localhost",
|
||||||
"passwordShownOnce": "[redacted]",
|
"passwordShownOnce": "[redacted]",
|
||||||
"mustChange": true,
|
"mustChange": true,
|
||||||
@@ -584,7 +584,7 @@
|
|||||||
],
|
],
|
||||||
"evidence": {
|
"evidence": {
|
||||||
"svc": {
|
"svc": {
|
||||||
"id": "msv_01a1b001a21edb1db0b90caa39",
|
"id": "msv_01a1b00502c0755b9fe965ba46",
|
||||||
"status": "needs_setup",
|
"status": "needs_setup",
|
||||||
"tenant": true,
|
"tenant": true,
|
||||||
"ariwebKind": "site_bound",
|
"ariwebKind": "site_bound",
|
||||||
@@ -592,7 +592,7 @@
|
|||||||
"siteCountAllocated": 0
|
"siteCountAllocated": 0
|
||||||
},
|
},
|
||||||
"mb": {
|
"mb": {
|
||||||
"id": "mb_01a1b001a23523c0be408a7704",
|
"id": "mb_01a1b00502e82fb99c6a1d925b",
|
||||||
"address": "kim@aw-e2e.localhost",
|
"address": "kim@aw-e2e.localhost",
|
||||||
"passwordShownOnce": "[redacted]",
|
"passwordShownOnce": "[redacted]",
|
||||||
"mustChange": true,
|
"mustChange": true,
|
||||||
@@ -644,7 +644,7 @@
|
|||||||
"name": "메일 전용 도메인 등록(solo-e2e.localhost, purpose mail)",
|
"name": "메일 전용 도메인 등록(solo-e2e.localhost, purpose mail)",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"id": "d_01a1b001c45817fdf71c1fb567",
|
"id": "d_01a1b005251eb41041d686f464",
|
||||||
"jobCancelled": null
|
"jobCancelled": null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -652,7 +652,7 @@
|
|||||||
"name": "독립 메일 서비스 생성(독립 옵션 소비·사이트 수 미소비)",
|
"name": "독립 메일 서비스 생성(독립 옵션 소비·사이트 수 미소비)",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"id": "msv_01a1b001c45e9bb2bc1ae08bf6",
|
"id": "msv_01a1b005252540cb9d7cb9ef0b",
|
||||||
"kind": "standalone",
|
"kind": "standalone",
|
||||||
"mailServicesAllocated": 1,
|
"mailServicesAllocated": 1,
|
||||||
"sitesAllocated": 0
|
"sitesAllocated": 0
|
||||||
@@ -661,7 +661,7 @@
|
|||||||
],
|
],
|
||||||
"evidence": {
|
"evidence": {
|
||||||
"r": {
|
"r": {
|
||||||
"id": "msv_01a1b001c45e9bb2bc1ae08bf6",
|
"id": "msv_01a1b005252540cb9d7cb9ef0b",
|
||||||
"kind": "standalone",
|
"kind": "standalone",
|
||||||
"mailServicesAllocated": 1,
|
"mailServicesAllocated": 1,
|
||||||
"sitesAllocated": 0
|
"sitesAllocated": 0
|
||||||
@@ -701,8 +701,8 @@
|
|||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"status": "active",
|
"status": "active",
|
||||||
"firstDue": "2026-11-07T08:37:48.329Z",
|
"firstDue": "2026-11-07T08:41:29.707Z",
|
||||||
"nextRun": "2026-11-06T08:37:48.329Z"
|
"nextRun": "2026-11-06T08:41:29.707Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -712,7 +712,7 @@
|
|||||||
"timedOut": false,
|
"timedOut": false,
|
||||||
"optionStatus": "active",
|
"optionStatus": "active",
|
||||||
"lastJob": null,
|
"lastJob": null,
|
||||||
"siteServer": "srv_01a1b000fe3cf87ac50582b199",
|
"siteServer": "srv_01a1b0045ea56d81b8cfa4ebd8",
|
||||||
"backup": {
|
"backup": {
|
||||||
"status": "done",
|
"status": "done",
|
||||||
"tier": "monthly",
|
"tier": "monthly",
|
||||||
@@ -733,14 +733,14 @@
|
|||||||
},
|
},
|
||||||
"opt": {
|
"opt": {
|
||||||
"status": "active",
|
"status": "active",
|
||||||
"firstDue": "2026-11-07T08:37:48.329Z",
|
"firstDue": "2026-11-07T08:41:29.707Z",
|
||||||
"nextRun": "2026-11-06T08:37:48.329Z"
|
"nextRun": "2026-11-06T08:41:29.707Z"
|
||||||
},
|
},
|
||||||
"run1": {
|
"run1": {
|
||||||
"timedOut": false,
|
"timedOut": false,
|
||||||
"optionStatus": "active",
|
"optionStatus": "active",
|
||||||
"lastJob": null,
|
"lastJob": null,
|
||||||
"siteServer": "srv_01a1b000fe3cf87ac50582b199",
|
"siteServer": "srv_01a1b0045ea56d81b8cfa4ebd8",
|
||||||
"backup": {
|
"backup": {
|
||||||
"status": "done",
|
"status": "done",
|
||||||
"tier": "monthly",
|
"tier": "monthly",
|
||||||
@@ -763,19 +763,19 @@
|
|||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"backup": {
|
"backup": {
|
||||||
"id": "bk_01a1b001de7311dbc020282a43",
|
"id": "bk_01a1b0053ed9625e728bbaf863",
|
||||||
"createdAt": "2026-11-06T08:37:48.332Z",
|
"createdAt": "2026-11-06T08:41:29.710Z",
|
||||||
"scope": {
|
"scope": {
|
||||||
"files": true,
|
"files": true,
|
||||||
"db": true,
|
"db": true,
|
||||||
"uploads": true,
|
"uploads": true,
|
||||||
"config": true,
|
"config": true,
|
||||||
"storeServerId": "srv_01a1b000feeb9e34dab18cf0ad",
|
"storeServerId": "srv_01a1b0045f7689a3ac44add5a3",
|
||||||
"verifyMethod": "sha256 + 격리 환경 읽기 확인"
|
"verifyMethod": "sha256 + 격리 환경 읽기 확인"
|
||||||
},
|
},
|
||||||
"sizeBytes": 1893,
|
"sizeBytes": 1896,
|
||||||
"verifyState": "verified",
|
"verifyState": "verified",
|
||||||
"expiresAt": "2027-02-07T08:37:54.932Z",
|
"expiresAt": "2027-02-07T08:41:36.218Z",
|
||||||
"tier": "monthly"
|
"tier": "monthly"
|
||||||
},
|
},
|
||||||
"included": [
|
"included": [
|
||||||
@@ -809,7 +809,7 @@
|
|||||||
"name": "복원 요청 → 운영자 승인 대기 · 중복 요청 없음",
|
"name": "복원 요청 → 운영자 승인 대기 · 중복 요청 없음",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"id": "rs_01a1b001e223d31d0a835f0ffc",
|
"id": "rs_01a1b00542f2daa13dc0dc0605",
|
||||||
"status": "awaiting_approval",
|
"status": "awaiting_approval",
|
||||||
"dup": false,
|
"dup": false,
|
||||||
"finalConfirmation": {
|
"finalConfirmation": {
|
||||||
@@ -838,19 +838,19 @@
|
|||||||
"evidence": {
|
"evidence": {
|
||||||
"info": {
|
"info": {
|
||||||
"backup": {
|
"backup": {
|
||||||
"id": "bk_01a1b001de7311dbc020282a43",
|
"id": "bk_01a1b0053ed9625e728bbaf863",
|
||||||
"createdAt": "2026-11-06T08:37:48.332Z",
|
"createdAt": "2026-11-06T08:41:29.710Z",
|
||||||
"scope": {
|
"scope": {
|
||||||
"files": true,
|
"files": true,
|
||||||
"db": true,
|
"db": true,
|
||||||
"uploads": true,
|
"uploads": true,
|
||||||
"config": true,
|
"config": true,
|
||||||
"storeServerId": "srv_01a1b000feeb9e34dab18cf0ad",
|
"storeServerId": "srv_01a1b0045f7689a3ac44add5a3",
|
||||||
"verifyMethod": "sha256 + 격리 환경 읽기 확인"
|
"verifyMethod": "sha256 + 격리 환경 읽기 확인"
|
||||||
},
|
},
|
||||||
"sizeBytes": 1893,
|
"sizeBytes": 1896,
|
||||||
"verifyState": "verified",
|
"verifyState": "verified",
|
||||||
"expiresAt": "2027-02-07T08:37:54.932Z",
|
"expiresAt": "2027-02-07T08:41:36.218Z",
|
||||||
"tier": "monthly"
|
"tier": "monthly"
|
||||||
},
|
},
|
||||||
"included": [
|
"included": [
|
||||||
@@ -880,7 +880,7 @@
|
|||||||
"deferred": []
|
"deferred": []
|
||||||
},
|
},
|
||||||
"rq": {
|
"rq": {
|
||||||
"id": "rs_01a1b001e223d31d0a835f0ffc",
|
"id": "rs_01a1b00542f2daa13dc0dc0605",
|
||||||
"status": "awaiting_approval",
|
"status": "awaiting_approval",
|
||||||
"dup": false,
|
"dup": false,
|
||||||
"finalConfirmation": {
|
"finalConfirmation": {
|
||||||
@@ -970,8 +970,8 @@
|
|||||||
"name": "외부 배포 사이트 생성(초안) + 저장본",
|
"name": "외부 배포 사이트 생성(초안) + 저장본",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"id": "s_01a1b002cdb5f0c48a793c5469",
|
"id": "s_01a1b0062e696e228a49d5fe73",
|
||||||
"group_id": "g_01a1b001050da5f0aac64cb28b",
|
"group_id": "g_01a1b004656a3fd8bdbc431252",
|
||||||
"name": "E2E 외부 사이트",
|
"name": "E2E 외부 사이트",
|
||||||
"purpose": "e2e",
|
"purpose": "e2e",
|
||||||
"webmaker_project_id": "00000000000000000000000000000004",
|
"webmaker_project_id": "00000000000000000000000000000004",
|
||||||
@@ -999,9 +999,9 @@
|
|||||||
"retention_until": null,
|
"retention_until": null,
|
||||||
"delete_after": null,
|
"delete_after": null,
|
||||||
"deleted_at": null,
|
"deleted_at": null,
|
||||||
"created_by": "u_01a1b0010475de80f28e1f95f8",
|
"created_by": "u_01a1b00464ed4b2b09e40fa791",
|
||||||
"created_at": "2026-11-06T08:38:56.181Z",
|
"created_at": "2026-11-06T08:42:37.545Z",
|
||||||
"updated_at": "2026-11-06T08:38:56.187Z",
|
"updated_at": "2026-11-06T08:42:37.550Z",
|
||||||
"runtime": "static",
|
"runtime": "static",
|
||||||
"consent_version": null,
|
"consent_version": null,
|
||||||
"pending_cleanup_json": null,
|
"pending_cleanup_json": null,
|
||||||
@@ -1042,8 +1042,8 @@
|
|||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"token": "[redacted]",
|
"token": "[redacted]",
|
||||||
"install": "curl -fsSL http://127.0.0.1:46137/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:46137 --token … --external --site s_01a1b002cdb5f0c48a793c5469",
|
"install": "curl -fsSL http://127.0.0.1:42077/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:42077 --token … --external --site s_01a1b0062e696e228a49d5fe73",
|
||||||
"expiresAt": "2026-11-06T08:48:56.214Z",
|
"expiresAt": "2026-11-06T08:52:37.584Z",
|
||||||
"status": "pending"
|
"status": "pending"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1126,8 +1126,8 @@
|
|||||||
"agreed": false
|
"agreed": false
|
||||||
},
|
},
|
||||||
"tok": {
|
"tok": {
|
||||||
"install": "curl -fsSL http://127.0.0.1:46137/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:46137 --token … --external --site s_01a1b002cdb5f0c48a793c5469",
|
"install": "curl -fsSL http://127.0.0.1:42077/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:42077 --token … --external --site s_01a1b0062e696e228a49d5fe73",
|
||||||
"expiresAt": "2026-11-06T08:48:56.214Z"
|
"expiresAt": "2026-11-06T08:52:37.584Z"
|
||||||
},
|
},
|
||||||
"conn": {
|
"conn": {
|
||||||
"status": "connected",
|
"status": "connected",
|
||||||
@@ -1311,7 +1311,7 @@
|
|||||||
"approve": 200,
|
"approve": 200,
|
||||||
"sites": 1,
|
"sites": 1,
|
||||||
"mailboxes": 5,
|
"mailboxes": 5,
|
||||||
"product": "pv_01a1b001033b6c20005814ab9e"
|
"product": "pv_01a1b004639bf7bb78dcc6fcad"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1347,7 +1347,7 @@
|
|||||||
"approve": 200,
|
"approve": 200,
|
||||||
"sites": 1,
|
"sites": 1,
|
||||||
"mailboxes": 5,
|
"mailboxes": 5,
|
||||||
"product": "pv_01a1b001033b6c20005814ab9e"
|
"product": "pv_01a1b004639bf7bb78dcc6fcad"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1430,9 +1430,9 @@
|
|||||||
"name": "요청(보내는 그룹, 초안 사이트) → 받는 사용자 알림",
|
"name": "요청(보내는 그룹, 초안 사이트) → 받는 사용자 알림",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"id": "tr_01a1b002ef104ca1036d3185cd",
|
"id": "tr_01a1b0064f9fe7ba31d9dbdbd2",
|
||||||
"status": "requested",
|
"status": "requested",
|
||||||
"expiresAt": "2026-11-13T08:39:04.720Z",
|
"expiresAt": "2026-11-13T08:42:46.047Z",
|
||||||
"bobNotified": true
|
"bobNotified": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1460,7 +1460,7 @@
|
|||||||
"bad": "final_confirmation_mismatch",
|
"bad": "final_confirmation_mismatch",
|
||||||
"ok": 200,
|
"ok": 200,
|
||||||
"status": "completed",
|
"status": "completed",
|
||||||
"cutover": "2026-11-06T08:39:04.745Z"
|
"cutover": "2026-11-06T08:42:46.076Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1489,9 +1489,9 @@
|
|||||||
"excluded": 3
|
"excluded": 3
|
||||||
},
|
},
|
||||||
"rq": {
|
"rq": {
|
||||||
"id": "tr_01a1b002ef104ca1036d3185cd",
|
"id": "tr_01a1b0064f9fe7ba31d9dbdbd2",
|
||||||
"status": "requested",
|
"status": "requested",
|
||||||
"expiresAt": "2026-11-13T08:39:04.720Z",
|
"expiresAt": "2026-11-13T08:42:46.047Z",
|
||||||
"bobNotified": true
|
"bobNotified": true
|
||||||
},
|
},
|
||||||
"acc": {
|
"acc": {
|
||||||
@@ -1503,7 +1503,7 @@
|
|||||||
"bad": "final_confirmation_mismatch",
|
"bad": "final_confirmation_mismatch",
|
||||||
"ok": 200,
|
"ok": 200,
|
||||||
"status": "completed",
|
"status": "completed",
|
||||||
"cutover": "2026-11-06T08:39:04.745Z"
|
"cutover": "2026-11-06T08:42:46.076Z"
|
||||||
},
|
},
|
||||||
"after": {
|
"after": {
|
||||||
"aliceSees": 404,
|
"aliceSees": 404,
|
||||||
@@ -1718,7 +1718,7 @@
|
|||||||
"detail": {
|
"detail": {
|
||||||
"status": "done",
|
"status": "done",
|
||||||
"canRetry": false,
|
"canRetry": false,
|
||||||
"jobId": "j_01a1b00105ee38a83dc81ee219"
|
"jobId": "j_01a1b004666d3964ce5450810c"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1743,7 +1743,7 @@
|
|||||||
"dep": {
|
"dep": {
|
||||||
"status": "done",
|
"status": "done",
|
||||||
"canRetry": false,
|
"canRetry": false,
|
||||||
"jobId": "j_01a1b00105ee38a83dc81ee219"
|
"jobId": "j_01a1b004666d3964ce5450810c"
|
||||||
},
|
},
|
||||||
"rt": {
|
"rt": {
|
||||||
"status": 400,
|
"status": 400,
|
||||||
@@ -1769,7 +1769,7 @@
|
|||||||
"detail": {
|
"detail": {
|
||||||
"title": "주문 AW-20261106-0001 승인 — 권리가 활성화되었습니다",
|
"title": "주문 AW-20261106-0001 승인 — 권리가 활성화되었습니다",
|
||||||
"category": "billing",
|
"category": "billing",
|
||||||
"link": "/orders/o_01a1b001056b3235366163b734"
|
"link": "/orders/o_01a1b00465dbbb0e3b6e62dbd4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1785,7 +1785,7 @@
|
|||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"status": "approved",
|
"status": "approved",
|
||||||
"approvedAt": "2026-11-06T08:36:59.420Z"
|
"approvedAt": "2026-11-06T08:40:40.718Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -1793,7 +1793,7 @@
|
|||||||
"n": {
|
"n": {
|
||||||
"title": "주문 AW-20261106-0001 승인 — 권리가 활성화되었습니다",
|
"title": "주문 AW-20261106-0001 승인 — 권리가 활성화되었습니다",
|
||||||
"category": "billing",
|
"category": "billing",
|
||||||
"link": "/orders/o_01a1b001056b3235366163b734"
|
"link": "/orders/o_01a1b00465dbbb0e3b6e62dbd4"
|
||||||
},
|
},
|
||||||
"a": {
|
"a": {
|
||||||
"action": "order.approve",
|
"action": "order.approve",
|
||||||
@@ -1801,7 +1801,7 @@
|
|||||||
},
|
},
|
||||||
"same": {
|
"same": {
|
||||||
"status": "approved",
|
"status": "approved",
|
||||||
"approvedAt": "2026-11-06T08:36:59.420Z"
|
"approvedAt": "2026-11-06T08:40:40.718Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1844,9 +1844,9 @@
|
|||||||
"rpo_minutes": 30,
|
"rpo_minutes": 30,
|
||||||
"snapshot_interval_minutes": 60,
|
"snapshot_interval_minutes": 60,
|
||||||
"retention_count": 3,
|
"retention_count": 3,
|
||||||
"external_store": "/home/master/work/Ariweb-suite/test/.tmp/e2e-20261106083656/dr-external",
|
"external_store": "/home/master/work/Ariweb-suite/test/.tmp/e2e-20261106084037/dr-external",
|
||||||
"updated_at": "2026-11-06T08:39:12.885Z",
|
"updated_at": "2026-11-06T08:42:54.251Z",
|
||||||
"updated_by": "op_01a1b000fd55691854cd6d073f"
|
"updated_by": "op_01a1b0045ddd88b602a5012e9a"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1906,9 +1906,9 @@
|
|||||||
"rpo_minutes": 30,
|
"rpo_minutes": 30,
|
||||||
"snapshot_interval_minutes": 60,
|
"snapshot_interval_minutes": 60,
|
||||||
"retention_count": 3,
|
"retention_count": 3,
|
||||||
"external_store": "/home/master/work/Ariweb-suite/test/.tmp/e2e-20261106083656/dr-external",
|
"external_store": "/home/master/work/Ariweb-suite/test/.tmp/e2e-20261106084037/dr-external",
|
||||||
"updated_at": "2026-11-06T08:39:12.885Z",
|
"updated_at": "2026-11-06T08:42:54.251Z",
|
||||||
"updated_by": "op_01a1b000fd55691854cd6d073f"
|
"updated_by": "op_01a1b0045ddd88b602a5012e9a"
|
||||||
},
|
},
|
||||||
"snap": {
|
"snap": {
|
||||||
"verify": "ok",
|
"verify": "ok",
|
||||||
@@ -1942,7 +1942,7 @@
|
|||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"mailJob": {
|
"mailJob": {
|
||||||
"id": "j_01a1b001b25ba4cb9489fd0cfe",
|
"id": "j_01a1b00513188ba0a43d6875f9",
|
||||||
"status": "awaiting_external"
|
"status": "awaiting_external"
|
||||||
},
|
},
|
||||||
"halJobs": 19
|
"halJobs": 19
|
||||||
@@ -1954,7 +1954,7 @@
|
|||||||
"detail": {
|
"detail": {
|
||||||
"sessionKept": "[redacted]",
|
"sessionKept": "[redacted]",
|
||||||
"mailJob": {
|
"mailJob": {
|
||||||
"id": "j_01a1b001b25ba4cb9489fd0cfe",
|
"id": "j_01a1b00513188ba0a43d6875f9",
|
||||||
"status": "awaiting_external"
|
"status": "awaiting_external"
|
||||||
},
|
},
|
||||||
"same": true
|
"same": true
|
||||||
@@ -1973,7 +1973,7 @@
|
|||||||
"evidence": {
|
"evidence": {
|
||||||
"before": {
|
"before": {
|
||||||
"mailJob": {
|
"mailJob": {
|
||||||
"id": "j_01a1b001b25ba4cb9489fd0cfe",
|
"id": "j_01a1b00513188ba0a43d6875f9",
|
||||||
"status": "awaiting_external"
|
"status": "awaiting_external"
|
||||||
},
|
},
|
||||||
"halJobs": 19
|
"halJobs": 19
|
||||||
@@ -1981,7 +1981,7 @@
|
|||||||
"pr": {
|
"pr": {
|
||||||
"sessionKept": "[redacted]",
|
"sessionKept": "[redacted]",
|
||||||
"mailJob": {
|
"mailJob": {
|
||||||
"id": "j_01a1b001b25ba4cb9489fd0cfe",
|
"id": "j_01a1b00513188ba0a43d6875f9",
|
||||||
"status": "awaiting_external"
|
"status": "awaiting_external"
|
||||||
},
|
},
|
||||||
"same": true
|
"same": true
|
||||||
@@ -2012,8 +2012,8 @@
|
|||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": [
|
"detail": [
|
||||||
{
|
{
|
||||||
"id": "s_01a1b0019643bfa4d94d352071",
|
"id": "s_01a1b004f6d16fb55a118684f7",
|
||||||
"group_id": "g_01a1b001053169a7ba81639ba6",
|
"group_id": "g_01a1b004658f4107f66903cf3c",
|
||||||
"name": "동시 A",
|
"name": "동시 A",
|
||||||
"purpose": "e2e",
|
"purpose": "e2e",
|
||||||
"webmaker_project_id": "00000000000000000000000000000002",
|
"webmaker_project_id": "00000000000000000000000000000002",
|
||||||
@@ -2041,9 +2041,9 @@
|
|||||||
"retention_until": null,
|
"retention_until": null,
|
||||||
"delete_after": null,
|
"delete_after": null,
|
||||||
"deleted_at": null,
|
"deleted_at": null,
|
||||||
"created_by": "u_01a1b001053159d6f8fc9c9f67",
|
"created_by": "u_01a1b004658ed2b5199271673a",
|
||||||
"created_at": "2026-11-06T08:37:36.451Z",
|
"created_at": "2026-11-06T08:41:17.777Z",
|
||||||
"updated_at": "2026-11-06T08:37:36.457Z",
|
"updated_at": "2026-11-06T08:41:17.781Z",
|
||||||
"runtime": "static",
|
"runtime": "static",
|
||||||
"consent_version": null,
|
"consent_version": null,
|
||||||
"pending_cleanup_json": null,
|
"pending_cleanup_json": null,
|
||||||
@@ -2062,8 +2062,8 @@
|
|||||||
"nextJob": null
|
"nextJob": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "s_01a1b00196459b9d7accccd93b",
|
"id": "s_01a1b004f6d3c983e60bedd048",
|
||||||
"group_id": "g_01a1b001053169a7ba81639ba6",
|
"group_id": "g_01a1b004658f4107f66903cf3c",
|
||||||
"name": "동시 B",
|
"name": "동시 B",
|
||||||
"purpose": "e2e",
|
"purpose": "e2e",
|
||||||
"webmaker_project_id": "00000000000000000000000000000003",
|
"webmaker_project_id": "00000000000000000000000000000003",
|
||||||
@@ -2091,9 +2091,9 @@
|
|||||||
"retention_until": null,
|
"retention_until": null,
|
||||||
"delete_after": null,
|
"delete_after": null,
|
||||||
"deleted_at": null,
|
"deleted_at": null,
|
||||||
"created_by": "u_01a1b001053159d6f8fc9c9f67",
|
"created_by": "u_01a1b004658ed2b5199271673a",
|
||||||
"created_at": "2026-11-06T08:37:36.453Z",
|
"created_at": "2026-11-06T08:41:17.779Z",
|
||||||
"updated_at": "2026-11-06T08:37:36.458Z",
|
"updated_at": "2026-11-06T08:41:17.782Z",
|
||||||
"runtime": "static",
|
"runtime": "static",
|
||||||
"consent_version": null,
|
"consent_version": null,
|
||||||
"pending_cleanup_json": null,
|
"pending_cleanup_json": null,
|
||||||
@@ -2151,8 +2151,8 @@
|
|||||||
"name": "외부 배포 사이트 생성(초안) + 저장본",
|
"name": "외부 배포 사이트 생성(초안) + 저장본",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"id": "s_01a1b002cdb5f0c48a793c5469",
|
"id": "s_01a1b0062e696e228a49d5fe73",
|
||||||
"group_id": "g_01a1b001050da5f0aac64cb28b",
|
"group_id": "g_01a1b004656a3fd8bdbc431252",
|
||||||
"name": "E2E 외부 사이트",
|
"name": "E2E 외부 사이트",
|
||||||
"purpose": "e2e",
|
"purpose": "e2e",
|
||||||
"webmaker_project_id": "00000000000000000000000000000004",
|
"webmaker_project_id": "00000000000000000000000000000004",
|
||||||
@@ -2180,9 +2180,9 @@
|
|||||||
"retention_until": null,
|
"retention_until": null,
|
||||||
"delete_after": null,
|
"delete_after": null,
|
||||||
"deleted_at": null,
|
"deleted_at": null,
|
||||||
"created_by": "u_01a1b0010475de80f28e1f95f8",
|
"created_by": "u_01a1b00464ed4b2b09e40fa791",
|
||||||
"created_at": "2026-11-06T08:38:56.181Z",
|
"created_at": "2026-11-06T08:42:37.545Z",
|
||||||
"updated_at": "2026-11-06T08:38:56.187Z",
|
"updated_at": "2026-11-06T08:42:37.550Z",
|
||||||
"runtime": "static",
|
"runtime": "static",
|
||||||
"consent_version": null,
|
"consent_version": null,
|
||||||
"pending_cleanup_json": null,
|
"pending_cleanup_json": null,
|
||||||
@@ -2223,8 +2223,8 @@
|
|||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"token": "[redacted]",
|
"token": "[redacted]",
|
||||||
"install": "curl -fsSL http://127.0.0.1:46137/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:46137 --token … --external --site s_01a1b002cdb5f0c48a793c5469",
|
"install": "curl -fsSL http://127.0.0.1:42077/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:42077 --token … --external --site s_01a1b0062e696e228a49d5fe73",
|
||||||
"expiresAt": "2026-11-06T08:48:56.214Z",
|
"expiresAt": "2026-11-06T08:52:37.584Z",
|
||||||
"status": "pending"
|
"status": "pending"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2419,9 +2419,9 @@
|
|||||||
"errorCode": "partial_failure",
|
"errorCode": "partial_failure",
|
||||||
"overall": "partial",
|
"overall": "partial",
|
||||||
"children": [
|
"children": [
|
||||||
|
"srv_01a1b0045f7689a3ac44add5a3:done:",
|
||||||
"srv_missing_e2e:failed:서버가 없습니다",
|
"srv_missing_e2e:failed:서버가 없습니다",
|
||||||
"srv_01a1b000feeb9e34dab18cf0ad:done:",
|
"srv_01a1b0045ea56d81b8cfa4ebd8:done:"
|
||||||
"srv_01a1b000fe3cf87ac50582b199:done:"
|
|
||||||
],
|
],
|
||||||
"timedOut": false
|
"timedOut": false
|
||||||
}
|
}
|
||||||
@@ -2458,9 +2458,9 @@
|
|||||||
"errorCode": "partial_failure",
|
"errorCode": "partial_failure",
|
||||||
"overall": "partial",
|
"overall": "partial",
|
||||||
"children": [
|
"children": [
|
||||||
|
"srv_01a1b0045f7689a3ac44add5a3:done:",
|
||||||
"srv_missing_e2e:failed:서버가 없습니다",
|
"srv_missing_e2e:failed:서버가 없습니다",
|
||||||
"srv_01a1b000feeb9e34dab18cf0ad:done:",
|
"srv_01a1b0045ea56d81b8cfa4ebd8:done:"
|
||||||
"srv_01a1b000fe3cf87ac50582b199:done:"
|
|
||||||
],
|
],
|
||||||
"timedOut": false
|
"timedOut": false
|
||||||
},
|
},
|
||||||
@@ -2499,7 +2499,7 @@
|
|||||||
"name": "critical 사건 등록 → 선언 → 승인 부족 자격 거부 → 3단계(순서·식별정보·문구) 거부/승인 → 자격 발급(1회)",
|
"name": "critical 사건 등록 → 선언 → 승인 부족 자격 거부 → 3단계(순서·식별정보·문구) 거부/승인 → 자격 발급(1회)",
|
||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"id": "em_01a1b0030f3fad74ec4433ce4c",
|
"id": "em_01a1b00670143d9f75bc136275",
|
||||||
"noCred": "approvals_insufficient",
|
"noCred": "approvals_insufficient",
|
||||||
"wrongStep": "wrong_step",
|
"wrongStep": "wrong_step",
|
||||||
"badIds": "identifiers_mismatch",
|
"badIds": "identifiers_mismatch",
|
||||||
@@ -2507,7 +2507,7 @@
|
|||||||
"approved": "approved",
|
"approved": "approved",
|
||||||
"approvals": 3,
|
"approvals": 3,
|
||||||
"credential": "[redacted]",
|
"credential": "[redacted]",
|
||||||
"expiresAt": "2026-11-06T09:09:12.972Z"
|
"expiresAt": "2026-11-06T09:12:54.370Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2528,14 +2528,14 @@
|
|||||||
"evidence": {
|
"evidence": {
|
||||||
"healthy": "hal_healthy",
|
"healthy": "hal_healthy",
|
||||||
"sess": {
|
"sess": {
|
||||||
"id": "em_01a1b0030f3fad74ec4433ce4c",
|
"id": "em_01a1b00670143d9f75bc136275",
|
||||||
"noCred": "approvals_insufficient",
|
"noCred": "approvals_insufficient",
|
||||||
"wrongStep": "wrong_step",
|
"wrongStep": "wrong_step",
|
||||||
"badIds": "identifiers_mismatch",
|
"badIds": "identifiers_mismatch",
|
||||||
"badText": "final_confirm_mismatch",
|
"badText": "final_confirm_mismatch",
|
||||||
"approved": "approved",
|
"approved": "approved",
|
||||||
"approvals": 3,
|
"approvals": 3,
|
||||||
"expiresAt": "2026-11-06T09:09:12.972Z"
|
"expiresAt": "2026-11-06T09:12:54.370Z"
|
||||||
},
|
},
|
||||||
"perf": {
|
"perf": {
|
||||||
"forbidden": "action_forbidden",
|
"forbidden": "action_forbidden",
|
||||||
@@ -2587,8 +2587,8 @@
|
|||||||
"ok": true,
|
"ok": true,
|
||||||
"detail": {
|
"detail": {
|
||||||
"status": "readonly",
|
"status": "readonly",
|
||||||
"deleteAfter": "2026-12-06T08:39:04.688Z",
|
"deleteAfter": "2026-12-06T08:42:46.007Z",
|
||||||
"readonlyUntil": "2026-12-06T08:39:04.688Z"
|
"readonlyUntil": "2026-12-06T08:42:46.007Z"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -2614,8 +2614,8 @@
|
|||||||
},
|
},
|
||||||
"un": {
|
"un": {
|
||||||
"status": "readonly",
|
"status": "readonly",
|
||||||
"deleteAfter": "2026-12-06T08:39:04.688Z",
|
"deleteAfter": "2026-12-06T08:42:46.007Z",
|
||||||
"readonlyUntil": "2026-12-06T08:39:04.688Z"
|
"readonlyUntil": "2026-12-06T08:42:46.007Z"
|
||||||
},
|
},
|
||||||
"sweep": {
|
"sweep": {
|
||||||
"sweep": 200,
|
"sweep": 200,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# 로컬 종단 간 검증 기록 — 2026-11-06
|
# 로컬 종단 간 검증 기록 — 2026-11-06
|
||||||
|
|
||||||
생성: 2026-11-06T08:39:15.596Z · `node --no-warnings test/e2e.test.mjs` (test/e2e/)
|
생성: 2026-11-06T08:42:57.005Z · `node --no-warnings test/e2e.test.mjs` (test/e2e/)
|
||||||
|
|
||||||
실행 환경: 실제 HAL·고객 포털·Node Agent(명령 stub 모드) 프로세스 4대 + 가짜 Webmaker/AriMail/발신 메일 서버(127.0.0.1). 실 DNS·실 메일 왕복·실 서버는 포함하지 않는다.
|
실행 환경: 실제 HAL·고객 포털·Node Agent(명령 stub 모드) 프로세스 4대 + 가짜 Webmaker/AriMail/발신 메일 서버(127.0.0.1). 실 DNS·실 메일 왕복·실 서버는 포함하지 않는다.
|
||||||
|
|
||||||
@@ -88,20 +88,20 @@
|
|||||||
|
|
||||||
### 2. 개인 사용자 그룹 생성과 다른 사용자 초대
|
### 2. 개인 사용자 그룹 생성과 다른 사용자 초대
|
||||||
|
|
||||||
- ✔ 팀 그룹 만들기 → 현재 그룹 전환 — g_01a1b001050da5f0aac64cb28b
|
- ✔ 팀 그룹 만들기 → 현재 그룹 전환 — g_01a1b004656a3fd8bdbc431252
|
||||||
- ✔ 이메일 초대(7일) → 초대 메일 링크 — CuKQ5wejxWQRySeHUeXtDHc6UV_gtoBe
|
- ✔ 이메일 초대(7일) → 초대 메일 링크 — gDQeFdZYzURAfDUw-yHeUH762uhAoRwS
|
||||||
- ✔ 초대 수락(1회용) → 별칭 user-02 · 역할 member — {"alias":"user-02","role":"member","reuse":"invite_invalid"}
|
- ✔ 초대 수락(1회용) → 별칭 user-02 · 역할 member — {"alias":"user-02","role":"member","reuse":"invite_invalid"}
|
||||||
- ✔ 권한 없는 구성원의 직접 API 접근 → 403 + 필요한 역할 — {"requiredRole":["owner","admin"],"yourRole":"member"}
|
- ✔ 권한 없는 구성원의 직접 API 접근 → 403 + 필요한 역할 — {"requiredRole":["owner","admin"],"yourRole":"member"}
|
||||||
- ✔ 그룹 전환 격리: 개인 그룹으로 바꾸면 팀 데이터가 보이지 않음 — {"team":{"live":0,"purchased":0,"inUse":0,"reserved":0,"unallocated":0},"personal":{"live":0,"purchased":0,"inUse":0,"reserved":0,"unallocated":0}}
|
- ✔ 그룹 전환 격리: 개인 그룹으로 바꾸면 팀 데이터가 보이지 않음 — {"team":{"live":0,"purchased":0,"inUse":0,"reserved":0,"unallocated":0},"personal":{"live":0,"purchased":0,"inUse":0,"reserved":0,"unallocated":0}}
|
||||||
|
|
||||||
### 3. 상품 주문, 결제 확인, 권리 활성화
|
### 3. 상품 주문, 결제 확인, 권리 활성화
|
||||||
|
|
||||||
- ✔ 상품 목록(공개 버전만·가격·한도·미확정 정책 표시) — {"count":2,"team":{"id":"pv_01a1b001033bcca913e287fd2e","price":49000,"sites":3},"deferred":3,"paymentMethods":["manual_transfer"]}
|
- ✔ 상품 목록(공개 버전만·가격·한도·미확정 정책 표시) — {"count":2,"team":{"id":"pv_01a1b004639c49d0dc8ae615b6","price":49000,"sites":3},"deferred":3,"paymentMethods":["manual_transfer"]}
|
||||||
- ✔ 주문 제출(수동 결제) → 결제 대기·주문 번호·입금 안내 · 같은 키 재제출은 중복 없음 — {"orderNo":"AW-20261106-0001","status":"awaiting_payment","total":63800,"dueAt":"2026-11-13T08:36:59.371Z","hasInstructions":true}
|
- ✔ 주문 제출(수동 결제) → 결제 대기·주문 번호·입금 안내 · 같은 키 재제출은 중복 없음 — {"orderNo":"AW-20261106-0001","status":"awaiting_payment","total":63800,"dueAt":"2026-11-13T08:40:40.667Z","hasInstructions":true}
|
||||||
- ✔ 입금 확인 전 승인 거부(409 payment_not_confirmed) — payment_not_confirmed
|
- ✔ 입금 확인 전 승인 거부(409 payment_not_confirmed) — payment_not_confirmed
|
||||||
- ✔ 운영자 입금 확인 → 승인 대기 목록에 권리 변화·현재 사용량 표시 — {"status":"awaiting_approval","delta":["sites","web_disk","web_out","mail_storage","mail_msgs","mailboxes","mail_services","mail_storage","mail_msgs","mailboxes"]}
|
- ✔ 운영자 입금 확인 → 승인 대기 목록에 권리 변화·현재 사용량 표시 — {"status":"awaiting_approval","delta":["sites","web_disk","web_out","mail_storage","mail_msgs","mailboxes","mail_services","mail_storage","mail_msgs","mailboxes"]}
|
||||||
- ✔ 운영자 승인 → 권리 활성화(재승인은 중복 없음) — {"granted":10,"already":true}
|
- ✔ 운영자 승인 → 권리 활성화(재승인은 중복 없음) — {"granted":10,"already":true}
|
||||||
- ✔ 고객 결제 화면: 활성 상품·권리·다음 청구일 — {"sites":3,"subs":1,"nextBilling":"2026-12-06T08:36:59.420Z"}
|
- ✔ 고객 결제 화면: 활성 상품·권리·다음 청구일 — {"sites":3,"subs":1,"nextBilling":"2026-12-06T08:40:40.718Z"}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -112,25 +112,25 @@
|
|||||||
"bill": {
|
"bill": {
|
||||||
"sites": 3,
|
"sites": 3,
|
||||||
"subs": 1,
|
"subs": 1,
|
||||||
"nextBilling": "2026-12-06T08:36:59.420Z"
|
"nextBilling": "2026-12-06T08:40:40.718Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 초안 사이트 생성
|
### 4. 초안 사이트 생성
|
||||||
|
|
||||||
- ✔ 사이트 생성(새 Webmaker 프로젝트·배포 방식 관리형) → 초안·사이트 수 미소비·다음 단계 안내 — {"id":"s_01a1b00105c6ccdc2e6bed72ab","lifecycle":"draft","projectId":"00000000000000000000000000000001","nextSteps":["build","import","domain","mode","perms"]}
|
- ✔ 사이트 생성(새 Webmaker 프로젝트·배포 방식 관리형) → 초안·사이트 수 미소비·다음 단계 안내 — {"id":"s_01a1b004663ab3d2ed1c59d189","lifecycle":"draft","projectId":"00000000000000000000000000000001","nextSteps":["build","import","domain","mode","perms"]}
|
||||||
- ✔ 사이트 목록 필터(초안)·사용량 요약에 예약 0 — {"drafts":1,"sitesReserved":0,"sitesAllocated":0}
|
- ✔ 사이트 목록 필터(초안)·사용량 요약에 예약 0 — {"drafts":1,"sitesReserved":0,"sitesAllocated":0}
|
||||||
|
|
||||||
### 5. Webmaker에서 페이지 제작
|
### 5. Webmaker에서 페이지 제작
|
||||||
|
|
||||||
- ✔ 제작 화면 열기: 포털 SSO 티켓 → Webmaker /api/auth/sso 302(1회용) — {"portalRedirect":"http://127.0.0.1:44585/api/auth/sso?ticket=…","webmaker":302,"reuse":401}
|
- ✔ 제작 화면 열기: 포털 SSO 티켓 → Webmaker /api/auth/sso 302(1회용) — {"portalRedirect":"http://127.0.0.1:38791/api/auth/sso?ticket=…","webmaker":302,"reuse":401}
|
||||||
- ✔ Webmaker 에서 페이지 저장(저장본 2개) → 포털 저장본 목록·배포 전 확인 통과 — {"versions":1,"precheckOk":true}
|
- ✔ Webmaker 에서 페이지 저장(저장본 2개) → 포털 저장본 목록·배포 전 확인 통과 — {"versions":1,"precheckOk":true}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"sso": {
|
"sso": {
|
||||||
"portalRedirect": "http://127.0.0.1:44585/api/auth/sso?ticket=…",
|
"portalRedirect": "http://127.0.0.1:38791/api/auth/sso?ticket=…",
|
||||||
"webmaker": 302,
|
"webmaker": 302,
|
||||||
"reuse": 401
|
"reuse": 401
|
||||||
},
|
},
|
||||||
@@ -143,14 +143,14 @@
|
|||||||
|
|
||||||
### 6. 관리형 배포
|
### 6. 관리형 배포
|
||||||
|
|
||||||
- ✔ 배포 요청 → 10단계 작업·사이트 수 예약·같은 요청 재제출은 하나 — {"jobId":"j_01a1b00105ee38a83dc81ee219","steps":10,"again":false,"siteCount":"reserved","server":null}
|
- ✔ 배포 요청 → 10단계 작업·사이트 수 예약·같은 요청 재제출은 하나 — {"jobId":"j_01a1b004666d3964ce5450810c","steps":10,"again":false,"siteCount":"reserved","server":null}
|
||||||
- ✔ HAL·Agent 를 거쳐 작업 완료 대기(최대 40초) — {"status":"done","steps":["accept:done","prepare_version:done","prepare_target:done","apply:done","data_check:done","start:done","internal_check:done","external_check:done","domain_https:done","done:done"]}
|
- ✔ HAL·Agent 를 거쳐 작업 완료 대기(최대 40초) — {"status":"done","steps":["accept:done","prepare_version:done","prepare_target:done","apply:done","data_check:done","start:done","internal_check:done","external_check:done","domain_https:done","done:done"]}
|
||||||
- ✔ 배포 뒤 사이트 상태·버전·건강 — {"lifecycle":"needs_domain","version":"20261106083700-rev-c1-000000","verify":"needs_domain","health":"ok","agentHasSite":true}
|
- ✔ 배포 뒤 사이트 상태·버전·건강 — {"lifecycle":"needs_domain","version":"20261106084041-rev-c1-000000","verify":"needs_domain","health":"ok","agentHasSite":true}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"d": {
|
"d": {
|
||||||
"jobId": "j_01a1b00105ee38a83dc81ee219",
|
"jobId": "j_01a1b004666d3964ce5450810c",
|
||||||
"steps": 10,
|
"steps": 10,
|
||||||
"again": false,
|
"again": false,
|
||||||
"siteCount": "reserved",
|
"siteCount": "reserved",
|
||||||
@@ -173,7 +173,7 @@
|
|||||||
},
|
},
|
||||||
"after": {
|
"after": {
|
||||||
"lifecycle": "needs_domain",
|
"lifecycle": "needs_domain",
|
||||||
"version": "20261106083700-rev-c1-000000",
|
"version": "20261106084041-rev-c1-000000",
|
||||||
"verify": "needs_domain",
|
"verify": "needs_domain",
|
||||||
"health": "ok",
|
"health": "ok",
|
||||||
"agentHasSite": true
|
"agentHasSite": true
|
||||||
@@ -183,14 +183,14 @@
|
|||||||
|
|
||||||
### 7. 도메인 연결과 HTTPS 발급
|
### 7. 도메인 연결과 HTTPS 발급
|
||||||
|
|
||||||
- ✔ 도메인 추가(웹·대표 지정) → 소유 확인 TXT 값 안내 → 작업이 외부 대기(TXT) — {"domainId":"d_01a1b00119adec1932fea26a6e","txtName":"_ariweb-verify.aw-e2e.localhost","txtValueShape":"ariweb-verify=…","copyable":true}
|
- ✔ 도메인 추가(웹·대표 지정) → 소유 확인 TXT 값 안내 → 작업이 외부 대기(TXT) — {"domainId":"d_01a1b0047a331aa3d1923d51a8","txtName":"_ariweb-verify.aw-e2e.localhost","txtValueShape":"ariweb-verify=…","copyable":true}
|
||||||
- ✔ 도메인 목록·상세: 소유 확인·DNS·인증서 상태 표시 — {}
|
- ✔ 도메인 목록·상세: 소유 확인·DNS·인증서 상태 표시 — {}
|
||||||
- ✔ (정리) 도메인 연결 작업 취소 — 포털이 외부 대기 중에도 5초마다 HAL domain.probe 를 새로 만들어 큐를 채우므로(결함 항목) 뒤 흐름을 위해 멈춘다 — {"queuedProbes":0}
|
- ✔ (정리) 도메인 연결 작업 취소 — 포털이 외부 대기 중에도 5초마다 HAL domain.probe 를 새로 만들어 큐를 채우므로(결함 항목) 뒤 흐름을 위해 멈춘다 — {"queuedProbes":0}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"dm": {
|
"dm": {
|
||||||
"domainId": "d_01a1b00119adec1932fea26a6e",
|
"domainId": "d_01a1b0047a331aa3d1923d51a8",
|
||||||
"txtName": "_ariweb-verify.aw-e2e.localhost",
|
"txtName": "_ariweb-verify.aw-e2e.localhost",
|
||||||
"txtValueShape": "ariweb-verify=…",
|
"txtValueShape": "ariweb-verify=…",
|
||||||
"copyable": true
|
"copyable": true
|
||||||
@@ -233,9 +233,9 @@
|
|||||||
|
|
||||||
### 10. 사이트 대표 메일과 메일함 생성
|
### 10. 사이트 대표 메일과 메일함 생성
|
||||||
|
|
||||||
- ✔ 사이트 대표 메일 생성(사이트 연결 도메인·배정) → AriMail 테넌트 준비·도메인별 보장량·ariweb 표시 — {"id":"msv_01a1b001a21edb1db0b90caa39","status":"needs_setup","tenant":true,"ariwebKind":"site_bound","limitAccounts":6,"siteCountAllocated":0}
|
- ✔ 사이트 대표 메일 생성(사이트 연결 도메인·배정) → AriMail 테넌트 준비·도메인별 보장량·ariweb 표시 — {"id":"msv_01a1b00502c0755b9fe965ba46","status":"needs_setup","tenant":true,"ariwebKind":"site_bound","limitAccounts":6,"siteCountAllocated":0}
|
||||||
- ✔ 같은 사이트에 두 번째 대표 메일 거부 — mail_domain_in_use
|
- ✔ 같은 사이트에 두 번째 대표 메일 거부 — mail_domain_in_use
|
||||||
- ✔ 메일함 생성: 초기 비밀번호 1회 표시·접속 안내 → 재조회에는 비밀번호 없음 — {"id":"mb_01a1b001a23523c0be408a7704","address":"kim@aw-e2e.localhost","passwordShownOnce":"[redacted]","mustChange":true,"imapHost":"127.0.0.1","leakedOnReload":false,"inArimail":true}
|
- ✔ 메일함 생성: 초기 비밀번호 1회 표시·접속 안내 → 재조회에는 비밀번호 없음 — {"id":"mb_01a1b00502e82fb99c6a1d925b","address":"kim@aw-e2e.localhost","passwordShownOnce":"[redacted]","mustChange":true,"imapHost":"127.0.0.1","leakedOnReload":false,"inArimail":true}
|
||||||
- ✔ 초대 방식 메일함(링크 만료·재발송·사용 완료 상태) — {"inviteState":"pending","accepted":200,"reuse":"invite_used"}
|
- ✔ 초대 방식 메일함(링크 만료·재발송·사용 완료 상태) — {"inviteState":"pending","accepted":200,"reuse":"invite_used"}
|
||||||
- ✔ DNS 확인: 미반영/잘못된 값 구분 표시(로컬 DNS 에는 레코드 없음 → missing) — {"ok":false,"missing":3,"items":["mx:missing","spf:missing","dkim:missing","dmarc:recommended"]}
|
- ✔ DNS 확인: 미반영/잘못된 값 구분 표시(로컬 DNS 에는 레코드 없음 → missing) — {"ok":false,"missing":3,"items":["mx:missing","spf:missing","dkim:missing","dmarc:recommended"]}
|
||||||
- ✔ 활성화 작업 → DNS 외부 대기(awaiting_external) · 멱등 — {"status":"awaiting_external","waitReason":"DNS 레코드가 아직 반영되지 않았습니다(누락 3, 잘못된 값 0). 도메인 DNS 에 안내된 값을 넣은 뒤 '이어서 진행' 을 누르세요","sameJob":true,"steps":["entitlement:done","dns:waiting","prepare:pending","verify:pending","activate:pending"]}
|
- ✔ 활성화 작업 → DNS 외부 대기(awaiting_external) · 멱등 — {"status":"awaiting_external","waitReason":"DNS 레코드가 아직 반영되지 않았습니다(누락 3, 잘못된 값 0). 도메인 DNS 에 안내된 값을 넣은 뒤 '이어서 진행' 을 누르세요","sameJob":true,"steps":["entitlement:done","dns:waiting","prepare:pending","verify:pending","activate:pending"]}
|
||||||
@@ -244,7 +244,7 @@
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"svc": {
|
"svc": {
|
||||||
"id": "msv_01a1b001a21edb1db0b90caa39",
|
"id": "msv_01a1b00502c0755b9fe965ba46",
|
||||||
"status": "needs_setup",
|
"status": "needs_setup",
|
||||||
"tenant": true,
|
"tenant": true,
|
||||||
"ariwebKind": "site_bound",
|
"ariwebKind": "site_bound",
|
||||||
@@ -252,7 +252,7 @@
|
|||||||
"siteCountAllocated": 0
|
"siteCountAllocated": 0
|
||||||
},
|
},
|
||||||
"mb": {
|
"mb": {
|
||||||
"id": "mb_01a1b001a23523c0be408a7704",
|
"id": "mb_01a1b00502e82fb99c6a1d925b",
|
||||||
"address": "kim@aw-e2e.localhost",
|
"address": "kim@aw-e2e.localhost",
|
||||||
"passwordShownOnce": "[redacted]",
|
"passwordShownOnce": "[redacted]",
|
||||||
"mustChange": true,
|
"mustChange": true,
|
||||||
@@ -287,13 +287,13 @@
|
|||||||
|
|
||||||
### 12. 독립 메일 서비스 생성
|
### 12. 독립 메일 서비스 생성
|
||||||
|
|
||||||
- ✔ 메일 전용 도메인 등록(solo-e2e.localhost, purpose mail) — {"id":"d_01a1b001c45817fdf71c1fb567","jobCancelled":null}
|
- ✔ 메일 전용 도메인 등록(solo-e2e.localhost, purpose mail) — {"id":"d_01a1b005251eb41041d686f464","jobCancelled":null}
|
||||||
- ✔ 독립 메일 서비스 생성(독립 옵션 소비·사이트 수 미소비) — {"id":"msv_01a1b001c45e9bb2bc1ae08bf6","kind":"standalone","mailServicesAllocated":1,"sitesAllocated":0}
|
- ✔ 독립 메일 서비스 생성(독립 옵션 소비·사이트 수 미소비) — {"id":"msv_01a1b005252540cb9d7cb9ef0b","kind":"standalone","mailServicesAllocated":1,"sitesAllocated":0}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"r": {
|
"r": {
|
||||||
"id": "msv_01a1b001c45e9bb2bc1ae08bf6",
|
"id": "msv_01a1b005252540cb9d7cb9ef0b",
|
||||||
"kind": "standalone",
|
"kind": "standalone",
|
||||||
"mailServicesAllocated": 1,
|
"mailServicesAllocated": 1,
|
||||||
"sitesAllocated": 0
|
"sitesAllocated": 0
|
||||||
@@ -307,8 +307,8 @@
|
|||||||
|
|
||||||
- ✔ 백업 옵션 주문(대상 사이트)·입금 확인·승인 → backup 권리 — {"granted":7,"orderStatus":"approved"}
|
- ✔ 백업 옵션 주문(대상 사이트)·입금 확인·승인 → backup 권리 — {"granted":7,"orderStatus":"approved"}
|
||||||
- ✔ 백업 화면: 구매 가능 여부·저장 한도·일정·보존·첫 백업 기한·검증 방식(상품정책에서) — {"eligible":true,"reasons":[],"deferred":[],"policy":null,"status":200}
|
- ✔ 백업 화면: 구매 가능 여부·저장 한도·일정·보존·첫 백업 기한·검증 방식(상품정책에서) — {"eligible":true,"reasons":[],"deferred":[],"policy":null,"status":200}
|
||||||
- ✔ 옵션 활성화(확인 필수) → 첫 백업 예정 시각 — {"status":"active","firstDue":"2026-11-07T08:37:48.329Z","nextRun":"2026-11-06T08:37:48.329Z"}
|
- ✔ 옵션 활성화(확인 필수) → 첫 백업 예정 시각 — {"status":"active","firstDue":"2026-11-07T08:41:29.707Z","nextRun":"2026-11-06T08:41:29.707Z"}
|
||||||
- ✔ 지금 백업 실행 → HAL backup.create(저장 서버 ≠ 운영 서버) → Agent → 검증 — {"timedOut":false,"optionStatus":"active","lastJob":null,"siteServer":"srv_01a1b000fe3cf87ac50582b199","backup":{"status":"done","tier":"monthly","location":null},"job":null,"optionFailures":0}
|
- ✔ 지금 백업 실행 → HAL backup.create(저장 서버 ≠ 운영 서버) → Agent → 검증 — {"timedOut":false,"optionStatus":"active","lastJob":null,"siteServer":"srv_01a1b0045ea56d81b8cfa4ebd8","backup":{"status":"done","tier":"monthly","location":null},"job":null,"optionFailures":0}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -321,14 +321,14 @@
|
|||||||
},
|
},
|
||||||
"opt": {
|
"opt": {
|
||||||
"status": "active",
|
"status": "active",
|
||||||
"firstDue": "2026-11-07T08:37:48.329Z",
|
"firstDue": "2026-11-07T08:41:29.707Z",
|
||||||
"nextRun": "2026-11-06T08:37:48.329Z"
|
"nextRun": "2026-11-06T08:41:29.707Z"
|
||||||
},
|
},
|
||||||
"run1": {
|
"run1": {
|
||||||
"timedOut": false,
|
"timedOut": false,
|
||||||
"optionStatus": "active",
|
"optionStatus": "active",
|
||||||
"lastJob": null,
|
"lastJob": null,
|
||||||
"siteServer": "srv_01a1b000fe3cf87ac50582b199",
|
"siteServer": "srv_01a1b0045ea56d81b8cfa4ebd8",
|
||||||
"backup": {
|
"backup": {
|
||||||
"status": "done",
|
"status": "done",
|
||||||
"tier": "monthly",
|
"tier": "monthly",
|
||||||
@@ -342,8 +342,8 @@
|
|||||||
|
|
||||||
### 14. 백업 복원과 외부 사이트 확인
|
### 14. 백업 복원과 외부 사이트 확인
|
||||||
|
|
||||||
- ✔ 복원 안내(포함 데이터·영향·보호 시점 유지·되돌릴 수 있는 마지막 시각·완료 방식) — {"backup":{"id":"bk_01a1b001de7311dbc020282a43","createdAt":"2026-11-06T08:37:48.332Z","scope":{"files":true,"db":true,"uploads":true,"config":true,"storeServerId":"srv_01a1b000feeb9e34dab18cf0ad","verifyMethod":"sha256 + 격리 환경 읽기 확인"},"sizeBytes":1893,"verifyState":"verified","expiresAt":"2027-02-0
|
- ✔ 복원 안내(포함 데이터·영향·보호 시점 유지·되돌릴 수 있는 마지막 시각·완료 방식) — {"backup":{"id":"bk_01a1b0053ed9625e728bbaf863","createdAt":"2026-11-06T08:41:29.710Z","scope":{"files":true,"db":true,"uploads":true,"config":true,"storeServerId":"srv_01a1b0045f7689a3ac44add5a3","verifyMethod":"sha256 + 격리 환경 읽기 확인"},"sizeBytes":1896,"verifyState":"verified","expiresAt":"2027-02-0
|
||||||
- ✔ 복원 요청 → 운영자 승인 대기 · 중복 요청 없음 — {"id":"rs_01a1b001e223d31d0a835f0ffc","status":"awaiting_approval","dup":false,"finalConfirmation":{"group":"E2E 팀","site":"E2E 사이트","domain":null}}
|
- ✔ 복원 요청 → 운영자 승인 대기 · 중복 요청 없음 — {"id":"rs_01a1b00542f2daa13dc0dc0605","status":"awaiting_approval","dup":false,"finalConfirmation":{"group":"E2E 팀","site":"E2E 사이트","domain":null}}
|
||||||
- ✔ 운영자 최종 확인(그룹·사이트·백업 시각) 불일치 거부 → 일치 승인(멱등) — {"bad":"final_confirmation_mismatch","ok":400}
|
- ✔ 운영자 최종 확인(그룹·사이트·백업 시각) 불일치 거부 → 일치 승인(멱등) — {"bad":"final_confirmation_mismatch","ok":400}
|
||||||
- ✔ 9단계 작업 진행 → 사용자 확인 필요(보호 시점·되돌리기 가능) — {"steps":[]}
|
- ✔ 9단계 작업 진행 → 사용자 확인 필요(보호 시점·되돌리기 가능) — {"steps":[]}
|
||||||
|
|
||||||
@@ -351,19 +351,19 @@
|
|||||||
{
|
{
|
||||||
"info": {
|
"info": {
|
||||||
"backup": {
|
"backup": {
|
||||||
"id": "bk_01a1b001de7311dbc020282a43",
|
"id": "bk_01a1b0053ed9625e728bbaf863",
|
||||||
"createdAt": "2026-11-06T08:37:48.332Z",
|
"createdAt": "2026-11-06T08:41:29.710Z",
|
||||||
"scope": {
|
"scope": {
|
||||||
"files": true,
|
"files": true,
|
||||||
"db": true,
|
"db": true,
|
||||||
"uploads": true,
|
"uploads": true,
|
||||||
"config": true,
|
"config": true,
|
||||||
"storeServerId": "srv_01a1b000feeb9e34dab18cf0ad",
|
"storeServerId": "srv_01a1b0045f7689a3ac44add5a3",
|
||||||
"verifyMethod": "sha256 + 격리 환경 읽기 확인"
|
"verifyMethod": "sha256 + 격리 환경 읽기 확인"
|
||||||
},
|
},
|
||||||
"sizeBytes": 1893,
|
"sizeBytes": 1896,
|
||||||
"verifyState": "verified",
|
"verifyState": "verified",
|
||||||
"expiresAt": "2027-02-07T08:37:54.932Z",
|
"expiresAt": "2027-02-07T08:41:36.218Z",
|
||||||
"tier": "monthly"
|
"tier": "monthly"
|
||||||
},
|
},
|
||||||
"included": [
|
"included": [
|
||||||
@@ -393,7 +393,7 @@
|
|||||||
"deferred": []
|
"deferred": []
|
||||||
},
|
},
|
||||||
"rq": {
|
"rq": {
|
||||||
"id": "rs_01a1b001e223d31d0a835f0ffc",
|
"id": "rs_01a1b00542f2daa13dc0dc0605",
|
||||||
"status": "awaiting_approval",
|
"status": "awaiting_approval",
|
||||||
"dup": false,
|
"dup": false,
|
||||||
"finalConfirmation": {
|
"finalConfirmation": {
|
||||||
@@ -445,10 +445,10 @@
|
|||||||
|
|
||||||
### 16. 외부 배포 사이트 생성과 배포
|
### 16. 외부 배포 사이트 생성과 배포
|
||||||
|
|
||||||
- ✔ 외부 배포 사이트 생성(초안) + 저장본 — {"id":"s_01a1b002cdb5f0c48a793c5469","group_id":"g_01a1b001050da5f0aac64cb28b","name":"E2E 외부 사이트","purpose":"e2e","webmaker_project_id":"00000000000000000000000000000004","template":null,"lang":"ko","timezone":"Asia/Seoul","lifecycle":"draft","deploy_mode":"external","primary_domain":null,"site_cou
|
- ✔ 외부 배포 사이트 생성(초안) + 저장본 — {"id":"s_01a1b0062e696e228a49d5fe73","group_id":"g_01a1b004656a3fd8bdbc431252","name":"E2E 외부 사이트","purpose":"e2e","webmaker_project_id":"00000000000000000000000000000004","template":null,"lang":"ko","timezone":"Asia/Seoul","lifecycle":"draft","deploy_mode":"external","primary_domain":null,"site_cou
|
||||||
- ✔ 배포 방식 화면: 외부 대상·고객 책임·미제공 기능(메일 미지원)·건별 비용·동의 버전 — {"notProvided":"[redacted]","consentVersion":"external-deploy-2026-10-0.1.1","agreed":false}
|
- ✔ 배포 방식 화면: 외부 대상·고객 책임·미제공 기능(메일 미지원)·건별 비용·동의 버전 — {"notProvided":"[redacted]","consentVersion":"external-deploy-2026-10-0.1.1","agreed":false}
|
||||||
- ✔ 동의 전 Agent 발급 거부(consent_required) → 동의 기록(버전) — {"before":"consent_required","consent":200}
|
- ✔ 동의 전 Agent 발급 거부(consent_required) → 동의 기록(버전) — {"before":"consent_required","consent":200}
|
||||||
- ✔ 외부 Agent 일회용 토큰·설치 명령(토큰은 저장하지 않음) — {"token":"[redacted]","install":"curl -fsSL http://127.0.0.1:46137/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:46137 --token … --external --site s_01a1b002cdb5f0c48a793c5469","expiresAt":"2026-11-06T08:48:56.214Z","status":"pending"}
|
- ✔ 외부 Agent 일회용 토큰·설치 명령(토큰은 저장하지 않음) — {"token":"[redacted]","install":"curl -fsSL http://127.0.0.1:42077/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:42077 --token … --external --site s_01a1b0062e696e228a49d5fe73","expiresAt":"2026-11-06T08:52:37.584Z","status":"pending"}
|
||||||
- ✔ 고객 서버 역할의 외부 Agent 프로세스 등록·실행(HAL 등록, 사이트 귀속) — {"agentId":"[redacted]"}
|
- ✔ 고객 서버 역할의 외부 Agent 프로세스 등록·실행(HAL 등록, 사이트 귀속) — {"agentId":"[redacted]"}
|
||||||
- ✔ 포털 연결 확인(외부 Agent 상태 connected) — {"status":"connected","stale":false,"halAgentId":"[redacted]"}
|
- ✔ 포털 연결 확인(외부 Agent 상태 connected) — {"status":"connected","stale":false,"halAgentId":"[redacted]"}
|
||||||
- ✔ 배포 전 확인(외부: 관리형 용량 확인 없음) — {"ok":true,"blocks":[]}
|
- ✔ 배포 전 확인(외부: 관리형 용량 확인 없음) — {"ok":true,"blocks":[]}
|
||||||
@@ -465,8 +465,8 @@
|
|||||||
"agreed": false
|
"agreed": false
|
||||||
},
|
},
|
||||||
"tok": {
|
"tok": {
|
||||||
"install": "curl -fsSL http://127.0.0.1:46137/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:46137 --token … --external --site s_01a1b002cdb5f0c48a793c5469",
|
"install": "curl -fsSL http://127.0.0.1:42077/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:42077 --token … --external --site s_01a1b0062e696e228a49d5fe73",
|
||||||
"expiresAt": "2026-11-06T08:48:56.214Z"
|
"expiresAt": "2026-11-06T08:52:37.584Z"
|
||||||
},
|
},
|
||||||
"conn": {
|
"conn": {
|
||||||
"status": "connected",
|
"status": "connected",
|
||||||
@@ -554,7 +554,7 @@
|
|||||||
- ✔ 축소 미리보기(팀→베이직): 줄여야 할 항목(메일함 6→5) 구체 표시 — {"shortages":["mailboxes:1"]}
|
- ✔ 축소 미리보기(팀→베이직): 줄여야 할 항목(메일함 6→5) 구체 표시 — {"shortages":["mailboxes:1"]}
|
||||||
- ✔ 축소 요청 → 보류(사용 중 권리 즉시 회수 없음) — {"fits":false,"hold":"holding","sitesStillPurchased":3}
|
- ✔ 축소 요청 → 보류(사용 중 권리 즉시 회수 없음) — {"fits":false,"hold":"holding","sitesStillPurchased":3}
|
||||||
- ✔ 정리: 메일함 배정 6→5 축소 → 재검증 적합 → 축소 주문 생성 — {"allocate":200,"fits":true,"shortages":[],"order":"awaiting_payment"}
|
- ✔ 정리: 메일함 배정 6→5 축소 → 재검증 적합 → 축소 주문 생성 — {"allocate":200,"fits":true,"shortages":[],"order":"awaiting_payment"}
|
||||||
- ✔ 축소 주문 입금 확인·승인 → 권리 교체(베이직) — {"approve":200,"sites":1,"mailboxes":5,"product":"pv_01a1b001033b6c20005814ab9e"}
|
- ✔ 축소 주문 입금 확인·승인 → 권리 교체(베이직) — {"approve":200,"sites":1,"mailboxes":5,"product":"pv_01a1b004639bf7bb78dcc6fcad"}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -589,7 +589,7 @@
|
|||||||
"approve": 200,
|
"approve": 200,
|
||||||
"sites": 1,
|
"sites": 1,
|
||||||
"mailboxes": 5,
|
"mailboxes": 5,
|
||||||
"product": "pv_01a1b001033b6c20005814ab9e"
|
"product": "pv_01a1b004639bf7bb78dcc6fcad"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -623,10 +623,10 @@
|
|||||||
### 20. 사이트 소유권 이전
|
### 20. 사이트 소유권 이전
|
||||||
|
|
||||||
- ✔ 이전 범위 미리보기(사이트·도메인·대표 메일·배정·진행 작업·미납 / 제외 항목) — {"sites":1,"domains":1,"siteMail":1,"needed":{"backup":1,"web_disk":1073741824,"mail_msgs":500,"mail_storage":2147483648,"mailboxes":6},"excluded":3}
|
- ✔ 이전 범위 미리보기(사이트·도메인·대표 메일·배정·진행 작업·미납 / 제외 항목) — {"sites":1,"domains":1,"siteMail":1,"needed":{"backup":1,"web_disk":1073741824,"mail_msgs":500,"mail_storage":2147483648,"mailboxes":6},"excluded":3}
|
||||||
- ✔ 요청(보내는 그룹, 초안 사이트) → 받는 사용자 알림 — {"id":"tr_01a1b002ef104ca1036d3185cd","status":"requested","expiresAt":"2026-11-13T08:39:04.720Z","bobNotified":true}
|
- ✔ 요청(보내는 그룹, 초안 사이트) → 받는 사용자 알림 — {"id":"tr_01a1b0064f9fe7ba31d9dbdbd2","status":"requested","expiresAt":"2026-11-13T08:42:46.047Z","bobNotified":true}
|
||||||
- ✔ (정리) 받는 쪽 권리에 맞게 범위 조정: 백업 옵션 종료·메일함 배정 6→5(받는 그룹 베이직 5개) — {"endBackup":200,"alloc":200}
|
- ✔ (정리) 받는 쪽 권리에 맞게 범위 조정: 백업 옵션 종료·메일함 배정 6→5(받는 그룹 베이직 5개) — {"endBackup":200,"alloc":200}
|
||||||
- ✔ 받는 그룹 수락 → 권리 부족이면 보류(필요한 상품 안내) — {"status":200,"tstatus":"reviewing","hold":null}
|
- ✔ 받는 그룹 수락 → 권리 부족이면 보류(필요한 상품 안내) — {"status":200,"tstatus":"reviewing","hold":null}
|
||||||
- ✔ 운영자 심사(소유 증빙·도메인 확인) 미입력 거부 → 최종 확인 일치 승인 → 원자적 완료·청구 전환 시각 — {"bad":"final_confirmation_mismatch","ok":200,"status":"completed","cutover":"2026-11-06T08:39:04.745Z"}
|
- ✔ 운영자 심사(소유 증빙·도메인 확인) 미입력 거부 → 최종 확인 일치 승인 → 원자적 완료·청구 전환 시각 — {"bad":"final_confirmation_mismatch","ok":200,"status":"completed","cutover":"2026-11-06T08:42:46.076Z"}
|
||||||
- ✔ 완료 뒤: 보내는 쪽은 접근 불가(404), 받는 쪽 대시보드·사용량 일치, 불변 감사 — {"aliceSees":404,"bobSees":200,"bobUsageSites":0,"audit":true}
|
- ✔ 완료 뒤: 보내는 쪽은 접근 불가(404), 받는 쪽 대시보드·사용량 일치, 불변 감사 — {"aliceSees":404,"bobSees":200,"bobUsageSites":0,"audit":true}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -645,9 +645,9 @@
|
|||||||
"excluded": 3
|
"excluded": 3
|
||||||
},
|
},
|
||||||
"rq": {
|
"rq": {
|
||||||
"id": "tr_01a1b002ef104ca1036d3185cd",
|
"id": "tr_01a1b0064f9fe7ba31d9dbdbd2",
|
||||||
"status": "requested",
|
"status": "requested",
|
||||||
"expiresAt": "2026-11-13T08:39:04.720Z",
|
"expiresAt": "2026-11-13T08:42:46.047Z",
|
||||||
"bobNotified": true
|
"bobNotified": true
|
||||||
},
|
},
|
||||||
"acc": {
|
"acc": {
|
||||||
@@ -659,7 +659,7 @@
|
|||||||
"bad": "final_confirmation_mismatch",
|
"bad": "final_confirmation_mismatch",
|
||||||
"ok": 200,
|
"ok": 200,
|
||||||
"status": "completed",
|
"status": "completed",
|
||||||
"cutover": "2026-11-06T08:39:04.745Z"
|
"cutover": "2026-11-06T08:42:46.076Z"
|
||||||
},
|
},
|
||||||
"after": {
|
"after": {
|
||||||
"aliceSees": 404,
|
"aliceSees": 404,
|
||||||
@@ -745,7 +745,7 @@
|
|||||||
|
|
||||||
### 23. 실패 작업의 재시도와 되돌리기
|
### 23. 실패 작업의 재시도와 되돌리기
|
||||||
|
|
||||||
- ✔ 배포 이력: 실패/성공 기록 · 재시도 가능 여부 · 문의용 작업 번호 — {"status":"done","canRetry":false,"jobId":"j_01a1b00105ee38a83dc81ee219"}
|
- ✔ 배포 이력: 실패/성공 기록 · 재시도 가능 여부 · 문의용 작업 번호 — {"status":"done","canRetry":false,"jobId":"j_01a1b004666d3964ce5450810c"}
|
||||||
- ✔ 재시도 요청(POST /api/sites/:id/jobs/:jobId/retry) — {"status":400,"error":"job_not_retryable"}
|
- ✔ 재시도 요청(POST /api/sites/:id/jobs/:jobId/retry) — {"status":400,"error":"job_not_retryable"}
|
||||||
- ✔ 되돌리기 요청(POST /api/sites/:id/rollback) — 이전 버전 없으면 거부 — {"status":409,"error":"no_previous","message":"되돌릴 이전 버전이 없습니다"}
|
- ✔ 되돌리기 요청(POST /api/sites/:id/rollback) — 이전 버전 없으면 거부 — {"status":409,"error":"no_previous","message":"되돌릴 이전 버전이 없습니다"}
|
||||||
|
|
||||||
@@ -754,7 +754,7 @@
|
|||||||
"dep": {
|
"dep": {
|
||||||
"status": "done",
|
"status": "done",
|
||||||
"canRetry": false,
|
"canRetry": false,
|
||||||
"jobId": "j_01a1b00105ee38a83dc81ee219"
|
"jobId": "j_01a1b004666d3964ce5450810c"
|
||||||
},
|
},
|
||||||
"rt": {
|
"rt": {
|
||||||
"status": 400,
|
"status": 400,
|
||||||
@@ -770,16 +770,16 @@
|
|||||||
|
|
||||||
### 24. 운영자 승인, 감사 기록, 고객 알림의 일치
|
### 24. 운영자 승인, 감사 기록, 고객 알림의 일치
|
||||||
|
|
||||||
- ✔ 고객 알림 센터에 승인 알림 — {"title":"주문 AW-20261106-0001 승인 — 권리가 활성화되었습니다","category":"billing","link":"/orders/o_01a1b001056b3235366163b734"}
|
- ✔ 고객 알림 센터에 승인 알림 — {"title":"주문 AW-20261106-0001 승인 — 권리가 활성화되었습니다","category":"billing","link":"/orders/o_01a1b00465dbbb0e3b6e62dbd4"}
|
||||||
- ✔ 감사 기록: order.approve 는 삭제 불가(immutable) — {"action":"order.approve","immutable":true}
|
- ✔ 감사 기록: order.approve 는 삭제 불가(immutable) — {"action":"order.approve","immutable":true}
|
||||||
- ✔ 운영자 화면과 고객 주문 화면의 상태 일치 — {"status":"approved","approvedAt":"2026-11-06T08:36:59.420Z"}
|
- ✔ 운영자 화면과 고객 주문 화면의 상태 일치 — {"status":"approved","approvedAt":"2026-11-06T08:40:40.718Z"}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"n": {
|
"n": {
|
||||||
"title": "주문 AW-20261106-0001 승인 — 권리가 활성화되었습니다",
|
"title": "주문 AW-20261106-0001 승인 — 권리가 활성화되었습니다",
|
||||||
"category": "billing",
|
"category": "billing",
|
||||||
"link": "/orders/o_01a1b001056b3235366163b734"
|
"link": "/orders/o_01a1b00465dbbb0e3b6e62dbd4"
|
||||||
},
|
},
|
||||||
"a": {
|
"a": {
|
||||||
"action": "order.approve",
|
"action": "order.approve",
|
||||||
@@ -787,7 +787,7 @@
|
|||||||
},
|
},
|
||||||
"same": {
|
"same": {
|
||||||
"status": "approved",
|
"status": "approved",
|
||||||
"approvedAt": "2026-11-06T08:36:59.420Z"
|
"approvedAt": "2026-11-06T08:40:40.718Z"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -795,7 +795,7 @@
|
|||||||
### 25. HAL, 로그인, 비밀정보 관리, 인증서 기반의 재해복구 훈련
|
### 25. HAL, 로그인, 비밀정보 관리, 인증서 기반의 재해복구 훈련
|
||||||
|
|
||||||
- ✔ 설정 전 준비 상태(미설정 항목) — {"ready":false,"missingConfig":["rto_minutes","rpo_minutes","snapshot_interval_minutes","retention_count"],"lastDrill":null,"lastSnapshot":null,"config":{"rto_minutes":null,"rpo_minutes":null,"snapshot_interval_minutes":null,"retention_count":null,"external_store":null},"label":"정식 운영 준비 전(복구 훈련 또는
|
- ✔ 설정 전 준비 상태(미설정 항목) — {"ready":false,"missingConfig":["rto_minutes","rpo_minutes","snapshot_interval_minutes","retention_count"],"lastDrill":null,"lastSnapshot":null,"config":{"rto_minutes":null,"rpo_minutes":null,"snapshot_interval_minutes":null,"retention_count":null,"external_store":null},"label":"정식 운영 준비 전(복구 훈련 또는
|
||||||
- ✔ RTO·RPO·사본 주기·보존 개수·외부 보관 위치 설정 — {"id":1,"rto_minutes":60,"rpo_minutes":30,"snapshot_interval_minutes":60,"retention_count":3,"external_store":"/home/master/work/Ariweb-suite/test/.tmp/e2e-20261106083656/dr-external","updated_at":"2026-11-06T08:39:12.885Z","updated_by":"op_01a1b000fd55691854cd6d073f"}
|
- ✔ RTO·RPO·사본 주기·보존 개수·외부 보관 위치 설정 — {"id":1,"rto_minutes":60,"rpo_minutes":30,"snapshot_interval_minutes":60,"retention_count":3,"external_store":"/home/master/work/Ariweb-suite/test/.tmp/e2e-20261106084037/dr-external","updated_at":"2026-11-06T08:42:54.251Z","updated_by":"op_01a1b0045ddd88b602a5012e9a"}
|
||||||
- ✔ 복구 사본 생성·검증·외부 보관(vault.key 제외) — {"verify":"ok","external":true,"sha":true}
|
- ✔ 복구 사본 생성·검증·외부 보관(vault.key 제외) — {"verify":"ok","external":true,"sha":true}
|
||||||
- ✔ 복원 요청 → 승인 전 시작 거부 → 승인 → 기존 제어 중지 확인 없이는 거부 → 시작(명령 안내) → 확인 항목 부족 거부 → 완료 — {"early":"restore_not_approved","noStop":"old_control_not_confirmed","command":true,"incomplete":"checks_incomplete","final":"completed"}
|
- ✔ 복원 요청 → 승인 전 시작 거부 → 승인 → 기존 제어 중지 확인 없이는 거부 → 시작(명령 안내) → 확인 항목 부족 거부 → 완료 — {"early":"restore_not_approved","noStop":"old_control_not_confirmed","command":true,"incomplete":"checks_incomplete","final":"completed"}
|
||||||
- ✔ 복구 훈련: 항목 하나 실패 → failed, 모두 성공·측정 RTO/RPO → 준비 완료 — {"first":"failed","second":"success","ready":true,"measured":{}}
|
- ✔ 복구 훈련: 항목 하나 실패 → failed, 모두 성공·측정 RTO/RPO → 준비 완료 — {"first":"failed","second":"success","ready":true,"measured":{}}
|
||||||
@@ -827,9 +827,9 @@
|
|||||||
"rpo_minutes": 30,
|
"rpo_minutes": 30,
|
||||||
"snapshot_interval_minutes": 60,
|
"snapshot_interval_minutes": 60,
|
||||||
"retention_count": 3,
|
"retention_count": 3,
|
||||||
"external_store": "/home/master/work/Ariweb-suite/test/.tmp/e2e-20261106083656/dr-external",
|
"external_store": "/home/master/work/Ariweb-suite/test/.tmp/e2e-20261106084037/dr-external",
|
||||||
"updated_at": "2026-11-06T08:39:12.885Z",
|
"updated_at": "2026-11-06T08:42:54.251Z",
|
||||||
"updated_by": "op_01a1b000fd55691854cd6d073f"
|
"updated_by": "op_01a1b0045ddd88b602a5012e9a"
|
||||||
},
|
},
|
||||||
"snap": {
|
"snap": {
|
||||||
"verify": "ok",
|
"verify": "ok",
|
||||||
@@ -854,15 +854,15 @@
|
|||||||
|
|
||||||
### 26. 새로 고침, 재로그인, HAL 재시작 후 진행 작업 상태 유지
|
### 26. 새로 고침, 재로그인, HAL 재시작 후 진행 작업 상태 유지
|
||||||
|
|
||||||
- ✔ 재시작 전: 포털 진행 작업(메일 활성화 외부 대기)·HAL 작업 목록 — {"mailJob":{"id":"j_01a1b001b25ba4cb9489fd0cfe","status":"awaiting_external"},"halJobs":19}
|
- ✔ 재시작 전: 포털 진행 작업(메일 활성화 외부 대기)·HAL 작업 목록 — {"mailJob":{"id":"j_01a1b00513188ba0a43d6875f9","status":"awaiting_external"},"halJobs":19}
|
||||||
- ✔ 포털 재시작 → 재로그인 없이 세션 유지·같은 작업 id·상태 유지 — {"sessionKept":"[redacted]","mailJob":{"id":"j_01a1b001b25ba4cb9489fd0cfe","status":"awaiting_external"},"same":true}
|
- ✔ 포털 재시작 → 재로그인 없이 세션 유지·같은 작업 id·상태 유지 — {"sessionKept":"[redacted]","mailJob":{"id":"j_01a1b00513188ba0a43d6875f9","status":"awaiting_external"},"same":true}
|
||||||
- ✔ HAL 재시작 → 운영자 세션·작업 목록·서버 등록 유지 — {"opsSessionKept":"[redacted]","halJobs":19,"sameCount":true}
|
- ✔ HAL 재시작 → 운영자 세션·작업 목록·서버 등록 유지 — {"opsSessionKept":"[redacted]","halJobs":19,"sameCount":true}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"before": {
|
"before": {
|
||||||
"mailJob": {
|
"mailJob": {
|
||||||
"id": "j_01a1b001b25ba4cb9489fd0cfe",
|
"id": "j_01a1b00513188ba0a43d6875f9",
|
||||||
"status": "awaiting_external"
|
"status": "awaiting_external"
|
||||||
},
|
},
|
||||||
"halJobs": 19
|
"halJobs": 19
|
||||||
@@ -870,7 +870,7 @@
|
|||||||
"pr": {
|
"pr": {
|
||||||
"sessionKept": "[redacted]",
|
"sessionKept": "[redacted]",
|
||||||
"mailJob": {
|
"mailJob": {
|
||||||
"id": "j_01a1b001b25ba4cb9489fd0cfe",
|
"id": "j_01a1b00513188ba0a43d6875f9",
|
||||||
"status": "awaiting_external"
|
"status": "awaiting_external"
|
||||||
},
|
},
|
||||||
"same": true
|
"same": true
|
||||||
@@ -886,7 +886,7 @@
|
|||||||
### 27. 마지막 사이트 수·용량·메일함 동시 요청 시 하나만 성공
|
### 27. 마지막 사이트 수·용량·메일함 동시 요청 시 하나만 성공
|
||||||
|
|
||||||
- ✔ 밥 개인 그룹: 베이직(사이트 1) 주문·승인 — {"granted":6}
|
- ✔ 밥 개인 그룹: 베이직(사이트 1) 주문·승인 — {"granted":6}
|
||||||
- ✔ 사이트 2개 생성·저장본 — [{"id":"s_01a1b0019643bfa4d94d352071","group_id":"g_01a1b001053169a7ba81639ba6","name":"동시 A","purpose":"e2e","webmaker_project_id":"00000000000000000000000000000002","template":null,"lang":"ko","timezone":"Asia/Seoul","lifecycle":"draft","deploy_mode":"managed","primary_domain":null,"site_count_sta
|
- ✔ 사이트 2개 생성·저장본 — [{"id":"s_01a1b004f6d16fb55a118684f7","group_id":"g_01a1b004658f4107f66903cf3c","name":"동시 A","purpose":"e2e","webmaker_project_id":"00000000000000000000000000000002","template":null,"lang":"ko","timezone":"Asia/Seoul","lifecycle":"draft","deploy_mode":"managed","primary_domain":null,"site_count_sta
|
||||||
- ✔ 두 사이트 동시 최초 배포 요청 → 하나만 200, 다른 쪽 409 precheck_failed(sites 부족) — {"ok":1,"blocked":"precheck_failed","shortage":"block"}
|
- ✔ 두 사이트 동시 최초 배포 요청 → 하나만 200, 다른 쪽 409 precheck_failed(sites 부족) — {"ok":1,"blocked":"precheck_failed","shortage":"block"}
|
||||||
- ✔ (정리) 선행 결함으로 영원히 진행 중인 배포 취소·예약 반환 — {"cancel":200,"cleanup":200,"unallocated":0}
|
- ✔ (정리) 선행 결함으로 영원히 진행 중인 배포 취소·예약 반환 — {"cancel":200,"cleanup":200,"unallocated":0}
|
||||||
|
|
||||||
@@ -902,10 +902,10 @@
|
|||||||
|
|
||||||
### 28. 외부 Linux 서버 Agent 연결·배포·재배포·제거·실패 정리
|
### 28. 외부 Linux 서버 Agent 연결·배포·재배포·제거·실패 정리
|
||||||
|
|
||||||
- ✔ 외부 배포 사이트 생성(초안) + 저장본 — {"id":"s_01a1b002cdb5f0c48a793c5469","group_id":"g_01a1b001050da5f0aac64cb28b","name":"E2E 외부 사이트","purpose":"e2e","webmaker_project_id":"00000000000000000000000000000004","template":null,"lang":"ko","timezone":"Asia/Seoul","lifecycle":"draft","deploy_mode":"external","primary_domain":null,"site_cou
|
- ✔ 외부 배포 사이트 생성(초안) + 저장본 — {"id":"s_01a1b0062e696e228a49d5fe73","group_id":"g_01a1b004656a3fd8bdbc431252","name":"E2E 외부 사이트","purpose":"e2e","webmaker_project_id":"00000000000000000000000000000004","template":null,"lang":"ko","timezone":"Asia/Seoul","lifecycle":"draft","deploy_mode":"external","primary_domain":null,"site_cou
|
||||||
- ✔ 배포 방식 화면: 외부 대상·고객 책임·미제공 기능(메일 미지원)·건별 비용·동의 버전 — {"notProvided":"[redacted]","consentVersion":"external-deploy-2026-10-0.1.1","agreed":false}
|
- ✔ 배포 방식 화면: 외부 대상·고객 책임·미제공 기능(메일 미지원)·건별 비용·동의 버전 — {"notProvided":"[redacted]","consentVersion":"external-deploy-2026-10-0.1.1","agreed":false}
|
||||||
- ✔ 동의 전 Agent 발급 거부(consent_required) → 동의 기록(버전) — {"before":"consent_required","consent":200}
|
- ✔ 동의 전 Agent 발급 거부(consent_required) → 동의 기록(버전) — {"before":"consent_required","consent":200}
|
||||||
- ✔ 외부 Agent 일회용 토큰·설치 명령(토큰은 저장하지 않음) — {"token":"[redacted]","install":"curl -fsSL http://127.0.0.1:46137/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:46137 --token … --external --site s_01a1b002cdb5f0c48a793c5469","expiresAt":"2026-11-06T08:48:56.214Z","status":"pending"}
|
- ✔ 외부 Agent 일회용 토큰·설치 명령(토큰은 저장하지 않음) — {"token":"[redacted]","install":"curl -fsSL http://127.0.0.1:42077/agent/v1/install.sh | bash -s -- --hal http://127.0.0.1:42077 --token … --external --site s_01a1b0062e696e228a49d5fe73","expiresAt":"2026-11-06T08:52:37.584Z","status":"pending"}
|
||||||
- ✔ 고객 서버 역할의 외부 Agent 프로세스 등록·실행(HAL 등록, 사이트 귀속) — {"agentId":"[redacted]"}
|
- ✔ 고객 서버 역할의 외부 Agent 프로세스 등록·실행(HAL 등록, 사이트 귀속) — {"agentId":"[redacted]"}
|
||||||
- ✔ 포털 연결 확인(외부 Agent 상태 connected) — {"status":"connected","stale":false,"halAgentId":"[redacted]"}
|
- ✔ 포털 연결 확인(외부 Agent 상태 connected) — {"status":"connected","stale":false,"halAgentId":"[redacted]"}
|
||||||
- ✔ 배포 전 확인(외부: 관리형 용량 확인 없음) — {"ok":true,"blocks":[]}
|
- ✔ 배포 전 확인(외부: 관리형 용량 확인 없음) — {"ok":true,"blocks":[]}
|
||||||
@@ -986,7 +986,7 @@
|
|||||||
|
|
||||||
### 30. 모듈 업데이트, 일부 서버 실패, 대상별 되돌리기와 상태 조정
|
### 30. 모듈 업데이트, 일부 서버 실패, 대상별 되돌리기와 상태 조정
|
||||||
|
|
||||||
- ✔ agent 모듈을 두 서버 + 없는 서버에 배포 → 대상별 자식 작업·일부 실패를 성공으로 묶지 않음(partial/all_failed) — {"status":"failed","errorCode":"partial_failure","overall":"partial","children":["srv_missing_e2e:failed:서버가 없습니다","srv_01a1b000feeb9e34dab18cf0ad:done:","srv_01a1b000fe3cf87ac50582b199:done:"],"timedOut":false}
|
- ✔ agent 모듈을 두 서버 + 없는 서버에 배포 → 대상별 자식 작업·일부 실패를 성공으로 묶지 않음(partial/all_failed) — {"status":"failed","errorCode":"partial_failure","overall":"partial","children":["srv_01a1b0045f7689a3ac44add5a3:done:","srv_missing_e2e:failed:서버가 없습니다","srv_01a1b0045ea56d81b8cfa4ebd8:done:"],"timedOut":false}
|
||||||
- ✔ 모듈 건강 확인 작업·목표/실제 버전 차이(drift) 표시·다시 맞추기 작업 — {"health":"done","drift":1,"reconcile":200,"overviewComponents":["HAL:ok","portal:ok","webmaker:ok","arimail:unknown","backup:ok","hawkeye:ok"]}
|
- ✔ 모듈 건강 확인 작업·목표/실제 버전 차이(drift) 표시·다시 맞추기 작업 — {"health":"done","drift":1,"reconcile":200,"overviewComponents":["HAL:ok","portal:ok","webmaker:ok","arimail:unknown","backup:ok","hawkeye:ok"]}
|
||||||
- ✔ 되돌리기는 3단계 확인(영향 범위·식별정보·최종 실행) 없이는 거부 — {"step1":"confirm_impact_required","step2":"identifiers_mismatch"}
|
- ✔ 되돌리기는 3단계 확인(영향 범위·식별정보·최종 실행) 없이는 거부 — {"step1":"confirm_impact_required","step2":"identifiers_mismatch"}
|
||||||
|
|
||||||
@@ -997,9 +997,9 @@
|
|||||||
"errorCode": "partial_failure",
|
"errorCode": "partial_failure",
|
||||||
"overall": "partial",
|
"overall": "partial",
|
||||||
"children": [
|
"children": [
|
||||||
|
"srv_01a1b0045f7689a3ac44add5a3:done:",
|
||||||
"srv_missing_e2e:failed:서버가 없습니다",
|
"srv_missing_e2e:failed:서버가 없습니다",
|
||||||
"srv_01a1b000feeb9e34dab18cf0ad:done:",
|
"srv_01a1b0045ea56d81b8cfa4ebd8:done:"
|
||||||
"srv_01a1b000fe3cf87ac50582b199:done:"
|
|
||||||
],
|
],
|
||||||
"timedOut": false
|
"timedOut": false
|
||||||
},
|
},
|
||||||
@@ -1026,21 +1026,21 @@
|
|||||||
### 31. 긴급 복구의 승인 부족·만료 자격·허용 범위 밖 작업 거부와 정상 복구
|
### 31. 긴급 복구의 승인 부족·만료 자격·허용 범위 밖 작업 거부와 정상 복구
|
||||||
|
|
||||||
- ✔ HAL 정상 상태에서 선언 거부(hal_healthy) — hal_healthy
|
- ✔ HAL 정상 상태에서 선언 거부(hal_healthy) — hal_healthy
|
||||||
- ✔ critical 사건 등록 → 선언 → 승인 부족 자격 거부 → 3단계(순서·식별정보·문구) 거부/승인 → 자격 발급(1회) — {"id":"em_01a1b0030f3fad74ec4433ce4c","noCred":"approvals_insufficient","wrongStep":"wrong_step","badIds":"identifiers_mismatch","badText":"final_confirm_mismatch","approved":"approved","approvals":3,"credential":"[redacted]","expiresAt":"2026-11-06T09:09:12.972Z"}
|
- ✔ critical 사건 등록 → 선언 → 승인 부족 자격 거부 → 3단계(순서·식별정보·문구) 거부/승인 → 자격 발급(1회) — {"id":"em_01a1b00670143d9f75bc136275","noCred":"approvals_insufficient","wrongStep":"wrong_step","badIds":"identifiers_mismatch","badText":"final_confirm_mismatch","approved":"approved","approvals":3,"credential":"[redacted]","expiresAt":"2026-11-06T09:12:54.370Z"}
|
||||||
- ✔ 일반 배포(module.deploy) 거부 · 범위 밖 거부 · 잘못된 자격 거부 · 허용 행동 수행 · 확인 뒤 자격 폐기 · 폐기 뒤 거부 · 조정 · 종료 — {"forbidden":"action_forbidden","outOfScope":"out_of_scope","badCred":"bad_credential","performed":400,"revoked":true,"afterRevoke":"credential_revoked","reconcile":200,"closed":"closed"}
|
- ✔ 일반 배포(module.deploy) 거부 · 범위 밖 거부 · 잘못된 자격 거부 · 허용 행동 수행 · 확인 뒤 자격 폐기 · 폐기 뒤 거부 · 조정 · 종료 — {"forbidden":"action_forbidden","outOfScope":"out_of_scope","badCred":"bad_credential","performed":400,"revoked":true,"afterRevoke":"credential_revoked","reconcile":200,"closed":"closed"}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"healthy": "hal_healthy",
|
"healthy": "hal_healthy",
|
||||||
"sess": {
|
"sess": {
|
||||||
"id": "em_01a1b0030f3fad74ec4433ce4c",
|
"id": "em_01a1b00670143d9f75bc136275",
|
||||||
"noCred": "approvals_insufficient",
|
"noCred": "approvals_insufficient",
|
||||||
"wrongStep": "wrong_step",
|
"wrongStep": "wrong_step",
|
||||||
"badIds": "identifiers_mismatch",
|
"badIds": "identifiers_mismatch",
|
||||||
"badText": "final_confirm_mismatch",
|
"badText": "final_confirm_mismatch",
|
||||||
"approved": "approved",
|
"approved": "approved",
|
||||||
"approvals": 3,
|
"approvals": 3,
|
||||||
"expiresAt": "2026-11-06T09:09:12.972Z"
|
"expiresAt": "2026-11-06T09:12:54.370Z"
|
||||||
},
|
},
|
||||||
"perf": {
|
"perf": {
|
||||||
"forbidden": "action_forbidden",
|
"forbidden": "action_forbidden",
|
||||||
@@ -1060,7 +1060,7 @@
|
|||||||
- ✔ Source 옵션 주문(대상 사이트)·승인 → source 권리 — {"granted":7}
|
- ✔ Source 옵션 주문(대상 사이트)·승인 → source 권리 — {"granted":7}
|
||||||
- ✔ Source 옵션 활성화(권리 안에서) → 저장소·브랜치·변경 이력·clone 정보 — {"activate":200,"status":"active","provider":"gitea","changes":1,"clone":true}
|
- ✔ Source 옵션 활성화(권리 안에서) → 저장소·브랜치·변경 이력·clone 정보 — {"activate":200,"status":"active","provider":"gitea","changes":1,"clone":true}
|
||||||
- ✔ export(저장본 내려받기) — {"status":200,"type":"application/gzip"}
|
- ✔ export(저장본 내려받기) — {"status":200,"type":"application/gzip"}
|
||||||
- ✔ 옵션 해제 → 30일 읽기 전용(만료일·삭제 예정일·재활성화 안내) · push 차단 — {"status":"readonly","deleteAfter":"2026-12-06T08:39:04.688Z","readonlyUntil":"2026-12-06T08:39:04.688Z"}
|
- ✔ 옵션 해제 → 30일 읽기 전용(만료일·삭제 예정일·재활성화 안내) · push 차단 — {"status":"readonly","deleteAfter":"2026-12-06T08:42:46.007Z","readonlyUntil":"2026-12-06T08:42:46.007Z"}
|
||||||
- ✔ 삭제 정리 작업(sweep)은 삭제 예정일 전이면 지우지 않음 — {"sweep":200,"statusAfter":"readonly"}
|
- ✔ 삭제 정리 작업(sweep)은 삭제 예정일 전이면 지우지 않음 — {"sweep":200,"statusAfter":"readonly"}
|
||||||
|
|
||||||
```json
|
```json
|
||||||
@@ -1078,8 +1078,8 @@
|
|||||||
},
|
},
|
||||||
"un": {
|
"un": {
|
||||||
"status": "readonly",
|
"status": "readonly",
|
||||||
"deleteAfter": "2026-12-06T08:39:04.688Z",
|
"deleteAfter": "2026-12-06T08:42:46.007Z",
|
||||||
"readonlyUntil": "2026-12-06T08:39:04.688Z"
|
"readonlyUntil": "2026-12-06T08:42:46.007Z"
|
||||||
},
|
},
|
||||||
"sweep": {
|
"sweep": {
|
||||||
"sweep": 200,
|
"sweep": 200,
|
||||||
|
|||||||
Reference in New Issue
Block a user