Commit Graph

273 Commits

Author SHA1 Message Date
Haewon Kam
01ad08c5f3 chore(supporters): 원진 네이버 소유 확인 값 (wonjin.webforai.kr)
2026-09-14 서치어드바이저 발급분. 사이트마다 값이 달라 옮겨 쓰면 확인되지 않는다.
배포 확인: 뷰와 원진이 서로 다른 값을 내고 오라클은 아직 없다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 16:07:06 +09:00
Haewon Kam
9b717dbcfc fix(worker): 빌드마다 템플릿 화면 코드를 갱신 · 뷰 네이버 소유 확인 값
템플릿은 data 단계에서만 복사돼, --from build 로 돌리면 그 사이에 고친 화면 코드가
기존 병원 폴더에 닿지 않았다. 오늘 두 건이 이 이유로 배포되지 않았다.
- 검색엔진 소유 확인 메타: site.json 에 값이 들어갔는데 화면에 안 나왔다
- 회복 일정 플래너 계측(plan_procedure_select·plan_result·plan_save): 세 사이트 모두 없었다

refreshTemplateCode() 가 build 단계에서 화면 코드만 다시 덮는다.
src/layouts·components·pages·styles·lib 과 lib.ts·content.config.ts 가 대상이고,
병원 데이터·글·이미지는 건드리지 않는다. 병원별로 갈리는 astro.config.mjs·vercel.json 의
치환값, 구조 기준선, home_text 도 덮지 않는다. 내용이 같은 파일은 건너뛴다.

뷰 브리프에 네이버 서치어드바이저 소유 확인 값을 넣었다(viewpl.webforai.kr 용).
사이트마다 값이 달라 옮겨 쓰면 확인되지 않는다는 것을 주석에 적었다.

검증: 세 사이트 재배포 후 뷰에 소유 확인 메타가 나오고 다른 두 곳에는 안 나온다.
플래너 계측은 세 곳 모두 번들에 들어갔다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 16:01:44 +09:00
Haewon Kam
f68e4785bf chore(front): webforai.kr 네이버 소유 확인 메타 추가
네이버 서치어드바이저는 DNS TXT 를 받지 않아 메타 태그로만 소유가 확인된다.
구글은 webforai.kr 도메인 속성을 DNS TXT 로 확인해 메타가 필요 없다.

VITE_SITE=discovery 빌드에만 들어간다. infinith-demo 빌드에는 나가지 않는다.
서포터즈 사이트는 코드가 달라 briefs/<clinic>/clinic.json 의 site.naverSiteVerification
으로 각각 넣는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 15:44:39 +09:00
Haewon Kam
247d29173d fix(supporters): 검색엔진 소유 확인 메타 태그를 실제로 렌더
site.json 에 googleSiteVerification·naverSiteVerification 키는 있었는데 어디에서도
메타 태그로 내지 않았다. 값을 넣어도 소유 확인이 되지 않는 상태였다.
색인 등록을 시작하려다 드러났다.

Base.astro 가 값이 있을 때만 메타를 낸다. 없으면 태그 자체가 나가지 않는다.
소유 확인은 색인 허용과 무관하므로 noindex 상태에서도 미리 해 둘 수 있다.

구글은 DNS TXT 로도 되지만 네이버 서치어드바이저는 메타 태그나 파일만 받는다.

검증: 값을 넣은 빌드에 메타 2개, 값 없는 빌드에 0개. 게이트 41/41, check 오류 0건, tsc 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 15:33:49 +09:00
Haewon Kam
3d8603f5e1 docs: 핸드오버 §5-4·§0 에 도메인 연결 완료 반영
webforai.kr 등록·네임서버 위임·주소 연결이 모두 끝났다. 연결된 주소 4개와
각 Vercel 프로젝트를 표로 적었다.

AI Discovery 랜딩을 별도 프로젝트(infinith-discovery)로 뺀 이유를 남겼다.
/discovery 가 infinith-demo 안의 경로라 도메인만 붙이면 기존 INFINITH 랜딩이 뜨고,
SPA 라 rewrite 로도 안 된다. 루트에서 무엇을 그릴지 VITE_SITE 로 정한다.

새 병원을 붙이는 순서를 2단계로 줄였다. 레지스트리에 서브도메인을 넣고
워커를 --domain 으로 돌리면 DNS·인증서는 Vercel 이 한다.

아직 꺼져 있는 자동연장·도메인 잠금을 상태 표와 프롬프트에 적었다.
이 도메인 하나에 병원 사이트가 전부 얹히므로 갱신을 놓치면 한꺼번에 멈춘다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 15:29:47 +09:00
Haewon Kam
7dd14f43bc feat(front): 배포별 head 메타 (제목·설명·og)
index.html 을 두 배포가 공용으로 쓰는데 제목이 하나뿐이라, webforai.kr 이 AI Discovery
랜딩을 띄우면서 제목은 'INFINITH - Infinite Marketing' 으로 나갔다. 설명과 og 태그는
아예 없었다. 답변엔진이 읽는 첫 신호라 비워 두면 안 되는 자리다.

