cabloy 5.1.60 → 5.1.62

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.
Files changed (232) hide show
  1. package/.claude/hooks/contract-loop-gate.ts +296 -0
  2. package/.claude/settings.json +16 -0
  3. package/.claude/skills/cabloy-backend-scaffold/SKILL.md +2 -0
  4. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -0
  5. package/.claude/skills/cabloy-contract-loop/SKILL.md +89 -16
  6. package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +102 -14
  7. package/.claude/skills/cabloy-contract-loop/references/resource-custom-state-pattern.md +4 -0
  8. package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +32 -14
  9. package/.claude/skills/cabloy-domain-planning/SKILL.md +212 -0
  10. package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +13 -0
  11. package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +2 -0
  12. package/.claude/skills/cabloy-module-removal/SKILL.md +144 -0
  13. package/.claude/skills/cabloy-resource-field-update/SKILL.md +7 -0
  14. package/.claude/skills/cabloy-zova-source-reading/SKILL.md +221 -0
  15. package/.claude/skills/cabloy-zova-source-reading/references/analysis-modes.md +91 -0
  16. package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +117 -0
  17. package/CHANGELOG.md +64 -0
  18. package/CLAUDE.md +11 -0
  19. package/cabloy-docs/.vitepress/config.mjs +197 -5
  20. package/cabloy-docs/ai/cli-to-skill-map.md +7 -0
  21. package/cabloy-docs/ai/docs-skills-rules-mapping.md +22 -0
  22. package/cabloy-docs/ai/future-skill-roadmap.md +12 -7
  23. package/cabloy-docs/ai/introduction.md +1 -0
  24. package/cabloy-docs/ai/playbook-backend-module.md +6 -0
  25. package/cabloy-docs/ai/playbook-module-removal.md +164 -0
  26. package/cabloy-docs/ai/skills.md +12 -0
  27. package/cabloy-docs/backend/backend-contract-emission-output-inspection.md +189 -0
  28. package/cabloy-docs/backend/backend-contract-emission-source-reading-map.md +160 -0
  29. package/cabloy-docs/backend/backend-contract-emission-specimen.md +170 -0
  30. package/cabloy-docs/backend/backend-resource-module-contract-chain.md +323 -0
  31. package/cabloy-docs/backend/backend-source-reading-debug-checklist.md +173 -0
  32. package/cabloy-docs/backend/backend-source-reading-roadmap.md +129 -0
  33. package/cabloy-docs/backend/backend-source-reading-verify-playbook.md +166 -0
  34. package/cabloy-docs/backend/bean-scene-authoring.md +4 -4
  35. package/cabloy-docs/backend/broadcast-guide.md +3 -3
  36. package/cabloy-docs/backend/cli.md +20 -11
  37. package/cabloy-docs/backend/config-guide.md +4 -4
  38. package/cabloy-docs/backend/controller-aop-guide.md +10 -10
  39. package/cabloy-docs/backend/controller-guide.md +12 -2
  40. package/cabloy-docs/backend/crud-workflow.md +7 -3
  41. package/cabloy-docs/backend/dto-guide.md +18 -2
  42. package/cabloy-docs/backend/dto-infer-generation.md +201 -25
  43. package/cabloy-docs/backend/election-guide.md +2 -2
  44. package/cabloy-docs/backend/entity-guide.md +30 -3
  45. package/cabloy-docs/backend/error-guide.md +3 -3
  46. package/cabloy-docs/backend/event-guide.md +4 -4
  47. package/cabloy-docs/backend/external-aop-guide.md +2 -2
  48. package/cabloy-docs/backend/field-indexes.md +9 -3
  49. package/cabloy-docs/backend/foundation.md +8 -8
  50. package/cabloy-docs/backend/i18n-guide.md +6 -6
  51. package/cabloy-docs/backend/internal-aop-guide.md +2 -2
  52. package/cabloy-docs/backend/introduction.md +15 -0
  53. package/cabloy-docs/backend/migration-and-changes.md +3 -3
  54. package/cabloy-docs/backend/model-guide.md +16 -6
  55. package/cabloy-docs/backend/openapi-guide.md +3 -0
  56. package/cabloy-docs/backend/queue-guide.md +3 -3
  57. package/cabloy-docs/backend/redlock-guide.md +2 -2
  58. package/cabloy-docs/backend/schedule-guide.md +2 -2
  59. package/cabloy-docs/backend/scripts.md +8 -0
  60. package/cabloy-docs/backend/serialization-guide.md +12 -2
  61. package/cabloy-docs/backend/service-guide.md +18 -9
  62. package/cabloy-docs/backend/startup-guide.md +5 -5
  63. package/cabloy-docs/backend/status-guide.md +271 -0
  64. package/cabloy-docs/backend/unit-testing.md +3 -3
  65. package/cabloy-docs/backend/vona-source-reading-map.md +157 -0
  66. package/cabloy-docs/backend/websocket-protocol-guide.md +5 -5
  67. package/cabloy-docs/backend/websocket-usage-guide.md +15 -8
  68. package/cabloy-docs/frontend/a-model-under-the-hood.md +281 -0
  69. package/cabloy-docs/frontend/a-openapi-under-the-hood.md +248 -0
  70. package/cabloy-docs/frontend/a-router-guide.md +307 -0
  71. package/cabloy-docs/frontend/api-guide.md +6 -4
  72. package/cabloy-docs/frontend/api-schema-guide.md +1 -0
  73. package/cabloy-docs/frontend/app-startup-guide.md +7 -4
  74. package/cabloy-docs/frontend/bean-scene-authoring.md +3 -1
  75. package/cabloy-docs/frontend/behavior-guide.md +16 -16
  76. package/cabloy-docs/frontend/cli.md +14 -2
  77. package/cabloy-docs/frontend/command-scene-authoring.md +504 -0
  78. package/cabloy-docs/frontend/component-guide.md +5 -5
  79. package/cabloy-docs/frontend/component-props-guide.md +1 -1
  80. package/cabloy-docs/frontend/component-v-model-guide.md +2 -2
  81. package/cabloy-docs/frontend/design-principles.md +6 -0
  82. package/cabloy-docs/frontend/fetch-interceptor-guide.md +440 -0
  83. package/cabloy-docs/frontend/filter-query-select-data-flow-guide.md +260 -0
  84. package/cabloy-docs/frontend/form-guide.md +786 -0
  85. package/cabloy-docs/frontend/form-scene-to-page-meta-guide.md +303 -0
  86. package/cabloy-docs/frontend/foundation.md +33 -0
  87. package/cabloy-docs/frontend/frontend-source-reading-roadmap.md +249 -0
  88. package/cabloy-docs/frontend/generated-contract-consumption-debug-checklist.md +190 -0
  89. package/cabloy-docs/frontend/generated-contract-consumption-entry-branch.md +205 -0
  90. package/cabloy-docs/frontend/generated-contract-consumption-list-branch.md +157 -0
  91. package/cabloy-docs/frontend/generated-contract-consumption-specimen.md +203 -0
  92. package/cabloy-docs/frontend/generated-contract-consumption-verify-playbook.md +189 -0
  93. package/cabloy-docs/frontend/generic-component-guide.md +1 -1
  94. package/cabloy-docs/frontend/introduction.md +38 -5
  95. package/cabloy-docs/frontend/ioc-and-beans.md +6 -0
  96. package/cabloy-docs/frontend/mock-guide.md +1 -0
  97. package/cabloy-docs/frontend/model-architecture.md +288 -39
  98. package/cabloy-docs/frontend/model-resource-best-practices.md +379 -0
  99. package/cabloy-docs/frontend/model-resource-cookbook.md +508 -0
  100. package/cabloy-docs/frontend/model-resource-internals-deep-dive.md +238 -0
  101. package/cabloy-docs/frontend/model-resource-owner-pattern.md +402 -0
  102. package/cabloy-docs/frontend/model-resource-usage-guide.md +334 -0
  103. package/cabloy-docs/frontend/model-state-guide.md +371 -15
  104. package/cabloy-docs/frontend/module-scope.md +8 -8
  105. package/cabloy-docs/frontend/modules-and-suites.md +2 -1
  106. package/cabloy-docs/frontend/navigation-guards-guide.md +7 -0
  107. package/cabloy-docs/frontend/openapi-sdk-guide.md +17 -6
  108. package/cabloy-docs/frontend/page-guide.md +15 -9
  109. package/cabloy-docs/frontend/page-meta-guide.md +466 -0
  110. package/cabloy-docs/frontend/page-params-guide.md +3 -3
  111. package/cabloy-docs/frontend/page-query-guide.md +2 -2
  112. package/cabloy-docs/frontend/page-route-guide.md +6 -0
  113. package/cabloy-docs/frontend/permission-formscene-action-visibility-guide.md +263 -0
  114. package/cabloy-docs/frontend/quickstart.md +18 -2
  115. package/cabloy-docs/frontend/reading-zova-for-vue-developers.md +266 -0
  116. package/cabloy-docs/frontend/resource-entry-page-deep-dive.md +271 -0
  117. package/cabloy-docs/frontend/resource-list-page-deep-dive.md +279 -0
  118. package/cabloy-docs/frontend/rest-resource-source-reading-map.md +522 -0
  119. package/cabloy-docs/frontend/rest-resource-under-the-hood.md +622 -0
  120. package/cabloy-docs/frontend/root-behaviors-guide.md +282 -0
  121. package/cabloy-docs/frontend/route-alias-guide.md +6 -0
  122. package/cabloy-docs/frontend/router-stack-guide.md +229 -0
  123. package/cabloy-docs/frontend/router-tabs-introduction.md +26 -3
  124. package/cabloy-docs/frontend/router-tabs-layout-integration.md +367 -0
  125. package/cabloy-docs/frontend/router-tabs-mechanism.md +6 -0
  126. package/cabloy-docs/frontend/router-tabs-route-meta-cookbook.md +7 -0
  127. package/cabloy-docs/frontend/router-tabs-vs-stack.md +167 -0
  128. package/cabloy-docs/frontend/router-view-hosts-guide.md +450 -0
  129. package/cabloy-docs/frontend/server-data.md +4 -1
  130. package/cabloy-docs/frontend/system-startup-guide.md +2 -2
  131. package/cabloy-docs/frontend/table-action-visibility-permission-flow-guide.md +263 -0
  132. package/cabloy-docs/frontend/table-cell-cookbook.md +568 -0
  133. package/cabloy-docs/frontend/table-guide.md +373 -0
  134. package/cabloy-docs/frontend/table-resource-crud-cookbook.md +496 -0
  135. package/cabloy-docs/frontend/zova-app-guide.md +251 -0
  136. package/cabloy-docs/frontend/zova-form-source-reading-map.md +293 -0
  137. package/cabloy-docs/frontend/zova-form-under-the-hood.md +561 -0
  138. package/cabloy-docs/frontend/zova-reactivity-under-the-hood.md +320 -0
  139. package/cabloy-docs/frontend/zova-router-under-the-hood.md +561 -0
  140. package/cabloy-docs/frontend/zova-source-reading-map.md +421 -0
  141. package/cabloy-docs/frontend/zova-table-controller-render-supplement.md +225 -0
  142. package/cabloy-docs/frontend/zova-table-source-reading-map.md +317 -0
  143. package/cabloy-docs/frontend/zova-table-under-the-hood.md +532 -0
  144. package/cabloy-docs/frontend/zova-vs-vue3-comparison.md +308 -0
  145. package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-debug-checklist.md +245 -0
  146. package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-source-reading-map.md +139 -0
  147. package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-verify-playbook.md +248 -0
  148. package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions.md +511 -0
  149. package/cabloy-docs/fullstack/contract-loop-playbook.md +356 -0
  150. package/cabloy-docs/fullstack/edition-collaboration-differences.md +6 -0
  151. package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +199 -23
  152. package/cabloy-docs/fullstack/introduction.md +15 -1
  153. package/cabloy-docs/fullstack/openapi-to-sdk.md +135 -11
  154. package/cabloy-docs/fullstack/suites-and-modules.md +333 -0
  155. package/cabloy-docs/fullstack/tutorial-1-first-module.md +3 -0
  156. package/cabloy-docs/fullstack/tutorial-2-first-crud.md +4 -0
  157. package/cabloy-docs/fullstack/tutorial-3-frontend-metadata-sharing.md +6 -2
  158. package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +60 -23
  159. package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +14 -7
  160. package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +6 -0
  161. package/cabloy-docs/fullstack/tutorials-overview.md +17 -4
  162. package/cabloy-docs/reference/bean-scene-boilerplates.md +15 -13
  163. package/cabloy-docs/reference/package-map.md +4 -3
  164. package/package.json +2 -1
  165. package/scripts/init.ts +2 -18
  166. package/scripts/initTestData.ts +25 -0
  167. package/scripts/upgrade.ts +17 -2
  168. package/vona/pnpm-lock.yaml +48 -194
  169. package/vona/src/suite/a-training/modules/training-student/package.json +53 -0
  170. package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +400 -0
  171. package/vona/src/suite/a-training/modules/training-student/src/.metadata/locales.ts +18 -0
  172. package/vona/src/suite/a-training/modules/training-student/src/.metadata/this.ts +2 -0
  173. package/vona/src/suite/a-training/modules/training-student/src/bean/meta.index.ts +12 -0
  174. package/vona/src/suite/a-training/modules/training-student/src/bean/meta.version.ts +21 -0
  175. package/vona/src/suite/a-training/modules/training-student/src/bean/ssrMenu.student.ts +29 -0
  176. package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +15 -0
  177. package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +15 -0
  178. package/vona/src/suite/a-training/modules/training-student/src/controller/student.ts +74 -0
  179. package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +28 -0
  180. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectReq.tsx +44 -0
  181. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectRes.tsx +11 -0
  182. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +45 -0
  183. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSummary.tsx +42 -0
  184. package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +28 -0
  185. package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +25 -0
  186. package/vona/src/suite/a-training/modules/training-student/src/entity/student.tsx +84 -0
  187. package/vona/src/suite/a-training/modules/training-student/src/index.ts +2 -0
  188. package/vona/src/suite/a-training/modules/training-student/src/model/student.ts +10 -0
  189. package/vona/src/suite/a-training/modules/training-student/src/service/student.ts +57 -0
  190. package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +173 -0
  191. package/vona/src/suite/a-training/modules/training-student/tsconfig.build.json +11 -0
  192. package/vona/src/suite/a-training/modules/training-student/tsconfig.json +7 -0
  193. package/vona/src/suite/a-training/package.json +12 -0
  194. package/vona/src/suite/a-training/tsconfig.base.json +4 -0
  195. package/vona/src/suite/a-training/tsconfig.json +10 -0
  196. package/zova/packages-cli/cli/package.json +2 -2
  197. package/zova/packages-cli/cli-set-front/cli/templates/openapi/config/boilerplate/module/openapi.config.ts +6 -1
  198. package/zova/packages-cli/cli-set-front/package.json +1 -1
  199. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +34 -4
  200. package/zova/packages-zova/zova/package.json +2 -2
  201. package/zova/pnpm-lock.yaml +416 -690
  202. package/zova/src/suite/a-training/modules/training-student/cli/openapi.config.ts +9 -0
  203. package/zova/src/suite/a-training/modules/training-student/package.json +52 -0
  204. package/zova/src/suite/a-training/modules/training-student/src/.metadata/component/formFieldLevel.ts +31 -0
  205. package/zova/src/suite/a-training/modules/training-student/src/.metadata/index.ts +258 -0
  206. package/zova/src/suite/a-training/modules/training-student/src/.metadata/locales.ts +7 -0
  207. package/zova/src/suite/a-training/modules/training-student/src/.metadata/this.ts +2 -0
  208. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/baseURL.ts +5 -0
  209. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/index.ts +3 -0
  210. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +196 -0
  211. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +4146 -0
  212. package/zova/src/suite/a-training/modules/training-student/src/api/trainingStudent.ts +151 -0
  213. package/zova/src/suite/a-training/modules/training-student/src/apiSchema/trainingStudent.ts +43 -0
  214. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionDeleteForce.tsx +51 -0
  215. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionSummary.tsx +56 -0
  216. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.level.tsx +63 -0
  217. package/zova/src/suite/a-training/modules/training-student/src/component/formFieldLevel/controller.tsx +117 -0
  218. package/zova/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +9 -0
  219. package/zova/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +9 -0
  220. package/zova/src/suite/a-training/modules/training-student/src/index.ts +2 -0
  221. package/zova/src/suite/a-training/modules/training-student/src/model/student.ts +42 -0
  222. package/zova/src/suite/a-training/modules/training-student/tsconfig.build.json +13 -0
  223. package/zova/src/suite/a-training/modules/training-student/tsconfig.json +5 -0
  224. package/zova/src/suite/a-training/package.json +12 -0
  225. package/zova/src/suite/a-training/tsconfig.base.json +4 -0
  226. package/zova/src/suite/a-training/tsconfig.json +4 -0
  227. package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +29 -7
  228. package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/select/controller.tsx +34 -11
  229. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
  230. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +3 -3
  231. package/zova/src/suite-vendor/a-zova/modules/a-table/src/lib/tableCell.ts +1 -1
  232. package/zova/src/suite-vendor/a-zova/package.json +2 -2
