Commit Graph

113 Commits

Author SHA1 Message Date
Haewon Kam
36731d3ad1 feat(discovery): JK성형외과 영문 기준 AEO/GEO 진단 추가
- 영문 사이트(jkplastic.com/en) 기준 v1.0 45/C, AEO 40/D, GEO 27/D
- audit_aeo_geo.py 자동 채점(21항목) + 영문 페이지 11개 원본 실측 보정
  - 자동 채점의 국문 전제 정규식이 놓친 B4(NAP)·C4(수치)·F1(alt) 보정
  - 외부 실측 가능한 C1·C4·C7·C8·D1·D3 확정, 오너 계정 필요한
    A6·D2·D4·E1~E4는 미검증으로 분모 제외
- discoveryResults.ts 레지스트리에 jkplastic 등록

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 10:26:51 +09:00
Haewon Kam
f38c0f3bda feat(front): 진단 요약과 보완 계획을 보여 준 뒤 빌드하게 한다
버튼만 두면 무엇에 동의하는지 모른 채 누르게 된다. 진단을 요약하고, 이 빌드가 무엇을
보완하는지 말한 뒤 누르게 한다.

처음 만든 판은 실행 항목을 카테고리로 갈라 "이 빌드로 채워지는 항목 5건"이라고 했는데
그 5건이 깨진 JSON-LD 수정·GBP 전화번호 등록·H1 재설계처럼 전부 병원 홈페이지 몫이었다.
카테고리는 무엇에 관한 문제인지를 말할 뿐 누가 고치는지를 말하지 않는다. 지키지 못할
약속이라 프레임을 바꿨다.

빌드는 홈페이지를 한 줄도 고치지 않는다. AI가 인용할 새 표면을 하나 더 만들어 약한
카테고리(콘텐츠·엔티티·표면)를 우회 보완할 뿐이다. 화면도 그렇게 말한다.
"이 빌드가 대신할 수 없는 것"으로 실행 항목이 그대로 병원 몫임을 밝힌다.