VITE_SITE=discovery 빌드는 AI Discovery 제목·설명을, 아니면 기존 INFINITH 제목을 넣는다.
설명과 og:title·og:description·og:type·og:locale 도 함께 넣는다.

검증: 변수 없는 빌드는 기존 제목 유지, discovery 빌드는 새 제목. tsc 0 에러.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 15:28:04 +09:00
Haewon Kam
8bd168e1c7 fix(worker): 사이트 주소 설정을 build 단계에서도 적용
--from build 로 재배포하면 vercel.json 의 SITE_URL 이 갱신되지 않아 canonical 과
사이트맵이 옛 .vercel.app 주소로 나갔다. 그 코드가 data 단계에만 있었기 때문이다.
오늘 세 사이트를 새 도메인에 붙이고 확인하다 드러났다.

applySiteUrl() 로 떼어내 data 와 build 두 단계에서 부른다. 어느 지점부터 돌려도
주소가 반영된다. 색인 허용 여부(PUBLIC_INDEXABLE, X-Robots-Tag 제거)도 같은 함수가 맡는다.

검증: 세 사이트 재배포 후 canonical·사이트맵이 모두 새 주소로 바뀌고 noindex 는 유지된다.
- viewpl.webforai.kr · wonjin.webforai.kr · oracle.webforai.kr

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 15:27:08 +09:00
Haewon Kam
98d52f20f1 feat(front): 루트 페이지를 배포별로 분기 (VITE_SITE=discovery)
webforai.kr 이 AI Discovery 랜딩을 띄워야 하는데, /discovery 는 infinith-demo 안의
경로라 도메인만 붙이면 기존 INFINITH 랜딩이 뜬다. SPA 라 rewrite 로도 안 된다.
React Router 가 주소로 판단하기 때문이다.

VITE_SITE=discovery 로 빌드한 배포만 루트에 AI Discovery 랜딩을 놓는다.
값이 없으면 지금까지처럼 INFINITH 랜딩이다. infinith-demo 의 동작은 바뀌지 않는다.

한 코드베이스로 두 사이트를 내는 방식이라 랜딩을 고칠 때 양쪽에 한 번에 반영된다.

검증: 변수 없는 빌드와 VITE_SITE=discovery 빌드 모두 성공, tsc 0 에러.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 15:17:48 +09:00
Haewon Kam
682d426a2a docs: 파이프라인 설명에 주변 안내 복원 · 워커 단계 주석을 실제와 맞춤
haewon 지적: 파이프라인 설명에서 주변 안내(/stay·/en/stay)가 빠져 있었다.
오늘 머지가 떨어뜨렸던 바로 그 페이지인데 설명에 없으니 계속 잊힌다.
§0 프롬프트, §1 표 3행, §3 되는 것 세 곳을 고쳤다.

워커 주석의 단계 목록도 낡아 있었다. 실제 PHASES 는 18단계인데 주석은 15단계였고
planner·heroes·publish 가 빠져 있었다. 주석과 실제가 18개로 맞는 것을 확인했다.
단계마다 무엇을 만드는지 한 줄씩 붙였다. tourism 이 /stay 를 만들고 planner 가
/plan 을 만든다는 것이 이름만으로는 드러나지 않아 오늘 같은 혼동이 났다.

사용법 주석에 --domain 과 --indexable 을 추가했다. 둘 다 다음 세션이 쓸 인자인데
적혀 있지 않았다.

배포본 세 곳의 /stay·/en/stay 가 모두 200 인 것을 확인했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 11:45:59 +09:00
Haewon Kam
d847027bf2 docs: 핸드오버에 도메인·레지스트리(§5-4) 반영 · §0 프롬프트 갱신
§0 프롬프트가 오늘 작업으로 낡았다. 브랜치 3개가 main 으로 합쳐졌고 작업 위치도
Productize-2(main)로 바뀌었다. 메인 체크아웃은 다른 작업의 미커밋 변경이 있어
건드리지 않는다는 것과, Supabase CLI 링크가 그쪽에만 있다는 것을 적었다.
결재 대기 중인 도메인 품의가 다음 세션의 첫 걸림돌이라 프롬프트 본문에 넣었다.

프롬프트에 원칙 두 줄 추가.
- 머지 직전에 브랜치 끝을 다시 읽는다. 오늘 이것을 놓쳐 첫 머지가 주변 안내와
  publish 단계를 떨어뜨렸다.
- 운영 DB 에 db push 를 쓰지 않는다. 이력이 실제와 어긋나 7개를 다시 실행하려 든다.

§5-4 신설: 주소 방식 결정과 근거, 지금 상태, 레지스트리에 넣은 컬럼·제약,
도메인 등록 후 순서(네임서버 위임 → --domain 재배포 → --indexable 은 붙이지 않음),
규모가 커질 때 대비할 것(병원 간 유사도 상한은 아직 없는 방어), DB 작업 주의.

