diff --git a/supporters/briefs/oracle/clinic.json b/supporters/briefs/oracle/clinic.json index f288fb8..6feb5c4 100644 --- a/supporters/briefs/oracle/clinic.json +++ b/supporters/briefs/oracle/clinic.json @@ -9,7 +9,9 @@ "gangnamunni": "https://www.gangnamunni.com/hospitals/125", "factSheet": { "kind": "피부과", - "areaLabel": "서울 강남 청담" + "areaLabel": "서울 강남 청담", + "name": "오라클피부과의원", + "shortName": "오라클피부과" }, "site": { "heroImage": { @@ -41,5 +43,6 @@ "sub_0" ], "_logoNote": "2026-09-10 haewon 지적(녹색 배너형 GIF는 완성도가 떨어짐) → 그룹 사이트 oraclemedicalgroup.com/images/logo_oracle_02.png (176×68, 투명 배경 워드마크)로 교체. 클리닉 사이트에는 CI 페이지가 없음(메뉴 CI소개가 빈 링크). 이전 배너형은 logo-horizontal.png 로 보존. haewon 제안(2026-09-10)대로 원본 배너에서 왼쪽 문구 영역을 잘라낸 logo-horizontal-cropped.png(133×49, 녹색 배경 유지)도 보관. 녹색 박스형을 쓰려면 logo 값을 이 파일로 바꾸고 --from youtube 재실행.", - "_imageNote": "2026-09-10: 본사 건물 외관은 그룹 사이트 oraclemedicalgroup.com/images/company_02.jpg (렌더링 이미지, 간판 오라클피부과의원). 같은 페이지의 다른 사진(화장품·모델·장비·전자차트)은 제외." -} \ No newline at end of file + "_imageNote": "2026-09-10: 본사 건물 외관은 그룹 사이트 oraclemedicalgroup.com/images/company_02.jpg (렌더링 이미지, 간판 오라클피부과의원). 같은 페이지의 다른 사진(화장품·모델·장비·전자차트)은 제외.", + "_factSheetNote": "상호 고정. 홈 제목 추정은 슬로건을 상호로 삼을 수 있다. 근거: supporters-oracle 기존 배포본 표기." +} diff --git a/supporters/briefs/viewclinic/clinic.json b/supporters/briefs/viewclinic/clinic.json new file mode 100644 index 0000000..487496f --- /dev/null +++ b/supporters/briefs/viewclinic/clinic.json @@ -0,0 +1,11 @@ +{ + "_comment": "병원별 고정값. 워커가 --name 등 인자보다 먼저 읽는다. factSheet 값은 뷰성형외과 홈페이지 표기와 대조해 확정한 것으로, 수작업 샘플 supporters/src/data/factSheet.json 과 같다. 홈 제목에서 상호를 추정하면 슬로건까지 들어가므로(\"안전을 최우선하는 뷰성형외과\") 여기서 고정한다.", + "factSheet": { + "name": "뷰성형외과의원", + "shortName": "뷰성형외과", + "kind": "성형외과", + "areaLabel": "서울 강남 신논현역", + "founded": "2005", + "urlEn": "https://www.viewplasticsurgery.com" + } +} diff --git a/supporters/briefs/wonjin/clinic.json b/supporters/briefs/wonjin/clinic.json index 075fc51..b45db57 100644 --- a/supporters/briefs/wonjin/clinic.json +++ b/supporters/briefs/wonjin/clinic.json @@ -2,5 +2,11 @@ "_comment": "병원별 고정값. 워커가 --youtube 등 인자보다 먼저 읽는다. haewon 결정 2026-09-08: 유튜브 기준 채널은 @wjwonjin (UC-EBM4e0VST1W_PQ0NzFMQg, 원장 설명 영상 736편). @wj2541(UCNBaQBCok5xIViCnrGdisoQ)은 브랜드 필름 채널이라 쓰지 않는다.", "youtube": "UC-EBM4e0VST1W_PQ0NzFMQg", "youtubeHandle": "@wjwonjin", - "logo": "supporters/briefs/wonjin/logo-horizontal.svg" + "logo": "supporters/briefs/wonjin/logo-horizontal.svg", + "factSheet": { + "name": "원진성형외과의원", + "shortName": "원진성형외과", + "kind": "성형외과" + }, + "_factSheetNote": "상호 고정. 홈 제목에서 추정하면 슬로건 '당신만 봅니다'가 상호가 되어 화면 전체와 네이버 지역검색(주변 안내 기준 좌표)까지 틀어진다. 근거: supporters-wonjin 기존 배포본 표기. kind 는 상호에 들어 있는 값이다. areaLabel·founded 는 근거를 확인하지 못해 비워 둔다." } diff --git a/workers/supporters-build/run.mjs b/workers/supporters-build/run.mjs index d1b69fe..b243a87 100644 --- a/workers/supporters-build/run.mjs +++ b/workers/supporters-build/run.mjs @@ -125,8 +125,12 @@ await phase('data', () => { const fact = readJson(join(DATA, 'factSheet.json')); const draft = existsSync(join(EV, 'facts.draft.json')) ? readJson(join(EV, 'facts.draft.json')).candidates ?? {} : {}; const first = (k) => Object.keys(draft[k] ?? {})[0] ?? ''; - const name = opt('name') || (readJson(join(EV, 'index.json')).pages.find((p) => p.type === 'home')?.title ?? '').replace(/\s*[|·-].*$/, '').trim(); - Object.assign(fact, { name: name || fact.name, shortName: name || fact.shortName, url: url.replace(/\/$/, ''), phone: first('phone').replace(/\./g, '-'), representative: /^[가-힣]{2,4}$/.test(first('representative')) ? first('representative') : '', businessNo: first('businessNo'), checkedAt: today, nextCheck: new Date(Date.now() + 30 * 864e5).toISOString().slice(0, 10) }); + // 상호: 사람이 확정한 고정값(briefs//clinic.json 의 factSheet) > --name > 홈 제목 추정. + // 홈 제목 추정은 슬로건이 붙은 제목을 그대로 상호로 삼는다("안전을 최우선하는 뷰성형외과"). + // 고정값을 여기서 먼저 읽어야 상호를 쓰는 뒤 단계(discover·news)까지 올바른 값이 간다. + const pinFact = (() => { const f = join(SUP, 'briefs', clinic, 'clinic.json'); return existsSync(f) ? (readJson(f).factSheet ?? {}) : {}; })(); + const name = pinFact.shortName || pinFact.name || opt('name') || (readJson(join(EV, 'index.json')).pages.find((p) => p.type === 'home')?.title ?? '').replace(/\s*[|·-].*$/, '').trim(); + Object.assign(fact, { name: pinFact.name || name || fact.name, shortName: pinFact.shortName || name || fact.shortName, url: url.replace(/\/$/, ''), phone: first('phone').replace(/\./g, '-'), representative: /^[가-힣]{2,4}$/.test(first('representative')) ? first('representative') : '', businessNo: first('businessNo'), checkedAt: today, nextCheck: new Date(Date.now() + 30 * 864e5).toISOString().slice(0, 10) }); const addr = first('address'); if (addr) { fact.address.full = addr; fact.address.street = addr.replace(/^(서울(특별시|시)?|경기도?|부산(광역시)?|인천(광역시)?|대구(광역시)?|대전(광역시)?|광주(광역시)?)\s*[가-힣]+구?\s*/, ''); fact.address.source = Object.values(draft.address ?? {})[0]?.[0] ?? ''; } writeJson(join(DATA, 'factSheet.json'), fact);