docs: 다음 세션 핸드오버 (Product build 절차·격리 구조·결정 대기·함정) + 오라클 핸드오버 커밋

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Haewon Kam 2026-09-11 14:14:46 +09:00
parent 008411b929
commit 99195f09f3
2 changed files with 154 additions and 0 deletions

View File

@ -0,0 +1,61 @@
# 다음 세션 핸드오버 · 2026-09-11 · 오라클피부과 서포터즈 (피부과 첫 자동 빌드)
작성 2026-09-10 · 작성자 Claude (haewon 세션) · 이전 핸드오버 `docs/NEXT_SESSION_2026-09-09.md`, 자동 빌드 전체 상태 `docs/NEXT_SESSION_SUPPORTERS_AUTOBUILD_v3.md`. 이 문서는 2026-09-10 피부과 작업(세션 1: PRD·질문뱅크·Top3 진단, 세션 2: 오라클 자동 빌드)만 다룬다.
## 0. 세션 시작 시 붙여 넣을 프롬프트
```
INFINITH 저장소. 자동 빌드 코드는 워크트리 ~/orca/workspaces/INFINITH/Productize (브랜치 feature/supporters-autobuild), 피부과 PRD·질문뱅크·진단·Before/After 는 메인 체크아웃 ~/Claude/Agentic Marketing/INFINITH (브랜치 feature/ai-sentiment-rubric) 에 있다. 둘 다 미커밋.
먼저 docs/NEXT_SESSION_2026-09-11_ORACLE.md 를 읽고 §3 결정 대기의 답을 받은 뒤 §2 순서대로 진행한다.
원칙: 근거 없는 사실은 생성하지 않는다("확인 대기"). 사람 게이트(의학 검토·게시 승인·이미지 육안·채널 확인)는 자동화하지 않는다. 고객 화면에 운영자 설명 없음. 확정 디자인은 텍스트만. 존댓말, 엠대시 금지, 은유 금지, 흰 배경 위 연보라 텍스트 금지(인디고 #1D0024). 세 병원을 한 화면에서 비교하는 산출물은 만들지 않는다.
```
## 1. 2026-09-10 에 끝낸 것
| 일 | 위치 | 상태 |
|---|---|---|
| 피부과 Top3 리서치(오라클·톡스앤필·차앤박) | 메인 `docs/reports/dermatology/00_research/` | 완료. 미확인 항목은 (e)절 |
| Top3 AEO/GEO 자동 채점 + 사람 보정 4항목 | 메인 `docs/reports/dermatology/01_readiness_report/*_{audit_aeo_geo,overrides,score}_2026-09-10.json` | 오라클 36/D(AEO 24·GEO 6) · 톡스앤필 68/B(54·67) · 차앤박 48/C(24·55). 표본 URL 2개 |
| 점수 계산기 `scripts/score_discovery_json.py`, 질문뱅크 생성기 `scripts/build_qb_dermatology.py` | 메인 | 원진 v1 49/C 로 검증. v2 는 v2Results 사람 판정이 없어 페이지 값과 다를 수 있음 |
| 질문뱅크 120문항 v0.1 (병원별 3칸 사전판정) | 메인 `docs/reports/dermatology/03_question_bank/` | 2엔진 실측 전. 러너 인자화 필요 |
| PRD v0.1 | 메인 `docs/prd/INFINITH_Dermatology_Supporters_PRD_v0.1.html` | §13 결정 질문 10건. 인디고 규칙 반영 |
| Before/After 페이지 빌더 `scripts/build_before_after.py` | 메인. 원진 픽스처 `docs/reports/wonjin/02_before_after/`, 오라클 `docs/reports/dermatology/02_before_after/Oracle_Before_After_2026-09-10.html` | 오라클 36/D → 75/B, AEO 24 → 77, GEO 6 → 81 |
| 오라클 서포터즈 자동 빌드 | Productize 워커, 작업 폴더 `~/supporters-builds/oracle`, 미리보기 **https://supporters-oracle.vercel.app** (noindex) | 글 8편(소개·지점 안내·상담 질문·시술 5영역), $0.61, 게이트 오류 0. 의학 검토·승인 전 초안 |
### 파이프라인에 새로 들어간 것 (Productize, 미커밋)
- `supporters/scripts/collect_evidence.mjs`: 프레임셋·meta refresh·JS 리다이렉트 추적, charset 감지(EUC-KR), 쿼리 보존(`index.php?doc=N`), 쿼리 변형 중복 판정, 피부과 시술 어휘·`branches` 유형, `--extra-url`, facts.draft.json 에 `branches`·`branchPages`.
- `supporters/scripts/ocr_evidence.mjs` + `ocr/vision_ocr.swift`: macOS Vision OCR(무료). 오라클 시술 83페이지가 이미지 글자였다. 워커 `ocr` 단계(evidence 다음), `--no-ocr`.
- `supporters/scripts/default_briefs.mjs`: `--industry derm|plastic` 자동 감지, 피부과 8영역, 조건 표 8행 브리프, 지점 안내 후보.
- `supporters/scripts/gate/rules.mjs`: PRICE_MENTION(error)·PRACTITIONER_MISSING(warn)·DEVICE_CLAIM(error)·피부과 금칙어. "100%"는 의료 맥락일 때만, 운영자 어휘 "복제"는 낱말 시작일 때만(피로회복제 오탐), 뉴스 제목 "부작용 없이" 제외. 테스트 41/41.
- `supporters/scripts/gen/prompt.mjs`(피부과 규칙 블록) · `gen/evidence.mjs`(normUrl 쿼리 보존, OCR 섹션 표기).
- `scripts/fetch_medical_tourism.py` 병원별 인자화 + 워커 `tourism` 단계(images 다음). `/stay`·`/en/stay` 하드코딩 제거.
- 워커 `inputs` 단계: `supporters/briefs/<clinic>/clinic.json``factSheet`·`site`(srcMatch)·`excludeImages` 를 자동값 위에 덮어씀(이미지 파일·갤러리·images.json 매니페스트에서 제외).
- `supporters/briefs/oracle/clinic.json`: 유튜브 @oracle_medical_group 고정, 로고 PNG, kind 피부과, 갤러리는 검단점 로비 1장, `sub_0*` 이미지 제외.
## 2. 다음 순서
1. **§3 결정 회수** (haewon).
2. **오라클 사람 확인**: (a) 의료진 67명 OCR 후보 확정(같은 이름 중복: 김승면 광주점·광주수완점), (b) 본사 시설 사진 요청(지금은 검단점 로비 1장), (c) 갤러리 육안 확인, (d) 푸터 표기 변경 확인(오라클랜드 주식회사 314-81-85931 대표 노영우 → 청담 오라클피부과의원 307-04-97234 대표 이영숙, 작업 중 사이트가 바뀜).
3. **뷰·원진 회귀**: 이번 변경(수집기·게이트·생성기·워커)이 두 병원에서 깨지지 않는지 `npm run gate:test`(41/41 확인됨) + 뷰 정답지 회귀 `npm run generate:regress`(비용 약 $2, 미실행) + 원진 `run.mjs --from data --skip-generate`.
4. **구조 기준선**: 오라클 첫 빌드라 `LAYOUT_NO_BASELINE` 경고. haewon 이 룩앤필을 승인하면 `node scripts/check.mjs --update-layout`.
5. **질문뱅크 러너 인자화** → 오라클 120문항 2엔진 실측(약 $2~4) → Before/After 페이지의 "환자 질문에 답할 수 있나" 카드에 실측값. 감성(기준표 v0.3) 판정 포함.
6. **커밋**: Productize(워커·스크립트·핸드오버)와 메인(PRD·뱅크·진단·Before/After·스크립트) 각각. 프론트 변경 없음이라 vercel --prod 불필요.
7. 톡스앤필·차앤박도 같은 워커로 빌드하면 세일즈 자료 3세트(각각 개별 Before/After). 한 화면 비교는 만들지 않는다.
## 3. haewon 결정 대기
1. **세일즈 사용 범위**: 오라클은 고객이 아니다. Before/After 페이지와 미리보기를 영업에 쓰려면 병원 자산(로고·사진·OCR 원문 재구성) 사용 범위를 정해야 한다. 미리보기는 noindex 이며 검색·AI 에 노출되지 않는다.
2. **지원 관계 고지 문구**(site.sponsorNotice): 비어 있어 글마다 DISCLOSURE_TOP_MISSING 경고. 고객이 아니므로 "지원 없음" 문안을 쓸지, 비워 둘지.
3. **주변 안내 사진**: TourAPI 사진이 없는 곳은 네이버 이미지 검색 폴백(제3자 저작물)을 쓴다. 공개 배포 시 `--no-naver-images` 로 끌지.
4. **의료진 OCR 후보 67명 노출**: 지금은 "OCR · 확인 대기"로 authors.json 에 있고 홈에는 안 나온다. 지점 안내 글의 담당 원장 표기에 쓸지.
5. 기존 미결: 도메인, 서포터즈 실명, 워커 상시 실행(Trigger.dev), PRD §13 의 파일럿 병원·가격 표기·상표명·실측 예산·리포트 영업 사용.
## 4. 함정 (이번 세션)
- 사이트 스크립트 사본: 워커 `data` 단계가 템플릿을 작업 폴더에 복사하므로, 규칙을 고친 뒤에는 `templates/supporters-astro/scripts/` 동기화 + 작업 폴더 `site/scripts/` 재복사(또는 `--from data`)가 필요하다. 규칙만 고치고 `--from build` 하면 옛 규칙으로 검사한다.
- `gen/evidence.mjs normUrl` 이 쿼리를 지우면 `doc=N` 페이지가 전부 한 페이지로 겹친다. 첫 생성 8편이 전부 휴지기탈모를 근거로 썼다. 고쳤고 재생성했다.
- OCR 주의문이 강하면("수치·고유명사를 옮기지 않는다") 모델이 OCR 근거를 전부 버린다. 지금 문안은 "깨진 글자만 제외".
- 색인 허용 빌드(PUBLIC_INDEXABLE=true)는 approvedAt 있는 글만 낸다. 승인 전 병원은 posts 가 0이므로 After 채점은 미리보기 빌드 + robots 보정으로 한다(overrides 에 근거 기록).
- 이미지 자동 분류 "시설"에 시술 설명 이미지(모델 얼굴·전후 사진)가 섞였다. 사람 육안 확인은 계속 필요하다. 제외는 clinic.json excludeImages 로.
- 오라클 공식 사이트는 Playwright networkidle 로 60초 타임아웃. `wait_until='load'` 로 캡처.
- 게이트 "100%"·"복제"·"부작용 없이" 오탐 3종은 전부 제3자 텍스트(관광공사 식당 소개·뉴스 제목)에서 나왔다. 제3자 텍스트 영역은 규칙을 의료 맥락으로 좁혀야 한다.

