# AIWK ZIP Auto Apply 현재 기준서

## 현재 버전
- v1.1.41
- 목적: ChatGPT 화면의 ZIP 산출물을 감지하고, ZIP 파일명 패턴에 맞는 `yyy_zip_apply.php`로 자동 POST 적용한다.
- 이번 기준: 새 ZIP 감지 또는 ZIP 적용 성공 후 사용자가 설정한 MP3/URL을 Chrome popup 창으로 직접 열고, 기존 알람창은 windowId로 닫아 제어한다.

## 절대 원칙
- 탭별 서버 선택 방식은 사용하지 않는다. 적용 서버 결정 기준은 항상 ZIP 파일명 패턴이다.
- 패턴 매칭이 안 되면 임의 기본 서버로 보내지 않는다. `패턴없음` 상태만 표시하고 건너뛴다.
- 사용자가 입력한 패턴/URL/경로 문자열은 저장 시 임의 보정하지 않는다.
- 다운로드 fallback, 임의 대체 좌표/값, 묵시적 서버 선택은 금지한다.
- 실패하면 상태와 로그에 원인을 남기고 중단한다.

## 적용 목록 형식
팝업의 `ZIP 파일명 패턴별 적용 목록`은 공용 설정 1개만 저장한다.

```text
ZIP파일명패턴 | 업로드 받을 PHP URL | ZIP 적용 기준폴더/ | ZIP 원본저장 기준폴더/
```

예시:

```text
aiwk_zip_auto_*.zip | https://home.yjm.kr/y/yyy_zip_apply.php | /mnt/d/D/_NR_/___zip_apply/auto_apply압축보관/ | /mnt/d/D/_NR_/_bak/yyy_zip_keep/
nssb_push_*.zip | https://n.yjm.kr/y/yyy_zip_apply.php | /var/www/html/y/
```

## 패턴 규칙
- `.zip`으로 끝나는 파일명만 ZIP 후보로 본다.
- ZIP 후보 파일명에 한글이 들어가면 제외한다.
- 공백으로 분리된 토큰 중 정상 ZIP 파일명만 인정한다.
- `zip`, `.zip` 단독은 후보가 아니다.
- 패턴 문자열은 사용자가 입력한 첫 번째 칸 그대로 매칭한다.

## PHP 연동 POST 필드
EXT가 `yyy_zip_apply.php`로 전송할 때 아래 필드를 사용한다.

```text
action=upload
zip_file[]=실제 ZIP Blob/File
flat_base_dir=ZIP 적용 기준폴더
zip_keep_root=ZIP 원본 보관/작업 기준폴더
keep_original_zip=1
aiwk_tab_id=zip_auto
s_tab=zip_auto 또는 tab 관련 값
server_id=매칭된 ZIP 패턴
```

## 감지/적용 구조
- 초기 1회는 현재 화면의 보이는 assistant 블록만 아래에서 위로 검사한다.
- 이후에는 새로 생성/변경되는 assistant 영역만 MutationObserver로 감시한다.
- 화면 밖 과거 문서 전체를 다시 검색하지 않는다.
- `document.body` 전체 fallback으로 과거 ZIP을 잡지 않는다.
- 하단 ZIP 패널은 드래그 이동 가능하고, 위치는 전역 1개로 저장한다.
- 하단 배지 왼쪽 표시는 `zip v버전` 형식을 유지한다.
- 하단 배지의 `적용` 버튼 오른쪽 복사용 영역은 드래그 이동 금지, 텍스트 선택/복사용 영역이다.

## URL5 연결 / 채팅 / 파일
- URL5는 `md5(origin + pathname).slice(0, 5)` 기반 연결 목록이다.
- 저장 키: `AIWK_URL5_LINKS_V1`, 활성 선택: `AIWK_URL5_ACTIVE_V1`.
- 팝업에서 현재 탭 자동생성·연결, ping, 채팅 전송, 파일 전송, 삭제가 가능하다.
- 수신 탭 화면에는 받은 채팅과 받은 파일명/용량/시간/다운로드 링크를 표시한다.
- 파일 전송 1차본은 단일 base64 메시지 방식이다. 큰 ZIP 안정화는 이후 chunk 방식으로 확장한다.

## ZIP 완료 알람
- 설정 항목: `알람 사용`, `알람 URL`, `▶ 테스트` 버튼.
- 저장 키는 기존 `AIWK_ZIP_AUTO_APPLY_V1_CFG` 안의 `alarmEnabled`, `alarmPlayUrl`, `alarmPopupWidth`, `alarmPopupHeight`를 사용한다. 현재 알람 popup windowId는 `AIWK_ZIP_AUTO_APPLY_V1_ALARM_WINDOW`에 별도 저장한다.
- `▶ 테스트`는 현재 입력된 URL을 그대로 Chrome popup 창으로 연다.
- 새 ZIP 감지 또는 ZIP 적용 성공 시 `alarmEnabled=true`이고 `alarmPlayUrl`이 있으면 service worker에 `AIWK_ZIP_ALARM_OPEN` 메시지를 보낸다.
- service worker는 `chrome.windows.create({ type:'popup', width:300, height:70, left:0, top:0 })`로 URL을 직접 연다.
- 별도 player HTML, iframe, Audio 객체는 사용하지 않는다.
- 사용자가 popup 창을 닫으면 알람이 끝난다.
- 새 알람을 열기 전 기존 알람 popup windowId가 남아 있으면 `chrome.windows.remove()`로 먼저 닫는다.
- ChatGPT ZIP 다운로드 클릭 또는 Chrome downloads ZIP 생성 이벤트가 감지되면 기존 알람 popup 창을 닫는다.
- 같은 ZIP 파일명과 같은 알람 URL 조합은 `AIWK_ZIP_AUTO_APPLY_V1_ALARM_LAST`로 중복 알람을 막는다. 새 ZIP 파일명은 다시 알람한다.
- 허용 URL 프로토콜은 `http:`, `https:`, `file:`이다. `file:`은 Chrome 확장 파일 URL 접근 허용 상태에 따라 동작이 제한될 수 있다.

## 현재 파일별 역할
- `manifest.json`: MV3 확장 정의, 권한, content script, service worker 등록.
- `popup.html`: 설정 UI, URL5 UI, ZIP 완료 알람 URL UI.
- `popup.css`: 팝업 스타일과 알람 URL/테스트 버튼 스타일.
- `popup.js`: 설정 저장/로드, URL5 조작, 알람 테스트 popup 요청.
- `content.js`: ChatGPT ZIP 감지, ZIP 적용 전송, ZIP 감지/성공 후 알람 요청, ZIP 다운로드 클릭 시 알람 닫기 요청.
- `service_worker.js`: 설정 기본값, TAB BUS, apply 탭 열기, POST 주입, 다운로드 캡처, 알람 popup 생성/닫기/windowId 관리.
- `libs/aiwk_zip_capture_page_hook_v001.js`: ChatGPT 다운로드 Blob/URL 캡처용 page hook.

## 바로 다음 점검 항목
- 실제 Chrome 확장 로드 후 알람 URL `▶` 테스트.
- 알람 popup이 좌상단 0,0으로 열리는지 확인.
- 새 알람을 열 때 기존 알람창이 닫히는지 확인.
- ZIP 다운로드 클릭 시 기존 알람창이 닫히는지 확인.
- ZIP 자동 적용 성공 뒤 동일 파일 중복 알람 차단 확인.
