cabloy 5.1.61 → 5.1.63

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 (230) hide show
  1. package/.claude/skills/cabloy-backend-scaffold/SKILL.md +2 -0
  2. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -1
  3. package/.claude/skills/cabloy-domain-planning/SKILL.md +212 -0
  4. package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +2 -0
  5. package/CHANGELOG.md +55 -0
  6. package/CLAUDE.md +1 -0
  7. package/cabloy-docs/.vitepress/config.mjs +158 -12
  8. package/cabloy-docs/ai/docs-skills-rules-mapping.md +8 -0
  9. package/cabloy-docs/ai/future-skill-roadmap.md +2 -0
  10. package/cabloy-docs/ai/skills.md +1 -0
  11. package/cabloy-docs/backend/backend-contract-emission-output-inspection.md +189 -0
  12. package/cabloy-docs/backend/backend-contract-emission-source-reading-map.md +160 -0
  13. package/cabloy-docs/backend/backend-contract-emission-specimen.md +170 -0
  14. package/cabloy-docs/backend/backend-resource-module-contract-chain.md +323 -0
  15. package/cabloy-docs/backend/backend-source-reading-debug-checklist.md +173 -0
  16. package/cabloy-docs/backend/backend-source-reading-roadmap.md +129 -0
  17. package/cabloy-docs/backend/backend-source-reading-verify-playbook.md +166 -0
  18. package/cabloy-docs/backend/bean-scene-authoring.md +4 -4
  19. package/cabloy-docs/backend/broadcast-guide.md +3 -3
  20. package/cabloy-docs/backend/cli.md +20 -11
  21. package/cabloy-docs/backend/config-guide.md +4 -4
  22. package/cabloy-docs/backend/controller-aop-guide.md +10 -10
  23. package/cabloy-docs/backend/controller-guide.md +12 -2
  24. package/cabloy-docs/backend/crud-workflow.md +7 -3
  25. package/cabloy-docs/backend/dto-guide.md +12 -2
  26. package/cabloy-docs/backend/dto-infer-generation.md +201 -25
  27. package/cabloy-docs/backend/election-guide.md +2 -2
  28. package/cabloy-docs/backend/entity-guide.md +12 -3
  29. package/cabloy-docs/backend/error-guide.md +3 -3
  30. package/cabloy-docs/backend/event-guide.md +4 -4
  31. package/cabloy-docs/backend/external-aop-guide.md +2 -2
  32. package/cabloy-docs/backend/field-indexes.md +9 -3
  33. package/cabloy-docs/backend/foundation.md +8 -8
  34. package/cabloy-docs/backend/i18n-guide.md +6 -6
  35. package/cabloy-docs/backend/internal-aop-guide.md +2 -2
  36. package/cabloy-docs/backend/introduction.md +13 -0
  37. package/cabloy-docs/backend/migration-and-changes.md +3 -3
  38. package/cabloy-docs/backend/model-guide.md +16 -6
  39. package/cabloy-docs/backend/openapi-guide.md +3 -0
  40. package/cabloy-docs/backend/queue-guide.md +3 -3
  41. package/cabloy-docs/backend/redlock-guide.md +2 -2
  42. package/cabloy-docs/backend/schedule-guide.md +2 -2
  43. package/cabloy-docs/backend/scripts.md +8 -0
  44. package/cabloy-docs/backend/serialization-guide.md +2 -2
  45. package/cabloy-docs/backend/service-guide.md +18 -9
  46. package/cabloy-docs/backend/startup-guide.md +5 -5
  47. package/cabloy-docs/backend/status-guide.md +7 -7
  48. package/cabloy-docs/backend/unit-testing.md +3 -3
  49. package/cabloy-docs/backend/vona-source-reading-map.md +157 -0
  50. package/cabloy-docs/backend/websocket-protocol-guide.md +5 -5
  51. package/cabloy-docs/backend/websocket-usage-guide.md +15 -8
  52. package/cabloy-docs/frontend/a-model-under-the-hood.md +281 -0
  53. package/cabloy-docs/frontend/a-openapi-under-the-hood.md +248 -0
  54. package/cabloy-docs/frontend/a-router-guide.md +307 -0
  55. package/cabloy-docs/frontend/api-guide.md +4 -4
  56. package/cabloy-docs/frontend/api-schema-guide.md +1 -0
  57. package/cabloy-docs/frontend/app-startup-guide.md +7 -4
  58. package/cabloy-docs/frontend/bean-scene-authoring.md +1 -1
  59. package/cabloy-docs/frontend/behavior-guide.md +16 -16
  60. package/cabloy-docs/frontend/cli.md +5 -5
  61. package/cabloy-docs/frontend/command-scene-authoring.md +17 -8
  62. package/cabloy-docs/frontend/component-guide.md +5 -5
  63. package/cabloy-docs/frontend/component-props-guide.md +1 -1
  64. package/cabloy-docs/frontend/component-v-model-guide.md +2 -2
  65. package/cabloy-docs/frontend/filter-query-select-data-flow-guide.md +260 -0
  66. package/cabloy-docs/frontend/form-guide.md +27 -30
  67. package/cabloy-docs/frontend/form-scene-to-page-meta-guide.md +303 -0
  68. package/cabloy-docs/frontend/foundation.md +10 -6
  69. package/cabloy-docs/frontend/frontend-source-reading-roadmap.md +249 -0
  70. package/cabloy-docs/frontend/generated-contract-consumption-debug-checklist.md +190 -0
  71. package/cabloy-docs/frontend/generated-contract-consumption-entry-branch.md +205 -0
  72. package/cabloy-docs/frontend/generated-contract-consumption-list-branch.md +157 -0
  73. package/cabloy-docs/frontend/generated-contract-consumption-specimen.md +203 -0
  74. package/cabloy-docs/frontend/generated-contract-consumption-verify-playbook.md +189 -0
  75. package/cabloy-docs/frontend/generic-component-guide.md +1 -1
  76. package/cabloy-docs/frontend/introduction.md +29 -7
  77. package/cabloy-docs/frontend/model-architecture.md +38 -2
  78. package/cabloy-docs/frontend/model-resource-cookbook.md +11 -8
  79. package/cabloy-docs/frontend/model-resource-internals-deep-dive.md +238 -0
  80. package/cabloy-docs/frontend/model-resource-owner-pattern.md +22 -2
  81. package/cabloy-docs/frontend/model-resource-usage-guide.md +22 -6
  82. package/cabloy-docs/frontend/model-state-guide.md +12 -9
  83. package/cabloy-docs/frontend/module-scope.md +8 -8
  84. package/cabloy-docs/frontend/modules-and-suites.md +2 -1
  85. package/cabloy-docs/frontend/navigation-guards-guide.md +7 -0
  86. package/cabloy-docs/frontend/openapi-sdk-guide.md +12 -4
  87. package/cabloy-docs/frontend/page-guide.md +9 -9
  88. package/cabloy-docs/frontend/page-meta-guide.md +466 -0
  89. package/cabloy-docs/frontend/page-params-guide.md +3 -3
  90. package/cabloy-docs/frontend/page-query-guide.md +2 -2
  91. package/cabloy-docs/frontend/page-route-guide.md +6 -0
  92. package/cabloy-docs/frontend/permission-formscene-action-visibility-guide.md +263 -0
  93. package/cabloy-docs/frontend/quickstart.md +14 -2
  94. package/cabloy-docs/frontend/resource-entry-page-deep-dive.md +271 -0
  95. package/cabloy-docs/frontend/resource-list-page-deep-dive.md +279 -0
  96. package/cabloy-docs/frontend/rest-resource-source-reading-map.md +522 -0
  97. package/cabloy-docs/frontend/rest-resource-under-the-hood.md +622 -0
  98. package/cabloy-docs/frontend/root-behaviors-guide.md +282 -0
  99. package/cabloy-docs/frontend/route-alias-guide.md +6 -0
  100. package/cabloy-docs/frontend/router-stack-guide.md +229 -0
  101. package/cabloy-docs/frontend/router-tabs-introduction.md +26 -3
  102. package/cabloy-docs/frontend/router-tabs-layout-integration.md +367 -0
  103. package/cabloy-docs/frontend/router-tabs-mechanism.md +6 -0
  104. package/cabloy-docs/frontend/router-tabs-route-meta-cookbook.md +7 -0
  105. package/cabloy-docs/frontend/router-tabs-vs-stack.md +167 -0
  106. package/cabloy-docs/frontend/router-view-hosts-guide.md +450 -0
  107. package/cabloy-docs/frontend/server-data.md +2 -1
  108. package/cabloy-docs/frontend/system-startup-guide.md +2 -2
  109. package/cabloy-docs/frontend/table-action-visibility-permission-flow-guide.md +263 -0
  110. package/cabloy-docs/frontend/table-cell-cookbook.md +571 -0
  111. package/cabloy-docs/frontend/table-guide.md +373 -0
  112. package/cabloy-docs/frontend/table-resource-crud-cookbook.md +496 -0
  113. package/cabloy-docs/frontend/zova-app-guide.md +251 -0
  114. package/cabloy-docs/frontend/zova-form-source-reading-map.md +7 -9
  115. package/cabloy-docs/frontend/zova-form-under-the-hood.md +5 -0
  116. package/cabloy-docs/frontend/zova-router-under-the-hood.md +561 -0
  117. package/cabloy-docs/frontend/zova-source-reading-map.md +101 -7
  118. package/cabloy-docs/frontend/zova-table-controller-render-supplement.md +225 -0
  119. package/cabloy-docs/frontend/zova-table-source-reading-map.md +317 -0
  120. package/cabloy-docs/frontend/zova-table-under-the-hood.md +532 -0
  121. package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-debug-checklist.md +245 -0
  122. package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-source-reading-map.md +139 -0
  123. package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-verify-playbook.md +248 -0
  124. package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions.md +511 -0
  125. package/cabloy-docs/fullstack/contract-loop-playbook.md +8 -2
  126. package/cabloy-docs/fullstack/edition-collaboration-differences.md +6 -0
  127. package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +181 -48
  128. package/cabloy-docs/fullstack/introduction.md +3 -0
  129. package/cabloy-docs/fullstack/openapi-to-sdk.md +116 -2
  130. package/cabloy-docs/fullstack/suites-and-modules.md +333 -0
  131. package/cabloy-docs/fullstack/tutorial-1-first-module.md +3 -0
  132. package/cabloy-docs/fullstack/tutorial-2-first-crud.md +4 -0
  133. package/cabloy-docs/fullstack/tutorial-3-frontend-metadata-sharing.md +4 -0
  134. package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +31 -19
  135. package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +5 -0
  136. package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +4 -0
  137. package/cabloy-docs/fullstack/tutorials-overview.md +1 -1
  138. package/cabloy-docs/reference/bean-scene-boilerplates.md +13 -13
  139. package/cabloy-docs/reference/package-map.md +4 -3
  140. package/package.json +1 -1
  141. package/vona/pnpm-lock.yaml +22 -258
  142. package/vona/src/suite/a-training/modules/training-student/package.json +53 -0
  143. package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +400 -0
  144. package/vona/src/suite/a-training/modules/training-student/src/.metadata/locales.ts +18 -0
  145. package/vona/src/suite/a-training/modules/training-student/src/.metadata/this.ts +2 -0
  146. package/vona/src/suite/a-training/modules/training-student/src/bean/meta.index.ts +12 -0
  147. package/vona/src/suite/a-training/modules/training-student/src/bean/meta.version.ts +21 -0
  148. package/vona/src/suite/a-training/modules/training-student/src/bean/ssrMenu.student.ts +29 -0
  149. package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +15 -0
  150. package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +15 -0
  151. package/vona/src/suite/a-training/modules/training-student/src/controller/student.ts +74 -0
  152. package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +28 -0
  153. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectReq.tsx +44 -0
  154. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectRes.tsx +11 -0
  155. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +45 -0
  156. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSummary.tsx +42 -0
  157. package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +28 -0
  158. package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +25 -0
  159. package/vona/src/suite/a-training/modules/training-student/src/entity/student.tsx +84 -0
  160. package/vona/src/suite/a-training/modules/training-student/src/index.ts +2 -0
  161. package/vona/src/suite/a-training/modules/training-student/src/model/student.ts +10 -0
  162. package/vona/src/suite/a-training/modules/training-student/src/service/student.ts +57 -0
  163. package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +173 -0
  164. package/vona/src/suite/a-training/modules/training-student/tsconfig.build.json +11 -0
  165. package/vona/src/suite/a-training/modules/training-student/tsconfig.json +7 -0
  166. package/vona/src/suite/a-training/package.json +12 -0
  167. package/vona/src/suite/a-training/tsconfig.base.json +4 -0
  168. package/vona/src/suite/a-training/tsconfig.json +10 -0
  169. package/zova/packages-zova/zova/package.json +2 -2
  170. package/zova/pnpm-lock.yaml +423 -682
  171. package/zova/src/suite/a-demo/modules/demo-basic/src/page/toolOne/render.tsx +5 -3
  172. package/zova/src/suite/a-home/modules/home-login/src/page/login/render.tsx +5 -3
  173. package/zova/src/suite/a-training/modules/training-student/cli/openapi.config.ts +9 -0
  174. package/zova/src/suite/a-training/modules/training-student/package.json +57 -0
  175. package/zova/src/suite/a-training/modules/training-student/src/.metadata/component/formFieldLevel.ts +31 -0
  176. package/zova/src/suite/a-training/modules/training-student/src/.metadata/index.ts +258 -0
  177. package/zova/src/suite/a-training/modules/training-student/src/.metadata/locales.ts +7 -0
  178. package/zova/src/suite/a-training/modules/training-student/src/.metadata/this.ts +2 -0
  179. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/baseURL.ts +5 -0
  180. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/index.ts +3 -0
  181. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +196 -0
  182. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +4146 -0
  183. package/zova/src/suite/a-training/modules/training-student/src/api/trainingStudent.ts +151 -0
  184. package/zova/src/suite/a-training/modules/training-student/src/apiSchema/trainingStudent.ts +43 -0
  185. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionDeleteForce.tsx +53 -0
  186. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionSummary.tsx +56 -0
  187. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.level.tsx +63 -0
  188. package/zova/src/suite/a-training/modules/training-student/src/component/formFieldLevel/controller.tsx +117 -0
  189. package/zova/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +9 -0
  190. package/zova/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +9 -0
  191. package/zova/src/suite/a-training/modules/training-student/src/index.ts +2 -0
  192. package/zova/src/suite/a-training/modules/training-student/src/model/student.ts +42 -0
  193. package/zova/src/suite/a-training/modules/training-student/tsconfig.build.json +13 -0
  194. package/zova/src/suite/a-training/modules/training-student/tsconfig.json +5 -0
  195. package/zova/src/suite/a-training/package.json +12 -0
  196. package/zova/src/suite/a-training/tsconfig.base.json +4 -0
  197. package/zova/src/suite/a-training/tsconfig.json +4 -0
  198. package/zova/src/suite/cabloy-basic/modules/basic-app/package.json +60 -0
  199. package/zova/src/suite/cabloy-basic/modules/basic-app/src/.metadata/index.ts +137 -0
  200. package/zova/src/suite/cabloy-basic/modules/basic-app/src/.metadata/locales.ts +7 -0
  201. package/zova/src/suite/cabloy-basic/modules/basic-app/src/.metadata/this.ts +2 -0
  202. package/zova/src/suite/cabloy-basic/modules/basic-app/src/bean/behavior.appModal.tsx +260 -0
  203. package/zova/src/suite/cabloy-basic/modules/basic-app/src/config/config.ts +39 -0
  204. package/zova/src/suite/cabloy-basic/modules/basic-app/src/config/locale/en-us.ts +7 -0
  205. package/zova/src/suite/cabloy-basic/modules/basic-app/src/config/locale/zh-cn.ts +7 -0
  206. package/zova/src/suite/cabloy-basic/modules/basic-app/src/index.ts +4 -0
  207. package/zova/src/suite/cabloy-basic/modules/basic-app/src/lib/appModalItem.ts +16 -0
  208. package/zova/src/suite/cabloy-basic/modules/basic-app/src/lib/index.ts +1 -0
  209. package/zova/src/suite/cabloy-basic/modules/basic-app/src/monkey.ts +38 -0
  210. package/zova/src/suite/cabloy-basic/modules/basic-app/src/monkeySys.ts +14 -0
  211. package/zova/src/suite/cabloy-basic/modules/basic-app/src/service/appModal.ts +89 -0
  212. package/zova/src/suite/cabloy-basic/modules/basic-app/src/types/appModal.ts +52 -0
  213. package/zova/src/suite/cabloy-basic/modules/basic-app/src/types/index.ts +1 -0
  214. package/zova/src/suite/cabloy-basic/modules/basic-app/tsconfig.build.json +13 -0
  215. package/zova/src/suite/cabloy-basic/modules/basic-app/tsconfig.json +5 -0
  216. package/zova/src/suite/cabloy-basic/modules/basic-commands/package.json +6 -1
  217. package/zova/src/suite/cabloy-basic/modules/basic-commands/src/.metadata/index.ts +16 -0
  218. package/zova/src/suite/cabloy-basic/modules/basic-commands/src/bean/command.alert.tsx +8 -14
  219. package/zova/src/suite/cabloy-basic/modules/basic-commands/src/bean/command.confirm.tsx +10 -7
  220. package/zova/src/suite/cabloy-basic/modules/basic-commands/src/bean/command.prompt.tsx +30 -0
  221. package/zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockForm/controller.tsx +5 -3
  222. package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +29 -7
  223. package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/select/controller.tsx +34 -11
  224. package/zova/src/suite/cabloy-basic/modules/basic-table/package.json +6 -1
  225. package/zova/src/suite/cabloy-basic/modules/basic-table/src/bean/tableCell.actionDelete.tsx +4 -2
  226. package/zova/src/suite/cabloy-basic/package.json +1 -0
  227. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
  228. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +3 -3
  229. package/zova/src/suite-vendor/a-zova/modules/a-table/src/lib/tableCell.ts +1 -1
  230. package/zova/src/suite-vendor/a-zova/package.json +2 -2
