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,511 @@
1
+ # Backend Metadata to Frontend Table Actions
2
+
3
+ This page explains one of the most practical fullstack contract chains in Cabloy Basic:
4
+
5
+ > backend field and row metadata can drive visible frontend table actions, while frontend action resources and generated contract consumers stay aligned with that backend truth.
6
+
7
+ This page sits between the pure direction guides:
8
+
9
+ - [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk)
10
+ - [Frontend Metadata Back to Backend](/fullstack/frontend-metadata-to-backend)
11
+
12
+ It is not only a forward-chain page and not only a reverse-chain page.
13
+
14
+ Instead, it explains one concrete business thread where both directions usually cooperate.
15
+
16
+ Use this page together with:
17
+
18
+ - [Contract Loop Playbook](/fullstack/contract-loop-playbook)
19
+ - [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk)
20
+ - [Frontend Metadata Back to Backend](/fullstack/frontend-metadata-to-backend)
21
+ - [Table Guide](/frontend/table-guide)
22
+ - [TableCell Authoring Cookbook](/frontend/table-cell-cookbook)
23
+ - [Table + Resource CRUD Cookbook](/frontend/table-resource-crud-cookbook)
24
+ - [Tutorial 3: Frontend Metadata Sharing](/fullstack/tutorial-3-frontend-metadata-sharing)
25
+ - [Tutorial 5: Backend Contract Sharing](/fullstack/tutorial-5-backend-contract-sharing)
26
+ - [Backend Metadata to Frontend Table Actions Verify Playbook](/fullstack/backend-metadata-to-frontend-table-actions-verify-playbook)
27
+ - [Backend Metadata to Frontend Table Actions Debug Checklist](/fullstack/backend-metadata-to-frontend-table-actions-debug-checklist)
28
+ - [Backend Metadata to Frontend Table Actions Source Reading Map](/fullstack/backend-metadata-to-frontend-table-actions-source-reading-map)
29
+
30
+ ## Why this page exists
31
+
32
+ Several Cabloy docs already explain parts of this story:
33
+
34
+ - backend field contracts
35
+ - OpenAPI generation
36
+ - frontend metadata sharing
37
+ - custom table-cell authoring
38
+ - resource-driven CRUD pages
39
+
40
+ What contributors and AI workflows often still want is one continuous answer to this narrower question:
41
+
42
+ > how does one row action or one table-cell decision travel from backend metadata to a visible frontend list page?
43
+
44
+ This page answers that question by treating table actions as one complete contract chain rather than as disconnected snippets.
45
+
46
+ ## The shortest correct mental model
47
+
48
+ If you only remember one idea, remember this one:
49
+
50
+ > in Cabloy Basic, a visible frontend table action usually belongs to a larger contract chain: backend metadata chooses the action resource identity, frontend runtime resolves that resource, and generated API/model layers keep the action semantics aligned with the backend contract.
51
+
52
+ That means the visible button or link in a table row is often only the last step of the chain, not the first.
53
+
54
+ ## The main chain in one view
55
+
56
+ A practical row-action chain often looks like this:
57
+
58
+ 1. backend resource entity or row DTO defines field or row-action metadata
59
+ 2. that metadata uses `ZovaRender.cell(...)`, `ZovaRender.tableActionRow(...)`, `ZovaRender.tableActionBulk(...)`, or `ZovaRender.block(...)`
60
+ 3. frontend resource/page runtime consumes the generated schema or DTO-backed block metadata
61
+ 4. `basic-page:blockPage` and `basic-page:blockTable` feed row schema and data into `ZTable`
62
+ 5. the `a-table` runtime resolves the referenced `tableCell` resource
63
+ 6. the `tableCell` bean renders the visible action and may delegate to commands or model methods
64
+ 7. if the action uses custom backend endpoints, frontend generated API and thin model facades keep the action semantics aligned with backend truth
65
+
66
+ That is the chain this page makes explicit.
67
+
68
+ ## Two common categories of table action work
69
+
70
+ Before diving into files, separate two cases.
71
+
72
+ ### Case A: metadata-only or built-in action path
73
+
74
+ Use this mental model when:
75
+
76
+ - built-in actions are enough
77
+ - row actions such as view/update/delete/create already exist
78
+ - the backend mainly needs to point to existing frontend resources
79
+
80
+ Representative examples include:
81
+
82
+ - `basic-table:actionView`
83
+ - `basic-table:actionUpdate`
84
+ - `basic-table:actionDelete`
85
+ - `basic-table:actionCreate`
86
+ - `basic-table:actionOperationsRow`
87
+
88
+ In this case, the main work is usually on the reverse-sharing side:
89
+
90
+ - backend metadata chooses frontend resource identities
91
+ - frontend runtime consumes them
92
+
93
+ ### Case B: custom action path with backend contract changes
94
+
95
+ Use this mental model when:
96
+
97
+ - the row action corresponds to a new backend endpoint such as `summary/:id` or `deleteForce/:id`
98
+ - frontend should consume a newly generated API surface
99
+ - the same resource-owner model should stay the semantic owner
100
+
101
+ In this case, both directions cooperate:
102
+
103
+ - **forward chain**: backend controller/DTO changes generate frontend API consumers
104
+ - **reverse chain**: backend metadata points to frontend action resources that expose those new actions in the list page
105
+
106
+ This is the most practical reason to keep the forward and reverse chains conceptually separate but operationally connected.
107
+
108
+ ## Step 1: Backend metadata chooses the visible action resource identity
109
+
110
+ The first source of truth for table action visibility often lives in backend field or row DTO metadata.
111
+
112
+ Representative entity-level field example:
113
+
114
+ ```typescript
115
+ @Api.field(
116
+ v.title($locale('Name')),
117
+ v.min(3, $locale('ZodErrorStringMin')),
118
+ v.required(),
119
+ ZovaRender.order(1),
120
+ ZovaRender.cell('basic-table:actionView'),
121
+ )
122
+ name: string;
123
+ ```
124
+
125
+ Representative row-action-column example:
126
+
127
+ ```typescript
128
+ @Api.field(
129
+ v.title($locale('Operations')),
130
+ ZovaRender.order(1, 'max'),
131
+ ZovaRender.cell('basic-table:actionOperationsRow', {
132
+ actions: [
133
+ ZovaRender.tableActionRow('basic-table:actionUpdate'),
134
+ ZovaRender.tableActionRow('basic-table:actionDelete'),
135
+ ],
136
+ }),
137
+ )
138
+ _operationsRow?: unknown;
139
+ ```
140
+
141
+ This is one of the most important fullstack facts about list pages.
142
+
143
+ The backend contract is not trying to render the button itself. It is choosing the frontend resource identity that should render the button.
144
+
145
+ A practical reading takeaway is:
146
+
147
+ - **the backend owns the action contract surface**
148
+ - **the frontend owns the action implementation**
149
+ - **metadata is the bridge**
150
+
151
+ ## Step 2: Block metadata composes the list page around those actions
152
+
153
+ Table actions do not live in isolation. They appear inside a resource-page block composition.
154
+
155
+ Representative shape:
156
+
157
+ ```tsx
158
+ ZovaRender.block('basic-page:blockPage', {
159
+ blocks: [
160
+ ZovaRender.block('basic-page:blockFilter'),
161
+ ZovaRender.block('basic-page:blockToolbarBulk', {
162
+ actions: [ZovaRender.tableActionBulk('basic-table:actionCreate')],
163
+ }),
164
+ ZovaRender.block('basic-page:blockTable'),
165
+ ZovaRender.block('basic-page:blockPager'),
166
+ ],
167
+ });
168
+ ```
169
+
170
+ That means the row-action chain usually sits inside a larger page contract chain:
171
+
172
+ - block composition decides the page shape
173
+ - row or field metadata decides the cell/action resources
174
+ - frontend blocks and table runtime consume both surfaces together
175
+
176
+ ## Step 3: `ModelResource` becomes the stable frontend resource owner
177
+
178
+ On the frontend side, the standard list runtime begins with the resource-owner model:
179
+
180
+ - `rest-resource.model.resource`
181
+
182
+ Its responsibilities include:
183
+
184
+ - resource bootstrap
185
+ - permissions
186
+ - `schemaFilter`
187
+ - `schemaRow`
188
+ - list query state
189
+ - item query state
190
+ - mutation ownership
191
+
192
+ This matters because the page runtime is not expected to rediscover resource contracts ad hoc.
193
+
194
+ A practical reading takeaway is:
195
+
196
+ - **pages consume resource semantics**
197
+ - **the model owns query and mutation semantics**
198
+
199
+ When a custom row action still belongs to the same business resource, keep that action inside the existing resource-owner story instead of inventing a competing owner.
200
+
201
+ ## Step 4: `basic-page` feeds the row schema into `ZTable`
202
+
203
+ On a standard CRUD list page:
204
+
205
+ - `basic-page:blockPage` owns the resource state
206
+ - `basic-page:blockTable` passes `data`, `schemaRow`, and `tableScope` into `ZTable`
207
+
208
+ That means the backend metadata chain becomes visible in the table only after this resource-page handoff:
209
+
210
+ 1. backend row schema / row DTO metadata exists
211
+ 2. `ModelResource` exposes the row schema
212
+ 3. `blockPage` exposes that schema to the page runtime
213
+ 4. `blockTable` passes it into `ZTable`
214
+ 5. `a-table` resolves the cell render resources from table-scene schema metadata
215
+
216
+ A practical rule is:
217
+
218
+ - if the action metadata looks right but the page still does not show it, inspect the page-block handoff before changing the cell bean itself
219
+
220
+ ## Step 5: `a-table` resolves the referenced `tableCell` resources
221
+
222
+ Inside the table runtime, `ControllerTable` resolves the `render` metadata into a real render provider.
223
+
224
+ Important behaviors include:
225
+
226
+ - no render -> text fallback
227
+ - onion-like render string -> resolve through the `tableCell` scene
228
+ - `tableCell` bean options merge with column props
229
+ - `checkVisible(...)` can filter a render before the column/cell is shown
230
+
231
+ This is why `ZovaRender.cell('basic-table:actionView')` or `ZovaRender.cell('basic-table:actionOperationsRow', ...)` is enough on the backend side.
232
+
233
+ The frontend runtime already knows how to turn that contract identity into a real action render.
234
+
235
+ ## Step 6: `tableCell` beans become the visible action implementations
236
+
237
+ Representative built-in row-action implementations include:
238
+
239
+ - `basic-table:actionView`
240
+ - `basic-table:actionUpdate`
241
+ - `basic-table:actionDelete`
242
+ - `basic-table:actionOperationsRow`
243
+
244
+ Their responsibilities usually stay small and focused.
245
+
246
+ ### `actionView`
247
+
248
+ Typical responsibility:
249
+
250
+ - render a visible link
251
+ - call `$performCommand('basic-commands:view', ...)`
252
+
253
+ ### `actionUpdate`
254
+
255
+ Typical responsibility:
256
+
257
+ - render an edit button
258
+ - call `$performCommand('basic-commands:edit', ...)`
259
+
260
+ ### `actionDelete`
261
+
262
+ Typical responsibility:
263
+
264
+ - render a delete button
265
+ - confirm the action
266
+ - call `$performCommand('basic-commands:delete', ...)`
267
+
268
+ ### `actionOperationsRow`
269
+
270
+ Typical responsibility:
271
+
272
+ - inspect the `actions` list
273
+ - filter actions by permission
274
+ - preload nested renders
275
+ - render each child action through `$$table.cellRender(...)`
276
+
277
+ A practical reading takeaway is:
278
+
279
+ - **single-action cells adapt render interaction to commands**
280
+ - **operations-row cells orchestrate several action resources together**
281
+
282
+ For deeper cell-authoring detail, continue with [TableCell Authoring Cookbook](/frontend/table-cell-cookbook).
283
+
284
+ ## Step 7: Bulk actions follow the same contract idea at page level
285
+
286
+ The same mental model also appears in bulk or page-level actions.
287
+
288
+ Representative example:
289
+
290
+ ```tsx
291
+ actions: [ZovaRender.tableActionBulk('basic-table:actionCreate')];
292
+ ```
293
+
294
+ And the corresponding frontend implementation can render a button that performs:
295
+
296
+ - `basic-commands:create`
297
+
298
+ This is the same contract idea at a different UI level:
299
+
300
+ - backend or shared page metadata chooses the action resource identity
301
+ - frontend runtime resolves that identity to a visible action implementation
302
+
303
+ ## Step 8: Where the forward chain enters for custom actions
304
+
305
+ So far, everything could still be handled by built-in commands and built-in resources.
306
+
307
+ The forward chain becomes important when the action itself depends on a new backend API contract.
308
+
309
+ Representative examples include actions such as:
310
+
311
+ - `summary/:id`
312
+ - `deleteForce/:id`
313
+
314
+ In that case, the practical chain becomes:
315
+
316
+ 1. backend controller exposes the custom endpoint
317
+ 2. backend DTOs define request/response contracts
318
+ 3. frontend OpenAPI generation produces typed API consumers
319
+ 4. the frontend module model wraps those generated consumers thinly
320
+ 5. a custom `tableCell.actionSummary.tsx` or `tableCell.actionDeleteForce.tsx` triggers the corresponding semantic action path
321
+ 6. backend row metadata points the visible row action at that frontend resource identity
322
+
323
+ This is why Tutorial 5 is a forward-chain tutorial even though the visible result is a row action in a table.
324
+
325
+ The action semantics are forward-generated; the visible table exposure is reverse-shared.
326
+
327
+ ## Step 9: Why the resource-owner model should stay the semantic owner
328
+
329
+ When a custom action still belongs to the same business resource, do not create a competing cache owner only because the action is custom.
330
+
331
+ Instead:
332
+
333
+ - generate the new frontend API contract from backend truth
334
+ - wrap it in the existing module model as a thin semantic facade
335
+ - keep invalidation and resource ownership coherent
336
+
337
+ This matters because row actions often affect:
338
+
339
+ - current row state
340
+ - list query invalidation
341
+ - related item views
342
+ - page refresh expectations
343
+
344
+ A practical rule is:
345
+
346
+ - if the action still belongs to the same resource, prefer extending the existing resource owner over inventing a second one
347
+
348
+ ## Step 10: A practical end-to-end example matrix
349
+
350
+ Here is the most useful way to think about common action types.
351
+
352
+ ### Built-in view action
353
+
354
+ Chain:
355
+
356
+ 1. backend field metadata uses `ZovaRender.cell('basic-table:actionView')`
357
+ 2. row schema reaches `ZTable`
358
+ 3. `a-table` resolves `basic-table:actionView`
359
+ 4. the frontend action cell performs `basic-commands:view`
360
+
361
+ This is mostly a reverse-sharing path.
362
+
363
+ ### Built-in operations row
364
+
365
+ Chain:
366
+
367
+ 1. backend row DTO metadata uses `ZovaRender.cell('basic-table:actionOperationsRow', { actions: [...] })`
368
+ 2. nested row-action metadata uses `ZovaRender.tableActionRow(...)`
369
+ 3. `actionOperationsRow` filters and renders child actions
370
+ 4. each child action delegates to its own command-oriented cell resource
371
+
372
+ This is also mainly a reverse-sharing path.
373
+
374
+ ### Custom summary action
375
+
376
+ Chain:
377
+
378
+ 1. backend controller and DTOs define `summary/:id`
379
+ 2. frontend OpenAPI generation creates the API consumer
380
+ 3. frontend model wraps the consumer thinly
381
+ 4. custom `tableCell.actionSummary.tsx` exposes the visible row action
382
+ 5. backend row metadata includes that action in the operations row
383
+
384
+ This uses both forward and reverse directions.
385
+
386
+ ## Step 11: How to classify the work before editing anything
387
+
388
+ Use this quick decision map.
389
+
390
+ ### Mostly reverse-chain work
391
+
392
+ Use this path when:
393
+
394
+ - you are only changing which built-in or existing frontend render resource a field or row should use
395
+ - no new backend endpoint is needed
396
+ - the visible change is mostly metadata-driven
397
+
398
+ Typical examples:
399
+
400
+ - switch one field to `basic-table:actionView`
401
+ - add an operations row using existing update/delete actions
402
+ - add a custom table-cell renderer that backend metadata points to
403
+
404
+ ### Mostly forward-chain work
405
+
406
+ Use this path when:
407
+
408
+ - the action semantics need a new backend endpoint or changed response contract
409
+ - frontend typed consumers must regenerate
410
+ - the row action is only the last visible step of a larger API-contract change
411
+
412
+ Typical examples:
413
+
414
+ - add summary, archive, approve, or force-delete actions with new backend contracts
415
+
416
+ ### Consumer drift
417
+
418
+ Suspect this when:
419
+
420
+ - generated artifacts already contain the expected action contracts or resource keys
421
+ - but the visible frontend behavior still looks stale
422
+
423
+ ### Local dependency drift
424
+
425
+ Suspect this when:
426
+
427
+ - generated `.zova-rest` output or SDK output looks correct
428
+ - but backend or frontend local consumers still do not see the refreshed shared types or resource identities
429
+
430
+ ## Common mistakes to avoid
431
+
432
+ ### Mistake 1: Treating the visible button as the start of the design
433
+
434
+ Usually the visible button is the end of the design. Start from the contract and metadata chain first.
435
+
436
+ ### Mistake 2: Adding a custom backend endpoint but manually duplicating its frontend contract
437
+
438
+ Prefer the forward-generation path before hand-writing request code.
439
+
440
+ ### Mistake 3: Creating a competing frontend state owner for an action that still belongs to the same resource
441
+
442
+ Prefer reusing the existing resource-owner model.
443
+
444
+ ### Mistake 4: Patching page-local table code when metadata already expresses the action correctly
445
+
446
+ If the contract is metadata-driven, keep it metadata-driven.
447
+
448
+ ### Mistake 5: Mixing up built-in action resources and custom action semantics
449
+
450
+ Built-in action resources often only adapt UI to commands. Custom action semantics may still need generated API and model work behind them.
451
+
452
+ ## A practical authoring order
453
+
454
+ If you want the shortest path to a correct table-action implementation, use this order:
455
+
456
+ 1. decide whether the work is mostly reverse-chain or forward-chain
457
+ 2. if forward-chain, change backend controller/DTO truth first
458
+ 3. regenerate frontend API consumers when backend contract changes
459
+ 4. keep frontend model follow-up thin and semantic
460
+ 5. point backend row metadata to the intended built-in or custom table-action resources
461
+ 6. verify the resource-page block chain still feeds the right schema into `ZTable`
462
+ 7. verify the visible row action in Admin
463
+
464
+ ## Verification checklist
465
+
466
+ When documenting or implementing this chain, verify in this order:
467
+
468
+ 1. confirm the backend metadata anchors actually point to the intended `ZovaRender.*(...)` resources
469
+ 2. confirm the page block composition still includes the intended list blocks
470
+ 3. confirm the current frontend `tableCell` resources exist and match the named identities
471
+ 4. if custom backend actions were added, regenerate the frontend contract surface first
472
+ 5. make sure the local dev workflow is running:
473
+
474
+ ```bash
475
+ npm run dev
476
+ ```
477
+
478
+ 6. open `http://localhost:7102/admin/`
479
+ 7. verify the visible list page behavior:
480
+ - bulk create action if relevant
481
+ - row operations visibility
482
+ - row action execution
483
+ - list invalidation or refresh after mutations
484
+ 8. if reverse-chain frontend resources changed, run the representative Basic handoff flow when needed:
485
+
486
+ ```bash
487
+ npm run zova :tools:metadata <module-name>
488
+ npm run build:zova:admin
489
+ npm run deps:vona
490
+ ```
491
+
492
+ 9. if docs changed, build the docs site:
493
+
494
+ ```bash
495
+ npm run docs:build
496
+ ```
497
+
498
+ ## Final takeaway
499
+
500
+ A frontend table action in Cabloy Basic is often not just a frontend button.
501
+
502
+ It is the visible result of a contract chain that may include:
503
+
504
+ - backend field or row metadata
505
+ - page block composition metadata
506
+ - generated frontend contract consumers
507
+ - resource-owner model semantics
508
+ - `tableCell` bean-scene resources
509
+ - `basic-page` list runtime
510
+
511
+ Once you read the system through that chain, row actions stop looking like scattered UI details and start looking like one coherent fullstack workflow.
@@ -71,6 +71,12 @@ Typical consumers:
71
71
  - schema-driven UI
