cabloy 5.1.61 → 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 (201) 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 +42 -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 +19 -28
  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 +568 -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 +406 -680
  171. package/zova/src/suite/a-training/modules/training-student/cli/openapi.config.ts +9 -0
  172. package/zova/src/suite/a-training/modules/training-student/package.json +52 -0
  173. package/zova/src/suite/a-training/modules/training-student/src/.metadata/component/formFieldLevel.ts +31 -0
  174. package/zova/src/suite/a-training/modules/training-student/src/.metadata/index.ts +258 -0
  175. package/zova/src/suite/a-training/modules/training-student/src/.metadata/locales.ts +7 -0
  176. package/zova/src/suite/a-training/modules/training-student/src/.metadata/this.ts +2 -0
  177. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/baseURL.ts +5 -0
  178. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/index.ts +3 -0
  179. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +196 -0
  180. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +4146 -0
  181. package/zova/src/suite/a-training/modules/training-student/src/api/trainingStudent.ts +151 -0
  182. package/zova/src/suite/a-training/modules/training-student/src/apiSchema/trainingStudent.ts +43 -0
  183. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionDeleteForce.tsx +51 -0
  184. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionSummary.tsx +56 -0
  185. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.level.tsx +63 -0
  186. package/zova/src/suite/a-training/modules/training-student/src/component/formFieldLevel/controller.tsx +117 -0
  187. package/zova/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +9 -0
  188. package/zova/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +9 -0
  189. package/zova/src/suite/a-training/modules/training-student/src/index.ts +2 -0
  190. package/zova/src/suite/a-training/modules/training-student/src/model/student.ts +42 -0
  191. package/zova/src/suite/a-training/modules/training-student/tsconfig.build.json +13 -0
  192. package/zova/src/suite/a-training/modules/training-student/tsconfig.json +5 -0
  193. package/zova/src/suite/a-training/package.json +12 -0
  194. package/zova/src/suite/a-training/tsconfig.base.json +4 -0
  195. package/zova/src/suite/a-training/tsconfig.json +4 -0
  196. package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +29 -7
  197. package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/select/controller.tsx +34 -11
  198. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
  199. package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +3 -3
  200. package/zova/src/suite-vendor/a-zova/modules/a-table/src/lib/tableCell.ts +1 -1
  201. package/zova/src/suite-vendor/a-zova/package.json +2 -2
@@ -2,12 +2,37 @@
2
2
 
3
3
  This guide explains how DTO inference and generation work in Vona within the Cabloy monorepo.
4
4
 
5
+ Use this page when your question is not only “what is a DTO?”, but also:
6
+
7
+ - when should a DTO stay explicit?
8
+ - when should a DTO be inferred?
9
+ - when should I wrap an inferred shape in a named DTO class?
10
+ - how do inferred DTO choices show up in generated metadata and downstream contract flow?
11
+
5
12
  ## Why DTO inference matters
6
13
 
7
- DTOs are essential for validation and OpenAPI metadata, but manually maintaining them becomes expensive and error-prone as models and relationships grow more complex.
14
+ DTOs are essential for validation and OpenAPI metadata, but manually maintaining them becomes expensive and error-prone as models, filters, and relationships grow more complex.
8
15
 
9
16
  Vona addresses that by dynamically inferring and generating DTOs from model structure and query shape.
10
17
 
18
+ That gives you a more useful spectrum than a simple “handwritten or not” decision:
19
+
20
+ - fully explicit named DTO classes
21
+ - inline inferred DTOs
22
+ - named DTO classes that wrap inferred helper surfaces
23
+
24
+ This is one of the most important practical distinctions in the backend contract loop.
25
+
26
+ ## This page’s role in the backend reading chain
27
+
28
+ A practical split is:
29
+
30
+ - [DTO Guide](/backend/dto-guide) explains DTOs as named contract artifacts
31
+ - [Backend Resource/Module Contract Chain](/backend/backend-resource-module-contract-chain) shows how one real module is wired end-to-end
32
+ - this page explains how DTO shapes are chosen, inferred, wrapped, and surfaced in generated metadata
33
+
34
+ That means this page is the DTO-mechanics deep dive, not the full module specimen page.
35
+
11
36
  ## DTO tools
