Commit Graph

9 Commits

Author SHA1 Message Date
Haewon Kam
82aa56fa40 chore(supporters): 통합 뒤 템플릿 재생성 (주변 안내 포함, 영어 홈 안전 기본값)
정본 supporters/ 와 템플릿의 페이지 집합이 같아졌다.
/stay·/en/stay·/en·/plan·/en/plan 이 양쪽에 모두 있다.

검증
- 뷰 34페이지, 게이트 41/41, check.mjs 오류 0건.
- 빈 데이터 템플릿 16페이지, 영어 홈에 병원 고유 사실 0건, 문장 성립.
- 내보내기 종료코드 0, tsc 0 에러.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 15:21:31 +09:00
Haewon Kam
e60ef04503 feat(supporters): 영어 화면의 병원 고유 사실을 데이터에서 읽도록 바꾸고 템플릿 재생성
templates/supporters-astro 는 supporters/ 에서 만들어지는 파생물인데, 정본이 된
supporters/ 코드에 뷰 고유 사실이 문장으로 박혀 있었다. 그대로 내보내면 다른 병원
사이트에 틀린 사실이 나간다. 빈 데이터로 빌드해 보니 실제로
"Founded 확인 대기 · Sinnonhyeon Station Exit 3" 가 나왔다.

데이터로 바꾼 곳 (전부 factSheetEn.json 에 이미 있던 값이다)
- 히어로 이미지 alt: site.json 의 heroImageAltEn 을 읽고, 없으면 한국어 alt 를 쓴다.
- 히어로 칩: 설립연도와 위치를 데이터에 있는 것만 잇는다. 둘 다 없으면 칩을 내지 않는다.
- 방문 카드 요약: factSheetEn 의 airportShort 가 있을 때만 경로를 적는다.
- 병원 카드 요약: 설립연도와 factSheetEn 의 building 첫 문장을 데이터에서 잇는다.
- 공항 카드: factSheetEn 의 airport 가 있을 때만 카드를 낸다.
- 영문 플래너 병원명: factSheetEn 의 shortName 을 읽고, 영문 표기가 없는 병원은
  한국어 상호를 쓴다.
- 404 안내: 상호를 factSheet 에서 읽는다.

템플릿 빈 데이터셋에 factSheetEn.json 이 없어서 뷰의 영문 사실이 통째로 남고 있었다.
빈 factSheetEn.json 을 만들고 site.json 에 heroImageAltEn 자리를 넣었다.

export_template.mjs 의 누락 검사가 상호만 찾아 지명으로 적힌 사실을 놓쳤다.
지명·건물 표현을 패턴에 넣고, 문장을 그리는 코드(src/pages·layouts·components·lib)만
내보내기를 멈추게 하고 데이터·빌드 도구는 알림만 하도록 나눴다. 빌드 도구의 기본 인자
때문에 검사가 늘 실패해 신호가 되지 못하던 문제도 함께 풀린다.

검증
- 빈 데이터 템플릿 빌드 14페이지, 영어 홈에 병원 고유 사실 0건, 사실을 말하던 조각은
  생략되고 요약문만 일반 문장으로 남는다.
- 뷰 사이트 빌드 32페이지, 영어 홈의 칩·공항 카드·요약문이 모두 그대로 나온다.
- 게이트 41/41 통과, check.mjs 오류 0건(경고 23건은 기존 건).
- 루트 tsc --noEmit 0 에러, 내보내기 종료코드 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 14:27:57 +09:00
Haewon Kam
5263593816 style(supporters): 태블릿·모바일 헤더 규칙 이식 (브랜드+언어 전환 한 줄, 메뉴 가로 스크롤) · 로고와 메뉴 겹침 해결
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:07:10 +09:00
Haewon Kam
aa5b05227f feat(supporters): 회복 일정 플래너를 템플릿·워커에 통합 (/plan·/en/plan), /recovery·/stay 를 /plan 으로 정리
- 템플릿: Planner.astro, lib/plan.ts·tour.ts, styles/plan.css, planStrings, pages plan·en/plan·404. Base 내비 회복 일정 → /plan, 언어 짝 /plan↔/en/plan, 옛 주소 리다이렉트(vercel.json), 사이트맵
- 워커 planner 단계(recovery 다음): scripts/build_planner_data.mjs 가 업종별 기본 규칙표(scripts/template/planner/procedures.plastic|derm.json)에 병원 시술 페이지 원문(recoveryNotes)을 matchKeywords 로 붙이고, 장소는 briefs/<clinic>/planner.places.json(큐레이션) 또는 범용 기본표(관광공사 기준 좌표)로 만든다
- 브리프: viewclinic·oracle 큐레이션 장소. 빈 템플릿(관광 데이터 없음)도 빌드·검증 통과(plan.test 14건)
- 이전 세션의 미커밋 작업(피부과 수집·OCR·게이트·언어 스위치, stay 페이지 제거)도 이 커밋에 함께 들어감. docs/prd 변경은 제외

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 11:27:59 +09:00
Haewon Kam
2fc3f93163 fix(supporters): 동선 지도를 실제 OpenStreetMap 타일로 교체 + 핫링크 차단 대응
지도가 회색 바탕에 점만 찍혀 있어 어디인지 알 수 없었다. OSM 타일을 좌표로 직접
깔고 그 위에 핀을 얹었다. 지도 라이브러리는 부르지 않는다.
- Web Mercator 로 lat/lng → 월드 픽셀을 계산하고, 모든 지점이 여백 안에 들어오는
  가장 확대된 배율을 고른다(뷰성형외과 동선은 z=15).