@@ -0,0 +1,466 @@
1
+ # Page Meta Guide
2
+
3
+ This guide explains how page metadata works in Zova within the Cabloy monorepo.
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 “which routed host owns this page?” but “how should the page author update task-level title, dirty state, or form scene in the routed shell?”.
6
+
7
+ In the current public Cabloy Basic source, Page Meta is mainly a `routerViewTabs` concern rather than a universal routed-host feature.
8
+
9
+ Read this together with:
10
+
11
+ - [Page Route Guide](/frontend/page-route-guide)
12
+ - [A-Router Guide](/frontend/a-router-guide)
13
+ - [Router View Hosts Guide](/frontend/router-view-hosts-guide)
14
+ - [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
15
+ - [Router Tabs Layout Integration](/frontend/router-tabs-layout-integration)
16
+ - [Router Tabs Route Meta Cookbook](/frontend/router-tabs-route-meta-cookbook)
17
+ - [Form Guide](/frontend/form-guide)
18
+ - [Permission, formScene, and Action Visibility Guide](/frontend/permission-formscene-action-visibility-guide)
19
+ - [SSR SEO Meta](/frontend/ssr-seo-meta)
20
+
21
+ ## Why this guide exists
22
+
23
+ After contributors understand route meta, router-view hosts, and the router-tabs model, the next practical question is often about task-level page presentation:
24
+
25
+ - when should a page update its visible task title?
26
+ - how should a page mark itself dirty?
27
+ - how can create/edit form state affect the routed shell?
28
+ - what is the difference between `route.meta` and `pageMeta`?
29
+ - why does `$router.setPageMeta(...)` matter in `routerViewTabs` but not in every host?
30
+
31
+ This guide is the authoring-focused answer to those questions.
32
+
33
+ ## The shortest accurate mental model
34
+
35
+ The shortest accurate model is:
36
+
37
+ 1. route meta such as `tabKey`, `componentKey`, and `keepAlive` defines routed-host identity and workbench behavior
38
+ 2. page code calls `$router.setPageMeta(this.$pageRoute, pageMeta)` when task-level presentation should change
39
+ 3. the shared router bean forwards that update to registered router-view hosts
40
+ 4. `routerViewTabs` delegates the update to `ModelTabs`
41
+ 5. `ModelTabs` stores the metadata on the current level-2 tab item
42
+ 6. the active layout reads that metadata to render task-level title and icon state
43
+
44
+ That is why page metadata is not the same thing as route metadata.
45
+
46
+ - **route meta** shapes routed identity and host behavior before or during route processing
47
+ - **page meta** updates task-level presentation after the page instance is already participating in the routed host
48
+
49
+ ## Source-confirmed runtime path
50
+
51
+ The highest-value current Basic source path is:
52
+
53
+ 1. `zova/src/suite-vendor/a-zova/modules/a-router/src/types/pageMeta.ts` defines `IPageMeta`
54
+ 2. `zova/src/suite-vendor/a-zova/modules/a-router/src/types/routerView.ts` allows routed work items to carry `pageMeta`
55
+ 3. `zova/src/suite-vendor/a-zova/modules/a-router/src/bean/bean.router.ts` forwards `$router.setPageMeta(...)` updates to registered router-view hosts
56
+ 4. `zova/src/suite-vendor/a-zova/modules/a-router/src/lib/routerViewBase.tsx` provides the default no-op host behavior
57
+ 5. `zova/src/suite-vendor/a-zova/modules/a-routertabs/src/component/routerViewTabs/controller.tsx` overrides `setPageMeta(...)` and delegates to `ModelTabs`
58
+ 6. `zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts` stores and merges `pageMeta` on the routed work item
59
+ 7. `zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx` shows the clearest current authoring path
60
+ 8. `zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.tabs.tsx` shows the clearest current visible shell consumer
61
+
62
+ A compact interpretation is:
63
+
64
+ - page code emits page meta through `$router.setPageMeta(...)`
65
+ - the router forwards it to the active routed host
66
+ - the tabs host stores it on the routed work item
67
+ - the shell renders title, dirty, and form-scene signals from that stored metadata
68
+
69
+ ## The public page-meta surface
70
+
71
+ The public page-meta type is `IPageMeta`.
72
+
73
+ Representative source:
74
+
75
+ - `zova/src/suite-vendor/a-zova/modules/a-router/src/types/pageMeta.ts`
76
+
77
+ Representative shape:
78
+
79
+ ```typescript
80
+ export interface IPageMeta {
81
+ pageTitle?: string;
82
+ pageDirty?: boolean;
83
+ formMeta?: IFormMeta;
84
+ }
85
+ ```
86
+
87
+ ### `pageTitle`
88
+
89
+ `pageTitle` is the task-level title for the current routed work item.
90
+
91
+ In the current Basic source, this is typically what the Admin layout uses for the level-2 item label instead of the broader menu-backed workspace title.
92
+
93
+ ### `pageDirty`
94
+
95
+ `pageDirty` tells the routed shell whether the current work item should appear dirty.
96
+
97
+ Typical visible effect:
98
+
99
+ - an asterisk or similar dirty indicator in the task-level UI
100
+
101
+ ### `formMeta`
102
+
103
+ `formMeta` lets the routed shell reflect form-scene context such as `create` or `edit`.
104
+
105
+ In the current Basic source, this can affect task-level icon treatment.
106
+
107
+ A practical way to read it is:
108
+
109
+ - page/form code derives `formMeta`
110
+ - the routed shell consumes `formMeta`
111
+ - `formScene` is therefore not only a form concern; it also becomes task-level visual state in the current tabs-based shell
112
+
113
+ If you want the full cross-layer runtime path from `formScene` to `formMeta`, then to `pageMeta`, and finally to visible shell/tab state, continue with [Form Scene to Page Meta Guide](/frontend/form-scene-to-page-meta-guide).
114
+
115
+ ## What page meta is not
116
+
117
+ Keep these boundaries clear.
118
+
119
+ ### It is not route meta
120
+
121
+ Do not treat `pageMeta` as a late mutation form of `route.meta`.
122
+
123
+ - `route.meta` belongs to route declaration and routed-host behavior
124
+ - `pageMeta` belongs to the active page instance and its task-level presentation
125
+
126
+ If your question is “which workspace should this route belong to?” or “should this route reuse one page instance?”, that is a route-meta question, not a page-meta question.
127
+
128
+ ### It is not business state ownership
129
+
130
+ Do not use `pageMeta` as the primary storage place for business data.
131
+
132
+ Business state still belongs in page/controller/model/service code.
133
+
134
+ `pageMeta` should stay small and presentation-oriented.
135
+
136
+ ### It is not guaranteed to be the browser document title
137
+
138
+ `pageTitle` is a task-level routed-shell title surface.
139
+
140
+ It may align with visible shell labels, but contributors should not assume it is automatically identical to browser-level document-title handling unless they verify the current consumer path.
141
+
142
+ A practical rule is:
143
+
144
+ - use **page meta** for task-level shell presentation
145
+ - use **SSR/browser metadata** for document title and SEO-oriented head output
146
+
147
+ For the SSR/browser metadata path, see [SSR SEO Meta](/frontend/ssr-seo-meta).
148
+
149
+ ### It is not a universal routed-host contract
150
+
151
+ `pageMeta` is most meaningful in hosts that actually model task-level routed items.
152
+
153
+ In the current source:
154
+
155
+ - `routerViewTabs` supports host-level page-meta updates
156
+ - `routerViewEmpty` does not add a richer host-level page-meta model
157
+ - `routerViewStack` does not override `setPageMeta(...)`
158
+
159
+ That means page-meta authoring is mainly a `routerViewTabs` concern.
160
+
161
+ ## The runtime path
162
+
163
+ ### 1. Page code calls `$router.setPageMeta(...)`
164
+
165
+ Representative source-confirmed usage in the current Basic repo:
166
+
167
+ - `zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx`
168
+ - `zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockForm/controller.tsx`
169
+
170
+ Representative pattern:
171
+
172
+ ```typescript
173
+ setPageMeta(data: any | undefined, pageDirty?: boolean) {
174
+ if (!this.$pageRoute) return;
175
+ const pageTitle = data?.[this.$props.pageTitleKey];
176
+ this.$router.setPageMeta(this.$pageRoute, { pageTitle, pageDirty, formMeta: this.formMeta });
177
+ }
178
+ ```
179
+
180
+ This is the authoring entrypoint most page contributors care about.
181
+
182
+ ### 2. `BeanRouter` forwards the update to registered hosts
183
+
184
+ Representative source:
185
+
186
+ - `zova/src/suite-vendor/a-zova/modules/a-router/src/bean/bean.router.ts`
187
+
188
+ Representative pattern:
189
+
190
+ ```typescript
191
+ setPageMeta(route, pageMeta) {
192
+ for (const routerView of this._routerViews) {
193
+ routerView.setPageMeta(route, pageMeta);
194
+ }
195
+ }
196
+ ```
197
+
198
+ This means the router bean is not itself the state owner.
199
+
200
+ It is the forwarding boundary between page code and routed hosts.
201
+
202
+ ### 3. `routerViewTabs` delegates to `ModelTabs`
203
+
204
+ Representative source:
205
+
206
+ - `zova/src/suite-vendor/a-zova/modules/a-routertabs/src/component/routerViewTabs/controller.tsx`
207
+ - `zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts`
208
+
209
+ Representative pattern:
210
+
211
+ ```typescript
212
+ public setPageMeta(route, pageMeta) {
213
+ this.$$modelTabs.setPageMeta(route, pageMeta);
214
+ }
215
+ ```
216
+
217
+ Inside `ModelTabs`, the update is resolved by `route.fullPath`, then applied to the current tab item.
218
+
219
+ This is the crucial source-level fact:
220
+
221
+ - **page metadata is stored on the routed work item, not on the route record itself**
222
+
223
+ ### 4. The active layout consumes the stored page meta
224
+
225
+ Representative Basic consumers:
226
+
227
+ - `zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.tabs.tsx`
228
+ - `zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.tabs.tsx`
229
+
230
+ In the current Basic source, the layout can use page meta for:
231
+
232
+ - task-level title rendering
233
+ - dirty indicators
234
+ - create/edit icon signals derived from `formMeta.formScene`
235
+
236
+ ## The most important authoring pattern
237
+
238
+ The current Basic `basic-pageentry` code shows the most important pattern.
239
+
240
+ ### Initialize task presentation from loaded data
241
+
242
+ When page data becomes ready, set the initial title and non-dirty state.
243
+
244
+ Representative pattern:
245
+
246
+ ```typescript
247
+ this.setPageMeta(this.formData, false);
248
+ ```
249
+
250
+ ### Mark the task dirty on form changes
251
+
252
+ Representative pattern:
253
+
254
+ ```typescript
255
+ onChanged={data => {
256
+ $$pageEntry.setPageMeta(data, true);
257
+ }}
258
+ ```
259
+
260
+ ### Clear dirty state after successful submit
261
+
262
+ Representative pattern:
263
+
264
+ ```typescript
265
+ async submitData(data) {
266
+ await mutationSubmit?.mutateAsync(data.value as any);
267
+ this.setPageMeta(data.value, false);
268
+ }
269
+ ```
270
+
271
+ This sequence gives the routed shell a stable task title, a live dirty signal, and scene-aware icon context without moving that concern into menu state or route meta.
272
+
273
+ ## FAQ-style scenarios
274
+
275
+ ### Scenario 1: the route is correct, but the task title is too generic
276
+
277
+ Typical situation:
278
+
279
+ - the workspace grouping is already correct through `tabKey`
280
+ - the page instance identity is already correct through `componentKey` or default behavior
281
+ - but the visible level-2 task label should show the loaded record name instead of a generic page label
282
+
283
+ Use page meta here, not route meta.
284
+
285
+ Representative pattern:
286
+
287
+ ```typescript
288
+ const pageTitle = data?.name;
289
+ this.$router.setPageMeta(this.$pageRoute, { pageTitle });
290
+ ```
291
+
292
+ This changes task-level presentation without changing workspace grouping or page-instance identity.
293
+
294
+ ### Scenario 2: a form starts clean, becomes dirty while editing, then returns clean after submit
295
+
296
+ This is the most common page-meta lifecycle.
297
+
298
+ Representative pattern:
299
+
300
+ ```typescript
301
+ this.setPageMeta(this.formData, false);
302
+
303
+ onChanged={data => {
304
+ this.setPageMeta(data, true);
305
+ }}
306
+
307
+ async submitData(data) {
308
+ await mutationSubmit?.mutateAsync(data.value as any);
309
+ this.setPageMeta(data.value, false);
310
+ }
311
+ ```
312
+
313
+ Use this when the shell should reflect unsaved work without moving dirty tracking into menu state or route declaration.
314
+
315
+ ### Scenario 3: create and edit pages should look different in the shell
316
+
317
+ If the shell should distinguish create work from edit work, include `formMeta` in page meta updates.
318
+
319
+ Representative pattern:
320
+
321
+ ```typescript
322
+ this.$router.setPageMeta(this.$pageRoute, {
323
+ pageTitle,
324
+ pageDirty,
325
+ formMeta: this.formMeta,
326
+ });
327
+ ```
328
+
329
+ In the current Basic source, this lets the layout derive task-level icon treatment from `formMeta.formScene`.
330
+
331
+ ### Scenario 4: I only want to change browser document title
332
+
333
+ Do not assume page meta is the right tool.
334
+
335
+ `pageTitle` is a routed-shell task-title surface first.
336
+
337
+ If the requirement is only browser document-title behavior, verify the current document-title consumer path before reusing page meta for that purpose.
338
+
339
+ ## A compact helper pattern
340
+
341
+ When a page repeatedly updates title, dirty state, and form scene together, keep the write path centralized.
342
+
343
+ Representative pattern:
344
+
345
+ ```typescript
346
+ setPageMeta(data: any | undefined, pageDirty?: boolean) {
347
+ if (!this.$pageRoute) return;
348
+ const pageTitle = data?.[this.$props.pageTitleKey];
349
+ this.$router.setPageMeta(this.$pageRoute, { pageTitle, pageDirty, formMeta: this.formMeta });
350
+ }
351
+ ```
352
+
353
+ This is usually better than scattering several independent `$router.setPageMeta(...)` calls across unrelated handlers.
354
+
355
+ ## When you should update page meta
356
+
357
+ Update page meta when the routed task presentation changes.
358
+
359
+ Typical cases:
360
+
361
+ - the loaded record changes the task title
362
+ - the form becomes dirty or returns to a clean state
363
+ - the form scene should visibly distinguish create vs edit work
364
+ - the current work item needs a more specific task label than the workspace title
365
+ - the page needs one small shell-facing metadata update without changing route identity or layout-owned menu info
366
+
367
+ Avoid updating page meta for concerns that are really:
368
+
369
+ - workspace grouping questions
370
+ - page-instance reuse questions
371
+ - broad business state storage
372
+ - low-level transient values that the shell does not need to present
373
+
374
+ ## `pageMeta` vs router-tabs route meta
375
+
376
+ Use this split:
377
+
378
+ - use route meta such as `tabKey`, `componentKey`, `componentKeyMode`, and `keepAlive` to decide **how the route participates in the workbench**
379
+ - use page meta to decide **how the current work item should be presented after it is already open**
380
+
381
+ A compact rule:
382
+
383
+ - **route meta answers identity**
384
+ - **page meta answers presentation**
385
+
386
+ ## Cache and dirty-state safety
387
+
388
+ The current router-tabs model resets restored `pageDirty` state when cached tabs are loaded.
389
+
390
+ This is intentional.
391
+
392
+ A restored work item should not automatically claim unsaved work unless the application can truly re-establish that state.
393
+
394
+ That means contributors should treat `pageDirty` as a live task-state presentation signal, not as a durable business-truth record.
395
+
396
+ ## Edition note
397
+
398
+ This guide describes the shared routed-host contract and the current public Cabloy Basic consumers.
399
+
400
+ The same architectural role applies across editions where the shared router-view host and router-tabs model are reused, but visible shell presentation can still differ by edition, layout, or UI layer.
401
+
402
+ ## Suggested reading order when debugging page-meta behavior
403
+
404
+ If the task is specifically about page metadata, read these in order:
405
+
406
+ 1. this page
407
+ 2. the concrete page controller that calls `$router.setPageMeta(...)`
408
+ 3. [Router View Hosts Guide](/frontend/router-view-hosts-guide)
409
+ 4. [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
410
+ 5. [Router Tabs Layout Integration](/frontend/router-tabs-layout-integration)
411
+
412
+ This keeps the authoring entrypoint in view before you descend into host and layout internals.
413
+
414
+ ## A compact authoring checklist
415
+
416
+ Before adding or changing page-meta logic, ask:
417
+
418
+ 1. is this really a task-presentation change rather than a route-identity change?
419
+ 2. does the shell need this information, or is it only business state?
420
+ 3. should the title come from loaded data, form state, or some other stable task label?
421
+ 4. should dirty state reset after successful submit?
422
+ 5. is the current routed host actually a page-meta consumer?
423
+
424
+ If those answers are clear, the page-meta update path is usually clear too.
425
+
426
+ ## Common mistakes to avoid
427
+
428
+ ### Mistake 1: using route meta when the real problem is task presentation
429
+
430
+ If the route is already in the right workspace and page instance, do not reach for `tabKey` or `componentKey` just to change the visible task label.
431
+
432
+ Use page meta instead.
433
+
434
+ ### Mistake 2: storing business payloads in page meta
435
+
436
+ Keep `pageMeta` small and shell-facing.
437
+
438
+ If the data matters to business logic, it probably belongs elsewhere.
439
+
440
+ ### Mistake 3: assuming every routed host consumes page meta
441
+
442
+ Do not overgeneralize `routerViewTabs` behavior to `routerViewEmpty` or `routerViewStack` without verification.
443
+
444
+ ### Mistake 4: assuming `pageDirty` is durable across cache restore
445
+
446
+ The current model intentionally clears restored dirty signals.
447
+
448
+ ## Summary
449
+
450
+ Page metadata is the routed-shell presentation layer for an already-open page task.
451
+
452
+ Use `$router.setPageMeta(this.$pageRoute, ...)` when the current work item should update its title, dirty state, or form-scene-driven visual context.
453
+
454
+ Keep the architectural split clear:
455
+
456
+ - route meta controls routed identity and host behavior
457
+ - page meta controls task-level presentation after the page is already open
458
+
459
+ ## See also
460
+
461
+ - [Router View Hosts Guide](/frontend/router-view-hosts-guide)
462
+ - [Router Tabs Introduction](/frontend/router-tabs-introduction)
463
+ - [Router Tabs Mechanism](/frontend/router-tabs-mechanism)
464
+ - [Router Tabs Layout Integration](/frontend/router-tabs-layout-integration)
465
+ - [Router Tabs Route Meta Cookbook](/frontend/router-tabs-route-meta-cookbook)
466
+ - [Form Guide](/frontend/form-guide)
@@ -11,7 +11,7 @@ Zova enhances route params handling with typed support so page controllers can w
11
11
  Example: add params support for page `counter`.
12
12
 
13
13
  ```bash
14
- npm run zova :refactor:pageParams counter -- --module=demo-student
14
+ npm run zova :refactor:pageParams counter -- --module=training-student
15
15
  ```
16
16
 
17
17
  ## Add params schema
@@ -47,7 +47,7 @@ Representative route idea:
47
47
  When the route definition changes, regenerate module metadata so the framework’s typed route information stays aligned.
48
48
 
49
49
  ```bash
50
- npm run zova :tools:metadata demo-student
50
+ npm run zova :tools:metadata training-student
51
51
  ```
52
52
 
53
53
  For the broader schema model behind `z`, coercion, defaults, and nested structures, see [Zod Guide](/frontend/zod-guide).
@@ -69,7 +69,7 @@ class ControllerPageCounter {
69
69
  Representative pattern:
70
70
 
71
71
  ```typescript
72
- const url = this.$router.getPagePath('/demo/student/counter/:id?', {
72
+ const url = this.$router.getPagePath('/training/student/counter/:id?', {
73
73
  params: {
74
74
  id: 1,
75
75
  },
@@ -13,7 +13,7 @@ That is important because query values are part of page behavior, not just incid
13
13
  Example: add query support for page `counter`.
14
14
 
15
15
  ```bash
16
- npm run zova :refactor:pageQuery counter -- --module=demo-student
16
+ npm run zova :refactor:pageQuery counter -- --module=training-student
17
17
  ```
18
18
 
19
19
  ## Add query schema
@@ -53,7 +53,7 @@ class ControllerPageCounter {
53
53
  Representative pattern:
54
54
 
55
55
  ```typescript
56
- const url = this.$router.getPagePath('/demo/student/counter', {
56
+ const url = this.$router.getPagePath('/training/student/counter', {
57
57
  query: {
58
58
  name: 'tom',
59
59
  age: 18,
@@ -114,6 +114,8 @@ That means route metadata chooses the logical layout, while env/config decides w
114
114
 
115
115
  This is the practical app-shell boundary in Zova: routed pages do not appear alone. They appear inside the resolved layout shell for the current runtime variant.
116
116
 
117
+ For the thin root app host that renders the routed tree before layout-specific behavior continues, see [Zova App Guide](/frontend/zova-app-guide).
118
+
117
119
  In the current Basic source, that shell is represented concretely by admin-style, web-style, and empty/minimal layout implementations.
118
120
 
119
121
  For the broader runtime-selection model behind env and flavor-aware configuration, see [Environment and Config Guide](/frontend/environment-config-guide).
@@ -129,10 +131,14 @@ Layout selection, navigation guards, and aliases are closely related but they so
129
131
 
130
132
  Read together with:
131
133
 
134
+ - [A-Router Guide](/frontend/a-router-guide)
135
+ - [Zova Router Under the Hood](/frontend/zova-router-under-the-hood)
132
136
  - [Navigation Guards Guide](/frontend/navigation-guards-guide)
133
137
  - [Route Alias Guide](/frontend/route-alias-guide)
134
138
  - [Frontend Quickstart](/frontend/quickstart)
135
139
 
140
+ If your next question is no longer about the public route record itself but about the `a-router` package that makes routes operational, continue with [A-Router Guide](/frontend/a-router-guide).
141
+
136
142
  ## Implementation checks for page-routing changes
137
143
 
138
144
  When editing page routing, do not only change the URL string.