12
37
 
13
38
  Several DTO-oriented tools are available, including:
@@ -23,12 +48,46 @@ Several DTO-oriented tools are available, including:
23
48
 
24
49
  These tools let DTOs emerge from model-aware structure instead of always being hand-authored from scratch.
25
50
 
51
+ ## Three useful DTO shapes to distinguish
52
+
53
+ ### 1. Explicit named DTO classes
54
+
55
+ Use this shape when the contract should be a stable named artifact with strong public identity.
56
+
57
+ Typical reasons:
58
+
59
+ - the contract is long-lived and reused broadly
60
+ - the contract needs stronger customization
61
+ - the contract should be easy to find and discuss by name
62
+
63
+ ### 2. Inline inferred DTOs
64
+
65
+ Use this shape when the contract closely follows model or query truth and only one action needs it.
66
+
67
+ Typical reasons:
68
+
69
+ - one endpoint needs one inferred relation-aware shape
70
+ - a separate named class would add little value
71
+ - the contract is more about one query result than about a reusable domain artifact
72
+
73
+ ### 3. Named DTO classes that wrap inferred helpers
74
+
75
+ This is the most practical middle ground in real Cabloy code.
76
+
77
+ The class stays explicit and discoverable, but its shape is derived from model/entity/query truth through `$Dto.*` helpers.
78
+
79
+ That means the contract can be:
80
+
81
+ - readable by name
82
+ - reusable by other code and docs
83
+ - still close to model and query truth rather than manually duplicated
84
+
26
85
  ## When each inferred DTO shape is useful
27
86
 
28
87
  A practical mental model is:
29
88
 
30
89
  - use `$Dto.get` for one-item read contracts
31
- - use `$Dto.listAndCount` for paginated or list-plus-total contracts
90
+ - use `$Dto.listAndCount` for list-plus-total contracts
32
91
  - use `$Dto.query` and `$Dto.queryPage` for query-input or query-result patterns
33
92
  - use `$Dto.create` and `$Dto.update` for write contracts derived from model structure
34
93
  - use `$Dto.aggregate` and `$Dto.group` for summary-oriented result shapes
@@ -43,13 +102,109 @@ A practical rule is:
43
102
  - prefer explicit DTO classes when the contract is long-lived, heavily customized, or needs a strong named public identity
44
103
  - wrap inferred DTOs into named DTO classes when reuse becomes more important than one-off convenience
45
104
 
