# IKEv2 Shop Sync Healthcheck Runbook (코드 기반 대응)

## 목적
- VPN ↔ Shop 동기화 파이프라인 검증 결과를 `code` 기준으로 빠르게 판정하고 복구한다.
- 대상:
  - `IKEv2SellerOffice4U/Crons/cron_shop_sync_healthcheck.php`
  - `mylib/ikev2_shop_sync_event_receiver.php`

---

## 1) 빠른 실행
### 기본 점검
- `php IKEv2SellerOffice4U/Crons/cron_shop_sync_healthcheck.php --json`

### 주문 이력 반영 포함 점검
- `php IKEv2SellerOffice4U/Crons/cron_shop_sync_healthcheck.php --od-id="{주문번호}" --json`

### 최근 코드 분포 집계 (권장)
- `php IKEv2SellerOffice4U/Crons/cron_shop_sync_code_summary.php --limit=100 --json`
- 필터 예시: `--user-id="{user_id}"`, `--od-id="{od_id}"`, `--code="S_ACCEPTED"`

### 성공 기준
- 최상위 `ok: true`
- 최상위 `code: "S_OK"`
- `first.response.code: "S_ACCEPTED"`
- `duplicate.response.code: "S_DUPLICATE_IGNORED"` (중복검사 미사용 시 제외)
- `checks.order_history.match: true` (od-id 지정 시)

---

## 2) 코드 체계
- `S_*` : 성공(success)
- `I_*` : 정보(info)
- `W_*` : 경고(warning)
- `E_*` : 오류(error)

---

## 3) Healthcheck 코드별 조치
| 코드 | 의미 | 1차 조치 | 2차 조치 |
|---|---|---|---|
| `S_OK` | 전체 점검 통과 | 기록만 남김 | 정기 점검 유지 |
| `E_CFG_ENDPOINT` | 엔드포인트 미설정 | `.env`의 `IKEV2_SHOP_SYNC_ENDPOINT` 설정 | `config.php` env 로드 확인 |
| `E_DELIVERY_FIRST` | 첫 전송 실패 | 수신 URL 접근/방화벽 확인 | 수신 로그 및 웹서버 에러로그 점검 |
| `E_IDEMPOTENCY_DUPLICATE` | 중복방지 실패 | 수신부 `event_id` dedupe 파일 확인 | `data/ikev2_shop_sync_seen.json` 권한/쓰기 점검 |
| `W_INBOUND_LOG_MISSING` | 인바운드 로그 미탐지 | `data/ikev2_shop_sync_inbound.jsonl` 경로/권한 확인 | 디스크 용량/락 경합 점검 |
| `S_HISTORY_UPDATED` | 주문이력 반영 성공 | 기록만 남김 | - |
| `I_HISTORY_NOT_REQUESTED` | `od-id` 미지정 점검 | 필요시 `--od-id`로 재실행 | - |
| `E_HISTORY_ORDER_NOT_FOUND` | 주문번호 미존재 | 주문번호 오타/환경(DB) 확인 | 운영 DB와 테스트 DB 혼선 확인 |
| `E_HISTORY_UPDATE_FAILED` | 주문이력 UPDATE 실패 | DB 권한/락 상태 확인 | SQL 오류로그 확인 |
| `E_HISTORY_SQL_API` | SQL API 미로딩 | 그누보드 부트스트랩 확인 | `_common.php` 로딩 경로/작업디렉터리 확인 |
| `E_HISTORY_G5` | `$g5` 컨텍스트 미존재 | 그누보드 초기화 확인 | include 순서 재점검 |
| `E_HISTORY_ORDER_TABLE` | 주문 테이블 식별 실패 | `$g5['g5_shop_order_table']` 확인 | dbconfig/테이블 prefix 점검 |
| `E_HISTORY_OD_EMPTY` | 주문번호 누락 | `--od-id` 전달 확인 | 호출부 payload 검증 |
| `E_HISTORY_REFLECTION_MISSING` | 반영상태 응답 누락 | 수신부 최신 배포 여부 확인 | 캐시/배포 경로 불일치 점검 |
| `E_HISTORY_UNKNOWN` | 미정의 반영 실패 | 수신부 raw response 확인 | 코드맵 업데이트 |

---

## 4) Receiver API 코드별 조치
| 코드 | 위치 | 의미 | 조치 |
|---|---|---|---|
| `S_ACCEPTED` | receiver POST 응답 | 정상 수신 | 후속 점검 계속 |
| `S_DUPLICATE_IGNORED` | receiver POST 응답 | 동일 이벤트 무시 | 정상 동작 |
| `E_METHOD_NOT_ALLOWED` | receiver 응답 | POST 아님 | 호출 메서드 수정 |
| `E_BODY_EMPTY` | receiver 응답 | 빈 body | 전송 payload 확인 |
| `E_SIG_MISSING` | receiver 응답 | 서명 없음 | `X-VPN-Sync-Signature` 추가 |
| `E_SIG_INVALID` | receiver 응답 | 서명 불일치 | 양쪽 secret 일치 점검 |
| `E_JSON_INVALID` | receiver 응답 | JSON 파싱 실패 | content-type/body 인코딩 점검 |
| `E_FIELDS_REQUIRED` | receiver 응답 | 필수 필드 누락 | `event_id/event_type/user_id` 확인 |
| `E_HISTORY_TOKEN` | history 조회 응답 | 토큰 오류 | `token` 파라미터 재확인 |

---

## 5) 장애 대응 순서 (권장)
1. `code`의 `E_*` 존재 여부부터 확인
2. `first.response.code` → `duplicate.response.code` 순으로 전송/중복부터 복구
3. 전송 성공 후 `order_history_reflection.code` 복구
4. 마지막으로 `W_*` 정리(로그 파일/권한/디스크)

---

## 6) 운영 기록 템플릿
| 시각(KST) | 실행옵션 | primary code | errors | warnings | 조치 | 결과 |
|---|---|---|---|---|---|---|
|  |  |  |  |  |  |  |

### 코드 분포 기록 템플릿
| 시각(KST) | 구간(최근 N건) | 최다 code | 비율 | 최다 history_code | 비고 |
|---|---|---|---|---|---|
|  |  |  |  |  |  |

---

## 참고 파일
- `IKEv2SellerOffice4U/Crons/cron_shop_sync_healthcheck.php`
- `IKEv2SellerOffice4U/Crons/cron_shop_sync_code_summary.php`
- `mylib/ikev2_shop_sync_event_receiver.php`
- `data/ikev2_shop_sync_inbound.jsonl`
- `data/ikev2_shop_sync_seen.json`
- `ikev2_shop_to_vpn_backend_action_request_spec.md`