§5 결정 대기 5번(도메인)을 결정으로 바꾸고, §7 파일 참조에 오늘 산출물을 넣었다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 11:37:08 +09:00
Haewon Kam
d4969da451 docs(db): 마이그레이션 파일과 운영 DB 대조표 (읽기 전용 조회)
migration repair 를 하기 전에 무엇이 다른지 먼저 확인했다. 이력에는 10개 중 3개만
기록돼 있고 나머지는 SQL 편집기로 직접 만든 상태라, 그대로 repair 하면 파일과 DB 가
다른데 같다고 기록돼 db diff·db pull 이 어긋난 결과를 낸다.

정본은 마이그레이션 파일로 정했다(haewon 2026-09-14).

결과: 표 17개 중 15개가 정확히 일치한다. 손볼 곳은 세 가지다.
- clinic_registry: 파일에만 is_active·verified_at·verified_by, DB 에만 notes.
  notes 는 74곳 전부에 값이 있어 실제로 쓰이므로 파일에 반영해야 한다.
- channel_latest·channel_weekly_delta 는 뷰이고 정의가 마이그레이션 파일에 없다.

DB 는 조회만 했고 바꾸지 않았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 11:26:18 +09:00
Haewon Kam
9d8360d634 feat(db): clinic_registry 에 서브도메인 컬럼·유니크·예약어 제약 추가
서포터즈 사이트를 공용 도메인(webforai.kr)의 병원별 서브도메인에 두기로 했다.
수백 곳으로 늘 때 이름을 코드가 지으면 "뷰"·"연세"처럼 여러 병원이 쓰는 이름에서
충돌이 나므로, 이 표를 서브도메인의 단일 원본으로 둔다.

컬럼
- subdomain: 공용 도메인 앞에 붙는 라벨 (viewpl → viewpl.webforai.kr)
- clinic_slug: 워커 --clinic 값. 빌드 폴더·Vercel 프로젝트 이름에 쓰여 서브도메인과 다를 수 있다
- subdomain_assigned_at: 배정 시각. 색인 전환 전에 주소를 바꾸는 편이 싸므로 판단에 쓴다

제약
- subdomain·clinic_slug 각각 대소문자 무시 유니크
- 형식: 소문자·숫자·붙임표, 2~40자, 붙임표로 시작·끝 금지, 연속 붙임표 금지
- 예약어 70여개 차단. 메일·인증(mx·dmarc·autodiscover)을 병원에 내주면 메일 수신과
  도메인 소유 확인이 깨지고, 회수하는 시점에는 이미 색인된 주소가 깨진다

배정: 뷰 viewpl · 원진 wonjin · 오라클 oracle.
오라클은 이 레지스트리가 성형외과 73곳으로 만들어져 등록돼 있지 않아 함께 넣었다.

운영 DB 적용 중 확인한 것: 마이그레이션 이력에 10개 중 3개만 기록돼 있고 나머지는
SQL 편집기로 직접 만든 상태다. 그래서 db push 대신 이 파일만 따로 적용했다.
20260406_clinic_registry.sql 에 있는 verified_by·verified_at·is_active 는 실제 표에 없다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 11:09:52 +09:00
Haewon Kam
f26155565c fix(supporters): 클릭 집계에 호텔·항공 이벤트와 place_id 추가
방금 가져온 Planner.astro 가 호텔·항공 링크에 data-ga="hotel"·"flight" 를 붙이는데
Base.astro 의 리스너가 그 두 값을 다루지 않아 클릭이 집계되지 않았다.
메인 체크아웃의 미커밋 Base.astro 에는 이 처리가 있었고, 그쪽을 버리기 전에 옮겼다.

- click_hotel · click_flight 를 리스너에 추가
- data-ga-id 를 place_id 로 함께 보낸다 (어느 장소를 눌렀는지)
- 플래너 이벤트와 수술일 미전송 원칙을 주석에 적었다

검증: 뷰 34페이지, 게이트 41/41, check.mjs 오류 0건, tsc 0 에러, 내보내기 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 09:02:07 +09:00
Haewon Kam
e44ff60537 feat(supporters): 회복 일정 플래너 계측 이벤트 (메인 체크아웃 미커밋분에서 가져옴)
메인 체크아웃(feature/ai-sentiment-rubric)의 작업 트리에 커밋되지 않은 채 남아 있던
플래너 계측 코드가 main 에 없었다. 기록 노트 머리말이 "2026-09-12 추가 작업: 플래너
계측 이벤트 구현"이라고 적은 그 코드다. 브랜치 통합은 커밋된 상태까지만 가져가므로
빠졌고, 그래서 배포된 세 사이트에 플래너 계측이 없었다.

Planner.astro 의 계측 부분만 가져왔다(haewon 결정). 같은 미커밋분이 Base.astro 에도
GA4 태그를 넣는데, main 에는 이미 같은 태그가 들어가 있어 그대로 두었다. 두 구현이
겹치면 태그가 두 번 들어간다.