46
- This is one of the most important distinctions in the backend contract loop.
105
+ A practical reading takeaway is:
106
+
107
+ > the best default is often not “handwritten DTO or no DTO.” It is “named DTO class backed by the right inferred helper.”
108
+
109
+ ## `training-student` as the decision specimen
110
+
111
+ The current `training-student` module is a strong specimen because it shows several different DTO choices in one compact family.
112
+
113
+ Relevant source files include:
114
+
115
+ - `vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx`
116
+ - `vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx`
117
+ - `vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx`
118
+ - `vona/src/suite/a-training/modules/training-student/src/dto/studentSelectReq.tsx`
119
+ - `vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx`
120
+ - `vona/src/suite/a-training/modules/training-student/src/dto/studentSelectRes.tsx`
121
+ - `vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts`
122
+
123
+ ### Create and update DTOs
124
+
125
+ Representative source facts:
126
+
127
+ - `DtoStudentCreate` extends `$Dto.create(() => ModelStudent)`
128
+ - `DtoStudentUpdate` extends `$Dto.update(() => ModelStudent)`
129
+
130
+ These are good examples of **named DTO classes that wrap inference**.
131
+
132
+ Why this is a good fit:
133
+
134
+ - the contracts are operation-specific and worth naming
135
+ - the underlying field truth already exists in the model/entity thread
136
+ - rewriting all fields manually would add duplication without adding much clarity
137
+
138
+ So the code gets both:
139
+
140
+ - a stable named DTO artifact
141
+ - inference-backed contract derivation
142
+
143
+ ### View DTO
144
+
145
+ Representative source fact:
146
+
147
+ - `DtoStudentView` extends `$Dto.get(() => ModelStudent)`
148
+
149
+ This is the one-item read version of the same pattern.
150
+
151
+ Again, the class keeps a named public identity, while the DTO shape stays close to model truth.
152
+
153
+ ### Query/filter DTO
154
+
155
+ `DtoStudentSelectReq` is especially important because it shows that query contracts are often more than a simple list of optional fields.
156
+
157
+ Representative source facts:
158
+
159
+ - it extends `$Dto.queryPage(EntityStudent, ['name', 'level', 'createdAt'])`
160
+ - it also adds `@Dto({ openapi: { filter: { table: 'trainingStudent' } }, fields: { ... } })`
161
+ - `level` uses preprocess logic so string query input can be normalized before schema validation
162
+ - `createdAt` uses `v.filterTransform('a-web:dateRange')`
163
+
164
+ This makes it a strong specimen of a **query DTO that still wraps inference, but adds operation-specific shaping**.
165
+
166
+ A practical reading takeaway is:
167
+
168
+ - inference gives the structural baseline
169
+ - explicit field metadata adds the operation-specific contract behavior
170
+
171
+ ### Row-item response DTO
172
+
173
+ `DtoStudentSelectResItem` is useful for a different reason.
174
+
175
+ Representative source fact:
176
+
177
+ - it extends `$Dto.get(() => ModelStudent)`
178
+
179
+ But it also adds response-facing metadata such as:
180
+
181
+ - page block metadata
182
+ - row-action metadata
183
+ - table-cell-related render hints
184
+
185
+ That means a named DTO can still wrap inference while carrying richer response-facing semantics that matter downstream.
186
+
187
+ ### List-and-count response DTO
188
+
189
+ Representative source fact:
190
+
191
+ - `DtoStudentSelectRes` extends `$Dto.listAndCount(DtoStudentSelectResItem)`
192
+
193
+ This is the aggregate response wrapper for the list endpoint.
194
+
195
+ So the list-response chain is not one DTO only. It is:
196
+
197
+ 1. one query/filter request DTO
198
+ 2. one row-item DTO
199
+ 3. one list-and-count wrapper DTO
200
+
201
+ That is exactly the kind of shape where helper-level inference improves consistency more than manual duplication would.
47
202
 
48
203
  ## Main-details example
49
204
 
50
- A representative example uses an `Order -> Product` relation.
205
+ A representative example for relation-aware inferred contracts uses an `Order -> Product` relation.
51
206
 
52
- The key lesson is that when the return shape is richer than a simple entity array, an inferred DTO can capture the actual result shape more accurately than a hand-waved entity annotation.
207
+ The key lesson is that when the return shape is richer than a simple entity array, an inferred DTO can capture the real result shape more accurately than a hand-waved entity annotation.
53
208
 
54
209
  Representative pattern:
55
210
 
@@ -57,8 +212,6 @@ Representative pattern:
57
212
  @Api.body(v.array($Dto.get(() => ModelOrder, { include: { products: true } })))
58
213
  ```
59
214
 
60
- This shows the dynamic DTO layer participating directly in controller return contracts.
61
-
62
215
  Another useful inferred pattern is action-derived contract reuse:
63
216
 
64
217
  ```typescript
@@ -81,12 +234,6 @@ Examples include:
81
234
 
82
235
  That means DTO inference should often be considered together with relation design rather than only after the fact.
83
236
 
84
- A representative relation-aware response pattern is:
85
-
86
- ```typescript
87
- @Api.body(v.array($Dto.get(() => ModelOrder, { include: { products: true } })))
88
- ```
89
-
90
237
  A practical rule is:
91
238
 
92
239
  - keep inference inline when one action needs one contract shape only once
@@ -103,6 +250,30 @@ A practical rule is:
103
250
 
104
251
  For the query side of this topic, also see [ORM Aggregate and Group Guide](/backend/orm-aggregate-group-guide).
105
252
 
