# IKEv2 Seller UI Hotfix Runbook (만료/과금표시)

## 목적
- `IKEv2SellerOffice4U/vpn_users.php`에서 발생 가능한 표시 이상을 빠르게 판별/복구한다.
- 대상 이슈:
  - 만료일이 남아있는데 `만료됨`으로 보이는 문제
  - 비종량제인데 `포인트 소진 시까지`가 노출되는 문제
  - usage 계정에서 `(- 만료)` 같은 비정상 문구 노출

## 적용 범위
- 화면: `IKEv2SellerOffice4U/vpn_users.php`
- 데이터: `IKEv2SellerOffice4U/data/user_billing.json`
- 참고 로그: `IKEv2SellerOffice4U/logs/php_errors.log`

---

## 1) 5분 즉시 점검
### 절차
1. 페이지 강력 새로고침 1회
2. 자동 새로고침 OFF → 수동 새로고침 1회
3. 아래 3계정 스팟체크
   - usage 계정 1개
   - monthly/yearly/free 계정 1개
   - 오래된/이력 많은 계정 1개

### 기대 결과
- usage: `포인트 소진 시까지` + (유효한 만료일 있으면) `만료 예정/만료됨`
- non-usage: `포인트 소진 시까지` 미노출
- `(- 만료)` 미노출

### 즉시 FAIL 조건
- non-usage 행에 `포인트 소진 시까지` 노출
- usage 행에 `(- 만료)` 노출
- 미래 만료인데 상태가 `만료됨`

---

## 2) 30분 회귀 점검
### 절차
1. 계정 1건 과금타입 저장(재저장) 후 목록 재조회
2. 자동 새로고침 ON 후 2~3회 주기 관찰
3. 연결 상태 변화(연결/미연결) 계정 1건 확인

### 기대 결과
- 새로고침 전/후 표시 일관
- 과금 타입 배지(`종량제/월정액/연정액/무료/미설정`)가 저장값과 일치
- 상태/만료/과금 문구가 서로 모순되지 않음

---

## 3) 장애 분기별 핫픽스 가이드

### A. non-usage인데 `포인트 소진 시까지` 노출
- 확인: `user_billing.json`의 해당 `user_id.type`
- 응급조치: 관리자에서 과금 타입 재저장
- 코드 포인트: 렌더 로직에서 usage fallback 금지, 유효 타입만 허용

### B. usage에서 `(- 만료)` 노출
- 확인: 해당 사용자 `expire` 원문이 빈값/`-`/파싱불가인지
- 응급조치: `expire`를 정상 datetime으로 재저장 또는 비움
- 코드 포인트: usage 보조문구는 `expireTimestamp !== null`일 때만 출력

### C. 미래 만료인데 `만료됨`
- 확인: 서버 timezone(`Asia/Seoul`) + `expire` 포맷(`Y-m-d H:i:s`)
- 응급조치: 만료시각 재저장
- 코드 포인트: 상태 계산에서 파싱된 만료시각을 최우선 근거로 사용

---

## 4) 증거 수집 (재수정용)
- 필수 5종:
  1. 문제 `user_id`
  2. 화면 스크린샷(행 전체)
  3. 발생 시각(KST)
  4. `user_billing.json` 해당 사용자 블록
  5. `expire` 원문값

---

## 5) 결과 기록 템플릿
| 시각(KST) | user_id | 유형(usage/non-usage) | 실제표시 | 기대표시 | PASS/FAIL | 비고 |
|---|---|---|---|---|---|---|
|  |  |  |  |  |  |  |

---

## 완료 기준 (Release Gate)
- 5분 점검 PASS
- 30분 회귀 점검 PASS
- FAIL 조건 0건
- 신규 fatal/warning 로그 0건

## 참고 파일
- `IKEv2SellerOffice4U/vpn_users.php`
- `IKEv2SellerOffice4U/billing.php`
- `IKEv2SellerOffice4U/data/user_billing.json`

---

## 운영자용 10줄 대응 카드 (초간단)
1. `vpn_users.php` 강력 새로고침 1회.
2. 자동 새로고침 OFF 후 수동 새로고침 1회.
3. usage 계정 1개에서 `포인트 소진 시까지` 확인.
4. non-usage 계정 1개에서 `포인트 소진 시까지`가 없어야 함.
5. usage 행에 `(- 만료)`가 보이면 FAIL.
6. 미래 만료인데 `만료됨`이면 FAIL.
7. FAIL 시 해당 `user_id`와 발생시각(KST) 즉시 기록.
8. `user_billing.json`의 해당 `type` 값 캡처.
9. 화면 스크린샷(행 전체) + `expire` 원문 확보.
10. 관리자에서 과금/만료 재저장 후 재확인, 여전하면 개발 이관.