Files
Gnuboard7/tests/scenarios/layout-editor-shell-entry.yaml
2026-07-01 10:30:32 +09:00

113 lines
7.2 KiB
YAML

# audit:allow test-scenario-coverage reason: 본 매니페스트는(레이아웃 편집기 진입/셸/라우트 트리) 시나리오 매트릭스 SSoT. 핵심 회귀 가드는 test_files 의 통과 테스트(Vitest + PHPUnit)로 커버. Phase 1 은 백엔드 source 태깅 + G7Config 메타 보강 + 프론트 셸 골격에 한정 — 캔버스 렌더는 Phase 2, 요소 배치는 Phase 3.
feature: 레이아웃 편집기 셸 + 진입 경로 + 라우트 트리
description: |
레이아웃 편집기 진입 경로(템플릿 관리 버튼 / 운영 화면 FAB) 와 편집기 셸(상단 툴바 +
좌측 라우트 트리 + 캔버스 영역) 골격 + 라우트 트리 데이터 구성(소스 그룹핑).
배경:
- 기존 MVP 위지윅 편집기는 Phase 0 에서 완전 제거됨.
- 신규 편집기는 G7 코어의 한 기능으로 어떤 템플릿에도 종속되지 않고,
기존 템플릿 엔진(코어) 위에 얹혀진 형태로 동작 — 별도 시스템 격리 금지.
- TemplateApp.init() 일반 부팅 → renderTemplate() 안 checkLayoutEditorMode 분기로 진입.
- 셸은 state.reactRoot 에 같은 컨텍스트 래퍼 안에서 렌더(별도 createRoot/컨테이너 금지).
- 다국어는 lang-packs/_bundled/g7-core-{locale}/frontend/layout_editor.json 한 곳 SSoT.
- 활성 확장 SSoT 는 window.G7Config.activeModules / activePlugins (신규, 비파괴적).
- 라우트 트리 그룹핑을 위해 getRoutesDataWithModules 가 각 라우트에 source 메타 부여.
axes:
entry_path: [template_manage_button, ops_screen_floating_fab]
user_state: [authenticated_with_perm, authenticated_no_perm, guest]
ui_mode: [normal_render, edit_mode]
target_template: [active, inactive]
route_source: [template, module, plugin, core]
route_label_source: [editor_label, title, path]
route_visibility: [visible, hidden, redirect]
route_nesting: [flat, has_parent]
modal_definition: [inline, partial_ref, inherited_from_base]
base_layout_present: [yes, no]
session_expiry_recovery: [same_tab_return, fresh_open]
admin_ui_locale: [ko, en, ja]
exclusions:
- { user_state: guest, entry_path: ops_screen_floating_fab,
reason: "비로그인은 FAB 자체가 렌더되지 않음 — 클릭 진입 불가" }
- { ui_mode: edit_mode, entry_path: ops_screen_floating_fab,
reason: "편집 모드에서는 FAB 미표시 (8.2.2 (1))" }
- { user_state: authenticated_no_perm, entry_path: ops_screen_floating_fab,
reason: "권한 미보유 사용자는 FAB 미렌더 (8.2.2 (1))" }
effects:
- get_routes_data_with_modules_attaches_source_kind_and_identifier_to_template_routes
- get_routes_data_with_modules_attaches_source_kind_and_identifier_to_module_routes
- get_routes_data_with_modules_attaches_source_kind_and_identifier_to_plugin_routes
- get_routes_data_with_modules_attaches_source_to_auto_plugin_settings_routes
- get_routes_data_with_modules_preserves_meta_title_editor_label_hidden_parent
- template_composer_exposes_active_modules_meta_with_identifier_display_name_version
- template_composer_exposes_active_plugins_meta_with_identifier_display_name_version
- user_template_composer_exposes_active_extensions_meta_same_shape
- active_extensions_meta_is_full_set_not_filtered_by_has_settings
- g7config_modules_plugins_legacy_keys_remain_unchanged_for_backward_compat
- admin_blade_emits_active_modules_active_plugins_keys_to_window_g7config
- app_blade_emits_active_modules_active_plugins_keys_to_window_g7config
- layout_editor_chrome_mounts_in_same_react_root_no_new_create_root
- layout_editor_chrome_inherits_core_translation_provider
- layout_editor_chrome_inherits_core_transition_provider
- layout_editor_chrome_inherits_core_responsive_provider
- layout_editor_chrome_inherits_core_slot_provider
- check_layout_editor_mode_recognizes_admin_layout_editor_url_pattern
- render_with_layout_editor_called_from_render_template_branch
- mount_layout_editor_does_not_call_react_dom_create_root
- mount_layout_editor_does_not_create_new_dom_container
- bootstrap_rejects_user_without_core_templates_layouts_edit_with_denial_component
- bootstrap_uses_window_g7config_active_modules_as_active_extensions_ssot
- bootstrap_uses_window_g7config_active_plugins_as_active_extensions_ssot
- inactive_template_can_be_opened_for_editing
- edit_entry_fab_renders_only_for_permitted_authenticated_users_in_normal_render
- edit_entry_fab_hidden_for_guest
- edit_entry_fab_hidden_for_authenticated_without_perm
- edit_entry_fab_hidden_in_edit_mode
- edit_entry_fab_click_assembles_route_param_from_current_path
- edit_entry_fab_opens_new_tab_via_openwindow
- edit_entry_fab_uses_left_bottom_fixed_position
- edit_entry_fab_uses_layout_editor_t_keys_no_hardcoded_text
- route_tree_groups_by_source_template_module_plugin
- route_tree_includes_base_group_when_extends_target_exists
- route_tree_includes_modal_group_collected_from_modals_sections
- route_tree_modal_node_carries_modal_id_and_modal_host_layout
- route_tree_label_resolves_editor_label_first
- route_tree_label_falls_back_to_title_when_editor_label_absent
- route_tree_label_falls_back_to_path_when_title_absent
- route_tree_label_source_field_records_resolution_origin
- route_tree_marks_hidden_routes_dimmed_with_icon
- route_tree_marks_redirect_routes_dimmed
- route_tree_nests_children_by_path_or_meta_parent
- route_tree_preserves_group_boundary_during_nesting
- route_tree_displays_shared_layout_badge_for_multi_route_layouts
- route_tree_panel_collapse_toggle_shrinks_chrome_grid
- chrome_strings_render_via_layout_editor_t_keys_no_hardcoded_text
- chrome_i18n_keys_have_ko_en_parity
- session_expiry_returns_to_editor_in_same_tab_not_new_window
test_files:
- tests/Feature/Api/Public/PublicTemplateRoutesSourceTaggingTest.php
- tests/Feature/Api/Admin/LayoutEditorBootstrapTest.php
- tests/Unit/Services/TemplateServiceRoutesSourceTaggingTest.php
- tests/Feature/View/TemplateComposerActiveExtensionMetaTest.php
- resources/js/core/template-engine/layout-editor/__tests__/hooks/useEditorMode.test.ts
- resources/js/core/template-engine/layout-editor/__tests__/hooks/useRouteTree.test.ts
- resources/js/core/template-engine/layout-editor/__tests__/hooks/useEditEntryFab.test.ts
- resources/js/core/template-engine/layout-editor/__tests__/hooks/useEditorHistory.test.ts
- resources/js/core/template-engine/layout-editor/__tests__/components/RouteTreePanel.test.tsx
- resources/js/core/template-engine/layout-editor/__tests__/components/EditEntryFab.test.tsx
- resources/js/core/template-engine/layout-editor/__tests__/components/LayoutEditorChrome.test.tsx
- resources/js/core/template-engine/layout-editor/__tests__/i18n/chrome-i18n-coverage.test.ts
- resources/js/core/template-engine/layout-editor/__tests__/devtools/editorTrackers.test.ts
rules_layer_coverage:
- rule: service-direct-data-access
coverage: TemplateService::getRoutesDataWithModules 의 source 태깅은 라우트 메타 부여(읽기 + map 변형)만 수행, 새 mutation 없음
- rule: i18n-throw-hardcoded-korean
coverage: 편집기 chrome 의 모든 문자열은 layout_editor.* 키 — 평문 한국어 미사용. chrome-i18n-coverage.test.ts 가 정적 스캔으로 가드