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.
- package/.claude/skills/cabloy-backend-scaffold/SKILL.md +2 -0
- package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -1
- package/.claude/skills/cabloy-domain-planning/SKILL.md +212 -0
- package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +2 -0
- package/CHANGELOG.md +42 -0
- package/CLAUDE.md +1 -0
- package/cabloy-docs/.vitepress/config.mjs +158 -12
- package/cabloy-docs/ai/docs-skills-rules-mapping.md +8 -0
- package/cabloy-docs/ai/future-skill-roadmap.md +2 -0
- package/cabloy-docs/ai/skills.md +1 -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 +12 -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 +12 -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 +13 -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 +2 -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 +7 -7
- 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 +4 -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 +1 -1
- package/cabloy-docs/frontend/behavior-guide.md +16 -16
- package/cabloy-docs/frontend/cli.md +5 -5
- package/cabloy-docs/frontend/command-scene-authoring.md +17 -8
- 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/filter-query-select-data-flow-guide.md +260 -0
- package/cabloy-docs/frontend/form-guide.md +19 -28
- package/cabloy-docs/frontend/form-scene-to-page-meta-guide.md +303 -0
- package/cabloy-docs/frontend/foundation.md +10 -6
- 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 +29 -7
- package/cabloy-docs/frontend/model-architecture.md +38 -2
- package/cabloy-docs/frontend/model-resource-cookbook.md +11 -8
- package/cabloy-docs/frontend/model-resource-internals-deep-dive.md +238 -0
- package/cabloy-docs/frontend/model-resource-owner-pattern.md +22 -2
- package/cabloy-docs/frontend/model-resource-usage-guide.md +22 -6
- package/cabloy-docs/frontend/model-state-guide.md +12 -9
- 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 +12 -4
- package/cabloy-docs/frontend/page-guide.md +9 -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 +14 -2
- 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 +2 -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 +7 -9
- package/cabloy-docs/frontend/zova-form-under-the-hood.md +5 -0
- package/cabloy-docs/frontend/zova-router-under-the-hood.md +561 -0
- package/cabloy-docs/frontend/zova-source-reading-map.md +101 -7
- 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/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 +8 -2
- package/cabloy-docs/fullstack/edition-collaboration-differences.md +6 -0
- package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +181 -48
- package/cabloy-docs/fullstack/introduction.md +3 -0
- package/cabloy-docs/fullstack/openapi-to-sdk.md +116 -2
- 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 +4 -0
- package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +31 -19
- package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +5 -0
- package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +4 -0
- package/cabloy-docs/fullstack/tutorials-overview.md +1 -1
- package/cabloy-docs/reference/bean-scene-boilerplates.md +13 -13
- package/cabloy-docs/reference/package-map.md +4 -3
- package/package.json +1 -1
- package/vona/pnpm-lock.yaml +22 -258
- 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-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +406 -680
- 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
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# ModelResource Internals Deep Dive
|
|
2
|
+
|
|
3
|
+
This guide explains the internals of `ModelResource` in Zova through the current public Cabloy Basic source.
|
|
4
|
+
|
|
5
|
+
Use this page when you want to understand:
|
|
6
|
+
|
|
7
|
+
- how `ModelResource` bootstraps itself
|
|
8
|
+
- how `resourceApi` is resolved
|
|
9
|
+
- where permissions, schemas, and form-provider surfaces come from
|
|
10
|
+
- how query, mutation, and form helpers are organized
|
|
11
|
+
- how query-key prefixing and invalidation work
|
|
12
|
+
- why `ModelResource` is the stable resource-owner boundary under both list and entry pages
|
|
13
|
+
|
|
14
|
+
## Why this page exists
|
|
15
|
+
|
|
16
|
+
This page is the third layer of a small source-reading chain around same-resource model facades:
|
|
17
|
+
|
|
18
|
+
1. [Model Architecture](/frontend/model-architecture) for the broader role of Zova Model
|
|
19
|
+
2. [Generated Contract Consumption: Entry Branch](/frontend/generated-contract-consumption-entry-branch) for the consumer-side handoff into the owner
|
|
20
|
+
3. this page for the owner internals that make that handoff work
|
|
21
|
+
|
|
22
|
+
Several existing docs already explain the meaning and usage of the resource owner well:
|
|
23
|
+
|
|
24
|
+
- [Model Resource Owner Pattern](/frontend/model-resource-owner-pattern) explains the architecture and why the owner boundary exists
|
|
25
|
+
- [Using `ModelResource` in Your Module](/frontend/model-resource-usage-guide) explains application-level usage patterns
|
|
26
|
+
- [Resource Model Best Practices](/frontend/model-resource-best-practices) and [Resource Model Cookbook](/frontend/model-resource-cookbook) explain review and implementation guidance
|
|
27
|
+
- [Rest Resource Under the Hood](/frontend/rest-resource-under-the-hood) explains the module/runtime bridge around the owner
|
|
28
|
+
|
|
29
|
+
What those pages do not isolate directly is the one source-first path through `ModelResource` itself.
|
|
30
|
+
|
|
31
|
+
That is the gap this page fills.
|
|
32
|
+
|
|
33
|
+
## The shortest accurate mental model
|
|
34
|
+
|
|
35
|
+
A practical mental model is:
|
|
36
|
+
|
|
37
|
+
1. `ModelResource` is a selector-backed owner keyed by `resource`
|
|
38
|
+
2. bootstrap resolves the final `resourceApi`
|
|
39
|
+
3. the owner exposes computed surfaces for permissions, schema, and form provider
|
|
40
|
+
4. query helpers wrap the shared model/query runtime for select/view/item-style fetches
|
|
41
|
+
5. mutation helpers wrap the shared model/query runtime for create/update/delete behavior
|
|
42
|
+
6. form helpers let pages choose schema/data/mutation behavior from `formMeta`
|
|
43
|
+
7. query keys and invalidation are centralized as part of the owner contract
|
|
44
|
+
|
|
45
|
+
That means `ModelResource` is not only a fetch helper. It is the stable resource semantics boundary for the frontend.
|
|
46
|
+
|
|
47
|
+
## Source-confirmed reading path
|
|
48
|
+
|
|
49
|
+
When reading this topic, use this order:
|
|
50
|
+
|
|
51
|
+
1. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts`
|
|
52
|
+
2. `zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts`
|
|
53
|
+
3. `zova/packages-zova/zova-core/src/core/sys/util.ts`
|
|
54
|
+
4. `zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useQuery.ts`
|
|
55
|
+
5. `zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.query.ts`
|
|
56
|
+
6. `zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.persister.ts`
|
|
57
|
+
7. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/resource/controller.tsx`
|
|
58
|
+
8. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/entry/controller.tsx`
|
|
59
|
+
|
|
60
|
+
That order moves from the owner core, to the OpenAPI model it relies on, to path/config helpers, to query/persister behavior, and finally to the clearest current consumers.
|
|
61
|
+
|
|
62
|
+
## Initialization and bootstrap
|
|
63
|
+
|
|
64
|
+
The owner core lives in:
|
|
65
|
+
|
|
66
|
+
```text
|
|
67
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The first source-confirmed facts are:
|
|
71
|
+
|
|
72
|
+
- `@Model({ enableSelector: true })`
|
|
73
|
+
- `__init__(resource)` requires a concrete `resource`
|
|
74
|
+
- bootstrap happens before downstream consumers use the owner surfaces
|
|
75
|
+
|
|
76
|
+
This matters because `ModelResource` is not one global singleton.
|
|
77
|
+
|
|
78
|
+
It is a selector-backed owner whose runtime identity is the current resource name.
|
|
79
|
+
|
|
80
|
+
## `resourceApi` resolution
|
|
81
|
+
|
|
82
|
+
The bootstrap path uses:
|
|
83
|
+
|
|
84
|
+
- `this.$sdk.getBootstrap(this.resource)`
|
|
85
|
+
- `this.sys.util.parseResourceApi(resource, api)`
|
|
86
|
+
|
|
87
|
+
The path/config helper lives in:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
zova/packages-zova/zova-core/src/core/sys/util.ts
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
This confirms the owner flow:
|
|
94
|
+
|
|
95
|
+
- bootstrap data may override the final API path
|
|
96
|
+
- otherwise the resource name is translated into a default controller/action API path
|
|
97
|
+
|
|
98
|
+
That is why `resourceApi` should be treated as an owner-level resolved surface, not as one hard-coded string duplicated across pages.
|
|
99
|
+
|
|
100
|
+
## Metadata surfaces exposed by the owner
|
|
101
|
+
|
|
102
|
+
Inside `ModelResource`, the owner computes and exposes:
|
|
103
|
+
|
|
104
|
+
- `permissions`
|
|
105
|
+
- `formProvider`
|
|
106
|
+
- `schemaView`
|
|
107
|
+
- `schemaCreate`
|
|
108
|
+
- `schemaUpdate`
|
|
109
|
+
- `schemaFilter`
|
|
110
|
+
- `schemaRow`
|
|
111
|
+
- `schemaPages`
|
|
112
|
+
|
|
113
|
+
These surfaces are derived from:
|
|
114
|
+
|
|
115
|
+
- the bootstrap/runtime resource context
|
|
116
|
+
- the OpenAPI SDK/schema helpers
|
|
117
|
+
|
|
118
|
+
This is the clearest source-confirmed reason why both list pages and entry pages reuse the same owner: schema, permission, and provider surfaces belong to one resource boundary.
|
|
119
|
+
|
|
120
|
+
## Query helper layer
|
|
121
|
+
|
|
122
|
+
The query helpers are organized around:
|
|
123
|
+
|
|
124
|
+
- `selectGeneral(actionPath?, query?)`
|
|
125
|
+
- `select(query?)`
|
|
126
|
+
- `queryItem(...)`
|
|
127
|
+
- `view(id)`
|
|
128
|
+
|
|
129
|
+
`select(query?)` is only a thin wrapper over `selectGeneral(undefined, query)`.
|
|
130
|
+
|
|
131
|
+
The important source-confirmed detail is that the select key includes a hash of the query object:
|
|
132
|
+
|
|
133
|
+
- `['select', actionPath ?? '', hashkey(query)]`
|
|
134
|
+
|
|
135
|
+
That means query identity is deliberate and owner-controlled.
|
|
136
|
+
|
|
137
|
+
This is the owner-side boundary for list/query fetches, not the page shell.
|
|
138
|
+
|
|
139
|
+
## Mutation helper layer
|
|
140
|
+
|
|
141
|
+
The mutation helpers are organized around:
|
|
142
|
+
|
|
143
|
+
- `create()`
|
|
144
|
+
- `mutationItem(...)`
|
|
145
|
+
- `update(id)`
|
|
146
|
+
- `delete(id)`
|
|
147
|
+
|
|
148
|
+
The most important source-confirmed behavior is:
|
|
149
|
+
|
|
150
|
+
- select queries are invalidated after successful mutations
|
|
151
|
+
- item-root queries are invalidated for the specific row identity
|
|
152
|
+
|
|
153
|
+
That means mutation helpers do not only perform network requests. They also own the default resource-level invalidation policy.
|
|
154
|
+
|
|
155
|
+
## Form helper layer
|
|
156
|
+
|
|
157
|
+
The form-facing helpers are:
|
|
158
|
+
|
|
159
|
+
- `getFormSchema(formMeta)`
|
|
160
|
+
- `getFormApiSchemas(formMeta)`
|
|
161
|
+
- `getFormMutationSubmit(formMeta, id?)`
|
|
162
|
+
- `getFormData(formMeta, id?)`
|
|
163
|
+
- `getQueryDataDefaultValue(schemaName?)`
|
|
164
|
+
|
|
165
|
+
This is the clearest source-confirmed bridge from resource owner to entry-page form runtime.
|
|
166
|
+
|
|
167
|
+
A practical reading rule is:
|
|
168
|
+
|
|
169
|
+
- list pages mainly consume `schemaFilter`, `schemaRow`, and `select(...)`
|
|
170
|
+
- entry pages mainly consume `formMeta`-driven form helpers
|
|
171
|
+
|
|
172
|
+
## Query-key prefixing and invalidation behavior
|
|
173
|
+
|
|
174
|
+
The shared model/query behavior lives in:
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.useQuery.ts
|
|
178
|
+
zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.query.ts
|
|
179
|
+
zova/src/suite-vendor/a-zova/modules/a-model/src/bean/bean.model/bean.model.persister.ts
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The important source-confirmed behavior is:
|
|
183
|
+
|
|
184
|
+
- owner query keys are prefixed with bean full name
|
|
185
|
+
- selector-backed models also prefix by selector
|
|
186
|
+
- persister/query behavior therefore treats one resource owner as a distinct query namespace
|
|
187
|
+
|
|
188
|
+
This is why `ModelResource` query identity is stable even when multiple resources or multiple selectors exist at once.
|
|
189
|
+
|
|
190
|
+
## Current consumers that prove the contract
|
|
191
|
+
|
|
192
|
+
The clearest current consumers are:
|
|
193
|
+
|
|
194
|
+
- `rest-resource/src/page/resource/controller.tsx`
|
|
195
|
+
- `rest-resource/src/page/entry/controller.tsx`
|
|
196
|
+
|
|
197
|
+
These page shells prove that:
|
|
198
|
+
|
|
199
|
+
- list pages consume the owner for top-level list/schema/runtime entry
|
|
200
|
+
- entry pages consume the owner for form/provider/schema/runtime entry
|
|
201
|
+
|
|
202
|
+
That is enough to verify that `ModelResource` is the shared owner beneath both branches.
|
|
203
|
+
|
|
204
|
+
## What this guide does not re-explain
|
|
205
|
+
|
|
206
|
+
This page does **not** fully re-explain:
|
|
207
|
+
|
|
208
|
+
- why the resource owner pattern exists -> see [Model Resource Owner Pattern](/frontend/model-resource-owner-pattern)
|
|
209
|
+
- application-level facade and usage guidance -> see [Using `ModelResource` in Your Module](/frontend/model-resource-usage-guide)
|
|
210
|
+
- the full list-page runtime -> see [Resource List Page Deep Dive](/frontend/resource-list-page-deep-dive)
|
|
211
|
+
- the full entry-page runtime -> see [Resource Entry Page Deep Dive](/frontend/resource-entry-page-deep-dive)
|
|
212
|
+
|
|
213
|
+
Its job is only to explain the owner internals and their current consumer contract.
|
|
214
|
+
|
|
215
|
+
## Where to read next
|
|
216
|
+
|
|
217
|
+
Use these next steps depending on your question:
|
|
218
|
+
|
|
219
|
+
- if you want to step back to the broader model role, return to [Model Architecture](/frontend/model-architecture)
|
|
220
|
+
- if you want to step back to the consumer-side handoff, return to [Generated Contract Consumption: Entry Branch](/frontend/generated-contract-consumption-entry-branch)
|
|
221
|
+
- if you want the list-page runtime branch, read [Resource List Page Deep Dive](/frontend/resource-list-page-deep-dive)
|
|
222
|
+
- if you want the entry-page runtime branch, read [Resource Entry Page Deep Dive](/frontend/resource-entry-page-deep-dive)
|
|
223
|
+
- if you want the owner-pattern explanation, read [Model Resource Owner Pattern](/frontend/model-resource-owner-pattern)
|
|
224
|
+
- if you want application-level usage/facade rules, read [Using `ModelResource` in Your Module](/frontend/model-resource-usage-guide)
|
|
225
|
+
|
|
226
|
+
## Final takeaway
|
|
227
|
+
|
|
228
|
+
The most accurate way to read `ModelResource` is not as one generic CRUD helper.
|
|
229
|
+
|
|
230
|
+
Read it as the selector-backed resource owner that:
|
|
231
|
+
|
|
232
|
+
- bootstraps and resolves `resourceApi`
|
|
233
|
+
- exposes schema, permission, and provider surfaces
|
|
234
|
+
- owns query, mutation, and form helper boundaries
|
|
235
|
+
- defines query-key and invalidation behavior
|
|
236
|
+
- remains the stable resource semantics layer beneath both list pages and entry pages
|
|
237
|
+
|
|
238
|
+
That is the source-confirmed role of `ModelResource` in the current Cabloy Basic frontend architecture.
|
|
@@ -8,12 +8,33 @@ It uses the current `rest-resource` model as the main source specimen:
|
|
|
8
8
|
|
|
9
9
|
Read [Model Architecture](/frontend/model-architecture) and [Model State Guide](/frontend/model-state-guide) first if you want the broader Model runtime and helper surface.
|
|
10
10
|
|
|
11
|
+
If your next question is how `ModelResource` itself works internally at the source level, continue with [ModelResource Internals Deep Dive](/frontend/model-resource-internals-deep-dive).
|
|
12
|
+
|
|
13
|
+
If your next question is how the generic lower-level model runtime works beneath `ModelResource`, continue with [Model Runtime Under the Hood](/frontend/a-model-under-the-hood).
|
|
14
|
+
|
|
15
|
+
If your next question is how the whole `rest-resource` module works at runtime beyond the model itself, continue with [Rest Resource Under the Hood](/frontend/rest-resource-under-the-hood).
|
|
16
|
+
|
|
17
|
+
If your next question is which files to read next for that runtime, continue with [Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map).
|
|
18
|
+
|
|
11
19
|
If your next question is how to apply this pattern in your own module, continue with [Using `ModelResource` in Your Module](/frontend/model-resource-usage-guide).
|
|
12
20
|
|
|
13
21
|
If your next question is how to review or constrain that pattern in a larger codebase, continue with [Resource Model Best Practices and Anti-Patterns](/frontend/model-resource-best-practices).
|
|
14
22
|
|
|
15
23
|
If your next question is which common extension shapes to implement first, continue with [Resource Model Cookbook](/frontend/model-resource-cookbook).
|
|
16
24
|
|
|
25
|
+
> [!TIP]
|
|
26
|
+
> **Resource docs path**
|
|
27
|
+
>
|
|
28
|
+
> 1. **[Model Resource Owner Pattern](/frontend/model-resource-owner-pattern)** — learn why `ModelResource` is a resource owner
|
|
29
|
+
> 2. **[Rest Resource Under the Hood](/frontend/rest-resource-under-the-hood)** — learn how the module runtime pieces cooperate
|
|
30
|
+
> 3. **[Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map)** — learn which files to read next
|
|
31
|
+
> 4. **[Using `ModelResource` in Your Module](/frontend/model-resource-usage-guide)** — learn how to reuse the owner in application code
|
|
32
|
+
> 5. **[Resource Model Best Practices](/frontend/model-resource-best-practices)** — learn the review guardrails
|
|
33
|
+
> 6. **[Resource Model Cookbook](/frontend/model-resource-cookbook)** — learn the common implementation shapes
|
|
34
|
+
>
|
|
35
|
+
> **You are here:** step 1.
|
|
36
|
+
> **Next recommended page:** [Rest Resource Under the Hood](/frontend/rest-resource-under-the-hood).
|
|
37
|
+
|
|
17
38
|
## Why this page exists
|
|
18
39
|
|
|
19
40
|
Many examples of Zova Model start from a small feature model:
|
|
@@ -118,8 +139,7 @@ Because Zova Model prefixes query keys by bean identity and selector, the effect
|
|
|
118
139
|
So logical keys such as:
|
|
119
140
|
|
|
120
141
|
```typescript
|
|
121
|
-
['select', '', hashkey(query)]
|
|
122
|
-
['item', id, 'view']
|
|
142
|
+
['select', '', hashkey(query)][('item', id, 'view')];
|
|
123
143
|
```
|
|
124
144
|
|
|
125
145
|
can safely exist for many resources without colliding.
|
|
@@ -6,8 +6,24 @@ It is the practical follow-up to [Model Resource Owner Pattern](/frontend/model-
|
|
|
6
6
|
|
|
7
7
|
For review guardrails and design checks after applying the pattern, continue with [Resource Model Best Practices and Anti-Patterns](/frontend/model-resource-best-practices).
|
|
8
8
|
|
|
9
|
+
If you need the lower-level generic model runtime beneath this resource-owner usage layer, continue with [Model Runtime Under the Hood](/frontend/a-model-under-the-hood).
|
|
10
|
+
|
|
9
11
|
For implementation templates covering common extension scenarios, continue with [Resource Model Cookbook](/frontend/model-resource-cookbook).
|
|
10
12
|
|
|
13
|
+
> [!TIP]
|
|
14
|
+
> **Resource docs path**
|
|
15
|
+
>
|
|
16
|
+
> 1. **[Model Resource Owner Pattern](/frontend/model-resource-owner-pattern)** — learn why `ModelResource` is a resource owner
|
|
17
|
+
> 2. **[Rest Resource Under the Hood](/frontend/rest-resource-under-the-hood)** — learn how the module runtime pieces cooperate
|
|
18
|
+
> 3. **[Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map)** — learn which files to read next
|
|
19
|
+
> 4. **[Using `ModelResource` in Your Module](/frontend/model-resource-usage-guide)** — learn how to reuse the owner in application code
|
|
20
|
+
> 5. **[Resource Model Best Practices](/frontend/model-resource-best-practices)** — learn the review guardrails
|
|
21
|
+
> 6. **[Resource Model Cookbook](/frontend/model-resource-cookbook)** — learn the common implementation shapes
|
|
22
|
+
>
|
|
23
|
+
> **You are here:** step 4.
|
|
24
|
+
> **Previous recommended pages:** [Model Resource Owner Pattern](/frontend/model-resource-owner-pattern), [Rest Resource Under the Hood](/frontend/rest-resource-under-the-hood), and [Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map).
|
|
25
|
+
> **Next recommended pages:** [Resource Model Best Practices](/frontend/model-resource-best-practices), then [Resource Model Cookbook](/frontend/model-resource-cookbook).
|
|
26
|
+
|
|
11
27
|
Use this page when the main question is not only “what does `ModelResource` do?”, but also:
|
|
12
28
|
|
|
13
29
|
- when should I use it directly?
|
|
@@ -95,7 +111,7 @@ This is the right option when business semantics appear, but ownership should st
|
|
|
95
111
|
A representative shape is:
|
|
96
112
|
|
|
97
113
|
```typescript
|
|
98
|
-
const StudentResource = '
|
|
114
|
+
const StudentResource = 'training-student:student';
|
|
99
115
|
|
|
100
116
|
@Model()
|
|
101
117
|
export class ModelStudent extends BeanModelBase {
|
|
@@ -109,7 +125,7 @@ export class ModelStudent extends BeanModelBase {
|
|
|
109
125
|
id,
|
|
110
126
|
action: 'summary',
|
|
111
127
|
queryFn: async () => {
|
|
112
|
-
const res = await this.scope.api.
|
|
128
|
+
const res = await this.scope.api.trainingStudent.summary({ params: { id } });
|
|
113
129
|
return res ?? null;
|
|
114
130
|
},
|
|
115
131
|
meta: {
|
|
@@ -123,7 +139,7 @@ export class ModelStudent extends BeanModelBase {
|
|
|
123
139
|
id,
|
|
124
140
|
action: 'deleteForce',
|
|
125
141
|
mutationFn: async () => {
|
|
126
|
-
await this.scope.api.
|
|
142
|
+
await this.scope.api.trainingStudent.deleteForce({ params: { id } });
|
|
127
143
|
},
|
|
128
144
|
});
|
|
129
145
|
}
|
|
@@ -184,7 +200,7 @@ summary(id: TableIdentity) {
|
|
|
184
200
|
id,
|
|
185
201
|
action: 'summary',
|
|
186
202
|
queryFn: async () => {
|
|
187
|
-
const res = await this.scope.api.
|
|
203
|
+
const res = await this.scope.api.trainingStudent.summary({ params: { id } });
|
|
188
204
|
return res ?? null;
|
|
189
205
|
},
|
|
190
206
|
});
|
|
@@ -227,7 +243,7 @@ deleteForce(id: TableIdentity) {
|
|
|
227
243
|
id,
|
|
228
244
|
action: 'deleteForce',
|
|
229
245
|
mutationFn: async () => {
|
|
230
|
-
await this.scope.api.
|
|
246
|
+
await this.scope.api.trainingStudent.deleteForce({ params: { id } });
|
|
231
247
|
},
|
|
232
248
|
});
|
|
233
249
|
}
|
|
@@ -315,4 +331,4 @@ The most important practical insight is simple:
|
|
|
315
331
|
|
|
316
332
|
> use `ModelResource` directly when the generic owner already fits; add a thin facade only when the UI needs clearer business semantics.
|
|
317
333
|
|
|
318
|
-
That approach keeps the programming model more uniform and reduces mental burden.
|
|
334
|
+
That approach keeps the programming model more uniform and reduces mental burden.
|
|
@@ -6,6 +6,10 @@ Read [Model Architecture](/frontend/model-architecture) first if you want the br
|
|
|
6
6
|
|
|
7
7
|
If you specifically want the scalable resource-facade pattern, continue with [Model Resource Owner Pattern](/frontend/model-resource-owner-pattern).
|
|
8
8
|
|
|
9
|
+
If you want the generic lower-level model runtime beneath these helper families, continue with [A-Model Under the Hood](/frontend/a-model-under-the-hood).
|
|
10
|
+
|
|
11
|
+
If you want to understand how that owner pattern expands into the whole `rest-resource` module runtime, continue with [Rest Resource Under the Hood](/frontend/rest-resource-under-the-hood), then [Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map).
|
|
12
|
+
|
|
9
13
|
If you want to apply that pattern in your own module with a more uniform two-usage model, continue with [Using `ModelResource` in Your Module](/frontend/model-resource-usage-guide).
|
|
10
14
|
|
|
11
15
|
## Why the model-state layer exists
|
|
@@ -26,10 +30,10 @@ Current `a-model` source supports a broader state family that includes:
|
|
|
26
30
|
|
|
27
31
|
## Create a model
|
|
28
32
|
|
|
29
|
-
Example: create a model named `menu` in module `
|
|
33
|
+
Example: create a model named `menu` in module `training-student`.
|
|
30
34
|
|
|
31
35
|
```bash
|
|
32
|
-
npm run zova :create:bean model menu -- --module=
|
|
36
|
+
npm run zova :create:bean model menu -- --module=training-student
|
|
33
37
|
```
|
|
34
38
|
|
|
35
39
|
## Basic model definition
|
|
@@ -206,7 +210,7 @@ One of the most important model-state behaviors is automatic key prefixing.
|
|
|
206
210
|
When a model uses:
|
|
207
211
|
|
|
208
212
|
```typescript
|
|
209
|
-
queryKey: ['list']
|
|
213
|
+
queryKey: ['list'];
|
|
210
214
|
```
|
|
211
215
|
|
|
212
216
|
that logical key is prefixed internally with model identity, and with selector when selector mode is enabled.
|
|
@@ -306,6 +310,8 @@ What this example shows:
|
|
|
306
310
|
|
|
307
311
|
This is one of the best examples for understanding how Zova Model scales from simple data queries to reusable domain infrastructure.
|
|
308
312
|
|
|
313
|
+
If your next question is not only about the model class but about how generic routes, page shells, schema-driven blocks, and downstream CRUD blocks cooperate around that owner, continue with [Rest Resource Under the Hood](/frontend/rest-resource-under-the-hood).
|
|
314
|
+
|
|
309
315
|
#### Why `enableSelector` matters here
|
|
310
316
|
|
|
311
317
|
This model is not meant to represent only one concrete resource forever.
|
|
@@ -321,8 +327,7 @@ At runtime, model query keys are therefore prefixed not only by the bean full na
|
|
|
321
327
|
That means two consumers can both use logical keys such as:
|
|
322
328
|
|
|
323
329
|
```typescript
|
|
324
|
-
['select', '', hashkey(query)]
|
|
325
|
-
['item', id, 'view']
|
|
330
|
+
['select', '', hashkey(query)][('item', id, 'view')];
|
|
326
331
|
```
|
|
327
332
|
|
|
328
333
|
without colliding with each other, because the effective cache identity is separated by resource selector.
|
|
@@ -363,9 +368,7 @@ It separates three levels of identity:
|
|
|
363
368
|
Representative shapes are:
|
|
364
369
|
|
|
365
370
|
```typescript
|
|
366
|
-
['select', actionPath ?? '', hashkey(query)]
|
|
367
|
-
['item', id]
|
|
368
|
-
['item', id, action]
|
|
371
|
+
['select', actionPath ?? '', hashkey(query)][('item', id)][('item', id, action)];
|
|
369
372
|
```
|
|
370
373
|
|
|
371
374
|
This makes the invalidation strategy much clearer:
|
|
@@ -420,4 +423,4 @@ The most important usage insight is simple:
|
|
|
420
423
|
|
|
421
424
|
> In Zova, model state is not only “fetch some data”. It is a unified model-owned runtime for query state, local state, persistence, invalidation, and SSR-aware reuse.
|
|
422
425
|
|
|
423
|
-
Once that is clear, the helper family in `a-model` reads as one coherent system instead of several unrelated APIs.
|
|
426
|
+
Once that is clear, the helper family in `a-model` reads as one coherent system instead of several unrelated APIs.
|
|
@@ -40,11 +40,11 @@ These categories make module resources discoverable and consistently organized.
|
|
|
40
40
|
Representative CLI entrypoints include:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
npm run zova :init:config
|
|
44
|
-
npm run zova :init:constant
|
|
45
|
-
npm run zova :init:locale
|
|
46
|
-
npm run zova :init:error
|
|
47
|
-
npm run zova :create:bean api test -- --module=
|
|
43
|
+
npm run zova :init:config training-student
|
|
44
|
+
npm run zova :init:constant training-student
|
|
45
|
+
npm run zova :init:locale training-student
|
|
46
|
+
npm run zova :init:error training-student
|
|
47
|
+
npm run zova :create:bean api test -- --module=training-student
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
This matters because scope is not just a read surface. It is the organized destination for resources generated or initialized through the standard Zova workflow.
|
|
@@ -119,14 +119,14 @@ Representative pattern:
|
|
|
119
119
|
|
|
120
120
|
```typescript
|
|
121
121
|
@UseScope()
|
|
122
|
-
$$
|
|
122
|
+
$$scopeTrainingStudent: ScopeModuleTrainingStudent;
|
|
123
123
|
```
|
|
124
124
|
|
|
125
125
|
A common follow-up access pattern is:
|
|
126
126
|
|
|
127
127
|
```typescript
|
|
128
|
-
const res = await this.$$
|
|
129
|
-
console.log(this.$$
|
|
128
|
+
const res = await this.$$scopeTrainingStudent.api.test.echo();
|
|
129
|
+
console.log(this.$$scopeTrainingStudent.locale.HelloWorld());
|
|
130
130
|
```
|
|
131
131
|
|
|
132
132
|
This allows one module to consume another module’s scoped resources explicitly without flattening everything into one shared global namespace.
|
|
@@ -129,7 +129,7 @@ Representative patterns include:
|
|
|
129
129
|
|
|
130
130
|
```json
|
|
131
131
|
{
|
|
132
|
-
"name": "zova-module-
|
|
132
|
+
"name": "zova-module-training-student",
|
|
133
133
|
"zovaModule": {
|
|
134
134
|
"dependencies": {
|
|
135
135
|
"a-zova": "5.0.0"
|
|
@@ -160,6 +160,7 @@ This reinforces that modules are not merely folders. They are explicit package,
|
|
|
160
160
|
|
|
161
161
|
Read this together with:
|
|
162
162
|
|
|
163
|
+
- [Suites and Modules](/fullstack/suites-and-modules) for the cross-stack suite-first decision path in the monorepo
|
|
163
164
|
- [IoC and Beans](/frontend/ioc-and-beans)
|
|
164
165
|
- [Module Scope](/frontend/module-scope)
|
|
165
166
|
- [Frontend Scripts](/frontend/scripts)
|
|
@@ -66,3 +66,10 @@ When changing auth-sensitive routing behavior, ask:
|
|
|
66
66
|
4. should redirects happen at the routing-policy layer rather than being hardcoded into page logic?
|
|
67
67
|
|
|
68
68
|
That produces cleaner and more framework-native navigation behavior.
|
|
69
|
+
|
|
70
|
+
## Where to read next
|
|
71
|
+
|
|
72
|
+
- If you want the broader route-record surface first, continue with [Page Route Guide](/frontend/page-route-guide).
|
|
73
|
+
- If the guard decision depends on route metadata or task-level shell state, continue with [Page Meta Guide](/frontend/page-meta-guide).
|
|
74
|
+
- If the guard behavior is really part of a larger SSR decision path, continue with [SSR Architecture Overview](/frontend/ssr-architecture-overview).
|
|
75
|
+
- If you want the deeper routing runtime after the public policy surface is clear, descend into [Zova Router Under the Hood](/frontend/zova-router-under-the-hood).
|
|
@@ -20,12 +20,16 @@ For the bridge view, also see [Backend OpenAPI to Frontend SDK](/fullstack/opena
|
|
|
20
20
|
|
|
21
21
|
For the broader frontend contract-consumption ladder, also see [Server Data](/frontend/server-data), [API Schema Guide](/frontend/api-schema-guide), and [SDK Guide](/frontend/sdk-guide).
|
|
22
22
|
|
|
23
|
+
If your next question is how the lower-level OpenAPI/schema runtime works under `$sdk`, continue with [A-OpenAPI Under the Hood](/frontend/a-openapi-under-the-hood).
|
|
24
|
+
|
|
25
|
+
If your next question is how generated contract material becomes schema-driven frontend behavior or resource-owner consumption, continue with [API Schema Guide](/frontend/api-schema-guide) and [ModelResource Internals Deep Dive](/frontend/model-resource-internals-deep-dive).
|
|
26
|
+
|
|
23
27
|
## Initialize OpenAPI config
|
|
24
28
|
|
|
25
|
-
Example: initialize OpenAPI config for module `
|
|
29
|
+
Example: initialize OpenAPI config for module `training-student`.
|
|
26
30
|
|
|
27
31
|
```bash
|
|
28
|
-
npm run zova :openapi:config
|
|
32
|
+
npm run zova :openapi:config training-student
|
|
29
33
|
```
|
|
30
34
|
|
|
31
35
|
## Module-level config
|
|
@@ -53,10 +57,10 @@ Representative use case:
|
|
|
53
57
|
|
|
54
58
|
## Generate the SDK
|
|
55
59
|
|
|
56
|
-
Example: generate OpenAPI-based frontend services for module `
|
|
60
|
+
Example: generate OpenAPI-based frontend services for module `training-student`.
|
|
57
61
|
|
|
58
62
|
```bash
|
|
59
|
-
npm run zova :openapi:generate
|
|
63
|
+
npm run zova :openapi:generate training-student
|
|
60
64
|
```
|
|
61
65
|
|
|
62
66
|
## Build the rest-contract output
|
|
@@ -93,6 +97,10 @@ If the backend contract itself changes, first inspect or update the backend cont
|
|
|
93
97
|
|
|
94
98
|
Then return to this page for the frontend regeneration step.
|
|
95
99
|
|
|
100
|
+
If your next question is what that generated contract looks like when it is actually consumed in a practical frontend path, continue with [Generated Contract Consumption Specimen](/frontend/generated-contract-consumption-specimen).
|
|
101
|
+
|
|
102
|
+
If you then want a proof-oriented or symptom-first companion for the consumer-side path, continue with [Generated Contract Consumption Verify Playbook](/frontend/generated-contract-consumption-verify-playbook) and [Generated Contract Consumption Debug Checklist](/frontend/generated-contract-consumption-debug-checklist).
|
|
103
|
+
|
|
96
104
|
## Implementation checks for SDK regeneration decisions
|
|
97
105
|
|
|
98
106
|
When evaluating a request that depends on backend contracts, ask:
|
|
@@ -17,10 +17,10 @@ That combination is one of the clearest examples of Zova’s overall design phil
|
|
|
17
17
|
|
|
18
18
|
## Create a page
|
|
19
19
|
|
|
20
|
-
Example: create a page named `counter` in module `
|
|
20
|
+
Example: create a page named `counter` in module `training-student`.
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npm run zova :create:page counter -- --module=
|
|
23
|
+
npm run zova :create:page counter -- --module=training-student
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
## Route path generation
|
|
@@ -29,9 +29,9 @@ Zova automatically derives the page path from the module and page names.
|
|
|
29
29
|
|
|
30
30
|
Representative example:
|
|
31
31
|
|
|
32
|
-
- module: `
|
|
32
|
+
- module: `training-student`
|
|
33
33
|
- page: `counter`
|
|
34
|
-
- generated page path: `/
|
|
34
|
+
- generated page path: `/training/student/counter`
|
|
35
35
|
|
|
36
36
|
This matters because the framework already has conventions for route structure. AI should reuse those conventions rather than inventing unrelated paths.
|
|
37
37
|
|
|
@@ -123,7 +123,7 @@ A typical first step is keeping the page controller responsible for state while
|
|
|
123
123
|
#### Create the first render bean
|
|
124
124
|
|
|
125
125
|
```bash
|
|
126
|
-
npm run zova :refactor:firstRender page/counter -- --module=
|
|
126
|
+
npm run zova :refactor:firstRender page/counter -- --module=training-student
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
Representative render bean shape:
|
|
@@ -146,7 +146,7 @@ class RenderPageCounter extends BeanRenderBase {
|
|
|
146
146
|
#### Create the first style bean
|
|
147
147
|
|
|
148
148
|
```bash
|
|
149
|
-
npm run zova :refactor:firstStyle page/counter -- --module=
|
|
149
|
+
npm run zova :refactor:firstStyle page/counter -- --module=training-student
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
Representative style bean shape:
|
|
@@ -177,19 +177,19 @@ Representative refactors include:
|
|
|
177
177
|
#### Create another render bean
|
|
178
178
|
|
|
179
179
|
```bash
|
|
180
|
-
npm run zova :refactor:anotherRender page/counter another -- --module=
|
|
180
|
+
npm run zova :refactor:anotherRender page/counter another -- --module=training-student
|
|
181
181
|
```
|
|
182
182
|
|
|
183
183
|
#### Create another style bean
|
|
184
184
|
|
|
185
185
|
```bash
|
|
186
|
-
npm run zova :refactor:anotherStyle page/counter another -- --module=
|
|
186
|
+
npm run zova :refactor:anotherStyle page/counter another -- --module=training-student
|
|
187
187
|
```
|
|
188
188
|
|
|
189
189
|
#### Create a service bean for state management
|
|
190
190
|
|
|
191
191
|
```bash
|
|
192
|
-
npm run zova :create:bean service page/counter/counter -- --module=
|
|
192
|
+
npm run zova :create:bean service page/counter/counter -- --module=training-student
|
|
193
193
|
```
|
|
194
194
|
|
|
195
195
|
Representative service bean shape:
|