가져온 것
- track(): window.gtag 가 없으면 아무것도 하지 않는다. GA4 측정 ID 가 비어 있으면
  태그 자체가 안 나가므로 기본 상태에서 조용하다.
- plan_procedure_select · plan_result · plan_save 이벤트.
- leadBucket(): 수술일 원본을 보내지 않고 남은 기간 구간(past·0-7d·8-28d·29-90d·90d+)만
  보낸다. 체류 일수·출국 확정 여부·선호·국적도 값이 아닌 구간·플래그로 보낸다.
- 호텔·항공·상담 링크의 data-ga 속성. Base.astro 의 클릭 리스너가 이 값을 읽는다.

site.json 에 ga4MeasurementId 자리와 설명을 넣었다. 템플릿 빈 데이터셋에는 이미 있었다.

검증: 뷰 34페이지, 게이트 41/41, check.mjs 오류 0건, tsc 0 에러,
빈 데이터 템플릿 16페이지, 내보내기 0. 번들에서 gtag 미존재 시 조기 반환 확인.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-14 08:55:44 +09:00
Haewon Kam
85a9aa1f54 feat(supporters): 원진 랜딩 히어로를 글로벌 허브 리셉션 사진으로 (haewon 지정) · 갤러리 사진을 카드 후보에서 제외
haewon 육안 검토 결과: 원진 수집 이미지 66장 전부 사용 가능, 제외할 것 없음.
랜딩 히어로는 img_about_cover_03(글로벌 허브 리셉션·대기 공간)으로 지정.
이전 값 img_about_cover_01 은 원장이 모니터를 가리키는 사진이라 글 카드와 겹쳐 보였다.
alt 는 수집 원문("WJ 원진 소개 커버 이미지") 대신 무엇을 찍은 것인지 밝히는 문구로 쓴다.

갤러리에 실린 사진은 글 카드 후보에서 뺀다. 홈에서 글 목록 바로 아래가 갤러리라
카드 마지막 장과 갤러리 첫 장이 같으면 나란히 두 번 보인다.
다만 이렇게 빼서 글 수를 못 채우면 남는 글이 건물 사진으로 떨어져 더 나빠지므로,
후보가 글 수를 채울 수 있을 때만 뺀다.

결과
- 원진: 홈 13장 / 12종 · 최대 연속 1 (이전 9종 · 연속 2)
- 뷰: 홈 8장 / 4종 · 최대 연속 2. 쓸 수 있는 이미지가 3장뿐이라(건물 사진은 히어로)
  5편 중 2편이 건물 사진으로 떨어진다. 병원 제공 시설 사진이 있어야 풀린다.

검증: 두 사이트 npm run build 종료코드 0, check.mjs 오류 0건, 게이트 41/41,
tsc 0 에러, 내보내기 0. 미배포.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 16:55:40 +09:00
Haewon Kam
8f90bbb7cd docs·tools: 이미지 육안 검토 요청서 + 핸드오버 §5-3 (사람 게이트 근거·오라클 원인 확정)
build_image_review.mjs 를 검토 요청서로 다시 만들었다. 화면에 실제로 나가는 이미지를
먼저 보여주고(노란 테두리), 빼야 하는 유형을 무엇이 어떻게 생겼는지로 설명하며,
체크하면 excludeImages 에 넣을 목록이 만들어진다. 판단이 서지 않으면 빼는 쪽으로
보라고 적었다. 뷰 17장·원진 66장·오라클 0장, 그중 19장이 화면에 나간다.

핸드오버 §5-3 신설. 파일명·alt 검사로 91장 중 0장이 걸린 것을 근거로 이미지 육안 확인을
사람 게이트로 남긴다고 적었다. 규칙 문서 §4 의 IMAGE_RULE 계획은 이 유형에 효과가 없다.

오라클 원인 확정: 근거 수집일 2026-09-10 이 EUC-KR 디코딩 반영일 2026-09-11 보다
하루 빨라 옛 수집기가 alt 를 깨뜨렸다. 코드는 이미 고쳐져 있어 재수집이면 풀리지만
병원 사이트가 응답하지 않는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 16:50:14 +09:00
Haewon Kam
f75a0575db chore(supporters): 뷰 랜딩에서 가슴 라인 일러스트 제외 (haewon 지적)
view-motiva-preserve-motiva-smooth-silk 는 규칙상 시술 설명 일러스트로 허용되는
유형이지만, 랜딩의 '상담 전 질문' 카드 썸네일로 붙어 주제가 어긋나고 첫 화면에
신체 그림이 노출됐다. 홈 히어로는 이미 건물 외관으로 바꿔 둔 상태였다.

