# 업데이터 모듈 검증 가이드

## 1. 목적

통합 전에 `app/updater/` 모듈 단독으로 실행/오류 시나리오를 검증하기 위한 체크리스트입니다.

---

## 2. 검증 범위

- `update_manager.py`
  - 버전 비교
  - Supabase 조회
  - config.json 생성
  - updater.exe 복사 및 실행
- `updater_gui.py`
  - config.json 로드/검증
  - zip 다운로드
  - 압축 해제/파일 교체
  - 롤백 처리
  - 메인 앱 재실행

---

## 3. 실행 전 준비

1. `%TEMP%` 쓰기 권한 확인
2. 설치 대상 경로 쓰기 권한 확인
3. `updater.exe` 배포 위치 확인 (메인 exe와 동일 경로)
4. Supabase `program_version` 테이블 데이터 확인

---

## 4. 핵심 시나리오

### 4.1 정상 시나리오

1. `check_for_updates()`가 최신 안정 버전을 조회
2. `prepare_update()`가 `%TEMP%/voc_updater_config.json` 생성
3. `prepare_update()`가 `%TEMP%/updater.exe` 복사
4. `launch_updater()`가 updater 프로세스 실행
5. updater가 zip 다운로드 후 대상 경로 교체
6. updater가 메인 프로그램 재실행

### 4.2 오류 시나리오

1. Supabase URL/키 누락
   - 기대 결과: `ConfigError`
2. 다운로드 URL 누락
   - 기대 결과: `prepare_update()` 실패 반환
3. updater.exe 누락
   - 기대 결과: `prepare_update()` 실패 반환
4. 손상 zip 파일
   - 기대 결과: 설치 실패 + 롤백
5. 대상 경로 권한 부족
   - 기대 결과: 설치 실패 + 롤백

---

## 5. 반영된 에러 처리 강화

- `update_manager.py`
  - Supabase URL/키 사전 검증 추가
  - 설치 경로 판별 로직 정리 (`sys.frozen` 기준)
  - config.json 원자적 저장(`.tmp` 생성 후 교체)
  - updater.exe 누락 시 실패 반환 강화
  - OS별 프로세스 생성 플래그 분기
- `updater_gui.py`
  - config.json 필수 필드 검증 강화
  - 압축 해제 임시 폴더 분리
  - 임시 폴더 -> 대상 경로 복사 단계 명확화
  - 실패 시 롤백 + 임시 폴더 정리
  - OS별 재실행 플래그 분기

---

## 6. 통합 전 완료 조건

- 업데이터 단위 테스트 통과
- `py_compile` 통과
- 오류 시나리오에서 메시지/롤백 동작 확인
- 문서(`project_spec.md`, `api_contract.md`, `issue.md`) 동기화

---

## 7. 수동 리허설 절차 (샘플 zip)

### 7.1 목적

실제 통합 전에 updater.exe 단독 실행으로 "다운로드 -> 교체 -> 재실행" 경로를 눈으로 확인합니다.

### 7.2 준비물

1. 테스트용 설치 폴더 (예: `D:/tmp/voc_app_test`)
2. 샘플 업데이트 zip (루트에 `voc_noti.exe` 또는 테스트 파일 포함)
3. `%TEMP%/voc_updater_config.json` 파일

### 7.3 config.json 예시

```json
{
  "download_url": "https://example.com/voc_test_update.zip",
  "target_path": "D:/tmp/voc_app_test",
  "version": "9.9.9",
  "restart_exe": "voc_noti.exe"
}
```

### 7.4 실행 순서

1. `%TEMP%`에 config.json 배치
2. `updater.exe` 단독 실행
3. GUI에서 상태가 순서대로 진행되는지 확인
   - 다운로드 중
   - 압축 해제 중
   - 파일 교체 중
   - 완료
4. 대상 경로 파일 변경 여부 확인
5. 메인 앱 재실행 여부 확인

### 7.5 실패 리허설

1. 손상 zip URL로 config 구성
   - 기대: 실패 메시지 + 재시도 버튼
2. 대상 경로 쓰기 권한 제거
   - 기대: 설치 실패 + 기존 파일 유지(롤백)

### 7.6 확인 체크리스트

- [ ] 성공 시 업데이트 파일이 대상 경로에 반영됨
- [ ] 실패 시 기존 파일이 보존됨
- [ ] config/temp 파일이 종료 시 정리됨
- [ ] 상태 메시지가 한국어로 이해 가능하게 표시됨

