@zalkera/client 0.24.4 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/validate-storefront.mjs +5 -4
- package/dist/index.cjs +7 -1
- package/dist/index.d.cts +29 -5
- package/dist/index.d.ts +29 -5
- package/dist/index.js +7 -1
- package/llms.txt +28 -2
- package/package.json +1 -1
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
* 아니면(`border-[2px]`·`to-[50%]`) 안 잡고, `var(…)`·`theme(…)` 경유는 면제다. 테넌트 색은
|
|
36
36
|
* 토큰 경유가 규약. 초판이 `-[#` 세 형태만 봐서 18가지가 새던 자리 — [COLOR_UTILITY_ROOTS] 참고.
|
|
37
37
|
* S5 warning — src/app/globals.css 외의 .css 파일 존재(단일 CSS 원칙).
|
|
38
|
-
* C2 error — 섹션 렌더러 switch 가 계약
|
|
39
|
-
*
|
|
38
|
+
* C2 error — 섹션 렌더러 switch 가 **콘텐츠가 실제로 쓰는** 계약 타입을 덮지 못함. 그 타입을
|
|
39
|
+
* 렌더러가 모르면 그 섹션은 **조용히 안 그려진다**(미지 타입 스킵이 계약이라 에러도 안 난다).
|
|
40
40
|
* S8 error — **표현 계약(L1) 배선 부재**(declared 전용). globals.css 의 `@theme`+`--color-primary`
|
|
41
41
|
* 정의와 root layout 의 테마 주입(`parseThemeColors(` 호출 + `<html>` style)을 센다. 이게 없으면 콘솔의
|
|
42
42
|
* "말로 색 바꾸기"가 **성공 보고를 내고 화면은 그대로**인 거짓성공이 된다 — validator 가 여태 L1 의
|
|
@@ -2885,8 +2885,9 @@ function checkLayoutBlastRadius() {
|
|
|
2885
2885
|
}
|
|
2886
2886
|
|
|
2887
2887
|
/**
|
|
2888
|
-
* C2 — 섹션 렌더러 커버리지.
|
|
2889
|
-
*
|
|
2888
|
+
* C2 — 섹션 렌더러 커버리지. **콘텐츠가 쓰는 타입**을 SectionRenderer 의 case 와 대조한다
|
|
2889
|
+
* (계약 전량이 아니다 — 전량을 재면 계약에 타입이 하나 추가될 때 그것을 안 쓰는 기존 사이트가
|
|
2890
|
+
* 전부 관문에서 막혀, 계약의 하위호환 약속과 어긋난다). 어휘 사본이 넷이라 사람 주석 규약으로는 갈라짐을 못 막는다는 게 실측된 교훈이라,
|
|
2890
2891
|
* 레포 안에서 확인 가능한 짝은 기계가 센다. 계약을 못 읽으면(구 client·미설치) **검사를 건너뛴다** —
|
|
2891
2892
|
* BYO 레포에서 이 검사가 빌드를 막으면 안 되기 때문이다.
|
|
2892
2893
|
*/
|
package/dist/index.cjs
CHANGED
|
@@ -330,7 +330,7 @@ function safeJsonParse(text) {
|
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
// src/sections.ts
|
|
333
|
-
var SECTION_CONTRACT_REV =
|
|
333
|
+
var SECTION_CONTRACT_REV = 8;
|
|
334
334
|
var SECTION_CONTRACT = [
|
|
335
335
|
// 뷰티 — 조회형 둘(SERVICE_MENU·BOOKING_CTA)은 rev 6 에서 삭제됐다(위 KDoc).
|
|
336
336
|
// 시술 목록의 ItemList 는 사라진 것이 아니라 거처가 바뀌었다: `/products` 라우트와 소스가 조합하는
|
|
@@ -344,7 +344,13 @@ var SECTION_CONTRACT = [
|
|
|
344
344
|
{ type: "LOGO_WALL", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
345
345
|
{ type: "STATS_BAND", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
346
346
|
{ type: "TESTIMONIALS", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
347
|
+
// 방문 정보 단(rev 8) — 내점형 업장이 어휘만으로 조립된다. 셋 다 `jsonLd: null` 인 이유는
|
|
348
|
+
// 주소·영업시간의 구조화 데이터 거처가 섹션이 아니라 `site_config → organizationJsonLd`
|
|
349
|
+
// 이기 때문이다. 섹션 값은 표시 문자열(「휴진」)이라 구조화하면 지어낸 그래프가 된다.
|
|
350
|
+
{ type: "FACILITY_GALLERY", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
347
351
|
{ type: "FAQ_LIST", vertical: "GENERAL", jsonLd: "FAQPage", requiredRefs: [], requiredRefsAnyOf: [] },
|
|
352
|
+
{ type: "BUSINESS_HOURS", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
353
|
+
{ type: "DIRECTIONS", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
348
354
|
{ type: "LEAD_CTA", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] }
|
|
349
355
|
];
|
|
350
356
|
function sectionsOfVertical(vertical) {
|
package/dist/index.d.cts
CHANGED
|
@@ -893,7 +893,12 @@ declare class ZalkeraError extends Error {
|
|
|
893
893
|
* "productIds 가 있는가"에서 **"참조가 하나라도 있는가"**(`requiredRefsAnyOf`)로 옮겨갔다. 그 시대의
|
|
894
894
|
* 판단이었고 rev 6 이 뒤집었다(아래).
|
|
895
895
|
*
|
|
896
|
-
* rev
|
|
896
|
+
* rev 8 = **방문 정보 단 신설** — `FACILITY_GALLERY`·`BUSINESS_HOURS`·`DIRECTIONS` 를 GENERAL 로
|
|
897
|
+
* 더한다. 내점형 업장(의원·매장·공방·학원)이 어휘만으로 조립되게 하는 것이 목적이고, 셋 다
|
|
898
|
+
* `jsonLd: null` 이다 — 주소·영업시간의 구조화 데이터 거처는 섹션이 아니라 `site_config` 에서 나오는
|
|
899
|
+
* 홈의 조직 노드다. 섹션 값은 표시 문자열이라 구조화하면 지어낸 그래프가 되고 주체가 중복된다.
|
|
900
|
+
*
|
|
901
|
+
* rev 6 = **`SERVICE_MENU`·`BOOKING_CTA` 완전 삭제**. rev 3·5 가
|
|
897
902
|
* "조회형 섹션은 참조를 반드시 실어라"로 조이던 잣대가 **"조회형 섹션을 싣지 마라"로 반전**됐다.
|
|
898
903
|
* 경계 규칙: 값이 콘텐츠 파일에 사는 저작물은 **선언 섹션**의 소관이고, 값이 업무 DB 에
|
|
899
904
|
* 살고 화면이 비추기만 하는 조회는 **소스가 이 패키지를 직접 호출**해 그린다(`listProducts()`·
|
|
@@ -910,13 +915,12 @@ declare class ZalkeraError extends Error {
|
|
|
910
915
|
*
|
|
911
916
|
* rev 7 = **DB 방언 소거 — 거처가 하나 남았다**. `page`·`page_section`·`menu` 계열이 퇴역하면서
|
|
912
917
|
* 정본의 `dialects.id`(숫자 id 표기)가 가리킬 자리가 없어졌다. rev 4 가 방언을 1급으로 승격하며 rev 를
|
|
913
|
-
* 올렸던 것의 **역연산**이라 서술 정리가 아니라 잣대 변경이다.
|
|
914
|
-
* — 섹션 10종·`requiredRefs(AnyOf)` 는 한 글자도 안 바뀐다(동기 스크립트가 확인한다). 이 패키지에서
|
|
918
|
+
* 올렸던 것의 **역연산**이라 서술 정리가 아니라 잣대 변경이다. 이 패키지에서
|
|
915
919
|
* 함께 내려간 것은 그 거처를 읽던 표면이다: `getPage`·`listPages`·`listMenus` 와 그 타입들.
|
|
916
920
|
* 남은 표기는 소스 하나 — `content/pages/*.json` 이 쓰는 참조 표기(`asset` 계열 문자열)이고,
|
|
917
921
|
* 어휘 표의 `assetId` 계열 키 이름은 그 시절 표기가 굳은 것이다(대응은 정본 `dialects.reference`).
|
|
918
922
|
*/
|
|
919
|
-
declare const SECTION_CONTRACT_REV =
|
|
923
|
+
declare const SECTION_CONTRACT_REV = 8;
|
|
920
924
|
/** 업종 분류 — 어휘를 묶어 보여 줄 때의 그룹핑이지 사용 제한이 아니다(GENERAL 은 뷰티 사이트도 쓴다). */
|
|
921
925
|
type SectionVertical = "BEAUTY" | "GENERAL";
|
|
922
926
|
interface SectionSpec {
|
|
@@ -959,7 +963,9 @@ interface SectionSpec {
|
|
|
959
963
|
readonly requiredRefsAnyOf: readonly (readonly string[])[];
|
|
960
964
|
}
|
|
961
965
|
/**
|
|
962
|
-
* 아는 섹션
|
|
966
|
+
* 아는 섹션 전량. **종수를 여기 적지 않는다** — 적으면 아래 배열과 갈리고, 이 주석은 `dist/index.d.ts`
|
|
967
|
+
* 로 실려 **소비자 편집기 툴팁까지 배송**되므로 그 거짓이 그대로 나간다.
|
|
968
|
+
* **순서는 관행 아크**(주목→가치→신뢰→방문 정보→행동)이고,
|
|
963
969
|
* 어휘를 목록으로 보여 주는 자리는 이 순서를 그대로 쓰면 된다. 값 추가는 백엔드 스펙을 먼저 고친 뒤 여기로 옮긴다.
|
|
964
970
|
*
|
|
965
971
|
* `requiredRefs` 는 빈 배열이라도 **반드시 적는다**. 생략을 허용하면 동기 스크립트의 리터럴 정규식이
|
|
@@ -1014,12 +1020,30 @@ declare const SECTION_CONTRACT: readonly [{
|
|
|
1014
1020
|
readonly jsonLd: null;
|
|
1015
1021
|
readonly requiredRefs: readonly [];
|
|
1016
1022
|
readonly requiredRefsAnyOf: readonly [];
|
|
1023
|
+
}, {
|
|
1024
|
+
readonly type: "FACILITY_GALLERY";
|
|
1025
|
+
readonly vertical: "GENERAL";
|
|
1026
|
+
readonly jsonLd: null;
|
|
1027
|
+
readonly requiredRefs: readonly [];
|
|
1028
|
+
readonly requiredRefsAnyOf: readonly [];
|
|
1017
1029
|
}, {
|
|
1018
1030
|
readonly type: "FAQ_LIST";
|
|
1019
1031
|
readonly vertical: "GENERAL";
|
|
1020
1032
|
readonly jsonLd: "FAQPage";
|
|
1021
1033
|
readonly requiredRefs: readonly [];
|
|
1022
1034
|
readonly requiredRefsAnyOf: readonly [];
|
|
1035
|
+
}, {
|
|
1036
|
+
readonly type: "BUSINESS_HOURS";
|
|
1037
|
+
readonly vertical: "GENERAL";
|
|
1038
|
+
readonly jsonLd: null;
|
|
1039
|
+
readonly requiredRefs: readonly [];
|
|
1040
|
+
readonly requiredRefsAnyOf: readonly [];
|
|
1041
|
+
}, {
|
|
1042
|
+
readonly type: "DIRECTIONS";
|
|
1043
|
+
readonly vertical: "GENERAL";
|
|
1044
|
+
readonly jsonLd: null;
|
|
1045
|
+
readonly requiredRefs: readonly [];
|
|
1046
|
+
readonly requiredRefsAnyOf: readonly [];
|
|
1023
1047
|
}, {
|
|
1024
1048
|
readonly type: "LEAD_CTA";
|
|
1025
1049
|
readonly vertical: "GENERAL";
|
package/dist/index.d.ts
CHANGED
|
@@ -893,7 +893,12 @@ declare class ZalkeraError extends Error {
|
|
|
893
893
|
* "productIds 가 있는가"에서 **"참조가 하나라도 있는가"**(`requiredRefsAnyOf`)로 옮겨갔다. 그 시대의
|
|
894
894
|
* 판단이었고 rev 6 이 뒤집었다(아래).
|
|
895
895
|
*
|
|
896
|
-
* rev
|
|
896
|
+
* rev 8 = **방문 정보 단 신설** — `FACILITY_GALLERY`·`BUSINESS_HOURS`·`DIRECTIONS` 를 GENERAL 로
|
|
897
|
+
* 더한다. 내점형 업장(의원·매장·공방·학원)이 어휘만으로 조립되게 하는 것이 목적이고, 셋 다
|
|
898
|
+
* `jsonLd: null` 이다 — 주소·영업시간의 구조화 데이터 거처는 섹션이 아니라 `site_config` 에서 나오는
|
|
899
|
+
* 홈의 조직 노드다. 섹션 값은 표시 문자열이라 구조화하면 지어낸 그래프가 되고 주체가 중복된다.
|
|
900
|
+
*
|
|
901
|
+
* rev 6 = **`SERVICE_MENU`·`BOOKING_CTA` 완전 삭제**. rev 3·5 가
|
|
897
902
|
* "조회형 섹션은 참조를 반드시 실어라"로 조이던 잣대가 **"조회형 섹션을 싣지 마라"로 반전**됐다.
|
|
898
903
|
* 경계 규칙: 값이 콘텐츠 파일에 사는 저작물은 **선언 섹션**의 소관이고, 값이 업무 DB 에
|
|
899
904
|
* 살고 화면이 비추기만 하는 조회는 **소스가 이 패키지를 직접 호출**해 그린다(`listProducts()`·
|
|
@@ -910,13 +915,12 @@ declare class ZalkeraError extends Error {
|
|
|
910
915
|
*
|
|
911
916
|
* rev 7 = **DB 방언 소거 — 거처가 하나 남았다**. `page`·`page_section`·`menu` 계열이 퇴역하면서
|
|
912
917
|
* 정본의 `dialects.id`(숫자 id 표기)가 가리킬 자리가 없어졌다. rev 4 가 방언을 1급으로 승격하며 rev 를
|
|
913
|
-
* 올렸던 것의 **역연산**이라 서술 정리가 아니라 잣대 변경이다.
|
|
914
|
-
* — 섹션 10종·`requiredRefs(AnyOf)` 는 한 글자도 안 바뀐다(동기 스크립트가 확인한다). 이 패키지에서
|
|
918
|
+
* 올렸던 것의 **역연산**이라 서술 정리가 아니라 잣대 변경이다. 이 패키지에서
|
|
915
919
|
* 함께 내려간 것은 그 거처를 읽던 표면이다: `getPage`·`listPages`·`listMenus` 와 그 타입들.
|
|
916
920
|
* 남은 표기는 소스 하나 — `content/pages/*.json` 이 쓰는 참조 표기(`asset` 계열 문자열)이고,
|
|
917
921
|
* 어휘 표의 `assetId` 계열 키 이름은 그 시절 표기가 굳은 것이다(대응은 정본 `dialects.reference`).
|
|
918
922
|
*/
|
|
919
|
-
declare const SECTION_CONTRACT_REV =
|
|
923
|
+
declare const SECTION_CONTRACT_REV = 8;
|
|
920
924
|
/** 업종 분류 — 어휘를 묶어 보여 줄 때의 그룹핑이지 사용 제한이 아니다(GENERAL 은 뷰티 사이트도 쓴다). */
|
|
921
925
|
type SectionVertical = "BEAUTY" | "GENERAL";
|
|
922
926
|
interface SectionSpec {
|
|
@@ -959,7 +963,9 @@ interface SectionSpec {
|
|
|
959
963
|
readonly requiredRefsAnyOf: readonly (readonly string[])[];
|
|
960
964
|
}
|
|
961
965
|
/**
|
|
962
|
-
* 아는 섹션
|
|
966
|
+
* 아는 섹션 전량. **종수를 여기 적지 않는다** — 적으면 아래 배열과 갈리고, 이 주석은 `dist/index.d.ts`
|
|
967
|
+
* 로 실려 **소비자 편집기 툴팁까지 배송**되므로 그 거짓이 그대로 나간다.
|
|
968
|
+
* **순서는 관행 아크**(주목→가치→신뢰→방문 정보→행동)이고,
|
|
963
969
|
* 어휘를 목록으로 보여 주는 자리는 이 순서를 그대로 쓰면 된다. 값 추가는 백엔드 스펙을 먼저 고친 뒤 여기로 옮긴다.
|
|
964
970
|
*
|
|
965
971
|
* `requiredRefs` 는 빈 배열이라도 **반드시 적는다**. 생략을 허용하면 동기 스크립트의 리터럴 정규식이
|
|
@@ -1014,12 +1020,30 @@ declare const SECTION_CONTRACT: readonly [{
|
|
|
1014
1020
|
readonly jsonLd: null;
|
|
1015
1021
|
readonly requiredRefs: readonly [];
|
|
1016
1022
|
readonly requiredRefsAnyOf: readonly [];
|
|
1023
|
+
}, {
|
|
1024
|
+
readonly type: "FACILITY_GALLERY";
|
|
1025
|
+
readonly vertical: "GENERAL";
|
|
1026
|
+
readonly jsonLd: null;
|
|
1027
|
+
readonly requiredRefs: readonly [];
|
|
1028
|
+
readonly requiredRefsAnyOf: readonly [];
|
|
1017
1029
|
}, {
|
|
1018
1030
|
readonly type: "FAQ_LIST";
|
|
1019
1031
|
readonly vertical: "GENERAL";
|
|
1020
1032
|
readonly jsonLd: "FAQPage";
|
|
1021
1033
|
readonly requiredRefs: readonly [];
|
|
1022
1034
|
readonly requiredRefsAnyOf: readonly [];
|
|
1035
|
+
}, {
|
|
1036
|
+
readonly type: "BUSINESS_HOURS";
|
|
1037
|
+
readonly vertical: "GENERAL";
|
|
1038
|
+
readonly jsonLd: null;
|
|
1039
|
+
readonly requiredRefs: readonly [];
|
|
1040
|
+
readonly requiredRefsAnyOf: readonly [];
|
|
1041
|
+
}, {
|
|
1042
|
+
readonly type: "DIRECTIONS";
|
|
1043
|
+
readonly vertical: "GENERAL";
|
|
1044
|
+
readonly jsonLd: null;
|
|
1045
|
+
readonly requiredRefs: readonly [];
|
|
1046
|
+
readonly requiredRefsAnyOf: readonly [];
|
|
1023
1047
|
}, {
|
|
1024
1048
|
readonly type: "LEAD_CTA";
|
|
1025
1049
|
readonly vertical: "GENERAL";
|
package/dist/index.js
CHANGED
|
@@ -328,7 +328,7 @@ function safeJsonParse(text) {
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
// src/sections.ts
|
|
331
|
-
var SECTION_CONTRACT_REV =
|
|
331
|
+
var SECTION_CONTRACT_REV = 8;
|
|
332
332
|
var SECTION_CONTRACT = [
|
|
333
333
|
// 뷰티 — 조회형 둘(SERVICE_MENU·BOOKING_CTA)은 rev 6 에서 삭제됐다(위 KDoc).
|
|
334
334
|
// 시술 목록의 ItemList 는 사라진 것이 아니라 거처가 바뀌었다: `/products` 라우트와 소스가 조합하는
|
|
@@ -342,7 +342,13 @@ var SECTION_CONTRACT = [
|
|
|
342
342
|
{ type: "LOGO_WALL", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
343
343
|
{ type: "STATS_BAND", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
344
344
|
{ type: "TESTIMONIALS", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
345
|
+
// 방문 정보 단(rev 8) — 내점형 업장이 어휘만으로 조립된다. 셋 다 `jsonLd: null` 인 이유는
|
|
346
|
+
// 주소·영업시간의 구조화 데이터 거처가 섹션이 아니라 `site_config → organizationJsonLd`
|
|
347
|
+
// 이기 때문이다. 섹션 값은 표시 문자열(「휴진」)이라 구조화하면 지어낸 그래프가 된다.
|
|
348
|
+
{ type: "FACILITY_GALLERY", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
345
349
|
{ type: "FAQ_LIST", vertical: "GENERAL", jsonLd: "FAQPage", requiredRefs: [], requiredRefsAnyOf: [] },
|
|
350
|
+
{ type: "BUSINESS_HOURS", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
351
|
+
{ type: "DIRECTIONS", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] },
|
|
346
352
|
{ type: "LEAD_CTA", vertical: "GENERAL", jsonLd: null, requiredRefs: [], requiredRefsAnyOf: [] }
|
|
347
353
|
];
|
|
348
354
|
function sectionsOfVertical(vertical) {
|
package/llms.txt
CHANGED
|
@@ -1262,7 +1262,7 @@ content/
|
|
|
1262
1262
|
- **React key 는 `type`+index 로 짠다.** 섹션에 id 는 없고(계약에 그런 필드가 없다) `sortOrder` 도 없다 —
|
|
1263
1263
|
배열 순서가 곧 순서다(§9.1).
|
|
1264
1264
|
|
|
1265
|
-
### 9.3 어휘 (
|
|
1265
|
+
### 9.3 어휘 (13종)
|
|
1266
1266
|
|
|
1267
1267
|
**규약**
|
|
1268
1268
|
- 파싱 헬퍼는 이 패키지가 준다: `readConfig`/`parseConfig` + `asString`/`asId`/`asIdArray`/`asObjectArray`
|
|
@@ -1288,12 +1288,38 @@ content/
|
|
|
1288
1288
|
| `LOGO_WALL` | GENERAL | title?, **items**[{**assetId**, name?, href?}] | — |
|
|
1289
1289
|
| `STATS_BAND` | GENERAL | **items**[{**value**, **label**, suffix?}] — value 는 표시 문자열("1,200") | — |
|
|
1290
1290
|
| `TESTIMONIALS` | GENERAL | title?, **items**[{**quote**, author?, role?, assetId?}] | **없음(의도)** |
|
|
1291
|
+
| `FACILITY_GALLERY` | GENERAL | title?, eyebrow?, **items**[{**assetId**, caption?}] | — |
|
|
1291
1292
|
| `FAQ_LIST` | GENERAL | title?, **items**[{**question**, **answer**}] | `FAQPage` |
|
|
1293
|
+
| `BUSINESS_HOURS` | GENERAL | title?, eyebrow?, **rows**[{**days**, **time**, closed?}], note? | — |
|
|
1294
|
+
| `DIRECTIONS` | GENERAL | title?, eyebrow?, **address**, detail?, links?[{**label**, **href**}], items?[{**label**, **body**}] | — |
|
|
1292
1295
|
| `LEAD_CTA` | GENERAL | title?, body?, interest?, quick? | — (`submitLead` 계약) |
|
|
1293
1296
|
| `BEFORE_AFTER_GALLERY` | BEAUTY | **items**[{**beforeAssetId**, **afterAssetId**, caption?}] | — |
|
|
1294
1297
|
| `DOCTOR_INTRO` | BEAUTY | **name**, title?, photoAssetId?, bio? | — |
|
|
1295
1298
|
|
|
1296
|
-
**
|
|
1299
|
+
**13종이다.** rev 8 에서 방문 정보 단 셋(`FACILITY_GALLERY`·`BUSINESS_HOURS`·`DIRECTIONS`)이
|
|
1300
|
+
더해졌다 — 내점형 업장(의원·매장·공방·학원)이 어휘만으로 조립되게 하는 것이 목적이다. 종전에는
|
|
1301
|
+
`TEXT_MEDIA` 로 번역해야 했고, 그러면 「휴진」 같은 상태가 본문 문장에 묻혀 화면에서 구분되지 않았다.
|
|
1302
|
+
|
|
1303
|
+
**셋 다 JSON-LD 가 없다.** 섹션 값은 **화면에 보이는 문자열**(「휴진」·「평일 09:30–18:30」)이라
|
|
1304
|
+
구조화하면 지어낸 그래프가 되고, 홈이 이미 내는 주체 노드가 중복된다. `FAQ_LIST` 만 비-null 인 것은
|
|
1305
|
+
FAQ 내용의 거처가 섹션 config 뿐이어서이고, 이 셋은 그 반대형이다.
|
|
1306
|
+
|
|
1307
|
+
⚠ **그래서 화면과 그래프의 거처가 다르다.** 영업시간·주소를 고치라는 요청을 받으면 **둘 다** 봐라 —
|
|
1308
|
+
화면은 콘텐츠 파일의 이 섹션들이 내고, 기계가 읽는 값은 `site_config`(§4.10 의 조직 노드)가 낸다.
|
|
1309
|
+
한쪽만 고치면 사람이 보는 것과 검색·AI 가 읽는 것이 갈린다.
|
|
1310
|
+
|
|
1311
|
+
**섹션별 주의**
|
|
1312
|
+
- `FACILITY_GALLERY` — 사진이 하나도 없으면 그리지 마라. 제목만 남은 빈 격자는 「준비 중」으로 읽히는데
|
|
1313
|
+
실제로는 콘텐츠가 빠진 것이라, 그 둘이 화면에서 구분되지 않는다.
|
|
1314
|
+
- `BUSINESS_HOURS` — 쉬는 날은 `closed: true` 로 **표시하고**, 「휴진」 같은 문자열을 찾아내려 하지 마라.
|
|
1315
|
+
표기는 편집자 자유(「쉽니다」·「정기휴무」)라 문자열 매칭은 깨진다.
|
|
1316
|
+
- `DIRECTIONS` — `links` 는 **누르는 것**(지도 바로가기), `items` 는 **읽는 것**(주차·지하철·버스)이다.
|
|
1317
|
+
섞지 마라 — 렌더러가 버튼으로 그릴지 문단으로 그릴지 알 수 없다. 주차 안내를 `detail` 한 문자열에
|
|
1318
|
+
뭉치면 이 rev 가 잡겠다던 「본문에 묻힘」이 된다.
|
|
1319
|
+
`links[].href` 는 `safeLinkUrl()` 을 태운다. 허용 스킴은 `http`·`https`·`mailto`·`tel` 과 내부
|
|
1320
|
+
경로다. 지도 앱 딥링크(`kakaomap://` 류)는 **조용히 막히므로** 웹 지도 주소(https)를 적어라.
|
|
1321
|
+
|
|
1322
|
+
rev 6 에서 `SERVICE_MENU`·`BOOKING_CTA` 가 **삭제**됐다 — 둘 다 업무 데이터(상품·갈래)를
|
|
1297
1323
|
가리키는 **조회형**이었고, 조회의 자리는 선언이 아니라 소스이기 때문이다. 대체 타입을 만들지 마라
|
|
1298
1324
|
(`PRODUCT_GRID` 류 신설은 같은 위반의 재생산이다): 상품을 진열하려면 tsx 에서 `listProducts()` 를 부르고
|
|
1299
1325
|
원하는 대로 그려라. 미지 타입은 렌더러가 조용히 스킵하므로 옛 타입이 적힌 콘텐츠도 페이지를 죽이지 않는다.
|