253
+ ## How DTOs surface in generated metadata
254
+
255
+ When you change or add DTOs, do not think only about the local DTO file.
256
+
257
+ The current `training-student` module also makes DTOs visible through generated metadata in:
258
+
259
+ - `vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts`
260
+
261
+ The DTO-facing part of that generated registry includes:
262
+
263
+ - exports of the DTO classes themselves
264
+ - `IDtoRecord` registrations for DTO onion names
265
+ - a broader generated surface that keeps DTO availability aligned with controller, API path, and resource registrations
266
+
267
+ A practical reading takeaway is:
268
+
269
+ > DTO classes are not only local TypeScript artifacts. They become part of the generated contract registry that the rest of the backend thread can reason about.
270
+
271
+ This is also why DTO changes should be thought about together with:
272
+
273
+ - OpenAPI emission
274
+ - downstream frontend generation
275
+ - broader contract-loop verification
276
+
106
277
  ## Relationship to CRUD generation
107
278
 
108
279
  Inferred DTOs are not separate from the CRUD workflow. They sit on the same contract loop.
@@ -111,34 +282,39 @@ A useful split is:
111
282
 
112
283
  - CRUD generation gives you the initial backend thread
113
284
  - explicit DTOs give you stable named operation contracts
114
- - inferred DTOs let the contract stay close to model and query truth when a separate handwritten class would add little value
285
+ - inferred DTO helpers let the contract stay close to model and query truth when another handwritten class would add little value
115
286
 
116
287
  This helps keep the generated thread productive instead of forcing redundant DTO maintenance everywhere.
117
288
 
118
- ## Encapsulating inferred DTOs
119
-
120
- Inferred DTO logic can also be wrapped inside an explicit DTO class for reuse.
289
+ ## Relationship to OpenAPI and frontend generation
121
290
 
122
- That is useful because it gives teams a spectrum of options:
123
-
124
- - use inference directly for one endpoint
125
- - wrap the inferred DTO into a named reusable class when the contract is important elsewhere too
291
+ DTO inference and generation are not isolated authoring tricks. They are part of a broader backend contract workflow.
126
292
 
127
- ## Relationship to generation and metadata refresh
293
+ When model, relation, DTO, or controller contracts change, remember to consider the downstream path too:
128
294
 
129
- DTO inference and generation are not isolated authoring tricks. They are part of a broader backend contract workflow.
295
+ - backend OpenAPI output
296
+ - frontend SDK generation
297
+ - frontend schema-driven helpers
130
298
 
131
- When model, relation, or controller contracts change, remember to consider the downstream metadata and generated-contract path as well.
299
+ For the bridge step that carries this backend-authored contract across the stack, continue with [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk).
132
300
 
133
- Read this guide together with:
301
+ ## Read this guide together with
134
302
 
135
303
  - [DTO Guide](/backend/dto-guide)
304
+ - [Backend Resource/Module Contract Chain](/backend/backend-resource-module-contract-chain)
136
305
  - [Relations Guide](/backend/relations-guide)
137
306
  - [ORM Select Guide](/backend/orm-select-guide)
138
307
  - [ORM Aggregate and Group Guide](/backend/orm-aggregate-group-guide)
139
308
  - [OpenAPI Guide](/backend/openapi-guide)
140
309
  - [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk)
141
310
 
311
+ ## Where to read next
312
+
313
+ - If you want one concrete module specimen first, continue with [Backend Resource/Module Contract Chain](/backend/backend-resource-module-contract-chain).
314
+ - If your next question is about broader DTO design choices, continue with [DTO Guide](/backend/dto-guide).
315
+ - If your next question is about emitted backend contract output, continue with [OpenAPI Guide](/backend/openapi-guide).
316
+ - If your next question is about how backend-authored DTO and OpenAPI truth becomes generated frontend contract material, continue with [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk).
317
+
142
318
  ## Implementation checks for DTO inference and generation changes
143
319
 
144
320
  When evaluating a return shape or input contract that closely follows model structure, ask:
@@ -26,10 +26,10 @@ That makes election a coordination primitive, not just a boolean lock.
26
26
 
27
27
  ## Create `meta.election`
28
28
 
29
- Example: create `meta.election` in module `demo-student`.
29
+ Example: create `meta.election` in module `training-student`.
30
30
 
31
31
  ```bash
32
- npm run vona :create:bean meta election -- --module=demo-student
32
+ npm run vona :create:bean meta election -- --module=training-student
33
33
  ```
34
34
 
35
35
  Representative definition:
