cabloy 5.1.60 → 5.1.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/hooks/contract-loop-gate.ts +296 -0
- package/.claude/settings.json +16 -0
- package/.claude/skills/cabloy-backend-scaffold/SKILL.md +2 -0
- package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -0
- package/.claude/skills/cabloy-contract-loop/SKILL.md +89 -16
- package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +102 -14
- package/.claude/skills/cabloy-contract-loop/references/resource-custom-state-pattern.md +4 -0
- package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +32 -14
- package/.claude/skills/cabloy-domain-planning/SKILL.md +212 -0
- package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +13 -0
- package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +2 -0
- package/.claude/skills/cabloy-module-removal/SKILL.md +144 -0
- package/.claude/skills/cabloy-resource-field-update/SKILL.md +7 -0
- package/.claude/skills/cabloy-zova-source-reading/SKILL.md +221 -0
- package/.claude/skills/cabloy-zova-source-reading/references/analysis-modes.md +91 -0
- package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +117 -0
- package/CHANGELOG.md +64 -0
- package/CLAUDE.md +11 -0
- package/cabloy-docs/.vitepress/config.mjs +197 -5
- package/cabloy-docs/ai/cli-to-skill-map.md +7 -0
- package/cabloy-docs/ai/docs-skills-rules-mapping.md +22 -0
- package/cabloy-docs/ai/future-skill-roadmap.md +12 -7
- package/cabloy-docs/ai/introduction.md +1 -0
- package/cabloy-docs/ai/playbook-backend-module.md +6 -0
- package/cabloy-docs/ai/playbook-module-removal.md +164 -0
- package/cabloy-docs/ai/skills.md +12 -0
- package/cabloy-docs/backend/backend-contract-emission-output-inspection.md +189 -0
- package/cabloy-docs/backend/backend-contract-emission-source-reading-map.md +160 -0
- package/cabloy-docs/backend/backend-contract-emission-specimen.md +170 -0
- package/cabloy-docs/backend/backend-resource-module-contract-chain.md +323 -0
- package/cabloy-docs/backend/backend-source-reading-debug-checklist.md +173 -0
- package/cabloy-docs/backend/backend-source-reading-roadmap.md +129 -0
- package/cabloy-docs/backend/backend-source-reading-verify-playbook.md +166 -0
- package/cabloy-docs/backend/bean-scene-authoring.md +4 -4
- package/cabloy-docs/backend/broadcast-guide.md +3 -3
- package/cabloy-docs/backend/cli.md +20 -11
- package/cabloy-docs/backend/config-guide.md +4 -4
- package/cabloy-docs/backend/controller-aop-guide.md +10 -10
- package/cabloy-docs/backend/controller-guide.md +12 -2
- package/cabloy-docs/backend/crud-workflow.md +7 -3
- package/cabloy-docs/backend/dto-guide.md +18 -2
- package/cabloy-docs/backend/dto-infer-generation.md +201 -25
- package/cabloy-docs/backend/election-guide.md +2 -2
- package/cabloy-docs/backend/entity-guide.md +30 -3
- package/cabloy-docs/backend/error-guide.md +3 -3
- package/cabloy-docs/backend/event-guide.md +4 -4
- package/cabloy-docs/backend/external-aop-guide.md +2 -2
- package/cabloy-docs/backend/field-indexes.md +9 -3
- package/cabloy-docs/backend/foundation.md +8 -8
- package/cabloy-docs/backend/i18n-guide.md +6 -6
- package/cabloy-docs/backend/internal-aop-guide.md +2 -2
- package/cabloy-docs/backend/introduction.md +15 -0
- package/cabloy-docs/backend/migration-and-changes.md +3 -3
- package/cabloy-docs/backend/model-guide.md +16 -6
- package/cabloy-docs/backend/openapi-guide.md +3 -0
- package/cabloy-docs/backend/queue-guide.md +3 -3
- package/cabloy-docs/backend/redlock-guide.md +2 -2
- package/cabloy-docs/backend/schedule-guide.md +2 -2
- package/cabloy-docs/backend/scripts.md +8 -0
- package/cabloy-docs/backend/serialization-guide.md +12 -2
- package/cabloy-docs/backend/service-guide.md +18 -9
- package/cabloy-docs/backend/startup-guide.md +5 -5
- package/cabloy-docs/backend/status-guide.md +271 -0
- package/cabloy-docs/backend/unit-testing.md +3 -3
- package/cabloy-docs/backend/vona-source-reading-map.md +157 -0
- package/cabloy-docs/backend/websocket-protocol-guide.md +5 -5
- package/cabloy-docs/backend/websocket-usage-guide.md +15 -8
- package/cabloy-docs/frontend/a-model-under-the-hood.md +281 -0
- package/cabloy-docs/frontend/a-openapi-under-the-hood.md +248 -0
- package/cabloy-docs/frontend/a-router-guide.md +307 -0
- package/cabloy-docs/frontend/api-guide.md +6 -4
- package/cabloy-docs/frontend/api-schema-guide.md +1 -0
- package/cabloy-docs/frontend/app-startup-guide.md +7 -4
- package/cabloy-docs/frontend/bean-scene-authoring.md +3 -1
- package/cabloy-docs/frontend/behavior-guide.md +16 -16
- package/cabloy-docs/frontend/cli.md +14 -2
- package/cabloy-docs/frontend/command-scene-authoring.md +504 -0
- package/cabloy-docs/frontend/component-guide.md +5 -5
- package/cabloy-docs/frontend/component-props-guide.md +1 -1
- package/cabloy-docs/frontend/component-v-model-guide.md +2 -2
- package/cabloy-docs/frontend/design-principles.md +6 -0
- package/cabloy-docs/frontend/fetch-interceptor-guide.md +440 -0
- package/cabloy-docs/frontend/filter-query-select-data-flow-guide.md +260 -0
- package/cabloy-docs/frontend/form-guide.md +786 -0
- package/cabloy-docs/frontend/form-scene-to-page-meta-guide.md +303 -0
- package/cabloy-docs/frontend/foundation.md +33 -0
- package/cabloy-docs/frontend/frontend-source-reading-roadmap.md +249 -0
- package/cabloy-docs/frontend/generated-contract-consumption-debug-checklist.md +190 -0
- package/cabloy-docs/frontend/generated-contract-consumption-entry-branch.md +205 -0
- package/cabloy-docs/frontend/generated-contract-consumption-list-branch.md +157 -0
- package/cabloy-docs/frontend/generated-contract-consumption-specimen.md +203 -0
- package/cabloy-docs/frontend/generated-contract-consumption-verify-playbook.md +189 -0
- package/cabloy-docs/frontend/generic-component-guide.md +1 -1
- package/cabloy-docs/frontend/introduction.md +38 -5
- package/cabloy-docs/frontend/ioc-and-beans.md +6 -0
- package/cabloy-docs/frontend/mock-guide.md +1 -0
- package/cabloy-docs/frontend/model-architecture.md +288 -39
- package/cabloy-docs/frontend/model-resource-best-practices.md +379 -0
- package/cabloy-docs/frontend/model-resource-cookbook.md +508 -0
- package/cabloy-docs/frontend/model-resource-internals-deep-dive.md +238 -0
- package/cabloy-docs/frontend/model-resource-owner-pattern.md +402 -0
- package/cabloy-docs/frontend/model-resource-usage-guide.md +334 -0
- package/cabloy-docs/frontend/model-state-guide.md +371 -15
- package/cabloy-docs/frontend/module-scope.md +8 -8
- package/cabloy-docs/frontend/modules-and-suites.md +2 -1
- package/cabloy-docs/frontend/navigation-guards-guide.md +7 -0
- package/cabloy-docs/frontend/openapi-sdk-guide.md +17 -6
- package/cabloy-docs/frontend/page-guide.md +15 -9
- package/cabloy-docs/frontend/page-meta-guide.md +466 -0
- package/cabloy-docs/frontend/page-params-guide.md +3 -3
- package/cabloy-docs/frontend/page-query-guide.md +2 -2
- package/cabloy-docs/frontend/page-route-guide.md +6 -0
- package/cabloy-docs/frontend/permission-formscene-action-visibility-guide.md +263 -0
- package/cabloy-docs/frontend/quickstart.md +18 -2
- package/cabloy-docs/frontend/reading-zova-for-vue-developers.md +266 -0
- package/cabloy-docs/frontend/resource-entry-page-deep-dive.md +271 -0
- package/cabloy-docs/frontend/resource-list-page-deep-dive.md +279 -0
- package/cabloy-docs/frontend/rest-resource-source-reading-map.md +522 -0
- package/cabloy-docs/frontend/rest-resource-under-the-hood.md +622 -0
- package/cabloy-docs/frontend/root-behaviors-guide.md +282 -0
- package/cabloy-docs/frontend/route-alias-guide.md +6 -0
- package/cabloy-docs/frontend/router-stack-guide.md +229 -0
- package/cabloy-docs/frontend/router-tabs-introduction.md +26 -3
- package/cabloy-docs/frontend/router-tabs-layout-integration.md +367 -0
- package/cabloy-docs/frontend/router-tabs-mechanism.md +6 -0
- package/cabloy-docs/frontend/router-tabs-route-meta-cookbook.md +7 -0
- package/cabloy-docs/frontend/router-tabs-vs-stack.md +167 -0
- package/cabloy-docs/frontend/router-view-hosts-guide.md +450 -0
- package/cabloy-docs/frontend/server-data.md +4 -1
- package/cabloy-docs/frontend/system-startup-guide.md +2 -2
- package/cabloy-docs/frontend/table-action-visibility-permission-flow-guide.md +263 -0
- package/cabloy-docs/frontend/table-cell-cookbook.md +568 -0
- package/cabloy-docs/frontend/table-guide.md +373 -0
- package/cabloy-docs/frontend/table-resource-crud-cookbook.md +496 -0
- package/cabloy-docs/frontend/zova-app-guide.md +251 -0
- package/cabloy-docs/frontend/zova-form-source-reading-map.md +293 -0
- package/cabloy-docs/frontend/zova-form-under-the-hood.md +561 -0
- package/cabloy-docs/frontend/zova-reactivity-under-the-hood.md +320 -0
- package/cabloy-docs/frontend/zova-router-under-the-hood.md +561 -0
- package/cabloy-docs/frontend/zova-source-reading-map.md +421 -0
- package/cabloy-docs/frontend/zova-table-controller-render-supplement.md +225 -0
- package/cabloy-docs/frontend/zova-table-source-reading-map.md +317 -0
- package/cabloy-docs/frontend/zova-table-under-the-hood.md +532 -0
- package/cabloy-docs/frontend/zova-vs-vue3-comparison.md +308 -0
- package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-debug-checklist.md +245 -0
- package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-source-reading-map.md +139 -0
- package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-verify-playbook.md +248 -0
- package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions.md +511 -0
- package/cabloy-docs/fullstack/contract-loop-playbook.md +356 -0
- package/cabloy-docs/fullstack/edition-collaboration-differences.md +6 -0
- package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +199 -23
- package/cabloy-docs/fullstack/introduction.md +15 -1
- package/cabloy-docs/fullstack/openapi-to-sdk.md +135 -11
- package/cabloy-docs/fullstack/suites-and-modules.md +333 -0
- package/cabloy-docs/fullstack/tutorial-1-first-module.md +3 -0
- package/cabloy-docs/fullstack/tutorial-2-first-crud.md +4 -0
- package/cabloy-docs/fullstack/tutorial-3-frontend-metadata-sharing.md +6 -2
- package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +60 -23
- package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +14 -7
- package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +6 -0
- package/cabloy-docs/fullstack/tutorials-overview.md +17 -4
- package/cabloy-docs/reference/bean-scene-boilerplates.md +15 -13
- package/cabloy-docs/reference/package-map.md +4 -3
- package/package.json +2 -1
- package/scripts/init.ts +2 -18
- package/scripts/initTestData.ts +25 -0
- package/scripts/upgrade.ts +17 -2
- package/vona/pnpm-lock.yaml +48 -194
- package/vona/src/suite/a-training/modules/training-student/package.json +53 -0
- package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +400 -0
- package/vona/src/suite/a-training/modules/training-student/src/.metadata/locales.ts +18 -0
- package/vona/src/suite/a-training/modules/training-student/src/.metadata/this.ts +2 -0
- package/vona/src/suite/a-training/modules/training-student/src/bean/meta.index.ts +12 -0
- package/vona/src/suite/a-training/modules/training-student/src/bean/meta.version.ts +21 -0
- package/vona/src/suite/a-training/modules/training-student/src/bean/ssrMenu.student.ts +29 -0
- package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +15 -0
- package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +15 -0
- package/vona/src/suite/a-training/modules/training-student/src/controller/student.ts +74 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +28 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectReq.tsx +44 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectRes.tsx +11 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +45 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSummary.tsx +42 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +28 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +25 -0
- package/vona/src/suite/a-training/modules/training-student/src/entity/student.tsx +84 -0
- package/vona/src/suite/a-training/modules/training-student/src/index.ts +2 -0
- package/vona/src/suite/a-training/modules/training-student/src/model/student.ts +10 -0
- package/vona/src/suite/a-training/modules/training-student/src/service/student.ts +57 -0
- package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +173 -0
- package/vona/src/suite/a-training/modules/training-student/tsconfig.build.json +11 -0
- package/vona/src/suite/a-training/modules/training-student/tsconfig.json +7 -0
- package/vona/src/suite/a-training/package.json +12 -0
- package/vona/src/suite/a-training/tsconfig.base.json +4 -0
- package/vona/src/suite/a-training/tsconfig.json +10 -0
- package/zova/packages-cli/cli/package.json +2 -2
- package/zova/packages-cli/cli-set-front/cli/templates/openapi/config/boilerplate/module/openapi.config.ts +6 -1
- package/zova/packages-cli/cli-set-front/package.json +1 -1
- package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +34 -4
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +416 -690
- package/zova/src/suite/a-training/modules/training-student/cli/openapi.config.ts +9 -0
- package/zova/src/suite/a-training/modules/training-student/package.json +52 -0
- package/zova/src/suite/a-training/modules/training-student/src/.metadata/component/formFieldLevel.ts +31 -0
- package/zova/src/suite/a-training/modules/training-student/src/.metadata/index.ts +258 -0
- package/zova/src/suite/a-training/modules/training-student/src/.metadata/locales.ts +7 -0
- package/zova/src/suite/a-training/modules/training-student/src/.metadata/this.ts +2 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/baseURL.ts +5 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/index.ts +3 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +196 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +4146 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/trainingStudent.ts +151 -0
- package/zova/src/suite/a-training/modules/training-student/src/apiSchema/trainingStudent.ts +43 -0
- package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionDeleteForce.tsx +51 -0
- package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionSummary.tsx +56 -0
- package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.level.tsx +63 -0
- package/zova/src/suite/a-training/modules/training-student/src/component/formFieldLevel/controller.tsx +117 -0
- package/zova/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +9 -0
- package/zova/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +9 -0
- package/zova/src/suite/a-training/modules/training-student/src/index.ts +2 -0
- package/zova/src/suite/a-training/modules/training-student/src/model/student.ts +42 -0
- package/zova/src/suite/a-training/modules/training-student/tsconfig.build.json +13 -0
- package/zova/src/suite/a-training/modules/training-student/tsconfig.json +5 -0
- package/zova/src/suite/a-training/package.json +12 -0
- package/zova/src/suite/a-training/tsconfig.base.json +4 -0
- package/zova/src/suite/a-training/tsconfig.json +4 -0
- package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +29 -7
- package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/select/controller.tsx +34 -11
- package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +3 -3
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/lib/tableCell.ts +1 -1
- 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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
293
|
+
When model, relation, DTO, or controller contracts change, remember to consider the downstream path too:
|
|
128
294
|
|
|
129
|
-
|
|
295
|
+
- backend OpenAPI output
|
|
296
|
+
- frontend SDK generation
|
|
297
|
+
- frontend schema-driven helpers
|
|
130
298
|
|
|
131
|
-
|
|
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 `
|
|
29
|
+
Example: create `meta.election` in module `training-student`.
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
npm run vona :create:bean meta election -- --module=
|
|
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 `
|
|
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=
|
|
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>('
|
|
24
|
+
@Entity<IEntityOptionsStudent>('trainingStudent')
|
|
25
25
|
export class EntityStudent extends EntityBase {}
|
|
26
26
|
```
|
|
27
27
|
|
|
@@ -103,6 +103,24 @@ Representative examples include:
|
|
|
103
103
|
- helpers such as `v.default`, `v.optional`, `v.array`
|
|
104
104
|
- OpenAPI metadata such as `v.title`, `v.description`, `v.example`, `v.openapi`
|
|
105
105
|
|
|
106
|
+
When mixing helper metadata and an explicit zod schema in `@Api.field(...)`, keep a small but important ordering rule:
|
|
107
|
+
|
|
108
|
+
- `z.xxx(...)` returns the zod schema instance, so place it as the **last argument**
|
|
109
|
+
- put helper metadata such as `v.xxx(...)` and `ZovaRender.xxx(...)` before the zod schema
|
|
110
|
+
- otherwise helpers written after the zod schema may stop taking effect
|
|
111
|
+
|
|
112
|
+
Representative pattern:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
@Api.field(
|
|
116
|
+
v.title($locale('Level')),
|
|
117
|
+
ZovaRender.order(3),
|
|
118
|
+
ZovaRender.field('basic-select:formFieldSelect', { items: levelItems }),
|
|
119
|
+
z.number().int().min(1).max(3),
|
|
120
|
+
)
|
|
121
|
+
level: number;
|
|
122
|
+
```
|
|
123
|
+
|
|
106
124
|
A practical rule is:
|
|
107
125
|
|
|
108
126
|
- use inference for straightforward fields
|
|
@@ -148,3 +166,12 @@ When creating or updates entities:
|
|
|
148
166
|
3. keep validation, OpenAPI, serializer, and entity structure aligned
|
|
149
167
|
4. remember that entities feed DTO, model, and OpenAPI workflows downstream
|
|
150
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 `
|
|
16
|
+
Example: initialize error resources for module `training-student`.
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
npm run vona :init:error
|
|
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.
|
|
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=
|
|
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=
|
|
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: '
|
|
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('
|
|
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=
|
|
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: '
|
|
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=
|
|
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
|
-
|
|
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('
|
|
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('
|
|
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('
|
|
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.
|
|
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('
|
|
133
|
-
this.ctx.bean._getBean('
|
|
134
|
-
this.bean._newBean('
|
|
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 `
|
|
169
|
-
- onion name uses the shorter `module:bean` form such as `
|
|
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
|
|
23
|
+
npm run vona :init:locale training-student
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
Representative files include:
|
|
27
27
|
|
|
28
|
-
- `src/
|
|
29
|
-
- `src/
|
|
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.
|
|
49
|
-
const message2 = this.$scope.
|
|
50
|
-
const message3 = this.$scope.
|
|
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=
|
|
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('
|
|
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:
|
|
@@ -60,6 +73,7 @@ Use this path when the task is about runtime shape, startup, instances, workers,
|
|
|
60
73
|
- [Worker Guide](/backend/worker-guide)
|
|
61
74
|
- [Election Guide](/backend/election-guide)
|
|
62
75
|
- [Queue Guide](/backend/queue-guide)
|
|
76
|
+
- [Status Guide](/backend/status-guide)
|
|
63
77
|
- [Broadcast Guide](/backend/broadcast-guide)
|
|
64
78
|
- [Web Socket Guide](/backend/websocket-guide)
|
|
65
79
|
- [Web Socket Usage Guide](/backend/websocket-usage-guide)
|
|
@@ -94,6 +108,7 @@ If your task is already inside the runtime and distributed family, read these gu
|
|
|
94
108
|
- [Worker Guide](/backend/worker-guide)
|
|
95
109
|
- [Election Guide](/backend/election-guide)
|
|
96
110
|
- [Queue Guide](/backend/queue-guide)
|
|
111
|
+
- [Status Guide](/backend/status-guide)
|
|
97
112
|
- [Broadcast Guide](/backend/broadcast-guide)
|
|
98
113
|
- [Web Socket Guide](/backend/websocket-guide)
|
|
99
114
|
- [Web Socket Usage Guide](/backend/websocket-usage-guide)
|
|
@@ -35,7 +35,7 @@ Representative pattern:
|
|
|
35
35
|
|
|
36
36
|
```json
|
|
37
37
|
{
|
|
38
|
-
"name": "vona-module-
|
|
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=
|
|
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('
|
|
99
|
+
await this.bean.model.createTable('trainingStudent', table => {
|
|
100
100
|
table.basicFields();
|
|
101
101
|
table.string('name', 50);
|
|
102
102
|
table.string('description', 255);
|