빼고 나니 뷰에서 글 대표로 쓸 수 있는 이미지가 4장(건물·의료진 단체·일러스트 2)뿐이라
5편 중 2편이 건물 사진으로 떨어진다. 홈 기준 최대 연속 2다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 16:35:13 +09:00
Haewon Kam
f0857420e1 fix(supporters): 배포를 막던 게이트 두 건 · 대표 이미지 alt 의 효과 주장 제거
뷰 배포가 Vercel 빌드에서 멈췄다. 워커는 통과했는데 Vercel 이 막힌 이유는
--from deploy 가 빌드 게이트를 건너뛰고 바로 배포로 갔고, Vercel 은 자체 npm run build
(astro build && check.mjs)를 돌리기 때문이다. 실패는 두 가지였다.

1. HOME_DUPLICATE: 검토자 표시줄의 원장 이력이 병원 홈페이지 문장과 40자 일치했다.
   이 자리는 병원 의료진 페이지의 이력을 프로필 링크와 함께 그대로 옮기는 귀속 표시라
   설계상 일치한다. 다른 말로 바꿔 쓰면 이력이 사실과 달라진다.
   /stay 의 인용 블록(#recovery-quote)을 이미 같은 이유로 빼고 있어서, 같은 규칙으로
   .doctor-strip 을 QUOTED_BLOCKS 에 넣었다. 금칙어·운영자 어휘 검사는 그대로 적용된다.

2. 대표 이미지 alt 의 효과 주장: 배정된 alt 가 "손상된 피부 세포 재생과 콜라겐 생성으로
   흉터와 색소침착 개선" 처럼 결과를 주장했다. 의료법 56조 2항 8호 대상이고 주제도 맞지 않았다.
   이미지 자체는 문제가 없으므로 빼지 않고, 효과·결과 어휘가 있으면 출처만 밝히는 중립
   문구로 바꾼다. 수집기의 분류를 믿지 않는다(일러스트가 시설로 들어온다)는 이유로
   "시설 사진" 처럼 유형을 단정하지 않고 "홈페이지 이미지"로 쓴다.

검증: 세 사이트 모두 npm run build 종료코드 0(Vercel 이 돌리는 명령과 같다).
게이트 41/41, 샘플 check.mjs 오류 0건, tsc 0 에러, 내보내기 0.
연속 중복은 뷰 1·원진 1 이고, 오라클은 수집 이미지가 없어 그대로다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 16:27:30 +09:00
Haewon Kam
dd754cf212 feat(supporters): 글마다 다른 대표 이미지 배정 · 뷰 수집 이미지에서 의료광고 금지 유형 제외
haewon 지적: 목록 화면에 같은 사진이 나란히 선다.

원인은 PostCard 의 대체 순서다. thumbnail·hero·영상이 모두 없으면 건물 사진 하나로
수렴한다. 뷰는 5편 전부, 오라클은 8편 전부가 그랬고, 원진은 6편 중 3편이 같은
소개 커버를 쓰고 있었다.

heroes 단계를 워커에 넣었다(generate 다음, build 앞). scripts/assign_post_heroes.mjs 가
images.json 에서 글마다 다른 사진을 고른다.
- 글 분류별로 어울리는 유형을 먼저 쓴다. 병원 소개·방문은 시설, 시술 정보는 시술 설명
  일러스트, 안전은 장비 순이다. 방문 안내에 시술 일러스트가 붙는 것을 막는다.
- 의료진 사진은 쓰지 않는다. 저자·검토자 표시가 지정 용도이고, 글 대표로 쓰면 그 원장이
  쓴 글로 읽힌다.
- 홈 히어로·건물 사진과 겹치는 글도 다시 배정한다.
- 수집 원문 alt 를 그대로 쓰지 않는다. 원문은 술기 설명 문단이라 고객 화면에 낼 수 없어
  첫 구절만 줄여 쓴다. 캡션의 출처도 페이지 제목이 슬로건일 때 상호로 바꾼다.
- 이미지가 글보다 적으면 남는 글은 비워 둔다. 다시 쓰면 처음 문제로 돌아간다.

작업 중 더 큰 문제를 찾았다. 뷰의 수집 이미지 중 다섯 장이 의료광고 금지 유형인데
전부 시설(clinic)로 분류돼 홈과 /clinic 에 나가고 있었다.
- img02: 밑선 절개 흉터의 1개월·6개월 경과를 나란히 놓은 전후 사진
- stemcell_about_01: 팔에 주사·드레싱을 하는 시술 행위 사진
- view-abdominoplasty 2장, view-motiva-preserve-premium-standard 2장: "이미지 광고 모델" 표기가 있는 모델 신체 사진
- stemcell_count_01_mo: 장비 제조사의 성능 주장 그래픽
파일명과 alt 에 아무 신호가 없어 규칙 문서가 예고한 파일명·alt 검사로는 잡히지 않는다.
briefs/viewclinic/clinic.json 의 excludeImages 로 뺐고, 홈 히어로가 가슴 라인
일러스트였던 것과 건물 사진 alt 가 "가슴확대 시설 사진"이던 것도 함께 고정했다.

육안 검토용 scripts/build_image_review.mjs 를 만들었다. 세 병원 수집 이미지를 한 화면에
모아 분류·쓰이는 곳·의심 표시를 보여준다. 91장 중 파일명·alt 로 걸러진 것은 0장이었다.
이 유형은 사람이 봐야 갈린다는 뜻이다.

결과: 홈·목록의 연속 중복이 뷰 1, 원진 1 로 내려갔다(이전 뷰 6, 원진 3).
오라클은 수집 이미지가 0장이라 배정할 것이 없다. 근거의 이미지 alt 가 EUC-KR 에서
깨져(????) 분류기가 하나도 고르지 못하는 것이 원인으로 좁혀졌으나, 병원 사이트가
응답하지 않아 재수집·검증을 하지 못했다.

검증: 게이트 41/41, check.mjs 오류 0건, tsc 0 에러, 내보내기 종료코드 0. 모두 미배포.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 16:15:52 +09:00
Haewon Kam
4354d7fa6c fix(worker): 상호를 브리프 고정값에서 먼저 읽는다 · 뷰·원진·오라클 고정값 추가
재빌드 검증 중에 홈 제목 추정이 슬로건을 상호로 삼는 것을 발견했다.
뷰는 '안전을 최우선하는 뷰성형외과', 원진은 '당신만 봅니다'가 상호가 됐다.
원진은 그 이름으로 네이버 지역검색을 해 주변 안내 기준 좌표까지 실패했다.

data 단계가 briefs/<clinic>/clinic.json 의 factSheet 상호를 --name 과 홈 제목 추정보다
먼저 읽게 했다. 상호를 쓰는 뒤 단계(discover·news·tourism)까지 올바른 값이 간다.
inputs 단계의 고정값 덮어쓰기만으로는 그 단계들이 이미 틀린 이름으로 돈 뒤였다.

브리프 고정값: 뷰(name·shortName·kind·areaLabel·founded·urlEn),
원진(name·shortName·kind), 오라클(name·shortName 추가).
근거를 확인하지 못한 값은 비워 두었다.

재빌드 결과(미배포): 세 사이트 모두 제목이 기존 배포본과 일치하고 잃은 경로가 없다.
뷰는 /plan·/en/plan·/stay·/en/stay·/en 5개, 원진·오라클은 /en 이 새로 생겼다.
원진 주변 안내 수집도 좌표를 다시 잡아 국문 123곳·영문 99곳으로 성공했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 15:55:31 +09:00
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
0a0f64c29e merge: feature/ai-sentiment-rubric 진행분 (주변 안내 정본 반영, §8 인사이트) 반영
supporters/ 정본에 주변 안내(/stay·/en/stay)가 i18n 방식으로 들어왔다.
recoveryNotes 는 뷰 실데이터를 유지한다.
핸드오버 제목 날짜를 2026-09-12(토)로 맞추고, §8-1 과 §8-11 에 이번 통합에서
같은 사고를 되풀이한 기록과 재발 방지(머지 직전 브랜치 끝 재확인)를 남겼다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 15:20:46 +09:00
Haewon Kam
bb68bdacad merge: feature/supporters-autobuild 진행분 (주변 안내 /stay, 워커 publish 색인 단계) 반영
머지 뒤에 브랜치가 5개 커밋 앞서 있었다. 주변 안내(/stay·/en/stay) 복원과
워커 publish 단계(IndexNow·검색 콘솔 소유 확인)가 거기 있었고, 먼저 올린 머지가
이 둘을 떨어뜨렸다. supporters/ 정본은 i18n 방식을 유지하고, 사이트맵과 site.json 은
양쪽 추가를 모두 살렸다. 템플릿은 supporters/ 에서 다시 내보낸다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 15:19:41 +09:00
Haewon Kam
b79565a6a6 docs: 핸드오버에 2026-09-12 확인 결과·§4-1 완료·판단 2건 기록
§1: 미확인으로 남겨 둔 항목을 실제로 확인해 표 앞에 결과를 붙였다. 리드 CTA 와
v2 기준표는 이미 main 에 있고, Supabase 마이그레이션은 전부 적용됐으며,
discovery_results 는 없다. supporters-viewclinic 의 /plan 이 404 인 것도 적었다.

§2: feature/product-1.0 으로 합친 결과와, 핸드오버가 적지 않은 네 번째 브랜치
Productize(랜딩 SSR 프리렌더·robots/sitemap/llms.txt)를 적었다.

§4-1: 완료로 바꾸고 정본 결정이 초안과 반대 방향임을 밝혔다.

§5: haewon 이 답한 두 항목(Product 1.0 범위 b, supporters 정본)을 결정으로 적었다.

§5-2 신설: 이번 세션에 내린 판단 2건을 발견·이유·한 것·되돌리는 법으로 남겼다.
영문 의료광고 고지를 승인 없이 번역하지 않기로 한 것과, 누락 탐지기가 상호만 찾아
지명으로 적힌 사실을 놓치던 것을 고친 내용이다. 빈 데이터로 빌드해 봐야 하드코딩이
드러난다는 것과, 게이트가 통과해도 빈 값이 만든 비문은 잡히지 않는다는 것을 함께 적었다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 15:17:23 +09:00
Haewon Kam
e7a11ef67a fix(supporters): 영문 사실이 없는 병원에서 영어 홈이 깨지지 않도록 조각 단위로 조립
세 병원 재빌드를 앞두고 빈 데이터로 템플릿을 빌드해 보니 영어 홈이 깨졌다.
제목이 ", Seoul · Recovery planner", 히어로가 ", plan your stay before you fly.",
소개 문장이 "is a at ." 로 나왔다. 게이트는 이것을 오류로 잡지 않는다.
세 병원 모두 factSheetEn 이 비어 있어 그대로 배포하면 깨진 화면이 나간다.

고친 것
- 병원명: factSheetEn 의 영문 표기가 없으면 한국어 상호를 그대로 쓴다. 이름은 지어내지 않는다.
- 소개 문장: 업종·지역·설립연도 중 데이터에 있는 조각만 잇고, 하나도 없으면 문장 자체를 뺀다.
- 히어로 제목: 이름이 없으면 이름 줄을 빼고 문장을 대문자로 시작한다.
- 페이지 제목·설명·JSON-LD 이름: 같은 방식으로 조각을 잇는다. 제목에 박혀 있던 "Seoul" 을 뺐다.
- 머리말 기본값 "VIEW SUPPORTERS" 를 "SUPPORTERS" 로 바꿨다. 다른 병원 화면에 뷰가 나오던 자리다.

검증
- 빈 데이터 템플릿 14페이지: 제목 "Recovery planner, getting here, clinic facts",
  히어로 "Plan your stay before you fly." 로 문장이 성립한다.
- 뷰 32페이지: 제목·히어로·소개 문장이 모두 그대로다.
- 게이트 41/41, check.mjs 오류 0건, tsc 0 에러, 내보내기 종료코드 0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 15:15:45 +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
1a7195a96a docs: 하위 핸드오버에 월요일 세션·최종 상태 표기
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 19:51:55 +09:00
Haewon Kam
730f7822c3 docs: 제품 핸드오버에 §8 인사이트 12건, 월요일(09-14) 시작 절차 반영
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 19:51:22 +09:00
Haewon Kam
da6397ca3c fix(supporters): astro.config 의 /stay→/recovery 리다이렉트 제거 (주변 안내 페이지가 리다이렉트 HTML 로 덮이던 원인)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 18:30:24 +09:00
Haewon Kam
f26ba37948 docs: 주변 안내 복원과 '기존 페이지를 덮어쓰지 않는다' 함정 기록
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 18:29:04 +09:00
Haewon Kam
7b1be074ad docs: 주변 안내 복원 기록
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 18:29:04 +09:00
Haewon Kam
dca494fc21 feat(supporters): 주변 안내(/stay·/en/stay) 뷰 샘플에 추가 · 내비·언어 짝·사이트맵·스타일 이식, 구조 기준선 갱신
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 18:28:13 +09:00
Haewon Kam
d66e6279ed feat(supporters): 주변 안내(/stay·/en/stay) 복원 · 회복 일정 플래너(/plan)와 별개 페이지로
- 오라클 폴더에 남아 있던 최신본(장소·축제·동선 지도·날씨·시술 후 관리 접이식)을 /stay 로 복원. 제목 Around The Clinic, 회복 일정 플래너 링크
- 내비 '주변 안내'·'Nearby', 언어 짝 /stay↔/en/stay, 사이트맵, /stay 리다이렉트 제거(/recovery→/plan 은 유지)
- 구조 기준선 갱신(내비 항목 추가, haewon 지시 2026-09-11)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 18:28:12 +09:00
Haewon Kam
daf6350c49 docs: 제품 핸드오버에 발행(색인) 단계와 완료 정의 추가
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 15:28:51 +09:00
Haewon Kam
891b7bdece feat(supporters): 워커 publish 단계 · 배포 뒤 색인 작업 자동화 + 사람 체크리스트
- scripts/publish_site.mjs: 라이브 확인(홈·robots·sitemap·noindex), IndexNow(빙·네이버) 사이트맵 URL 알림, Google Search Console 사이트맵 제출·URL 색인 상태(서비스 계정 있을 때), 사람 몫 체크리스트(publish-checklist.md, status.humanTasks)
- 워커: data 단계에서 IndexNow 키 파일 생성, --indexable(noindex 헤더 제거·승인 글만), --domain(vercel domains add·SITE_URL), deploy 뒤 publish 단계, 상태 published_pending_tasks
- Base.astro: google/naver 소유 확인 메타(site.json googleSiteVerification·naverSiteVerification)
- 완료 정의: 배포가 아니라 색인 작업과 사람 체크리스트까지 (haewon 2026-09-11)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 15:28:48 +09:00
Haewon Kam
f01bc6cafc merge: feature/supporters-autobuild + feature/ai-sentiment-rubric 를 Product 1.0 한 줄기로 합침
Product 1.0 범위는 진단 + 서포터즈 초안(haewon 결정).

브랜치 확인 결과 핸드오버 §1 의 미확인 항목 두 건은 이미 해결 상태였다.
리드 CTA(DiscoveryLeadModal·discovery_leads 마이그레이션)와 AEO/GEO v2 기준표는
셋 다 main 에 있고 blob 이 동일하다. feature/discovery-url-cta 는 main 대비
ahead 0 / behind 22 인 낡은 포인터라 머지 대상에서 뺐다.

supporters/ 정본은 메인 쪽(뷰 수작업 샘플)으로 정했다(haewon 결정).
겹친 22개 파일 중 실제로 다른 것은 9개였고 전부 메인 쪽을 취했다.
layout-baseline.json 은 Base.astro 가 내는 언어 전환 링크 모양(a.lang-switch)과
짝이라 같은 쪽으로 가져왔다.

Productize 쪽에만 있던 두 가지를 정본으로 옮겼다.
- GA4 태그: site.json 의 ga4MeasurementId 가 G-형식일 때만 삽입한다.
  값이 없으면 스크립트가 아예 나가지 않는다. 키 이벤트 이름은
  data/ai_channels.json 의 conversion_events 와 맞춘다.
- 영문 법적 고지: 지원 관계·부작용 고지는 의료법 56조 대상이라 임의 번역하지 않는다.
  i18n.ts 에 병원 승인 없는 영문 번역이 들어 있어 푸터에서 쓰지 않도록 했다.
  site.json 의 sponsorNoticeEn · factSheet 의 sideEffectNoticeEn 이 채워지기 전까지
  영문 화면은 한국어 원문과 확인 대기 표기를 함께 낸다.

검증: astro build 32페이지, 게이트 41/41 통과, check.mjs 오류 0건
(경고 23건은 기존 건으로 site.sponsorNotice 미설정 18건과 원고 수치 한정 5건),
루트 tsc --noEmit 0 에러. GA4 는 임시 측정 ID 로 삽입·미삽입 양쪽을 확인하고 원복했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 14:34:47 +09:00
Haewon Kam
6c3e2888a7 docs: AI Discovery Product 빌드 핸드오버 (제품 여정·상태, 브랜치·배포 지도, 빌드 순서, 결정 대기, 함정)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:22:58 +09:00
Haewon Kam
c044546614 docs: 서포터즈 빌드 절차 문서를 제품 핸드오버의 하위 문서로 표기
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:22:18 +09:00
Haewon Kam
99195f09f3 docs: 다음 세션 핸드오버 (Product build 절차·격리 구조·결정 대기·함정) + 오라클 핸드오버 커밋
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:14:46 +09:00
Haewon Kam
008411b929 feat(supporters): 워커 planner 단계에 관리 문장 필터 (효과 주장·홍보·정형 고지·표 조각·재수술 조언 제외) + 세부 시술명 접두
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 14:10:17 +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
0108fe1ff1 chore(supporters): 원진 큐레이션 기준 좌표를 네이버 지역검색 결과로 갱신
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 13:46:39 +09:00
Haewon Kam
0cc37b1b89 feat(supporters): 원진 큐레이션 장소 브리프(briefs/wonjin/planner.places.json), 플래너 추천 장소 설명을 데이터 유무에 따라 표기
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 13:11:51 +09:00
Haewon Kam
93509bf9b3 chore(supporters): 플래너 추천 장소 설명을 관광공사 데이터 유무에 따라 표기
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 13:11:25 +09:00
Haewon Kam
620b2cda59 style(supporters): 지도 출처 줄을 행 밖으로 옮겨 지도 상자와 카드 아래선을 맞춤
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 11:52:37 +09:00
Haewon Kam
94d7edec45 style(supporters): 지도 출처 줄을 행 밖으로 옮겨 지도 상자와 카드 아래선을 맞춤
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 11:51:53 +09:00
Haewon Kam
df6ad3bbd2 style(supporters): 오시는 길 지도를 카드 높이에 맞춰 늘림
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 11:49:37 +09:00
Haewon Kam
d13ac35365 style(supporters): 오시는 길 지도를 카드 높이에 맞춰 늘림 (열 비율 1.5:1, invalidateSize)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 11:48:49 +09:00
Haewon Kam
ed8f65030d feat(supporters): 오시는 길 지도·길찾기(VisitMap) 템플릿 반영, 워커 tourism 단계가 factSheet.geo 좌표 기록
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-11 11:38:53 +09:00
Haewon Kam
587462552b feat(supporters): 오시는 길 지도·길찾기 (VisitMap) 방문 안내와 영어 홈에 추가
- OpenStreetMap 타일 + Leaflet(cdnjs) 지도, 병원 핀, 주소 복사, 문의 전화, 네이버·카카오 길찾기(영어 화면은 구글 길찾기 추가). 벤치마크 2026-09-11
- 좌표는 factSheet.geo(운영 기록 source 는 화면에 내지 않음), 없으면 관광공사 수집 메타, 둘 다 없으면 지도 없이 주소·버튼만

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