- 다크 섹션 위 주 버튼을 .btn-on-dark 로 뺀다. 기본 CTA 그라디언트(#4F1DA1→#021341)는
  끝 색이 배경(#0A1128)과 거의 같아 버튼으로 읽히지 않았다. 밝은 보라와 글로우로 떼어 놓는다.
- 문구에서 "결과"를 뺀다. 빌드가 끝나도 사진 확인과 확인 항목이 남아 최종이 아니고,
  누른 적 없는 사람에게 "결과 보기"부터 보이는 것도 맞지 않는다.
- 이전 단계로 가는 플로팅 버튼을 왼쪽 아래에 고정한다. 오른쪽 아래는 주 행동 자리이고,
  좁은 화면에서는 상단 절차 메뉴가 가로 스크롤 안으로 밀린다. 첫 단계에서는 띄우지 않는다.
- 떠 있던 승인 바와 BuildSiteCta 는 이 섹션과 역할이 겹쳐 지운다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 17:25:50 +09:00
Haewon Kam
14c4b82155 refactor(design): 요청문과 설명문을 텍스트 역할 토큰으로 가른다
"한 장씩 봐 주세요" 같은 요청문이 읽고 넘어가는 설명문과 같은 무게로 놓여 있어
지나치기 쉬웠다. 역할별 토큰과 클래스를 두고 화면에 적용한다.

  .ui-ask   요청문. 사람이 무엇을 해야 하는지 말하는 문장 (17px·600·인디고)
  .ui-ask-block  문단으로 서는 요청문. 왼쪽 규칙선으로 설명과 구분한다
  .ui-body  설명 본문 (16px·slate-600)
  .ui-note  보조·출처 (14px·slate-400)

크기는 기존 화면을 세어 맞췄다. text-base 167회·text-sm 58회가 지배적이라
body 를 16px, note 를 14px 로 두면 치환해도 크기가 변하지 않고 역할과 색만 정리된다.

한글 줄바꿈: word-break keep-all 로 어절을 지키고, 긴 URL·영문 토큰만
overflow-wrap anywhere 로 자른다. text-wrap 으로 마지막 줄에 한 어절만 남는 것을
줄이고, 62ch 로 줄 길이를 묶는다. 제목에도 keep-all 과 balance 를 건다.

다크 섹션은 .on-dark 로 값을 뒤집고, 그 안의 흰 카드는 .on-light 로 되돌린다.
이걸 두지 않으면 흰 글씨가 흰 배경에 얹혀 보이지 않는다(디자인 시스템 기록된 실수).

사진 확인 화면의 썸네일 줄이 누를 수 있는 것으로 안 읽혀 같이 고친다. 72px 카드,
호버 반응, 순번 배지, 현재 위치 표시, 안 정한 것 아래 띠, 범례, 이전·다음 이동을 둔다.
상태가 안 보이는 것이 크기보다 큰 문제였다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 16:56:52 +09:00
Haewon Kam
be1ea72fcc feat(front): 진단 리포트에서 사이트 빌드로 이어지는 화면
예전 전략마케팅 툴은 분석 진행 화면에서 단계를 보여 주고 리포트로 넘어갔다.
지금 버전은 진단과 사이트 빌드가 서로 모르는 상태로 떨어져 있어, 진단을 읽은 병원이
다음에 무엇을 하는지 알 수 없었다. 진단 → 빌드 → 사진 확인 → 확인 항목을 한 줄로 잇는다.

- /build/:id 를 추가한다. 예전 /report/loading 의 단계 UX(스피너·체크·진행바)를 잇되,
  진행 상황을 프런트가 만들지 않고 supporter_builds 를 폴링해 워커가 쓴 값을 읽는다.
  프런트가 파이프라인을 돌리지 않으므로 창을 닫아도 빌드는 계속되고, 재개 로직이 필요 없다.
- 워커 17단계를 고객이 읽을 수 있는 5묶음으로 접는다(src/lib/buildPhases.ts). 진행률은
  묶음이 아니라 끝난 워커 단계 수로 세어 한 묶음 안에서도 바가 움직인다.
- 경고로 끝난 단계는 완료 화면에 "확인 대기로 발행된 부분"으로 남긴다. 자동으로 못 채운
  값을 감추지 않는다. 멈춤은 발행 게이트와 실행 실패를 구분해 문구를 나눈다.
- 진단 리포트의 Action Plan 뒤에 빌드 구간을 둔다. 무엇을 만들어 주는지와 버튼만 둔다.
  버튼은 supporter_builds 에 queued 를 넣고 폴러가 집어 간다.
- 상단 메뉴를 경로로 가른다. 병원 작업 경로에서는 마케팅 메뉴 대신 4단계 절차를 띄운다.
  Pricing·Use Cases 는 사진을 고르는 중인 병원에게 방해다.
- 진단 데이터가 없는 병원(빌드만 한 곳)은 막다른 길 대신 빌드·사진 확인으로 잇는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 16:56:34 +09:00
Haewon Kam
5cf28d9eef feat(front): 병원이 사이트에 실을 사진을 한 장씩 고르는 화면
싣기 어려운 사진(환자·전후 비교·시술 장면·효과 주장 그래픽)은 파일명이나
설명문으로 걸러지지 않아 사람이 눈으로 봐야 한다. 그 과정이 제품 밖에 있어
빌드마다 검토서를 따로 만들어 보냈다.

/images/:clinicId 를 추가한다. supporter_builds.report.images 를 읽어 미리보기
사이트의 사진을 한 장씩 보여 주고, 사용·제외를 supporter_inputs(key=image_review)
에 쌓는다. 워커가 apply_inputs 에서 읽어 다음 빌드에 반영한다.

- 첫 화면 대표 → 사이트에 실림 → 아직 안 쓰임 순으로 정렬한다. 중간에 그만둬도
  실제로 노출되는 사진은 다 보게 된다
- 판정 기준은 법 조항이 아니라 눈으로 확인할 수 있는 질문으로 적는다
- 중간 저장한다. 같은 key 는 최신 행이 유효값이라 다시 들어오면 이어서 본다
- 사진 파일은 preview_url 에서 불러온다. 배포 전 빌드는 안내 문구로 빠진다

대상이 병원 담당자라 제작 과정과 내부 규칙은 화면에 쓰지 않는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 16:04:25 +09:00
Haewon Kam
bfde7f61b2 feat(landing): 히어로 문구를 'AI에게 병원을 묻습니다'로
특정 서비스명(ChatGPT와 Perplexity) 대신 AI로 바꿨다. webforai.kr 공유 이미지의
같은 문장도 함께 바꿨다. 아직 배포하지 않았다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 16:55:59 +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
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
5d3ce40f77 feat(discovery): 의료관광 연결 섹션 — TourAPI 다국어 주변 정보 + 회복 동선
/discovery/:id 에 외국인 환자용 주변 정보를 붙였다. 숙박·음식점·웰니스·관광·문화·
쇼핑·축제 125건과 이동 반경 기준 회복 동선. 다음 뷰성형외과 미팅용 프로토타입이다.

데이터 (scripts/fetch_medical_tourism.py → src/data/medicalTourism.json)
한국관광공사 TourAPI 영문(EngService2) 사전 수집. 실시간 호출이 아닌 이유는 영문
커버리지가 얇아 필터링이 많이 필요하고, 시연 중 외부 API 상태에 화면이 종속되지
않게 하기 위해서다. 좌표는 Naver 지역검색 실측(뷰성형외과의원, 봉은사로 107).

실측으로 드러난 것과 대응
- 영문 관광지(76)의 대부분이 관광지가 아니다. 반경 5km 100건 중 92건이 분류코드
  A02020500 "Medical Tourism Sites"(categoryCode2 로 확인)이며 병원과 유치
  에이전시다. 제목 키워드로는 "하이안과", "닥파인더코리아" 를 놓쳐 코드로 걸렀다.
  거리순 상위 100건이 거의 다 여기라 페이징을 넣어야 실제 관광지가 나온다.
- 스파·찜질방(A02020300/400)은 회복 여정에 맞아 wellness 로 분리했다.
- 영문 축제는 areacode 필드가 비어 있어 areaCode 필터가 0건을 반환한다. 좌표
  거리로 걸렀다.
- TourAPI 이미지 URL 이 http 라 https 사이트에서 혼합 콘텐츠로 차단된다. 수집
  단계에서 https 로 올린다.
- 반경을 목적별로 나눴다. 회복기에 자주 가는 숙박·식사는 5km, 관광은 10km.

만들지 않은 것
- 평점·리뷰·영업시간: TourAPI 미제공이라 null 로 두고 화면에 "미연동" 으로 적었다.
  Google Places 키가 아직 비어 있다(신청 중).
- 수술 전후 식이 적합성: 의학 판단이라 병원 입력만 쓴다. ClinicInputsPanel 에
  diet_guide 항목을 더해 supporter_inputs 로 받고, 입력 전에는 "병원 확인 대기"
  로 둔다. 개별 식당의 적합 여부를 추론하지 않는다.
- 회복 단계가 며칠째인지: 병원 입력(recovery). 화면의 단계는 이동 반경으로만
  정의해 의학적 함의를 담지 않는다.
- 한계 4가지를 meta.limits 에 담아 섹션 하단 "측정 가능 범위" 에 그대로 띄운다.

FilledIcons 에 Bed·Fork·Spa·MapPin·Ticket·Bag·Theater 7종 추가(라인 아이콘·이모지
금지 규칙에 따라 채움 SVG).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 11:31:55 +09:00
Haewon Kam
995e1e7dfa feat(supporters): 채널 발견+엔티티 검증 — discover_channels.mjs(사이트 전수·웹검색·핸들 변형·레지스트리·플랫폼 검색, 근거 점수 3-state), 워커 discover 단계 → surfaces/sameAs, 패널·리포트 발견 채널 표, 원진 리포트 갱신
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 10:06:28 +09:00
Haewon Kam
388a4a5ea4 feat(discovery): 원진성형외과 AI Answer Readiness 리포트 v2.0 — 자동 채점+보정 결과(discovery_wonjin.ts, AEO 15/D·GEO 45/C), 독립 HTML 리포트 빌더 + Chrome PDF, docs/reports/wonjin/01_readiness_report
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-08 09:46:15 +09:00
Haewon Kam
ee8c06f53b feat(supporters): haewon 결정 반영 — 채널 인기 전체 탭 제거, 단가 상한 $10 기본, 큐 폴러(poll.mjs)+launchd, /supporters/:id 페이지, URL 신청→빌드 큐, 수집기 UA·슬래시 수정, 기획 목록 일반화(원진 6편)
WIP: 원진성형외과 회귀는 글 생성 단계에서 네트워크 끊김(fetch failed)으로 중단. 다음 세션에 --from generate 로 재실행.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 18:54:01 +09:00
Haewon Kam
7e515b70ae feat(supporters): 승인 UI·입력 반영·워커 — §7-5 ClinicInputsPanel + supporter_builds/inputs 마이그레이션 + apply_inputs, §12-2 상단 고지·개설자 승인·색인 빌드 필터, §7-6 워커 E2E(뷰성형외과 URL → 5편 → 게이트 0오류)
- 게이트: DISCLOSURE_TOP_MISSING, APPROVED_*, UNAPPROVED_IN_INDEXABLE_BUILD, PRESS_VOICE 규칙화, 픽스처 추가 (16/16)
- 생성기: --site 옵션, 병원 확인 답변(clinicAnswers) 근거 [A]
- default_briefs.mjs 첫 배치 자동 기획, workers/supporters-build/run.mjs
- 랜딩: SAMPLE REPORT 라벨 "실제 사례"로 (haewon 지시)
- v2 §11-6·§11-7 기록, E2E 리포트

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 17:07:06 +09:00
Haewon Kam
76ec63bc1e feat(discovery): 기준표 v2.0 정식 채택 — 배지·헤더·랜딩 카피·비교 엑셀·덱 v2.0
- aeoGeoRubricV2 status active/2.0, 결과 rubricVersion 2.0. 리포트 헤더는 AEO·GEO 링 2개가 주, v1.0 종합은 보조 표기
- 랜딩: Hero 카피, ABMR 칩(AEO/GEO 목표), SampleReport(두 링 + 축별 8항목 바), Roadmap 제목, HowItWorks를 v2 계산값에서 파생. 발견 칩 수치 v1.1 스냅샷으로 정정
- 비교 엑셀 v2: scripts/build_supporters_v2_compare.ts(점수 계산 TS 단일 원본) → build_supporters_audit_v2_xlsx.py. 공식 AEO 42/GEO 56 · 서포터즈 noindex 상한 40(G1) · 색인 허용 AEO 94/GEO 77
- 덱 v2.0: build_viewclinic_deck_v2_0.py (17장, 표지 배지 v2.0, KPI AEO/GEO, 스코어카드 2장, Method v2.0) + 표준캔버스 + PDF. v1.0·v1.1 파일은 그대로
- docs/AEO_GEO_RUBRIC.md에 v2.0 채택 주석, AEO_GEO_RUBRIC_v2.md 재생성, 리포트 페이지 PDF 재출력

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 15:25:00 +09:00
Haewon Kam
c02de9ea51 feat(discovery): AEO/GEO 분리 채점 기준표 v2.0 초안 + 리포트 패널
- src/data/aeoGeoRubricV2.ts: AEO 답변 준비도 8항목·GEO 출처 준비도 8항목(각 100), 게이트 2종(크롤러 접근·본문 렌더링 → 상한 40), 부가 지표 11개
- v1.0 36항목을 v2 항목에 1:1 매핑(중복 0·미매핑 0, 스크립트 검사). 항목 점수 = v1 실측 레벨 가중 평균, 사람 판정(v2Results) 우선, 미검증은 분모 제외
- src/lib/discoveryScoreV2.ts 집계, src/components/discovery/AeoGeoV2Panel.tsx 리포트 패널(헤더 아래)
- 뷰성형외과 재채점: v1 54/C → AEO 42/C · GEO 56/C (사람 판정 4개는 수집기 원문 근거 초안). 태하: 게이트 G1(A2) 실패로 40 상한
- docs/AEO_GEO_RUBRIC_v2.md는 scripts/gen_rubric_v2_doc.ts로 코드에서 생성
- tsconfig exclude에 supporters·templates·evidence 추가 (Astro 하위 프로젝트가 루트 tsc에 잡히던 문제)

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 15:12:35 +09:00
Haewon Kam
13a8fca775 chore(reports): docs/reports를 고객·단계별 폴더로 분류
- viewclinic/01_readiness_report (진단 덱 v1.0·v2_표준캔버스·v1.1 + 빌더) / 02_poc_proposal (POC 정본·v3 + 빌더) / 03_question_bank (QB 120문항·실측·엑셀) / 04_supporters (GEO 계획·콘텐츠 기획·감사 엑셀)
- taeha/ (태하 리포트 + 빌더), ibk/ (기업은행 블로그 감사), landing/ (랜딩 시안·스크린샷·HTML 내보내기)
- README.md에 구조·정본/파생본·빌드 명령 안내
- 경로 참조 갱신: 핸드오버 문서 4개, QB 스크립트 3개, 빌더 docstring, discovery 페이지 주석
- 이전에 삭제된 POC v2_표준캔버스 2파일 삭제 반영

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 13:03:53 +09:00
Haewon Kam
90ad27ee73 fix: 뷰성형외과 AI Answer Readiness 리포트 v1.1 — 2026-09-07 재검증 정정 3건 + 병원 요청 슬라이드
정정 (원본 HTML 5개 URL 재파싱):
- 블로그 정지(2024-05) → 오판. www post-sitemap만 본 결과. blog.viewclinic.com은 09-07까지 발행, robots가 AI 봇 14종 명시 허용
- FAQ 0개 → 프리저베 페이지 FAQ 7문항 + 유효 FAQPage 스키마. C2 0→2
- 수술시간·회복 표기 없음 → 프리저베·코·윤곽 페이지에 텍스트 존재(가격대 없음). C4 1→2
- 총점 50 → 54 (C 유지), C 카테고리 28% → 44%. 그 외 판정(H1 5개, ItemList 파싱 실패, sameAs 빈 값, 표 0, 진료시간 이미지, WP 5.5.3)은 재확인

산출물:
- src/data/discovery_viewclinic.ts: 레벨·근거·keyFindings·actions 정정, auditedAt 2026-09-07 (/discovery/viewclinic 반영)
- 덱 v1.1 (16장): Corrections 슬라이드 + "뷰성형외과에 부탁드리는 것"(정보·확인·액션 3열) 추가. haewon 편집 원본 v1.0은 보존
- 20in 원본 + 표준캔버스 축소본, PDF 각 1부

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 11:45:29 +09:00
Haewon Kam
3ba8fc839d feat: /discovery CTA 'URL 입력으로 시작하기' — URL 입력 진단 신청 모달 + discovery_leads 저장
- 히어로·하단 CTA 버튼명 변경(무료 AEO/GEO 진단 받기 → URL 입력으로 시작하기), mailto 직행 제거
- DiscoveryLeadModal: URL(필수)·연락처(필수)·상호(선택) → Supabase discovery_leads insert
- RLS anon insert 전용(조회 불가), 저장 실패 시 o2oteam@o2o.kr mailto 폴백 (정직성 규약)
- 마이그레이션 20260831_discovery_leads.sql (적용은 supabase login 후 db push 필요)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WgWoJZAvvzMxTpWeenZSia
2026-08-31 16:58:38 +09:00
Haewon Kam
f50426eaed fix: 뷰성형외과 재채점 4건 반영 (A5·B4·C6·D6) — 48/C → 49/C
- audit_aeo_geo.py 재채점에서 확인된 기존 수작업 실측의 샘플링 누락 보정
- A5 2→3 (page/portfolio-sitemap lastmod 최신 2026-08-31), B4 2→1 (시술 페이지 세 번째 주소 표기),
  C6 1→3 (article:modified_time·dateModified 2026-04-17 실재), D6 unverified→0 (Wikidata 검색 결과 없음)
- keyFindings '15개월간 갱신 신호 없음' → '갱신 신호는 살아 있다(블로그만 2024-05 정지)'로 정정
- 검증 분모 88→89 (검증 32/36), 등급·목표(C→B) 변화 없음

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WgWoJZAvvzMxTpWeenZSia
2026-08-31 16:46:29 +09:00
Haewon Kam
18740ca800 feat: AI Discovery 랜딩 /discovery 구현 (시안 ai_discovery_landing.html 기준)
- 신규 라우트 /discovery → DiscoveryLandingPage, 기존 /discovery/:id 리포트와 공존
- 섹션 9종: Hero(ABMR 루프 + AI 답변 목업) / Why Now / How It Works / Sample Report / 8주 로드맵 / 정직성 스트립 / 최종 CTA
- ABMR 루프는 Solution.tsx 다이어그램 구조 복제, AGDP → ABMR 워딩 교체
- 점수·등급·카테고리 %·항목 수 전부 scoreDiscovery 계산값 파생, JSX 수치 하드코딩 없음
  (nextGradeTarget·scorePctColor 헬퍼를 discoveryScore에 추가)
- ScoreRing에 valueClassName·subLabel 옵션 prop 추가 (하위 호환)
- AI 답변 목업 "AEO / GEO 구축 후 목표 상태 예시" 라벨 유지, 연락처 o2oteam@o2o.kr 단일
- 시안 HTML·핸드오버 문서·POC 덱 산출물 포함

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WgWoJZAvvzMxTpWeenZSia
2026-08-31 16:17:25 +09:00
Haewon Kam
85d72e4cfb fix: npm run lint(tsc --noEmit) 실제 0 에러 달성 — 기존 93건 정리
- tsconfig에 supabase 제외 (Deno 런타임 코드를 프론트 tsc+DOM lib로 검사하던 오류 79건)
- src/vite-env.d.ts 추가 (import.meta.env 타입 6건)
- @types/react 부재 환경의 JSX key 시임 4건 (ColorSwatchCard·WorkflowCard·EnvKeyRow·ApiCard)
- transformPlan latestPosts 타입 캐스트, transformReport unknown 경유 캐스트, MultiChannelInput trim 가드
- Office 임시 잠금 파일(~$*.pptx) 삭제 반영

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WgWoJZAvvzMxTpWeenZSia
2026-08-31 16:17:12 +09:00
Haewon Kam
6a38b19ddd feat: 법무법인 태하 AI Discovery 케이스 (68점/B) + 기준표 업종 중립화 + 결과 레지스트리 분리
- 선정: 네이버 '마약 변호사' 파워링크 1위 광고주. 랜딩 taehadrug.com + 메인 taehalaw.com 실측
- 핵심 발견: 메인 도메인 가비아 WAF가 GPTBot·OAI-SearchBot 403 차단, 도메인 6개·전화번호 4종 엔티티 분산, canonical http://
- 기준표 D1/B2/B3/C7 라벨을 병의원·법률 공용으로 (강남언니/로톡, MedicalClinic/LegalService, Physician/Attorney)
- src/data/discoveryResults.ts 레지스트리 신설, /discovery/taeha
- INFINITH 덱 13장 + PDF

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 11:40:01 +09:00
Haewon Kam
978073dd0e feat: 강남언니·GBP 공개 페이지 실측 반영 (D1=3, D2=2, D4=1, B7=0) → 48점/C, 덱·PDF 재생성
- 강남언니 hospitals/189: 후기 19,316·의료진 26·이벤트 52
- GBP 4.9(901) 소유자 게시 활성, 전화번호 미등록, 웹사이트 viewplasticsurgery.com
- 영문 별도 도메인 존재하나 hreflang 미연결

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:59:56 +09:00
Haewon Kam
3888e0b60b fix: 다크 섹션 내 카드 h3가 전역 .text-white h3 규칙에 덮여 흰색으로 렌더되던 문제 (카테고리 한글명, 하지 않을 것, 측정 조건)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:44:31 +09:00
Haewon Kam
f86cf26cc0 style: 카테고리 설명문 +2pt, #4F1DA1
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:43:17 +09:00
Haewon Kam
f6168fe63a style: 카테고리 아이콘과 영문 헤딩 수직 가운데 정렬, 한글명은 아래 줄로
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:41:18 +09:00
Haewon Kam
d73538acad style: 카테고리 영문 헤딩 색상 #1D0024 (haewon 지정 인디고)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:40:28 +09:00
Haewon Kam
0cbfb9fe42 style: 카테고리 영문 헤딩 28px(원본 2배), 인디고 네이비 #0A1128 볼드
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:39:22 +09:00
Haewon Kam
62c86af128 style: 카테고리 영문 헤딩 42px 볼드, INFINITH 퍼플(#6C5CE7), Playfair 적용
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:38:05 +09:00
Haewon Kam
ef4d8218e9 feat: AI Discovery AEO/GEO 채점 기준표 v1.0 + /discovery/:id 리포트 (뷰성형외과 44점)
- 채점 기준표: 6 카테고리 36 항목 100점, 항목별 근거등급/통제/채점방식/howToCheck
- 집계: 미검증 항목 분모 제외, llms.txt 항목 제외
- 뷰성형외과 실측 결과 + 핵심 발견 5 + 액션 7 + 하지 않을 것 5
- DiscoveryReportPage: INFINITH 디자인 토큰, 본문 +2pt, 판정 배지/우선순위 +4pt 볼드, keep-all
- SeverityBadge className prop 추가
- Badge.tsx 복원 (PricingPage import 누락으로 빌드 깨져 있던 것)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-28 10:26:29 +09:00
Haewon Kam
7251c6d153 fix: Pricing 기본 토글을 월간 결제로 변경 (미팅 자료 명료화)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 11:41:41 +09:00
Haewon Kam
c020540085 fix: 잔존 옛 수치/가격 코멘트 정리 (블로그 550→551, 플레이스 777→776, 코멘트 149→29)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 11:36:27 +09:00
Haewon Kam
dc8a1db3f2 feat: 뷰성형외과 미팅 대비 — 데이터 갱신(2026-04-28) + URL 7분할 + 가격 개편
- mockReport.ts (view-clinic): 8채널 실측 갱신
  · YouTube · 강남언니 · 네이버 플레이스 · 네이버 블로그 → Firecrawl
  · Instagram (KR · EN) · Facebook (KR · EN) → Apify
  · createdAt 2026-04-13 → 2026-04-28
- mockPlan.ts (view-clinic): KPI 베이스라인 동기화 + scheduledDate 5월로 이동
- MultiChannelInput: 단일 textarea → 7-필드 분할 (홈페이지 · YT · IG · FB · 네이버플레이스 · 블로그 · 강남언니), 채널별 실시간 검증 아이콘
- PricingPage / FeatureComparisonTable: 49만/149만/399만 → 9만/29만/99만, 월 리포트 수 1회/4회/10회, 경쟁사 추적 1/3/5

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-28 11:25:45 +09:00
Haewon Kam
938ebacbf9 feat: PART III 랜딩 피봇 — 다채널 URL 입력 + Strategic Planner 포지셔닝
- MultiChannelInput: URL 뭉치 붙여넣기 → classifyUrls로 7개 채널 자동 분류
  (homepage·YouTube·Instagram·Facebook·네이버플레이스·블로그·강남언니)
  · "Analyze" pill 버튼 복원 + variant별 색 분기 (hero=dark brand,
    cta=#fff3eb→#e4cfff→#f5f9ff warm 3-stop)
  · placeholder 중앙 정렬 + "한 줄씩" 규칙 제거 (유연 파싱 노출)

- Navbar: Free Report CTA 제거 → Login + 문의하기 (contact@o2o.kr) duo
- LoginPage: 계약 고객용 스캐폴딩 페이지 신규 추가
- PricingPage: 계약 기반 영업 반영, FAQ에서 해지·환불 항목 제거
  (세부 정책 미확정 → 후속 추가)

- Landing 카피 Strategic Planner 포지셔닝 피봇:
  · Hero sub: "10분 진단 → 12개월 전략 설계"
  · Solution AGDP: Audit / Generation / Direction / Planning 재해석
  · Modules: Intelligence + Planning Available, 나머지 Coming Soon 정직화
  · TargetAudience: 전략 파트너 / 전략 자문 + Partner Program 신청 waitlist
  · Problems: 콘텐츠 소진 / 경쟁사 분석 부재 / 데이터 부족 3축
  · UseCases: 진단·전략·KPI(Medical) · 수주·자문·포트폴리오(Agency)

- discover-channels Edge Function: manualChannels 수용 — 사용자 붙여넣은
  URL이 Firecrawl 스크래핑보다 우선, naverPlace/gangnamUnni 직접 주입

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-17 09:01:41 +09:00
Haewon Kam
517075b3ef fix: PageNavigator(하단 도트 네비) 비활성화 — 캡처·데모 시 화면 가림
컴포넌트 파일은 보존하고 App.tsx 의 import + render 만 주석처리.
향후 재활성화 시 두 줄만 해제.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 14:29:03 +09:00
Haewon Kam
dc6e2f0504 fix: Production Workflow 카드 크기·위치 균일화
- Flexbox + items-center → CSS Grid 전환 (모든 컬럼 동일 너비)
- 카드 h-full + flex flex-col 로 높이 균등 (description 길이 무관)
- description flex-1 + 태그 mt-auto 로 하단 칩 정렬 통일
- 화살표 absolute -right-3 분리 (카드 너비에 영향 없음)
- step 수 4·5·6·7·8 모두 grid-cols 명시 (Tailwind purge 안전)

7개 데모 (view/banobagi/grand/wonjin/ts/irum/o2o) 모두 적용
- step 4: irum  / step 5: view  / step 6: 나머지 5개

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 14:22:20 +09:00
Haewon Kam
a9de4ecc3c feat: O2O Clinic 가상 데모 리포트·플랜 추가 (광고 소재용)
블러 처리 없이 외부 노출 가능한 가상 클리닉 데모 자산.
6개 실제 병원 분석 패턴의 베스트 프랙티스를 종합·재구성.

설정:
- 이름: O2O Clinic / 원장 오투오 / 개원 2017년 (9년차)
- 시술: 눈·코·윤곽 전문
- 컬러: Indigo Deep (#1E1B4B) + Cyan (#06B6D4)
- 포지셔닝: 균형 잡힌 운영 (Score 78) + 글로벌 확장 강점

라우팅:
- /report/o2o → mockReportO2O (overallScore 78)
- /plan/o2o → mockPlanO2O (8 채널전략·4 pillar·4주 캘린더)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 14:15:27 +09:00
Haewon Kam
9fc9d5cc71 fix: 원진성형외과 35년 → 25년 통일 (홈페이지 공식 표기 기준)
원진성형외과 공식 홈페이지(k-wonjin.co.kr) 의 '25년 헤리티지'
표기에 맞춰 모든 35년/1991년 표기를 25년/2001년으로 수정.

- mockReport_wonjin.ts: established 1991→2001, yearsInBusiness 35→25,
  transformation 포지셔닝 카피
- mockPlan_wonjin.ts: 폰트 sample text, toneOfVoice 예시, 5개 채널
  bioTemplate, content pillar, calendar 타이틀, workflow video script
  등 30+ 곳

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 13:51:01 +09:00
Haewon Kam
bde1627dda fix: 원진성형외과 도메인 wonjin.com → k-wonjin.co.kr 통일
원진성형외과 공식 홈페이지가 k-wonjin.co.kr 인데,
mockReport·mockPlan 의 다수 위치에 잘못된 wonjin.com 이
들어가 링크가 깨져있던 문제 수정.

- mockReport_wonjin.ts: domain, channelScores, linkedUrls,
  profileLink, FB link/linkedDomain, 카카오톡 url, primaryDomain,
  additionalDomains, screenshots caption/sourceUrl 모두 정정
- mockPlan_wonjin.ts: targetUrl, channelBranding bioTemplate 5개

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 13:46:25 +09:00
Haewon Kam
7dff2b7244 fix: Pretendard self-host + 한글 시스템 폰트 fallback 체인 강화
데모 환경에서 CDN(jsdelivr)·Google Fonts 차단된 망에서 Pretendard 가
로드되지 않아 명조체로 렌더링되는 문제 해결.

- public/fonts/PretendardVariable.woff2 self-hosting (~2MB, weight 45-920)
- @font-face 직접 정의 + <link rel="preload"> 로 첫 페인트 가속
- fallback 체인에 Apple SD Gothic Neo / Malgun Gothic / Noto Sans KR 추가
  → 어떤 OS에서도 한글이 명조체로 떨어지지 않음
- 기존 jsdelivr CDN 은 백업 경로로 유지 (3중 안전망)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 11:03:04 +09:00
Haewon Kam
105e8288e0 fix: Facebook 페이지 URL 중복 prepend + YouTube linkedUrl 상대경로 버그
- FacebookAudit: 'facebook.com/...' 형식 데이터에 'https://www.facebook.com/' 가
  중복 prepend 되어 'https://www.facebook.com/facebook.com/...' 깨진 URL 생성
- YouTubeAudit: linkedUrls 의 url 이 protocol 없이 그대로 href 에 들어가
  상대 경로로 인식되던 버그
- 6개 병원 (view/banobagi/grand/wonjin/ts/irum) 모두 영향

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 09:06:13 +09:00
Haewon Kam
99d72f81d6 fix: Instagram 핸들 클릭 시 항상 인스타그램 프로필로 이동
profileLink (병원 홈페이지 도메인) 이 우선되어 핸들 클릭 시
인스타그램이 아닌 홈페이지로 이동하던 버그 수정.
5개 병원 (banobagi/grand/wonjin/ts/irum) 모두 영향.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-15 08:59:49 +09:00
Haewon Kam
41577391d5 feat: 5개 병원 마케팅 플랜 전 섹션 병원별 맞춤화
각 mockPlan_{clinic}.ts에서 ...mockPlan (뷰성형외과) 스프레드를 완전 제거하고,
각 병원의 mockReport_{clinic}.ts 실측 데이터를 근거로 전 섹션 재구성:

- mockPlan_banobagi: 26년·6,853 리뷰·Black+Gold, 8개 채널전략
- mockPlan_grand: 이세환 원장·안면거상 전문·Navy Blue, 6개 채널전략
- mockPlan_wonjin: 35년·코성형·글로벌 3계정·Deep Purple, 6개 채널전략
- mockPlan_ts: 리얼모델·12,509 리뷰·Dark Navy+Crimson, 7개 채널전략
- mockPlan_irum: 다국어 KR/TH/JP·LINE 신규·Forest Green, 8개 채널전략

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 17:25:19 +09:00
Haewon Kam
f2441de0bf fix: 리포트 '마케팅 기획' 버튼 → 브랜딩 가이드 섹션으로 이동
- KPIDashboard의 CTA 버튼이 /plan/:id 로만 이동 → 스크롤 위치 불확정
- 수정: /plan/:id#branding-guide 로 해시 포함 이동
- MarketingPlanPage에 useEffect 추가: location.hash 감지 시
  sticky Navbar(80px) + ReportNav(48px) = 128px 오프셋 적용하여
  해당 섹션 상단이 nav 바로 아래에 정렬되도록 scrollTo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 16:48:44 +09:00
Haewon Kam
d816bb2d13 fix: 콘텐츠 캘린더 뿌연 현상 근본 해결 — isDragging bug fix
세션 내내 추적하던 'opacity 20-30% 흐림' 인상의 진짜 원인:
  const isDragging = draggedEntry?.entry.id === entry.id;
→ mock entry에 id가 없어 undefined === undefined → true
→ 모든 entry에 opacity-40 상시 적용됨

수정:
- isDragging: 오브젝트 참조 비교로 전환 (id 의존 제거)
- entry 배경/border: 더 진한 파스텔로 대비 강화
  (#F3F0FF → #EDE5FF, border #D5CDF5 → #B8A8E8 등)
- entry 제목: text-slate-700 → font-medium text-[#0A1128]
- 아이콘 opacity-60 제거 (100% 불투명)
- shadow-sm + hover:shadow-lg
- 섹션 dark 테마 복원 (Dark/White 섹션 교차 규칙 유지)
- 일자 셀 bg-slate-50/50 제거, 빈 셀 border 불투명화

6개 병원 데모(view-clinic/banobagi/grand/wonjin/ts/irum) 모두
ContentCalendar 컴포넌트를 공유하므로 한 번에 반영.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 16:40:43 +09:00
Haewon Kam
281efac932 fix: 콘텐츠 캘린더 뿌연 레이어 제거 — 셀 배경 제거 + entry shadow 강화
- 일자 셀 bg-slate-50/50(50% 투명) 제거 → entry 카드가 주간 카드 위 직접 노출
- 빈 셀 border-slate-200/60 → border-slate-200 (불투명)
- entry 카드에 contentTypeColors.shadow 추가 → 색상별 soft glow로 떠있는 느낌
- dark 테마 유지 (ChannelStrategy와 동일한 dark 섹션 + 흰 카드 패턴)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 16:23:09 +09:00
Haewon Kam
6b3b950ad0 fix: 플랜 페이지 전체 섹션 투명 현상 완전 해결 — initial opacity:0 전수 제거
- PlanHeader: motion.div/h1/p의 initial opacity:0 → plain HTML로 교체
  (배경 blob 애니메이션은 opacity 무관하여 유지)
- RepurposingProposal: 카드 motion.div → plain div, 확장 accordion도 plain div
- ChannelStrategy, ContentStrategy, AssetCollection, PlanCTA,
  BrandingGuide, WorkflowTracker, StrategyAdjustmentSection:
  initial={{ opacity: 0, ... }} 라인 전수 제거
- 이 환경의 framer-motion이 animate prop 완료 실패 → opacity:0에서 멈춤

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 16:06:21 +09:00
Haewon Kam
eaf215ea6d fix: 콘텐츠 캘린더 흐림 현상 근본 해결 — nav backdrop-blur 제거
- Navbar/ReportNav의 backdrop-blur-lg가 스크롤 시 섹션을 덮는
  GPU 합성 블러 레이어를 만들어 콘텐츠 캘린더가 흐려 보임
- bg-white/95 단색으로 교체 (시각적 차이 미미, 블러 부작용 제거)
- 이전 커밋(5f7d58c, aac1367)의 motion/whileInView 제거는
  원인이 아니었음 — 조상 nav의 backdrop-filter가 진범

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 15:59:10 +09:00
Haewon Kam
aac1367808 fix: 콘텐츠 캘린더 흐림 현상 완전 해결 — motion 제거
framer-motion animate가 프로덕션 빌드에서 완료되지 않는 문제로
SectionWrapper/ContentCalendar의 opacity:0 initial 상태가 유지됨.
motion.div/motion.button/motion.section을 일반 태그로 교체하고
모든 opacity 진입 애니메이션 제거.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 15:42:31 +09:00
Haewon Kam
5f7d58c490 fix: 콘텐츠 캘린더 흐림 현상 수정 — whileInView 제거
SectionWrapper의 motion.section이 opacity:0 initial 상태에서
framer-motion animate가 발동하지 않아 전체 섹션이 투명하게 보이는
문제를 수정. SectionWrapper를 일반 <section>으로 교체하고,
plan 컴포넌트들의 whileInView/viewport 애니메이션 제거.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 15:33:34 +09:00