View File

@ -0,0 +1,93 @@
# 다음 세션 핸드오버 · 2026-09-12 · 서포터즈 Product Build (회복 일정 플래너·오시는 길 지도 통합 이후)
작성 2026-09-11 · 작성자 Claude (haewon 세션) · 이전 핸드오버 `docs/NEXT_SESSION_2026-09-11_ORACLE.md`(오라클 첫 빌드), `docs/NEXT_SESSION_SUPPORTERS_AUTOBUILD_v3.md`(자동 빌드 전체).
이 문서는 2026-09-10~11 이틀간 붙인 기능(회복 일정 플래너 `/plan`·`/en/plan`, 오시는 길 지도, 전역 언어 전환, 모바일 헤더)과 그것을 워커·템플릿에 통합한 상태, 그리고 다음 병원을 Product로 빌드하는 절차를 다룬다.
## 0. 세션 시작 시 붙여 넣을 프롬프트
```
INFINITH 저장소. 자동 빌드(워커·템플릿)는 워크트리 ~/orca/workspaces/INFINITH/Productize (브랜치 feature/supporters-autobuild),
뷰성형외과 샘플 사이트(수동 배포)는 메인 체크아웃 ~/Claude/Agentic Marketing/INFINITH/supporters (브랜치 feature/ai-sentiment-rubric).
병원별 빌드 산출물은 ~/supporters-builds/<clinic>/site 이고 Vercel 프로젝트는 supporters-<clinic> 이다.
먼저 docs/NEXT_SESSION_2026-09-12_PRODUCT_BUILD.md 를 읽고 §4 결정 대기의 답을 받은 뒤 §3 절차대로 진행한다.
원칙: 근거 없는 사실은 생성하지 않는다("확인 대기"·"병원 확인 전"). 사람 게이트(의학 검토·게시 승인·이미지 육안·채널 확인·구조 기준선 승인)는 자동화하지 않는다.
고객 화면에 운영자 설명 없음(게이트 OPERATOR_VOCAB). 확정 디자인은 텍스트만. 존댓말, 엠대시 금지(커밋 메시지 포함), 은유 금지, 흰 배경 위 연보라 텍스트 금지(인디고 #1D0024).
데이터 타일에 웜 그라디언트 금지(CTA 카드 한 장에만). 새 페이지는 홈·영상 페이지의 섹션 리듬(다크 히어로+글래스 통계 → 틴트 카드 → 다크 통계 → 라이트 → 틴트 → 다크)으로 만든다.
배포는 병원 폴더(~/supporters-builds/<clinic>/site)나 메인 supporters/ 에서만 한다. Productize/supporters 는 어떤 Vercel 프로젝트에도 연결하지 않는다.
```
## 1. 2026-09-10~11 에 끝낸 것
| 일 | 위치 | 상태 |
|---|---|---|
| 회복 일정 플래너 `/plan`·`/en/plan` (수술일 기준 입국·출국 계산, 외출 등급·식사 단계 필터, 큐레이션+관광공사 추천, 체류 기간 행사, 숙소·항공 딥링크, ICS, 하단 요약 바) | 템플릿 `src/components/Planner.astro`, `src/lib/plan.ts`·`tour.ts`, `src/styles/plan.css`, `src/data/planStrings.json`, `src/pages/plan.astro`·`en/plan.astro`·`404.astro` | 뷰·원진·오라클 배포. 설계 근거 메인 `docs/INFINITH_Viewclinic_Supporters_Site_Design_v0.2.md` §13 |
| 워커 `planner` 단계(recovery 다음) | `workers/supporters-build/run.mjs`, `supporters/scripts/build_planner_data.mjs`, 기본표 `supporters/scripts/template/planner/procedures.{plastic,derm}.json`·`places.base.json` | 업종별 기본 규칙표 + 병원 시술 페이지 원문(recoveryNotes) 중 관리 문장만 붙임(CARE/NOT_CARE 필터, 세부 시술명 접두). 장소는 `briefs/<clinic>/planner.places.json`(큐레이션) 또는 범용 기본표 |
| 병원별 큐레이션 장소 브리프 | `supporters/briefs/{viewclinic,oracle,wonjin}/planner.places.json` | 뷰 31·오라클 28·원진 31곳. 전부 verify(출시 전 확인) |
| 오시는 길 지도·길찾기 (Leaflet+OSM, 주소 복사, 네이버·카카오 길찾기, 영어는 구글 추가) | 템플릿 `src/components/VisitMap.astro`, 방문 안내 §3, 뷰 영어 홈 Getting Here | 좌표 `factSheet.geo`. 워커 tourism 단계가 관광공사 수집 기준 좌표(네이버 지역검색)를 geo 에 기록 |
| 전역 언어 전환·모바일 헤더 | 템플릿 Base.astro(langswitch, T.nav), `global.css` ≤900px 헤더 규칙 | 로고·메뉴 겹침 해결. 390px 하네스로 8페이지×3사이트 검증 |
| 옛 주소 정리 | `vercel.json` redirects `/recovery`·`/stay`·`/en/recovery`·`/en/stay` → `/plan`·`/en/plan`. `recovery.astro`·`stay.astro` 는 템플릿에서 제거 | haewon 결정 2026-09-11: 메인 폴더의 `/plan` 이 정본 |
| 원진 관광공사 수집·원문 수집 | `~/supporters-builds/wonjin/site/src/data/medicalTourism*.json`, `recoveryNotes.json` | 장소 123·축제 24, 원문 32문장 중 관리 문장 16건 붙임 |
| Vercel 사고 재발 방지 | Productize `supporters/.vercel/project.json``.disabled-2026-09-11`, `supporters/DEPLOY_NOTE.md` | 두 폴더가 같은 프로젝트에 배포해 `/plan` 이 404 된 사고(09-11 10:20) 이후 |
커밋: Productize `aa5b052`(플래너 통합) → `ed8f650`(지도) → `5263593`(모바일 헤더) → `008411b`(관리 문장 필터). 메인 `65fb9be`~`93509bf`.
## 2. 격리 구조 (무엇이 무엇을 건드리는가)
| 폴더 | 브랜치 | 역할 | Vercel | 워커가 건드리나 |
|---|---|---|---|---|
| `~/Claude/Agentic Marketing/INFINITH/supporters` | feature/ai-sentiment-rubric | 뷰성형외과 샘플(정본 `/plan`) | `view-supporters-sample` (수동 `vercel --prod`) | 아니오. 워커는 이 경로를 모른다 |
| `Productize/supporters` | feature/supporters-autobuild | 템플릿 원본(개발용). `npm run export:template` 으로 `templates/supporters-astro` 생성 | 없음(연결 파일 비활성) | 아니오. 워커는 여기서 스크립트만 실행한다 |
| `Productize/templates/supporters-astro` | 〃 | 워커가 복사하는 템플릿 | 없음 | 읽기만 |
| `~/supporters-builds/<clinic>/site` | (저장소 밖) | 병원별 산출물 | `supporters-<clinic>` (워커가 `vercel link --project` 로 강제 연결) | **예.** `data` 단계가 `site/` 를 지우고 템플릿을 다시 복사한다(글·videos.json 만 보존) |
따라서: 워커를 어떤 병원으로 돌려도 뷰 샘플과 다른 병원 프로젝트는 영향이 없다. 단, 같은 병원을 `--from data` 이전 단계부터 다시 돌리면 그 병원 폴더의 **손수 고친 파일은 사라진다**. 이번에 손수 넣은 것은 전부 템플릿·브리프·워커 단계로 옮겨 두었으므로 재빌드 결과가 지금 라이브와 같아야 한다. 예외 두 가지는 §5.
## 3. Product build 절차 (다음 병원)
1. **키 확인**: `Productize/.env``TOUR_API_KEY`, `NAVER_CLIENT_ID/SECRET`, `OPENAI_API_KEY`(원문 번역), `YOUTUBE_API_KEY` 값이 있는지. `grep -E "^(TOUR_API_KEY|NAVER_CLIENT_ID)=." .env`.
2. **브리프 작성** `supporters/briefs/<clinic>/`
- `clinic.json`: 유튜브 채널 고정, 로고, `factSheet.kind`(피부과면 `"피부과"`, 이 값으로 업종 자동 판별) · `industry`(`derm`|`plastic`, 명시하면 우선), 갤러리·제외 이미지. 예시는 `briefs/oracle/clinic.json`.
- `planner.places.json`(선택): 병원 기준 큐레이션 장소. 없으면 범용 기본표(약국·편의점·죽·스무디·탕류·경과 확인·호텔 라운지)에 병원 이름·지역만 치환된다. 예시는 `briefs/wonjin/planner.places.json`(뷰 목록을 기준점만 바꿔 거리 보정).
3. **워커 실행** (Productize 루트)
```
node workers/supporters-build/run.mjs --clinic <id> --url https://<병원 홈페이지> --name "<상호>" [--industry derm] [--deploy]
```
단계 순서: evidence → ocr → data → discover → youtube → news → images → tourism → recovery → **planner** → inputs → briefs → generate → build → deploy. 부분 재실행은 `--from <단계>`. 생성 비용 약 $0.6/병원(글 6~8편).
4. **확인**: `~/supporters-builds/<id>/status.json``report.tourism`(좌표·장소 수)·`report.planner`(붙은 원문 문장 수)·`report.recovery`. 빌드 게이트 오류 0 인지.
5. **사람 게이트**: 의료진 후보 확정, 이미지 육안 확인, 구조 기준선 승인(`node scripts/check.mjs --update-layout`, 첫 빌드는 LAYOUT_NO_BASELINE 경고), 규칙표 provisional 값 원장 확인.
6. **모바일 검증**: 헤드리스 크롬은 창 최소 폭이 약 500px 이라 400px 직접 캡처가 부정확하다. 1280 창 안에 390px iframe 을 넣은 하네스로 찍는다(스크래치 `harness*.html` 방식, 홈·영상·방문·plan·뉴스룸·목록·글·병원 정보 8페이지).
7. **배포**: `--deploy` 또는 병원 폴더에서 `vercel --prod --yes`. 메인 `supporters/`(뷰 샘플)는 별도로 `git push``vercel --prod`.
기존 병원 재빌드(플래너·지도 포함 최신 템플릿 적용): `--from data` 로 돌리면 글·영상 집계는 보존되고 나머지는 새로 만든다. 원진처럼 원문 수집을 워커 밖에서 돌린 병원도 `recovery` 단계가 같은 결과를 낸다(`recoveryNotes.cache.json` 은 병원 폴더에 남아 번역 재사용).
## 4. haewon 결정 대기
1. **규칙표 provisional 값**(출국 가능 최소일·입원·실밥 등) 원장 확인. 뷰 `procedures.json` 의 clinic 값은 뷰 주의사항 페이지 근거, 나머지 병원은 원문 문장만 clinic. 화면에는 "병원 확인 전" 배지가 붙어 있으나 공개 전 확인 필요.
2. **제휴 계정 주체**(부킹닷컴 aid, 항공): INFINITH vs 병원. 지금은 제휴 ID 없이 검색 링크만.
3. **외국인환자 유치업 등록 여부 법무 확인**: 플래너는 정보 안내로 유지 중(예약·결제 없음).
4. **뷰 샘플을 템플릿에서 다시 뽑아 통일할지**: 메인 `supporters/` Base.astro 는 템플릿과 구현이 다르다(메인: i18n.ts 전역 전환, 영어 홈 `/en`; 템플릿: langswitch, 영어 입구 `/en/plan`). 플래너·지도 코드는 동일. 통일하면 뷰도 워커 폴더에서 관리하고 `view-supporters-sample` 은 수동 배포에서 워커 배포로 바뀐다.
5. **다음 병원**: 톡스앤필·차앤박(피부과 Top3 나머지)을 같은 워커로 빌드할지. 세 병원을 한 화면에서 비교하는 산출물은 만들지 않는다.
6. **P1 남은 것**: 일본어·중국어 화면(planStrings 같은 키로 추가), 국적별 기본 칩(관광 데이터랩), 관광공사 재수집 주기.
7. 기존 미결(오라클 핸드오버 §3): 세일즈 사용 범위, sponsorNotice 문구, 주변 안내 사진 폴백, 의료진 OCR 노출, 도메인·서포터즈 실명·워커 상시 실행.
## 5. 함정 (이번 이틀)
- **같은 Vercel 프로젝트에 두 폴더**: Productize/supporters 와 메인 supporters 가 둘 다 `view-supporters-sample` 에 연결돼 있어 서로 덮어썼다. 지금은 Productize 쪽 연결을 껐다. 워커 외 수동 `vercel link` 는 하지 않는다.
- **재빌드 시 사라지는 손수 편집**: 원진 폴더의 `factSheetEn.json`, `lib/i18n.ts`, 메인식 Base.astro 는 인스턴스 전용이다. 재빌드하면 템플릿 Base(langswitch)로 바뀌며 이것이 의도한 상태다. 오라클 폴더의 `scripts/gate/plan.test.mjs` 는 오라클 전용(id 8종 기준)이라 재빌드 후 템플릿 범용 테스트로 바뀐다.
- **전역 CSS 클래스 충돌**: 플래너 통계에 `kpi` 클래스를 쓰면 전역 `.kpi`(웜 그라디언트)가 덮어쓴다. `.stats.dates` 로 바꿨다. 새 클래스는 전역 CSS 와 이름이 겹치지 않는지 grep 한다.
- **게이트 OPERATOR_VOCAB**: 좌표 출처 문구의 "실측"이 고객 화면에 나가 빌드가 막혔다. 운영 기록(source)은 데이터에만 둔다.
- **관리 문장 필터가 필요한 이유**: 원진 원문 32문장 중 14건이 홍보문·정형 합병증 고지·표 조각이었다. 필터(`build_planner_data.mjs` CARE/NOT_CARE) 없이 "병원 안내 기준" 배지를 달면 의료광고 규정에 걸린다. 새 병원에서 제외된 문장 목록을 한 번 눈으로 본다(`status.report.planner`).
- **zsh 에서 `set -- $var` 는 단어 분리를 안 한다**: 하네스 생성처럼 반복이 필요하면 파이썬으로 쓴다.
- **엠대시**: 커밋 제목에 두 번 들어가 amend 했다. 커밋 메시지도 생성물이다.
- **Nominatim 좌표는 임시**: 원진 첫 좌표는 OSM 주소 검색이었고, 관광공사 수집(네이버 지역검색)으로 바뀌었다. 좌표 출처는 `factSheet.geo.source` 에 남는다.
## 6. 관련 파일 빠른 참조
- 워커: `workers/supporters-build/run.mjs` (phase 'planner' 307행 부근), 폴러 `poll.mjs`, launchd
- 플래너 데이터 생성: `supporters/scripts/build_planner_data.mjs`
- 기본표: `supporters/scripts/template/planner/`
- 관광 수집: `scripts/fetch_medical_tourism.py` (병원 좌표도 여기서 나온다)
- 원문 수집: `supporters/scripts/collect_recovery.mjs`
- 테스트: `supporters/scripts/gate/plan.test.mjs`(빈 관광 데이터면 관광 검사 건너뜀), `npm run gate:test`(41건)
- 설계 문서(메인): `docs/INFINITH_Viewclinic_Supporters_Site_Design_v0.2.md` §13, HTML판 `docs/prd/…_v0.2.html`
- 비교 이미지(메인): `docs/reports/viewclinic/04_supporters/planner/Recovery_Planner_Before_After_2026-09-10.png`