86 lines
5.8 KiB
YAML
86 lines
5.8 KiB
YAML
feature: 레이아웃 편집기 데이터 바인딩 — dataProps 전수 선언 + 검색형 데이터 연결
|
|
|
|
description: |
|
|
컴포넌트의 "데이터를 바라보는 prop"(데이터형 prop)을 capability.dataProps 로 명시 선언하고,
|
|
[속성] 탭 "데이터 연결" 전용 영역(DataBindingSection)에서 검색형 피커로 data_source/상태
|
|
(_global/_local/route/query/_computed) 의 후보를 키워드 검색해 선택, `{{<source>.<path>}}` 를
|
|
props[propKey] 에 기입한다(런타임 DataBindingEngine 동일). 캔버스는 샘플 데이터로 라이브 렌더
|
|
(컬렉션은 샘플 배열로 카드/행/항목 채움), 저장 후 실사용자 페이지는 실제 data_source fetch 로 렌더.
|
|
|
|
shape 3종(부록6 + 6-b):
|
|
- scalar — 입력 value/단일 스칼라값(스칼라 leaf 후보).
|
|
- array — 컬렉션 데이터 prop(data/items/images/datasets/filters/suggestions/reactions/
|
|
availableLocales/tabs/breadcrumbItems)(배열 leaf 후보 + itemFields 미리보기).
|
|
- object — 단일 도메인 객체(ProductCard.product / Avatar·UserInfo.author / UserProfile.user)
|
|
(직접 스칼라 leaf 보유 객체 노드 후보).
|
|
|
|
직교(부록6): dataProps 와 propControls/nodeEditor(정적 구조 편집)는 한 prop 에 둘 다 오지 않는다.
|
|
정적 구조 배열(columns/labels/options/static tabs)은 nodeEditor/options-list 소관, 런타임 데이터
|
|
컬렉션·입력 value·단일 객체는 dataProps 소관. audit editor-datapropspec-shape-valid 가 직교 위반·
|
|
shape enum·sources 종류를 정적 차단. 구조/수치/enum/boolean prop 에 데이터 연결 UI 0(회귀 가드).
|
|
|
|
친화 명칭: 후보 표시 명칭은 `$t:` 키 — data_source `label_key`(6-c 관리) + editor-spec
|
|
`stateLabels` 카탈로그(_global.currentUser·query.q 등). 편집 대상 템플릿 사전으로 해석, 미커버는
|
|
키 폴백(raw 키 노출 회피는 피커 책임). 언어팩 동적 로케일 자동 대응(고정 ko/en/ja 하드코딩 0).
|
|
|
|
axes:
|
|
shape: [scalar, array, object]
|
|
source_kind: [data_source, _global, _local, route, query, _computed]
|
|
current_value: [unconnected, single_path_binding, complex_binding, static_literal]
|
|
template: [sirsoft-basic, sirsoft-admin_basic]
|
|
|
|
exclusions:
|
|
- { shape: object, source_kind: query, reason: "query 는 스칼라 위주 — 객체 후보 희소(엔티티 객체 가드)" }
|
|
- { shape: object, source_kind: route, reason: "route 는 path params(스칼라) — 객체 후보 없음" }
|
|
- { current_value: complex_binding, shape: object, reason: "복합식 디그레이드는 shape 무관 — 단일 케이스로 충분" }
|
|
- { current_value: complex_binding, shape: array, reason: "동일" }
|
|
- { current_value: static_literal, source_kind: _global, reason: "정적 리터럴 디그레이드는 소스 무관" }
|
|
- { current_value: static_literal, source_kind: _local, reason: "동일" }
|
|
- { current_value: static_literal, source_kind: route, reason: "동일" }
|
|
- { current_value: static_literal, source_kind: query, reason: "동일" }
|
|
- { current_value: static_literal, source_kind: _computed, reason: "동일" }
|
|
|
|
effects:
|
|
# 스키마/선언
|
|
- datapropspec_object_shape_added_to_schema_and_audit_enum
|
|
- dataprops_declared_exhaustively_both_templates_admin18_basic10
|
|
- dataprops_orthogonal_to_propcontrols_and_nodeeditor_no_overlap
|
|
- structural_numeric_enum_boolean_props_have_zero_data_binding_ui
|
|
# 후보 풀
|
|
- binding_candidates_include_data_source_sample_shape
|
|
- binding_candidates_include_global_local_route_query_computed_state_trees
|
|
- object_node_candidate_emitted_for_entity_objects_not_pure_containers
|
|
- shape_filter_returns_only_matching_scalar_array_object_candidates
|
|
# 친화 명칭
|
|
- state_labels_catalog_declared_both_templates_with_t_keys
|
|
- candidate_label_resolved_via_edit_template_dictionary_fallback_to_key
|
|
- data_source_label_key_deferred_to_6c_with_exhaustive_coverage_mandate
|
|
# 연결/디그레이드
|
|
- select_candidate_writes_binding_expression_to_props_propkey
|
|
- clear_removes_binding_back_to_unconnected
|
|
- single_path_binding_prefilled_in_picker_via_parse
|
|
- complex_binding_degrades_to_code_edit_readonly_notice
|
|
# 라이브(브라우저)
|
|
- bound_array_prop_renders_sample_collection_live_on_canvas
|
|
- bound_scalar_prop_renders_live_value_on_canvas
|
|
- state_toggle_changes_bound_data_on_canvas
|
|
- save_persists_binding_user_page_fetches_real_data_source
|
|
|
|
test_files:
|
|
- resources/js/core/template-engine/layout-editor/__tests__/spec/bindingCandidates.test.ts
|
|
- resources/js/core/template-engine/layout-editor/__tests__/components/DataBindingSection.test.tsx
|
|
- resources/js/core/template-engine/layout-editor/__tests__/spec/adminPropControlCoverage.test.ts
|
|
- resources/js/core/template-engine/layout-editor/__tests__/spec/basicPropControlCoverage.test.ts
|
|
|
|
validation:
|
|
note: |
|
|
Vitest 단위가 후보 풀(scalar/array/object shape, per-state _local/route/query/_computed,
|
|
엔티티 객체 vs 순수 컨테이너, shape 필터, 키워드 검색, parseBindingExpression 디그레이드)과
|
|
dataProps 전수 선언·직교 가드·shape enum·label i18n·stateLabels 카탈로그 i18n 을 잠근다.
|
|
데이터 연결 UI 는 검색형 피커 + dnd-kit 캔버스 노드 선택 의존이라 Playwright 자동화 부적합
|
|
(DataBindingSection.tsx / specTypes.ts e2e:allow 정책과 동일). 라이브(데이터 prop 선택 →
|
|
검색형 피커 연결 → 캔버스 샘플 라이브 렌더 → 상태 토글 데이터 변화 → 저장 → 실사용자화면
|
|
fetch 렌더, 위지윅↔사용자 페이지 동일성)는 **Chrome MCP §공통 5단계 매트릭스**로 검증한다.
|
|
data_source label_key 전수 부여는 6-c(전 레이아웃 누락 0 의무).
|
|
e2e_exempt: "데이터 연결 UI = 검색형 피커 + dnd-kit 합성 이벤트 의존 — Chrome MCP 매트릭스로 라이브 검증(e2e:allow 정책 정합)"
|