- 타일은 img 가 아니라 CSS 배경으로 둔다. 장식 요소이고, 지도의 뜻은 감싸는 요소의
  aria-label 이 전한다. 스크린리더가 타일 조각을 하나씩 읽지 않는다.
- OSM 정책에 따라 "© OpenStreetMap contributors" 를 표기한다.

사진 핫링크
- 모든 사진에 referrerpolicy="no-referrer" 를 넣었다. 네이버 썸네일 CDN 이
  리퍼러를 보고 403 을 준다. 서버에서 검사할 때는 리퍼러가 없어 통과해 놓치기 쉽다.
- 사진 alt 를 채웠다. npm run build 의 접근성 게이트가 빈 alt 를 오류로 잡는다.
  로컬에서 astro build 만 돌려 게이트를 건너뛴 탓에 배포에서 처음 걸렸다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 14:01:16 +09:00
Haewon Kam
e32633e9a6 feat(supporters): /en/stay 를 참고 사이트 수준으로 다시 지음 — 설명문·이동시간·계절축제·동선·날씨
haewon 이 준 참고 사이트(스테이,머뭄)의 연동 범위에 맞춰 다시 만들었다. 앞서 만든 것은
거리순 표였고, 실제로 필요한 것은 설명문과 이동 시간이 붙은 카드, 계절로 묶은 축제,
시간표가 있는 동선이었다.

수집 (scripts/fetch_medical_tourism.py)
- detailCommon2 의 overview 를 가져온다. locationBasedList2 는 설명문을 주지 않아
  카드에 이름과 주소만 남았다. 123/125 건 확보.
- 이동 시간을 낸다. 참고 사이트 표기를 역산해 도보는 max(1, round(m/80)), 차는
  직선거리 km x 1.2 로 맞췄다(135m→2분, 566m→7분, 25km→30분). 2km 까지 도보로 보고,
  짧은 거리의 차 시간은 주차·신호 때문에 의미가 없어 최소 5분으로 둔다.
- 축제를 계절로 분류하고, 도보 시간 구간별 건수를 누적으로 집계한다.

사진 (125/125, 전부 실제로 열리는 것 확인)
목록 API 의 firstimage 만 쓰면 38건이 비었다. 폴백을 넷으로 걸었다.
  1) detailImage2 — 이미지 전용 오퍼레이션. 15건 회수(도산공원 7장이 여기 있었다)
  2) 국문 서비스 KorService2 — 영문 항목에 없어도 국문 항목에 있다. 10건
  3) 업체 공식 홈페이지 og:image — 2건
  4) Naver 이미지 검색 API — 11건
og:image 는 실제로 열어 보고 쓴다. 이미지가 아니거나 인스타 CDN 처럼 핫링크를
403 으로 막으면 화면에서 빈 칸이 되기 때문이다.
imageSource 를 항목마다 남겼다. naver 출처는 제3자 저작물이므로 내부 시연 범위이며,
공개 배포 전에는 걷어내거나 라이선스 있는 사진으로 교체해야 한다(haewon 판단).

화면 (supporters/src/pages/en/stay.astro)
- Around the clinic: 도보 시간 누적 필터, 범주별 카드, 사진 위 이동시간 배지, 설명문,
  공식 홈페이지가 있으면 링크하고 없으면 검색으로 보낸다.
- Festivals: 계절 탭.
- Shaping your days: 좌표로 그린 인라인 SVG 지도와 시간표. 외부 지도 라이브러리를
  부르지 않는다. 시각은 가정이며 화면에 그렇게 적었다.
- 오늘 날씨: Open-Meteo, 키 불필요. 빌드가 아니라 브라우저에서 받는다. 정적 빌드에
  넣으면 배포 시각의 날씨가 굳는다. 못 받으면 블록을 통째로 숨긴다.
  문구는 이 페이지의 목록에만 연결한다. 무엇을 해도 되는지는 의학 판단이라 말하지 않는다.
- 섹션 점프 바(글래스, 스티키) + IntersectionObserver 스크롤 스파이.

고친 것
- 항목마다 붙던 KO 태그를 헤더 언어 스위치 하나로 바꿨다. 짝이 있는 페이지는 서로 잇고
  없으면 그 언어의 입구로 보낸다. 영문 페이지가 늘면 PAIRS 표에 줄만 추가한다.