@@ -10,10 +10,10 @@ That makes entity design one of the main places where database structure and API
10
10
 
11
11
  ## Create an entity
12
12
 
13
- Example: create an entity named `student` in module `demo-student`.
13
+ Example: create an entity named `student` in module `training-student`.
14
14
 
15
15
  ```bash
16
- npm run vona :create:bean entity student -- --module=demo-student
16
+ npm run vona :create:bean entity student -- --module=training-student
17
17
  ```
18
18
 
19
19
  ## Entity definition
@@ -21,7 +21,7 @@ npm run vona :create:bean entity student -- --module=demo-student
21
21
  Representative pattern:
22
22
 
23
23
  ```typescript
24
- @Entity<IEntityOptionsStudent>('demoStudent')
24
+ @Entity<IEntityOptionsStudent>('trainingStudent')
25
25
  export class EntityStudent extends EntityBase {}
26
26
  ```
27
27
 
@@ -166,3 +166,12 @@ When creating or updates entities:
166
166
  3. keep validation, OpenAPI, serializer, and entity structure aligned
167
167
  4. remember that entities feed DTO, model, and OpenAPI workflows downstream
168
168
  5. keep identity and base-field assumptions consistent with the actual backend contract loop
169
+
170
+ ## Where to read next
171
+
172
+ If your next question is how entity field metadata becomes named transport contracts and emitted backend contract metadata, continue with:
173
+
174
+ - [DTO Guide](/backend/dto-guide)
175
+ - [Validation Guide](/backend/validation-guide)
176
+ - [OpenAPI Guide](/backend/openapi-guide)
177
+ - [Backend Resource/Module Contract Chain](/backend/backend-resource-module-contract-chain)
@@ -13,10 +13,10 @@ That matters because backend contracts often need errors that are:
13
13
 
14
14
  ## Initialize the error skeleton
15
15
 
16
- Example: initialize error resources for module `demo-student`.
16
+ Example: initialize error resources for module `training-student`.
17
17
 
18
18
  ```bash
19
- npm run vona :init:error demo-student
19
+ npm run vona :init:error training-student
20
20
  ```
21
21
 
22
22
  This gives the module the standard files for defining error codes and their language resources.
@@ -66,7 +66,7 @@ Cross-module error access uses the cross-module scope surface.
66
66
  Representative pattern:
67
67
 
68
68
  ```typescript
69
- this.$scope.demoStudent.error.ErrorTest.throw();
69
+ this.$scope.trainingStudent.error.ErrorTest.throw();
70
70
  ```
71
71
 
72
72
  A practical distinction is:
@@ -29,7 +29,7 @@ An event is defined as a typed bean.
29
29
  Representative generation workflow:
30
30
 
31
31
  ```bash
32
- npm run vona :create:bean event echo -- --module=demo-student
32
+ npm run vona :create:bean event echo -- --module=training-student
33
33
  ```
34
34
 
35
35
  Representative pattern:
@@ -79,13 +79,13 @@ Event listeners attach through `@EventListener({ match: ... })`.
79
79
  Representative generation workflow:
80
80
 
81
81
  ```bash
82
- npm run vona :create:bean eventListener echo -- --module=demo-student
82
+ npm run vona :create:bean eventListener echo -- --module=training-student
83
83
  ```
84
84
 
85
85
  Representative pattern:
86
86
 
87
87
  ```typescript
88
- @EventListener({ match: 'demo-student:echo' })
88
+ @EventListener({ match: 'training-student:echo' })
89
89
  export class EventListenerEcho implements IEventExecute<TypeEventData, TypeEventResult> {
90
90
  execute(data: TypeEventData, next: NextEventSync<TypeEventData, TypeEventResult>) {
91
91
  const dataNew = `${data}!`;
@@ -135,7 +135,7 @@ Vona can inspect the effective event-listener list for a named event.
135
135
  Representative pattern:
136
136
 
137
137
  ```typescript
138
- this.bean.onion.eventListener.inspectEventListener('demo-student:echo');
138
+ this.bean.onion.eventListener.inspectEventListener('training-student:echo');
139
139
  ```
140
140
 
141
141
  This is useful for debugging event composition and verifying which listeners are active.
@@ -13,13 +13,13 @@ External AOP uses `@Aop({ match: ... })` to associate an aspect class with one o
13
13
  Representative CLI generation pattern:
14
14
 
15
15
  ```bash
