---
task_id: task-2342
type: context
scope: task
created: 2026-05-02
updated: 2026-05-02
status: completed
---

# 맥락 노트: task-2342

**task**: task-2342

---

## 결정 근거

### 1차 조치: navigateFallbackDenylist 확장
- 원인은 `vite.config.ts`의 `workbox.navigateFallbackDenylist`에 `/downloads/`가 없어 SW가 zip 요청을 `/index.html` fallback으로 처리하던 것.
- 대안 비교:
  - **옵션 A (채택)**: denylist에 `/^\/downloads\//` 추가 — 한 줄 변경으로 즉시 해소, 위험 최소
  - 옵션 B (기각): globPatterns에 zip 포함 — precache가 11KB zip을 SW가 매번 캐시. 다른 다운로드 자원이 추가될 때마다 globPattern을 다시 손봐야 함. 또한 globPatterns 추가만으론 navigation 분류 자체는 막지 못함 (denylist가 본질).
  - 옵션 C (기각): `_redirects` 추가 — Cloudflare Pages 차원의 리다이렉트는 Service Worker가 가로채는 시점보다 늦게 작동하므로 SW 문제 자체를 해결하지 못함.
- 추가 안전장치로 `/\.(?:zip|pdf|exe|dmg|tar|gz)$/` regex도 등록하여 향후 동종 자원 추가 시 같은 사고를 선제적으로 차단.

### `_headers`에 `/downloads/*.zip` Content-Disposition: attachment 추가
- 일부 브라우저(특히 모바일 Safari)는 application/zip을 inline으로 처리 시도. 명시적 attachment 헤더로 다운로드를 보장.
- `_headers`는 Cloudflare Pages 표준 메커니즘이며 기존 항목을 보존하므로 회귀 위험 없음.

### skipWaiting/clientsClaim는 이번 범위 제외
- Codex Gate가 medium severity로 지적했으나, vite-plugin-pwa `registerType: "autoUpdate"` 옵션이 자동으로 새 SW 활성화를 유도하며 `src/main.tsx`의 `registerSW`가 주기적 update()를 수행. 추가 명시는 사용자 영향이 양면적이므로 별도 task에서 검토.

## 참조 자료

- task 지시서: `/home/jay/workspace/memory/tasks/task-2342.md`
- 코드: `/home/jay/projects/InsuRo/vite.config.ts:44-110`, `public/_headers`
- 빌드 산출물: `/home/jay/projects/InsuRo/.worktrees/task-2342-dev5/dist/sw.js`
- 프로덕션 SW: `https://insuro.biz/sw.js`
- PR: https://github.com/JonghyukJeon/InsuRo/pull/74
- 메모리 피드백 적중: "PWA 배포 후 구버전 로드 시 SW 캐시 우선 의심 (2026-04-29)"

## 주의사항

- 기존 사용자 브라우저는 옛 SW가 활성 상태일 수 있음 → hard reload(Ctrl+Shift+R) 또는 시크릿 모드로 갱신 안내 필요
- vite-plugin-pwa는 `globPatterns`에 매칭되지 않는 파일을 자동 precache하지 않으므로 zip이 캐시되지 않는 동작은 의도적
- `_headers` 변경은 Cloudflare Pages에서만 작동. 다른 호스팅으로 이전 시 별도 헤더 설정 필요