- .chip 클래스가 이미 있어 홈·뉴스룸·영상 페이지를 덮어쓰고 있었다. 새 스타일을
  .stay 아래로 모두 가뒀다.
- factSheet 에 영문 주소(fullEn)와 우편번호를 넣었다. 근거는 뷰성형외과 자신의
  한국관광공사 등재 항목(contentid 3364779)이며 fullEnSource 에 적었다.

템플릿은 같은 코드에 빈 데이터 스캐폴드를 둔다. 뷰성형외과 데이터가 새 병원 빌드로
새면 안 된다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 13:51:28 +09:00
Haewon Kam
a807d5dd9c refactor(supporters): 의료관광 연결을 /discovery 에서 서포터즈 사이트 /en/stay 로 옮김
붙일 자리를 잘못 잡았다. /discovery 는 INFINITH 제품의 진단 화면이고 병원마다 쓰는
범용 도구다. 외국인 환자가 보는 페이지는 병원 서포터즈 사이트다. 그쪽으로 옮겼다.

옮긴 것
- src/components/discovery/MedicalTourismPanel.tsx, src/types/medicalTourism.ts,
  src/data/medicalTourism.json 삭제. DiscoveryReportPage 원복.
- supporters/src/pages/en/stay.astro 신설. 독립 URL 과 자체 WebPage JSON-LD 를 가져
  AI 인용 단위가 된다. sitemap 에 등록하고 /visit 에서 hreflang 링크로 잇는다.
- 수집 스크립트 출력을 supporters/src/data/medicalTourism.json 으로 바꿨다.

영문 페이지 지원
- Base.astro 에 lang prop 추가(기본 ko). html lang · og:locale · 머리말 · 꼬리말이
  따라 바뀐다. 레이아웃을 하나로 유지해 한국어 페이지 동작은 그대로다.
- 의료광고 고지(지원 관계·부작용)는 규정 대상이라 임의로 번역하지 않는다. 병원이
  sponsorNoticeEn / sideEffectNoticeEn 을 확정하기 전에는 한국어 원문을 그대로 싣고
  영문 문구가 확인 대기임을 밝힌다.
- factSheet 에 nameEn / shortNameEn / shortNameEnSource 추가. 뷰성형외과 값의 근거는
  병원 자신의 영문 도메인 viewplasticsurgery.com 이며 한국관광공사 등재명도 같다.

페이지가 만들지 않는 것
- 평점·리뷰·영업시간: TourAPI 미제공이라 싣지 않는다.
- 식당의 회복 적합성: 의학 판단이라 병원이 확정한 영문 문구(site.json dietGuideEn)만
  싣는다. 확인 전에는 어떤 식당도 적합으로 표시하지 않는다고 페이지에 적는다.
- 회복 단계 일수: 병원 확정값(recoveryStagesEn). 단계는 이동 거리로만 정의한다.
- 하단에 이 페이지가 답하지 못하는 것 네 가지를 그대로 적었다.

템플릿 동기화
- templates/supporters-astro 에 같은 변경을 넣되 데이터는 빈 스캐폴드로 둔다.
  뷰성형외과 factSheet 와 관광 데이터가 새 병원 빌드에 새어 들어가면 안 된다.
  빈 데이터로 빌드해 6개 범주가 "No English listings" 로 나오는 것까지 확인했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 11:42:46 +09:00
Haewon Kam
eb873bc43a feat(supporters): 유튜브·로고 단계 — collect_youtube.mjs(API 집계·정보형 필터·쇼츠 판별), 워커 youtube 단계(로고·파비콘·homeVideos), 글↔영상 매칭, 카드 로고 대체, 기존 글 보존 재실행. 원진 재배포
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 09:09:00 +09:00
Haewon Kam
622441e6aa feat(supporters): 템플릿화 — 병원 고유값을 데이터로 분리하고 templates/supporters-astro 내보내기
- src/data/site.json 신설(매체 이름·로고·홈 큐레이션), factSheet에 kind·areaLabel·transitShort·transitNote·reservationUrl·doctorsUrl·youtube.title 추가
- lib.ts: PENDING('확인 대기')·v()·has()·surface()·editor() 도입, 스키마는 빈 값을 빼고 생성
- 페이지·컴포넌트 15개에서 뷰성형외과 하드코딩 제거, 빈 데이터 empty-state (글 0편·영상 0건·뉴스 0건·이미지 없음)
- 검증: 28페이지 표시 텍스트·구조 지문 이전 빌드와 동일(홈 title 마침표 1건만 정정), JSON-LD 차이는 빈 sameAs 제거뿐
- scripts/export_template.mjs + scripts/template/data(빈 데이터 세트) → templates/supporters-astro (빈 데이터로 10페이지 0오류 빌드, 게이트 통과)
- 게이트 픽스처를 자체 authors로 분리해 템플릿에서도 테스트 통과, 구조 기준선의 글 상세 페이지는 사전순 첫 글로 동적 선택

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 14:07:14 +09:00