16
- npm run vona :create:bean aop log -- --module=demo-student
16
+ npm run vona :create:bean aop log -- --module=training-student
17
17
  ```
18
18
 
19
19
  Representative shape:
20
20
 
21
21
  ```typescript
22
- @Aop({ match: 'demo-student.service.test' })
22
+ @Aop({ match: 'training-student.service.test' })
23
23
  export class AopLog extends BeanAopBase {}
24
24
  ```
25
25
 
@@ -15,7 +15,7 @@ Vona uses a bean named `meta.index` to configure a module’s field indexes.
15
15
  Create it with:
16
16
 
17
17
  ```bash
18
- npm run vona :create:bean meta index -- --module=demo-student
18
+ npm run vona :create:bean meta index -- --module=training-student
19
19
  ```
20
20
 
21
21
  Representative shell:
@@ -32,7 +32,7 @@ Representative pattern:
32
32
  ```typescript
33
33
  @Meta({
34
34
  indexes: {
35
- demoStudent: 'name',
35
+ trainingStudent: 'name',
36
36
  },
37
37
  })
38
38
  class MetaIndex {}
@@ -52,7 +52,7 @@ import { $tableColumns } from 'vona-module-a-ormutils';
52
52
 
53
53
  @Meta({
54
54
  indexes: {
55
- ...$tableColumns('demoStudent', 'name'),
55
+ ...$tableColumns('trainingStudent', 'name'),
56
56
  },
57
57
  })
58
58
  class MetaIndex {}
@@ -77,3 +77,9 @@ Also ask:
77
77
  3. is the typed style a better fit than raw string declarations?
78
78
 
79
79
  That leads to backend changes that are more production-aware and more aligned with Vona’s module metadata model.
80
+
81
+ ## Where to read next
82
+
83
+ - If you want the broader persistence-side source-reading chooser, continue with [Backend Source Reading Roadmap](/backend/backend-source-reading-roadmap).
84
+ - If you are deciding how indexed fields relate to backend persistence truth, continue with [Entity Guide](/backend/entity-guide).
85
+ - If the index question is part of a persisted-schema change, continue with [Migration and Changes](/backend/migration-and-changes).
@@ -89,7 +89,7 @@ A practical rule is:
89
89
 
90
90
  | Access style | Best for | Representative shape |
91
91
  | -------------------- | ------------------------------------------------------------------- | -------------------------------------------------------- |
92
- | Dependency injection | explicit wiring in the current class | `@Use('demo-student.service.student')` |
92
+ | Dependency injection | explicit wiring in the current class | `@Use('training-student.service.student')` |
93
93
  | Dependency lookup | ordinary module-oriented business code | `this.scope.service.student` |
94
94
  | Direct bean access | container-aware control through the app container or request scope | `this.bean._getBean(...)`, `this.ctx.bean._getBean(...)` |
95
95
  | Fresh bean creation | workflows that should not reuse the ordinary resolved bean instance | `this.bean._newBean(...)` |
@@ -106,7 +106,7 @@ Representative pattern:
106
106
 
107
107
  ```typescript
108
108
  class ControllerStudent {
109
- @Use('demo-student.service.student')
109
+ @Use('training-student.service.student')
110
110
  serviceStudent: ServiceStudent;
111
111
  }
112
112
  ```
@@ -119,7 +119,7 @@ Representative patterns:
119
119
 
120
120
  ```typescript
121
121
  this.scope.service.student.findOne();
122
- this.$scope.demoStudent.service.student.findOne();
122
+ this.$scope.trainingStudent.service.student.findOne();
123
123
  ```
124
124
 
125
125
  ### Direct bean access
@@ -129,9 +129,9 @@ Direct bean access exposes the container layer more explicitly.
129
129
  Representative patterns:
130
130
 
131
131
  ```typescript
132
- this.bean._getBean('demo-student.service.student');
133
- this.ctx.bean._getBean('demo-student.service.student');
134
- this.bean._newBean('demo-student.service.student');
132
+ this.bean._getBean('training-student.service.student');
133
+ this.ctx.bean._getBean('training-student.service.student');
134
+ this.bean._newBean('training-student.service.student');
135
135
  ```
