Compare commits
2 Commits
247d29173d
...
9b717dbcfc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b717dbcfc | ||
|
|
f68e4785bf |
@ -23,7 +23,9 @@
|
||||
"alt": "뷰성형외과 건물 외관",
|
||||
"width": 886,
|
||||
"height": 885
|
||||
}
|
||||
},
|
||||
"naverSiteVerification": "e47011473eef74d7b2c4f20e93f97a889cb699cc"
|
||||
},
|
||||
"_siteNote": "홈 히어로가 가슴 라인 일러스트로 잡혀 있었고 건물 사진의 alt 도 '가슴확대 시설 사진'으로 잘못 붙어 있었다. 건물 외관으로 고정한다."
|
||||
"_siteNote": "홈 히어로가 가슴 라인 일러스트로 잡혀 있었고 건물 사진의 alt 도 '가슴확대 시설 사진'으로 잘못 붙어 있었다. 건물 외관으로 고정한다.",
|
||||
"_verifyNote": "네이버 서치어드바이저 소유 확인 값(2026-09-14 발급, viewpl.webforai.kr 용). 사이트마다 값이 다르므로 다른 병원에 옮겨 쓰면 확인되지 않는다. 구글은 webforai.kr 도메인 속성을 DNS TXT 로 확인해 서브도메인 전부가 함께 확인된다."
|
||||
}
|
||||
|
||||
@ -19,6 +19,12 @@ export default defineConfig(({mode}) => {
|
||||
title: 'INFINITH - Infinite Marketing',
|
||||
description: 'AI 마케팅 분석 플랫폼. 채널을 진단하고 전략과 로드맵을 제안합니다.',
|
||||
};
|
||||
// 검색엔진 소유 확인. 배포마다 값이 다르므로 여기서 갈아끼운다.
|
||||
// 네이버 서치어드바이저는 DNS 를 받지 않아 메타 태그로만 확인된다.
|
||||
// 구글은 webforai.kr 도메인 속성을 DNS TXT 로 확인했으므로 메타가 필요 없다.
|
||||
const verify = isDiscovery
|
||||
? ['<meta name="naver-site-verification" content="6ebcb18640acf31bb3653822d178fcf071b94009" />']
|
||||
: [];
|
||||
const headHtml = [
|
||||
`<title>${head.title}</title>`,
|
||||
`<meta name="description" content="${head.description}" />`,
|
||||
@ -26,6 +32,7 @@ export default defineConfig(({mode}) => {
|
||||
`<meta property="og:title" content="${head.title}" />`,
|
||||
`<meta property="og:description" content="${head.description}" />`,
|
||||
`<meta property="og:locale" content="ko_KR" />`,
|
||||
...verify,
|
||||
].join('\n ');
|
||||
|
||||
return {
|
||||
|
||||
@ -55,6 +55,38 @@ function applySiteUrl() {
|
||||
return liveUrl;
|
||||
}
|
||||
|
||||
// 템플릿의 코드 파일을 빌드 폴더에 다시 덮는다. 병원 데이터·글·이미지는 건드리지 않는다.
|
||||
// 템플릿은 data 단계에서만 복사되므로, --from build 처럼 중간부터 돌리면 그 사이에 고친 화면 코드가
|
||||
// 기존 병원 폴더에 닿지 않는다. 2026-09-14 에 소유 확인 메타와 플래너 계측이 이 이유로 배포되지 않았다.
|
||||
// 병원별로 갈리는 것(astro.config.mjs·vercel.json 의 치환값, 구조 기준선, home_text)은 덮지 않는다.
|
||||
const CODE_DIRS = ['src/layouts', 'src/components', 'src/pages', 'src/styles', 'src/lib'];
|
||||
const CODE_FILES = ['src/lib.ts', 'src/content.config.ts'];
|
||||
function refreshTemplateCode() {
|
||||
if (!existsSync(TEMPLATE)) return '템플릿 없음';
|
||||
let n = 0;
|
||||
const copyIfDiff = (rel) => {
|
||||
const from = join(TEMPLATE, rel), to = join(SITE, rel);
|
||||
if (!existsSync(from)) return;
|
||||
if (existsSync(to) && readFileSync(from).equals(readFileSync(to))) return;
|
||||
mkdirSync(dirname(to), { recursive: true });
|
||||
cpSync(from, to, { recursive: true });
|
||||
n += 1;
|
||||
};
|
||||
for (const d of CODE_DIRS) {
|
||||
const from = join(TEMPLATE, d);
|
||||
if (!existsSync(from)) continue;
|
||||
const walk = (sub) => {
|
||||
for (const e of readdirSync(join(from, sub), { withFileTypes: true })) {
|
||||
const rel = join(d, sub, e.name);
|
||||
if (e.isDirectory()) walk(join(sub, e.name)); else copyIfDiff(rel);
|
||||
}
|
||||
};
|
||||
walk('');
|
||||
}
|
||||
for (const f of CODE_FILES) copyIfDiff(f);
|
||||
return n ? `화면 코드 ${n}개 갱신` : '화면 코드 최신';
|
||||
}
|
||||
|
||||
// ---------- 상태 ----------
|
||||
const statusPath = join(WORK, 'status.json');
|
||||
const status = existsSync(statusPath) ? JSON.parse(readFileSync(statusPath, 'utf8')) : { clinic, url, status: 'queued', phases: [], posts: [], createdAt: new Date().toISOString() };
|
||||
@ -456,6 +488,7 @@ await phase('heroes', () => {
|
||||
await phase('build', () => {
|
||||
// 주소·색인 설정을 먼저 적용한다. 원격 빌드가 이 값으로 canonical·사이트맵을 만든다.
|
||||
applySiteUrl();
|
||||
const refreshed = refreshTemplateCode();
|
||||
const inst = run('npm', ['ci', '--no-audit', '--no-fund'], { cwd: SITE });
|
||||
if (!inst.ok) throw new Error(`npm ci 실패\n${tail(inst.out)}`);
|
||||
const b = run('npx', ['astro', 'build'], { cwd: SITE });
|
||||
|
||||
Loading…
Reference in New Issue
Block a user