---

## 8. 실행 증적 (2026-02-18)

### 8.1 단위 테스트

실행 명령:

```bash
python test/test_updater_module.py -v
```

결과:
- 총 13개 테스트 통과
- 포함 시나리오: 버전 비교, 연결 설정 fallback/remote, 테이블명 폴백, 권한 오류, 손상 zip, 롤백

### 8.2 실환경 연결 테스트 (m1tcloud)

실행 명령:

```bash
python -c "import json; from pathlib import Path; from app.updater.update_manager import create_update_manager_from_settings; s=json.loads(Path('app/data/settings.json').read_text(encoding='utf-8')); m=create_update_manager_from_settings(s); print(m.supabase_url, m.version_table); v=m.check_for_updates(); print(v.version if v else 'NONE')"
```

결과:
- URL: `https://kong.m1tcloud.cc`
- 테이블: `program_versions`
- 조회 버전: `3.5.5`

---

## 9. 메인 통합 리허설 절차

### 9.1 목적

업데이터 단독 검증 이후, 메인 앱 통합 경로(트레이 메뉴/백그라운드)가 정상 연결되는지 확인합니다.

### 9.2 확인 항목

1. 앱 시작 시 업데이터 초기화 로그
   - `업데이터 초기화 완료`
2. 앱 시작 후 백그라운드 체크 시작 로그
   - `백그라운드 업데이트 체크 시작 (주기: N시간)`
3. 트레이 메뉴에 `업데이트 확인` 항목 표시
4. 트레이 `업데이트 확인` 클릭 시:
   - 최신 버전 없음: 토스트 안내
   - 최신 버전 있음: 설치 여부 다이얼로그 표시
5. 설치 승인 시:
   - `prepare_update` 성공
   - `launch_updater` 성공
   - 메인 앱 종료 처리

### 9.2.1 테스트 모드 즉시 확인 옵션

테스트 DB 모드에서 updater 연결을 즉시 검증하려면 아래 명령을 사용합니다.

```bash
python app/main.py --test --test-update-now
```

기대 동작:
- 앱 시작 후 약 1초 내 업데이트 확인 1회 실행
- 로그에 `수동 업데이트 확인 시작` 기록
- 최신/신규 버전 결과 로그 및 알림 표시

### 9.3 실패 시 기대 동작

- 연결 설정 오류: 사용자에게 설정 오류 메시지 표시 + 로그
- 네트워크 오류: 사용자에게 네트워크 오류 메시지 표시 + 로그
- updater.exe 누락: 업데이트 실행 실패 메시지 + 로그

### 9.5 중복 알림 방지 규칙

- 업데이트 안내창 표시 중에는 추가 안내창을 띄우지 않음
- 동일 버전 안내는 60초 이내 재표시하지 않음
- 테스트 모드 `--test --test-update-now` 사용 시 백그라운드 즉시 체크와 중복되지 않도록 단발 확인만 수행

### 9.4 코드 연결 지점

- `app/controllers/controller.py`
  - `start_background()`에서 updater 백그라운드 시작
  - `check_updates_manual()`/`_check_updates_once()` 수동 확인
  - `_show_update_prompt()` 승인 후 실행
- `app/view/tray_icon.py`
  - 트레이 메뉴 `업데이트 확인` 이벤트 연결

### 9.6 빌드 리허설

1. 업데이터 단독 빌드
   - `python app/update_build_setup.py`
2. 산출물 확인
   - `app/updater_build/dist/updater.exe` 존재
   - `app/updater_build/config.json` 존재
3. 메인 패키징
   - `python app/setup.py build`
4. 빌드 결과 폴더 확인
   - 메인 exe와 같은 폴더에 `updater.exe` 존재

### 9.7 빌드 리허설 실행 증적 (2026-02-18)

실행 명령:

```bash
python app/update_build_setup.py
python app/setup.py build
```

확인 결과:
- `app/updater_build/dist/updater.exe` 생성 확인
- `app/updater_build/config.json` 복사 확인
- `app/build/exe.win-amd64-3.11/VOC_Monitor.exe` 생성 확인
- `app/build/exe.win-amd64-3.11/updater.exe` 포함 확인
- `app/build/exe.win-amd64-3.11/app/updater/config.json` 포함 확인

추가 스모크 검증:
- 빌드된 `updater.exe`를 개발 경로에 복사 후 `prepare_update()` 실행
- 결과: `PREPARE True` / `%TEMP%/updater.exe` 존재 확인