136
136
 
137
137
  A practical distinction is:
@@ -165,8 +165,8 @@ This matters because naming is not cosmetic. It affects:
165
165
 
166
166
  A practical naming rule is:
167
167
 
168
- - most scene-based beans use the fully qualified `module.scene.bean` form such as `demo-student.service.student`
169
- - onion name uses the shorter `module:bean` form such as `demo-student:student`
168
+ - most scene-based beans use the fully qualified `module.scene.bean` form such as `training-student.service.student`
169
+ - onion name uses the shorter `module:bean` form such as `training-student:student`
170
170
  - bean scene is the middle grouping layer that turns one module into operational families like `service`, `model`, `entity`, `dto`, or `startup`
171
171
  - the built-in global `bean` scene is an intentional exception and uses the plain bean name in the global shorthand surface
172
172
 
@@ -20,13 +20,13 @@ Each module can provide its own locale resources.
20
20
  Representative initialization workflow:
21
21
 
22
22
  ```bash
23
- npm run vona :init:locale demo-student
23
+ npm run vona :init:locale training-student
24
24
  ```
25
25
 
26
26
  Representative files include:
27
27
 
28
- - `src/module/demo-student/src/config/locale/en-us.ts`
29
- - `src/module/demo-student/src/config/locale/zh-cn.ts`
28
+ - `src/suite/a-training/modules/training-student/src/config/locale/en-us.ts`
29
+ - `src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts`
30
30
 
31
31
  This makes localization part of the module model rather than a single global string table.
32
32
 
@@ -45,9 +45,9 @@ const message3 = this.scope.locale.StudentName.locale('zh-cn');
45
45
  ### Cross-module access
46
46
 
47
47
  ```typescript
48
- const message1 = this.$scope.demoStudent.locale.StudentName();
49
- const message2 = this.$scope.demoStudent.locale.StudentName.locale('en-us');
50
- const message3 = this.$scope.demoStudent.locale.StudentName.locale('zh-cn');
48
+ const message1 = this.$scope.trainingStudent.locale.StudentName();
49
+ const message2 = this.$scope.trainingStudent.locale.StudentName.locale('en-us');
50
+ const message3 = this.$scope.trainingStudent.locale.StudentName.locale('zh-cn');
51
51
  ```
52
52
 
53
53
  ## Project-level override
@@ -28,7 +28,7 @@ It can be used on controller methods, service methods, and other class methods t
28
28
  Representative CLI generation pattern:
29
29
 
30
30
  ```bash
31
- npm run vona :create:bean aopMethod log -- --module=demo-student
31
+ npm run vona :create:bean aopMethod log -- --module=training-student
32
32
  ```
33
33
 
34
34
  That generator-backed workflow matters because AOP Method beans participate in the same onion metadata system as other Vona extension points.