72
72
  - custom row or page actions
73
73
 
74
+ If your issue becomes one mixed Student row-action chain rather than a pure direction question, first continue with [Backend Metadata to Frontend Table Actions](/fullstack/backend-metadata-to-frontend-table-actions), then [Backend Metadata to Frontend Table Actions Source Reading Map](/fullstack/backend-metadata-to-frontend-table-actions-source-reading-map).
75
+
76
+ If the family root and source-reading map already match your case and the visible result is still wrong, continue with [Backend Metadata to Frontend Table Actions Debug Checklist](/fullstack/backend-metadata-to-frontend-table-actions-debug-checklist).
77
+
78
+ If you have already changed that mixed chain and now want to prove it layer by layer rather than diagnose a failure, continue with [Backend Metadata to Frontend Table Actions Verify Playbook](/fullstack/backend-metadata-to-frontend-table-actions-verify-playbook).
79
+
74
80
  ### Reverse chain
75
81
 
76
82
  Use the reverse chain when frontend-owned metadata or resources changed and backend-side tooling or metadata will consume them.
@@ -116,7 +122,7 @@ Then use the **forward chain**:
116
122
  4. keep frontend follow-up thin
117
123
  5. verify consumer alignment
118
124
 
119
- See [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk).
125
+ See [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk) for the end-to-end forward-chain bridge from backend-authored contract truth to generated frontend consumers.
120
126
 