@@ -0,0 +1,367 @@
1
+ # Router Tabs Layout Integration
2
+
3
+ This guide explains how the current Cabloy Basic layouts turn `ModelTabs` into visible router shell behavior in Zova.
4
+
5
+ Use this page after [Router View Hosts Guide](/frontend/router-view-hosts-guide) and [Router Tabs Mechanism](/frontend/router-tabs-mechanism) when your next question is no longer “how does the tabs model work?” but “how do the real layout controllers and render beans turn that model into the Admin or Web shell?”.
6
+
7
+ Read this page together with:
8
+
9
+ - [Router View Hosts Guide](/frontend/router-view-hosts-guide)
10
+ - [Router Tabs Introduction](/frontend/router-tabs-introduction)
11
+ - [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
12
+ - [Page Meta Guide](/frontend/page-meta-guide)
13
+ - [Router Tabs Admin and Web Comparison](/frontend/router-tabs-admin-web-comparison)
14
+ - [Zova Source Reading Map](/frontend/zova-source-reading-map)
15
+
16
+ > [!TIP]
17
+ > **Router ecosystem docs path**
18
+ > 1. **[Page Route Guide](/frontend/page-route-guide)** — learn the public route-record and layout surface
19
+ > 2. **[Zova Router Under the Hood](/frontend/zova-router-under-the-hood)** — learn how the core router runtime cooperates
20
+ > 3. **[Router View Hosts Guide](/frontend/router-view-hosts-guide)** — learn how routed pages are actually hosted
21
+ > 4. **[Router Tabs Mechanism](/frontend/router-tabs-mechanism)** — learn how the tabs host turns route visits into state
22
+ > 5. **[Router Tabs Layout Integration](/frontend/router-tabs-layout-integration)** — learn how the current Basic layouts turn that state into visible shell behavior
23
+ > 6. **[Router Tabs Route Meta Cookbook](/frontend/router-tabs-route-meta-cookbook)** — learn how route metadata intentionally drives the model
24
+ >
25
+ > **You are here:** step 5.
26
+ > **Previous pages:** [Router View Hosts Guide](/frontend/router-view-hosts-guide) and [Router Tabs Mechanism](/frontend/router-tabs-mechanism).
27
+ > **Next recommended page:** [Router Tabs Route Meta Cookbook](/frontend/router-tabs-route-meta-cookbook).
28
+
29
+ ## Why this page exists
30
+
31
+ The current router-tabs docs already explain:
32
+
33
+ - the business meaning of router tabs
34
+ - the shared `ModelTabs` mechanism
35
+ - the Admin vs Web visual comparison
36
+ - the route-meta inputs that drive the model
37
+
38
+ What contributors and AI workflows still often want next is the layout-integration bridge:
39
+
40
+ - where `ModelTabs` is created inside a real layout controller
41
+ - how the layout chooses `tabsOptions`
42
+ - how the render bean turns `tabs` into a visible shell
43
+ - which parts are shared model semantics and which parts are layout presentation
44
+
45
+ This page is that bridge.
46
+
47
+ If your next question is specifically about how page code feeds task-level title, dirty state, or form scene into the visible shell, continue with [Page Meta Guide](/frontend/page-meta-guide).
48
+
49
+ ## The shortest accurate mental model
50
+
51
+ For the current public Cabloy Basic source, the shortest accurate model is:
52
+
53
+ 1. the layout controller loads menus and creates a `ModelTabs` selector bean
54
+ 2. the layout passes layout-specific `tabsOptions` such as `scene`, `max`, `maxItems`, and `cache`
55
+ 3. the shared `ZRouterViewTabs` host keeps route visits and keep-alive behavior synchronized with `ModelTabs`
56
+ 4. the layout render bean reads `$$modelTabs.tabs`, `tabCurrent`, and related state to produce the visible shell
57
+ 5. Admin and Web reuse the same underlying tabs model but project it into different top-level UI structures
58
+
59
+ That is why layout integration is not merely cosmetic. It is the point where shared router-tabs state becomes the concrete shell experience.
60
+
61
+ ## The source files that matter most
62
+
63
+ ### Admin layout integration
64
+
65
+ - `zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/controller.tsx`
66
+ - `zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.tabs.tsx`
67
+ - `zova/src/suite/a-home/modules/home-layoutadmin/src/config/config.ts`
68
+
69
+ ### Web layout integration
70
+
71
+ - `zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/controller.tsx`
72
+ - `zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.tabs.tsx`
73
+ - `zova/src/suite/a-home/modules/home-layoutweb/src/config/config.ts`
74
+
75
+ ### Shared host/model layer used by both
76
+
77
+ - `zova/src/suite-vendor/a-zova/modules/a-routertabs/src/component/routerViewTabs/controller.tsx`
78
+ - `zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts`
79
+
80
+ ## Step-by-step layout integration path
81
+
82
+ ### 1. The layout controller, not the render bean, creates `ModelTabs`
83
+
84
+ The real integration starts in the layout controller.
85
+
86
+ In both Admin and Web, the controller is where:
87
+
88
+ - menus are loaded
89
+ - tabs config is read from the layout scope config
90
+ - a selector-scoped `ModelTabs` bean is created
91
+ - later menu changes refresh or reset visible tab info
92
+
93
+ This is the first important source-level fact about layout integration:
94
+
95
+ - **the render bean does not own tabs state**
96
+ - **the layout controller owns the decision to create and configure the tabs model**
97
+
98
+ ## 2. Admin layout integration
99
+
100
+ Representative controller source:
101
+
102
+ ```text
103
+ zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/controller.tsx
104
+ ```
105
+
106
+ ### Zova-native role
107
+
108
+ The Admin layout controller creates a workbench-oriented tabs model whose top level is anchored to menu-backed business workspaces.
109
+
110
+ ### Source-confirmed runtime behavior
111
+
112
+ Inside `_initTabs()` the Admin layout:
113
+
114
+ - reads `this.scope.config.tabs`
115
+ - builds `tabsOptions`
116
+ - uses `this.bean._getBeanSelector('a-routertabs.model.tabs', true, configTabs.scene, tabsOptions)`
117
+ - keeps the selected model on `this.$$modelTabs`
118
+ - watches menu data and calls `updateAllTabInfos()` when menus change
119
+
120
+ The important Admin-specific `tabsOptions` behavior is:
121
+
122
+ - `getInitialTabs()` returns `[{ tabKey: '/', affix: true }]` once menus are available
123
+ - `getTabInfo(tabKey)` resolves title and icon from the menu model by `link`
124
+
125
+ That means the Admin layout does two important things for the shared tabs model:
126
+
127
+ 1. it guarantees a fixed affixed top-level home workspace
128
+ 2. it derives visible workspace labels from menu-backed business information rather than from temporary page state
129
+
130
+ ### Why this matters
131
+
132
+ This is why Admin level-1 tabs feel stable and business-oriented.
133
+
134
+ The model itself is generic, but the layout controller injects business-facing tab identity and the initial affixed workspace rule.
135
+
136
+ ## 3. Admin render integration
137
+
138
+ Representative render source:
139
+
140
+ ```text
141
+ zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.tabs.tsx
142
+ ```
143
+
144
+ ### Zova-native role
145
+
146
+ The Admin render bean turns `ModelTabs` into an explicit two-level workbench shell.
147
+
148
+ ### Source-confirmed runtime behavior
149
+
150
+ The render bean exposes three main surfaces:
151
+
152
+ - `renderTabs()` for level-1 workspace tabs
153
+ - `renderTabItems()` for level-2 task items
154
+ - `_renderRouterViewTabs()` for the actual routed host outlet
155
+
156
+ Important details:
157
+
158
+ - level-1 rows iterate over `$$modelTabs.tabs`
159
+ - clicking a level-1 tab calls `$$modelTabs.activeTab(tabKey)`
160
+ - non-affix level-1 tabs expose `deleteTab(tabKey)`
161
+ - level-2 rows read `$$modelTabs.tabCurrent.items`
162
+ - the anchor item is intentionally skipped when `componentKey === tabKey`
163
+ - clicking a level-2 item calls `activeTabItem(tabKey, componentKey)`
164
+ - deleting a level-2 item calls `deleteTabItem(...)`
165
+ - page-level icon state is derived from `pageMeta` such as `pageDirty` and `formMeta.formScene`
166
+ - the actual routed content still enters through `<ZRouterViewTabs>`
167
+
168
+ For the authoring-side write path that produces those `pageMeta` values, see [Page Meta Guide](/frontend/page-meta-guide).
169
+
170
+ This is the second important source-level fact about layout integration:
171
+
172
+ - **the layout render bean does not replace the router host**
173
+ - **it wraps the shared host with a visible shell that reads the same model state**
174
+
175
+ ### What the Admin shell makes visible
176
+
177
+ Admin makes these model semantics explicit:
178
+
179
+ - level-1 workspace grouping
180
+ - level-2 task items
181
+ - dirty indicators
182
+ - create/edit task indicators
183
+ - close actions for both outer and inner levels
184
+
185
+ That is why Admin is the clearest business-meaning specimen for router tabs.
186
+
187
+ ## 4. Web layout integration
188
+
189
+ Representative controller source:
190
+
191
+ ```text
192
+ zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/controller.tsx
193
+ ```
194
+
195
+ ### Zova-native role
196
+
197
+ The Web layout controller creates a tabs model that is still shared in semantics, but whose initial top-level state is derived from the menu tree rather than from one affixed home workspace.
198
+
199
+ ### Source-confirmed runtime behavior
200
+
201
+ Inside `_initTabs()` the Web layout:
202
+
203
+ - reads `this.scope.config.tabs`
204
+ - builds `tabsOptions`
205
+ - creates the same selector-scoped `ModelTabs` bean
206
+ - watches menu data and calls `resetAllTabInfos()` when menus change
207
+
208
+ The important Web-specific `tabsOptions` behavior is:
209
+
210
+ - `getInitialTabs()` returns one item per top-level menu tree entry
211
+ - each initial tab uses `item.folder ? item.name : item.link` as `tabKey`
212
+ - `info` is stored directly from the menu tree item
213
+
214
+ That means the Web layout treats top-level workspace entries more like shell navigation nodes than like one pre-affixed home workspace plus later-opened work areas.
215
+
216
+ ### Why this matters
217
+
218
+ This is why the Web shell can feel menu-driven at the top level while still relying on the same `ModelTabs` state underneath.
219
+
220
+ The model stays shared, but the controller chooses a different initialization strategy.
221
+
222
+ ## 5. Web render integration
223
+
224
+ Representative render source:
225
+
226
+ ```text
227
+ zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.tabs.tsx
228
+ ```
229
+
230
+ ### Zova-native role
231
+
232
+ The Web render bean projects the same tabs model into a horizontal menu-like shell.
233
+
234
+ ### Source-confirmed runtime behavior
235
+
236
+ The render bean:
237
+
238
+ - iterates over `$$modelTabs.tabs`
239
+ - renders top-level entries through `_renderMenuItem(...)`
240
+ - supports folder, separator, and leaf menu shapes
241
+ - uses `tabKey === $$modelTabs.tabKeyCurrent` for top-level active state
242
+ - lets top-level shell clicks call `$$modelTabs.activeTab(tabKey)`
243
+ - lets nested leaf links navigate through `RouterLink`
244
+ - still renders the actual routed content through `<ZRouterViewTabs>`
245
+
246
+ This is the third important source-level fact about layout integration:
247
+
248
+ - **Web does not abandon the tabs model**
249
+ - **it simply renders the top-level workspace state through a menu-oriented shell instead of an explicit lifted tab row**
250
+
251
+ ## 6. Config is part of layout integration, not an afterthought
252
+
253
+ Representative config sources:
254
+
255
+ - `zova/src/suite/a-home/modules/home-layoutadmin/src/config/config.ts`
256
+ - `zova/src/suite/a-home/modules/home-layoutweb/src/config/config.ts`
257
+
258
+ ### Current Basic source values
259
+
260
+ Admin:
261
+
262
+ - `scene: ''`
263
+ - `max: 6`
264
+ - `maxItems: 3`
265
+ - `cache: true`
266
+ - `tabItem.maxWidth: '130px'`
267
+
268
+ Web:
269
+
270
+ - `scene: 'web'`
271
+ - `max: 6`
272
+ - `maxItems: 6`
273
+ - `cache: false`
274
+
275
+ ### Why this matters
276
+
277
+ These config differences directly shape shell behavior:
278
+
279
+ - `scene` chooses the selector-space identity of the tabs model
280
+ - `max` and `maxItems` change pruning density
281
+ - `cache` changes whether shell state is restored through cached model state
282
+ - Admin-only `tabItem.maxWidth` shapes inner task-row presentation
283
+
284
+ A practical reading takeaway is:
285
+
286
+ - **layout integration includes controller logic, render logic, and config together**
287
+
288
+ ## 7. What is shared vs what is layout-specific
289
+
290
+ ### Shared semantics
291
+
292
+ These remain in the shared model/host layer:
293
+
294
+ - route-to-workspace mapping
295
+ - `tabKey` and `componentKey` meaning
296
+ - keep-alive inclusion
297
+ - activation and pruning behavior
298
+ - page-meta storage on tab items
299
+ - routed content entering through `ZRouterViewTabs`
300
+
301
+ ### Layout-specific behavior
302
+
303
+ These belong mainly to the layout integration layer:
304
+
305
+ - how top-level entries are initialized from menu state
306
+ - whether there is an affixed home workspace
307
+ - whether the second level is shown explicitly
308
+ - whether the top level looks like tabs or a horizontal menu
309
+ - how close buttons, item width, and icon density are presented
310
+
311
+ This is the key boundary to preserve:
312
+
313
+ - **change shared semantics in the host/model layer only when the framework contract should change**
314
+ - **change visual shell behavior in the layout layer when only presentation should change**
315
+
316
+ ## 8. A practical reading order for source readers
317
+
318
+ If your question is specifically about how `ModelTabs` becomes a visible shell, use this order:
319
+
320
+ 1. `zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts`
321
+ 2. `zova/src/suite-vendor/a-zova/modules/a-routertabs/src/component/routerViewTabs/controller.tsx`
322
+ 3. `zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/controller.tsx`
323
+ 4. `zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.tabs.tsx`
324
+ 5. `zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/controller.tsx`
325
+ 6. `zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.tabs.tsx`
326
+ 7. the two layout config files
327
+
328
+ Use Admin first when you want the clearest expression of the workbench model.
329
+ Use Web next when you want to confirm that the same model can back a different shell style.
330
+
331
+ ## Common mistakes to avoid
332
+
333
+ ### Mistake 1: treating the layout render bean as the tabs state owner
334
+
335
+ It is not.
336
+
337
+ The render bean projects state visually. The controller and shared model own the state.
338
+
339
+ ### Mistake 2: assuming Admin-specific tab rows define the whole router-tabs contract
340
+
341
+ They do not.
342
+
343
+ Admin is one visible projection of a broader routed-host and tabs-model contract.
344
+
345
+ ### Mistake 3: assuming Web is not using router tabs because it looks like a menu
346
+
347
+ It is still using `ModelTabs` and `ZRouterViewTabs`.
348
+
349
+ Only the shell projection differs.
350
+
351
+ ### Mistake 4: changing layout presentation when the real change belongs in `ModelTabs`
352
+
353
+ If the behavior should be shared across shells, change the shared model/host layer first.
354
+
355
+ If only the visible shell should differ, change the layout layer first.
356
+
357
+ ## Edition note
358
+
359
+ This guide is source-confirmed against the current public Cabloy Basic layouts.
360
+
361
+ That means the integration story here is accurate for the current Basic Admin and Web shells, but should not be overgeneralized to every future edition or downstream layout without verification.
362
+
363
+ ## Final takeaway
364
+
365
+ If [Router Tabs Mechanism](/frontend/router-tabs-mechanism) explains how the shared tabs model works, this page explains how the real Basic layouts turn that shared model into visible shell behavior.
366
+
367
+ That is the missing bridge between framework-level tabs semantics and the actual layout code contributors edit.
@@ -4,6 +4,10 @@ This guide explains how the router-tabs mechanism works in Zova within the Cablo
4
4
 
5
5
  For the business meaning of the mechanism, see [Router Tabs Overview](/frontend/router-tabs-overview).
6
6
 
7
+ If you came here from [Router View Hosts Guide](/frontend/router-view-hosts-guide), this page is the next layer down: the host guide explains routed-host choice, while this page explains the shared `ModelTabs` semantics behind that host.
8
+
9
+ If your next question becomes specifically about how a page author should update task-level title, dirty state, or form scene through `$router.setPageMeta(...)`, continue with [Page Meta Guide](/frontend/page-meta-guide).
10
+
7
11
  ## Why this mechanism exists
8
12
 
9
13
  The router-tabs mechanism is designed to support a workbench-style frontend navigation model.
@@ -288,6 +292,8 @@ Representative page metadata includes:
288
292
 
289
293
  This metadata shapes the visible state of the level-2 tab.
290
294
 
295
+ For authoring-focused guidance on when page code should call `$router.setPageMeta(...)` and how to keep that separate from route meta, see [Page Meta Guide](/frontend/page-meta-guide).
296
+
291
297
  ### `pageTitle`
292
298
 
293
299
  `pageTitle` is typically used as the displayed title of the level-2 item.
@@ -2,12 +2,15 @@
2
2
 
3
3
  This guide provides practical route-meta recipes for the router-tabs mechanism in Zova within the Cabloy monorepo.
4
4
 
5
+ If you came here from [Router View Hosts Guide](/frontend/router-view-hosts-guide), [Router Tabs Mechanism](/frontend/router-tabs-mechanism), or [Router Tabs Layout Integration](/frontend/router-tabs-layout-integration), this page is the authoring layer: the earlier pages explain host/runtime behavior, and this page explains how route metadata intentionally drives it.
6
+
5
7
  Read this together with:
6
8
 
7
9
  - [Router Tabs Introduction](/frontend/router-tabs-introduction)
8
10
  - [Page Route Guide](/frontend/page-route-guide)
9
11
  - [Router Tabs Overview](/frontend/router-tabs-overview)
10
12
  - [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
13
+ - [Router Tabs Layout Integration](/frontend/router-tabs-layout-integration)
11
14
 
12
15
  ## Why this cookbook exists
13
16
 
@@ -39,6 +42,10 @@ Representative source definition:
39
42
 
40
43
  Use this decision split first:
41
44
 
45
+ - [Router View Hosts Guide](/frontend/router-view-hosts-guide) explains where host-level routed identity is consumed
46
+ - [Router Tabs Mechanism](/frontend/router-tabs-mechanism) explains how `ModelTabs` turns route data into tab state
47
+ - this page explains how to choose the route-meta inputs that drive that model
48
+
42
49
  - `tabKey` answers: which level-1 workspace should this route belong to?
43
50
  - `componentKey` answers: should this route visit reuse an existing page instance or remain separately open?
44
51
 
@@ -0,0 +1,167 @@
1
+ # Router Tabs vs Stack
2
+
3
+ This guide explains when to think in **Router Tabs** and when to think in **Router Stack** in Zova.
4
+
5
+ Use this page when you want to answer questions like:
6
+
7
+ - should this routed host behave like a workbench or like a linear routed stack?
8
+ - when do I need `tabKey` and `componentKey`?
9
+ - when is `fullPath` identity enough?
10
+ - when should page-meta-aware work items exist, and when are they unnecessary?
11
+
12
+ ## Why this comparison exists
13
+
14
+ The current frontend docs already explain the two nearby branches separately:
15
+
16
+ - [Router Tabs Introduction](/frontend/router-tabs-introduction) and the rest of the tabs series explain the workbench-tabs branch
17
+ - [Router Stack Guide](/frontend/router-stack-guide) explains the stack branch
18
+ - [Router View Hosts Guide](/frontend/router-view-hosts-guide) explains the shared routed-host layer above both
19
+
20
+ What many readers still need next is a decision page.
21
+
22
+ That is the gap this guide fills.
23
+
24
+ This page is intentionally a chooser between two host models. For the shared host boundary, keep [Router View Hosts Guide](/frontend/router-view-hosts-guide) as the main reference, and use this page only when the host question has already narrowed to tabs vs stack.
25
+
26
+ ## The shortest accurate mental model
27
+
28
+ A practical mental model is:
29
+
30
+ - **Router Tabs** = a workbench model with business/workspace grouping plus page-instance identity
31
+ - **Router Stack** = a linear routed-cache model where each route visit is one host identity
32
+
33
+ If you need grouped workspaces and task-level state, think in Tabs.
34
+
35
+ If you need a simple per-visit routed stack, think in Stack.
36
+
37
+ ## The core difference in one table
38
+
39
+ | Question | Router Tabs | Router Stack |
40
+ | ------------------------------------------------ | ------------------------------------------- | ------------------------------------------------------- |
41
+ | What owns the host state? | `ModelTabs` | `ModelStack` |
42
+ | What is the host controller? | `ControllerRouterViewTabs` | `ControllerRouterViewStack` |
43
+ | What is the main identity model? | `tabKey` + `componentKey` | `fullPath` |
44
+ | What is `tabKey` for? | level-1 workspace grouping | same as `fullPath` identity |
45
+ | What is `componentKey` for? | level-2 page-instance identity | same as `fullPath` identity |
46
+ | Does it support workbench semantics? | yes | no |
47
+ | Does it support page-meta-aware task updates? | yes | no dedicated stack equivalent |
48
+ | What kind of pruning does it do? | tab/work-item pruning inside the tabs model | linear recency-based pruning |
49
+ | What is the current public Basic shell emphasis? | visible and central | framework primitive, not the main visible shell pattern |
50
+
51
+ ## Identity model: Tabs
52
+
53
+ The tabs branch separates two questions:
54
+
55
+ 1. which business/workspace does this route belong to?
56
+ 2. which page instance inside that workspace is this?
57
+
58
+ That is why `ModelTabs` works with both:
59
+
60
+ - `tabKey`
61
+ - `componentKey`
62
+
63
+ A compact interpretation is:
64
+
65
+ - `tabKey` = level-1 grouping identity
66
+ - `componentKey` = level-2 page-instance identity
67
+
68
+ This is the right model when multiple routed visits should still belong to one durable business workspace.
69
+
70
+ ## Identity model: Stack
71
+
72
+ The stack branch collapses routed identity to `fullPath`.
73
+
74
+ In `ModelStack.prepareRouteMeta(...)`, the stack host returns:
75
+
76
+ - `tabKey = route.fullPath`
77
+ - `componentKey = route.fullPath`
78
+ - `fullPath = route.fullPath`
79
+
80
+ That means a stack visit is treated as one linear routed entry.
81
+
82
+ This is the right model when per-visit identity is enough and you do not need a separate workspace grouping layer.
83
+
84
+ ## Page-meta and workbench semantics
85
+
86
+ The tabs branch supports richer task/workbench semantics.
87
+
88
+ In the current public source:
89
+
90
+ - `ControllerRouterViewTabs` forwards `setPageMeta(...)`
91
+ - `ModelTabs` stores and updates page-meta information per routed work item
92
+
93
+ That makes tabs a good fit for:
94
+
95
+ - workbench titles
96
+ - dirty state
97
+ - task-level UI state that belongs to an open work item
98
+
99
+ The stack branch does not add that richer page-meta ownership model.
100
+
101
+ That is why stack should not be treated as “tabs with fewer UI decorations.” It is a different host model.
102
+
103
+ ## Choose Tabs when
104
+
105
+ Choose Router Tabs when you need:
106
+
107
+ - stable business/workspace grouping
108
+ - more than one open work item inside that grouping
109
+ - page-instance reuse decisions separate from workspace identity
110
+ - task-level page-meta behavior
111
+ - the current public Basic Admin/Web-style workbench semantics
112
+
113
+ This is the normal fit for the existing Router Tabs series.
114
+
115
+ ## Choose Stack when
116
+
117
+ Choose Router Stack when you need:
118
+
119
+ - a simpler per-visit routed host
120
+ - one identity per route visit
121
+ - bounded linear routed caching
122
+ - recency-based pruning without workbench grouping
123
+ - no tabs-style page-meta/workspace semantics
124
+
125
+ This is the normal fit when `fullPath` identity is the main thing that matters.
126
+
127
+ ## Current Cabloy Basic visibility note
128
+
129
+ In the current public Basic source:
130
+
131
+ - Router Tabs are the visibly emphasized shell model in the existing public layout docs
132
+ - Router Stack exists as a real framework host primitive
133
+ - Router Stack should therefore be understood as an available routed-host strategy, not as the most prominent visible Basic shell pattern
134
+
135
+ This distinction matters because the framework capability and the currently emphasized public shell are not always the same thing.
136
+
137
+ ## Suggested decision rule
138
+
139
+ Use this quick rule:
140
+
141
+ 1. do you need a durable business/workspace grouping layer?
142
+ - yes -> choose **Router Tabs**
143
+ - no -> continue
144
+ 2. do you only need each route visit to behave like one linear cached routed item?
145
+ - yes -> choose **Router Stack**
146
+ - no -> re-check whether you actually need tabs-level semantics
147
+
148
+ ## Read together with
149
+
150
+ Use this page together with:
151
+
152
+ - [Router View Hosts Guide](/frontend/router-view-hosts-guide)
153
+ - [Router Tabs Introduction](/frontend/router-tabs-introduction)
154
+ - [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
155
+ - [Router Stack Guide](/frontend/router-stack-guide)
156
+ - [A-Router Guide](/frontend/a-router-guide)
157
+
158
+ ## Final takeaway
159
+
160
+ The most accurate distinction is:
161
+
162
+ - **Router Tabs** are for grouped workbench semantics
163
+ - **Router Stack** is for linear routed-cache semantics
164
+
165
+ If you need workspace grouping, task identity, and page-meta-aware work items, think in Tabs.
166
+
167
+ If you need one identity per route visit with simpler recency-based caching, think in Stack.