@@ -51,7 +51,7 @@ class AopMethodLog {
51
51
  ### Representative usage
52
52
 
53
53
  ```typescript
54
- @Aspect.aopMethod('demo-student:log')
54
+ @Aspect.aopMethod('training-student:log')
55
55
  ```
56
56
 
57
57
  ### Parameter model
@@ -37,6 +37,19 @@ Start here when you need the core backend mental model first:
37
37
 
38
38
  This gives the architectural vocabulary for concepts such as bean, scope, suite, module, package, and backend access patterns.
39
39
 
40
+ ### Source-reading entry
41
+
42
+ Use these pages when the task is no longer only conceptual and you want the shortest path into current backend source:
43
+
44
+ - [Backend Source Reading Roadmap](/backend/backend-source-reading-roadmap)
45
+ - [Vona Source Reading Map](/backend/vona-source-reading-map)
46
+
47
+ A practical split is:
48
+
49
+ - stay on Introduction / Foundation / CLI when you still need the backend mental model
50
+ - move to the roadmap when you need help choosing the right backend reading cluster
51
+ - move to the source reading map when you already know the topic and want the shortest file-order path
52
+
40
53
  ### Contract and data family
41
54
 
42
55
  Use this path when the task is about the backend contract loop or ORM-backed backend data design:
@@ -35,7 +35,7 @@ Representative pattern:
35
35
 
36
36
  ```json
37
37
  {
38
- "name": "vona-module-demo-student",
38
+ "name": "vona-module-training-student",
39
39
  "vonaModule": {
40
40
  "fileVersion": 1
41
41
  }
@@ -55,7 +55,7 @@ Vona uses a bean named `meta.version` to organize migration code for a module.
55
55
  Create it with:
56
56
 
57
57
  ```bash
58
- npm run vona :create:bean meta version -- --module=demo-student
58
+ npm run vona :create:bean meta version -- --module=training-student
59
59
  ```
60
60
 
61
61
  Representative shell:
@@ -96,7 +96,7 @@ Representative pattern:
96
96
  export class MetaVersion extends BeanBase implements IMetaVersionUpdate {
97
97
  async update(options: IMetaVersionUpdateOptions) {
98
98
  if (options.version === 1) {
99
- await this.bean.model.createTable('demoStudent', table => {
99
+ await this.bean.model.createTable('trainingStudent', table => {
100
100
  table.basicFields();
101
101
  table.string('name', 50);
102
102
  table.string('description', 255);
@@ -17,10 +17,10 @@ That means model design affects not only SQL behavior, but also CRUD defaults, D
17
17
 
18
18
  ## Create a model
19
19
 
20
- Example: create a model named `student` in module `demo-student`.
20
+ Example: create a model named `student` in module `training-student`.
21
21
 
22
22
  ```bash
23
- npm run vona :create:bean model student -- --module=demo-student
23
+ npm run vona :create:bean model student -- --module=training-student
24
24
  ```
25
25
 
26
26
  ## Model definition
@@ -56,7 +56,7 @@ class ServiceStudent {
56
56
  ```typescript
57
57
  class ServiceStudent {
58
58
  async findAll(): Promise<EntityStudent[]> {
59
- return await this.$scope.demoStudent.model.student.select();
59
+ return await this.$scope.trainingStudent.model.student.select();
60
60
  }
61
61
  }
62
62
  ```
@@ -66,7 +66,7 @@ class ServiceStudent {
66
66
  ```typescript
67
67
  class ServiceStudent {
68
68
  async findAll(): Promise<EntityStudent[]> {
69
- return await this.bean._getBean('demo-student.model.student').select();
69
+ return await this.bean._getBean('training-student.model.student').select();
70
70
  }
71
71
  }
72
72
  ```
@@ -121,7 +121,7 @@ Representative patterns:
121
121
  ```typescript
122
122
  this.scope.model.student.builder().where('name', 'tom').orderBy('name');
123
123
  this.scope.model.student.builderSelect().where('name', 'tom').orderBy('name');
124
- this.scope.model.student.query('select * from demoStudent');
124
+ this.scope.model.student.query('select * from trainingStudent');
125
125
  ```
126
126
 
127
127
  A practical rule is:
@@ -155,7 +155,7 @@ Representative pattern:
155
155
  ```typescript
156
156
  config.onions = {
157
157
  model: {
158
- 'demo-student:student': {
158
+ 'training-student:student': {
159
159
  disableDeleted: true,
160
160
  disableInstance: true,
161
161
  client: 'mysql',
@@ -279,3 +279,13 @@ When creating backend persistence logic:
279
279
  4. choose deliberately among local scope, cross-module scope, and direct bean access
280
280
  5. remember that datasource, cache, and model options can change the behavior of the backend contract loop
281
281
  6. drop to raw SQL or lower-level query builder logic only when the higher-level model surface is insufficient
282
+
283
+ ## Where to read next
284
+
285
+ If your next question is how model persistence behavior fits into one complete backend contract thread, continue with:
286
+
287
+ - [Entity Guide](/backend/entity-guide)
288
+ - [DTO Guide](/backend/dto-guide)
289
+ - [CRUD Workflow](/backend/crud-workflow)
290
+ - [Vona Source Reading Map](/backend/vona-source-reading-map)
291
+ - [Backend Resource/Module Contract Chain](/backend/backend-resource-module-contract-chain)