121
127
  ### 2. Did frontend-owned metadata or resource truth change?
122
128
 
@@ -135,7 +141,7 @@ Then use the **reverse chain**:
135
141
  4. run `npm run deps:vona`
136
142
  5. verify backend consumers can see the refreshed handoff
137
143
 
138
- See [Frontend Metadata Back to Backend](/fullstack/frontend-metadata-to-backend).
144
+ See [Frontend Metadata Back to Backend](/fullstack/frontend-metadata-to-backend) for the end-to-end reverse-chain bridge from frontend-owned truth to backend-visible shared handoff.
139
145
 
140
146
  ### 3. Do generated artifacts look stale?
141
147
 
@@ -60,3 +60,9 @@ This rule prevents a common failure mode:
60
60
  - but gives the wrong operational example because it assumes the wrong edition
61
61
 
62
62
  That is exactly the kind of mistake good fullstack docs should prevent.
63
+
64
+ ## Where to read next
65
+
66
+ - If you want the shared bidirectional model first, continue with [Contract Loop Playbook](/fullstack/contract-loop-playbook).
67
+ - If your current task is the forward contract bridge, continue with [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk).
68
+ - If your current task is the reverse metadata/resource bridge, continue with [Frontend Metadata Back to Backend](/fullstack/frontend-metadata-to-backend).