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,622 @@
|
|
|
1
|
+
# Rest Resource Under the Hood
|
|
2
|
+
|
|
3
|
+
This guide explains the source-level runtime path behind the `rest-resource` module.
|
|
4
|
+
|
|
5
|
+
Use this page together with:
|
|
6
|
+
|
|
7
|
+
- [Model Resource Owner Pattern](/frontend/model-resource-owner-pattern)
|
|
8
|
+
- [Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map)
|
|
9
|
+
- [Using `ModelResource` in Your Module](/frontend/model-resource-usage-guide)
|
|
10
|
+
- [Table + Resource CRUD Cookbook](/frontend/table-resource-crud-cookbook)
|
|
11
|
+
- [Form Guide](/frontend/form-guide)
|
|
12
|
+
- [Zova Source Reading Map](/frontend/zova-source-reading-map)
|
|
13
|
+
|
|
14
|
+
Use this page after [Model Resource Owner Pattern](/frontend/model-resource-owner-pattern) when you want to move from the model-focused explanation to the internal cooperation among route records, generated page wrappers, page-shell controllers, schema-driven block rendering, selector-backed resource ownership, and downstream CRUD block runtimes.
|
|
15
|
+
|
|
16
|
+
If your next question is not “how does this runtime work?” but “which files should I read next?”, continue with [Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map).
|
|
17
|
+
|
|
18
|
+
If your next question is specifically how a resource entry route becomes a working entry page through `rest-resource`, `basic-pageentry`, `blockForm`, and `blockToolbarRow`, continue with [Resource Entry Page Deep Dive](/frontend/resource-entry-page-deep-dive).
|
|
19
|
+
|
|
20
|
+
If your next question is specifically how the resource list route becomes a working list page through `basic-page`, `blockFilter`, `blockTable`, `blockPager`, and `ZTable`, continue with [Resource List Page Deep Dive](/frontend/resource-list-page-deep-dive).
|
|
21
|
+
|
|
22
|
+
If your next question is specifically how filter state becomes `query`, then `ModelResource.select(query)`, and finally list/paged data, continue with [Filter to Query to Select Data Flow Guide](/frontend/filter-query-select-data-flow-guide).
|
|
23
|
+
|
|
24
|
+
If your next question is specifically how the resource owner works internally, continue with [ModelResource Internals Deep Dive](/frontend/model-resource-internals-deep-dive).
|
|
25
|
+
|
|
26
|
+
If your next question is specifically how the lower-level generic model runtime works beneath that owner, continue with [Model Runtime Under the Hood](/frontend/a-model-under-the-hood).
|
|
27
|
+
|
|
28
|
+
> [!TIP]
|
|
29
|
+
> **Resource docs path**
|
|
30
|
+
>
|
|
31
|
+
> 1. **[Model Resource Owner Pattern](/frontend/model-resource-owner-pattern)** — learn why `ModelResource` is a resource owner
|
|
32
|
+
> 2. **[Rest Resource Under the Hood](/frontend/rest-resource-under-the-hood)** — learn how the module runtime pieces cooperate
|
|
33
|
+
> 3. **[Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map)** — learn which files to read next
|
|
34
|
+
> 4. **[Using `ModelResource` in Your Module](/frontend/model-resource-usage-guide)** — learn how to reuse the owner in application code
|
|
35
|
+
> 5. **[Resource Model Best Practices](/frontend/model-resource-best-practices)** — learn the review guardrails
|
|
36
|
+
> 6. **[Resource Model Cookbook](/frontend/model-resource-cookbook)** — learn the common implementation shapes
|
|
37
|
+
>
|
|
38
|
+
> **You are here:** step 2.
|
|
39
|
+
> **Previous page:** [Model Resource Owner Pattern](/frontend/model-resource-owner-pattern).
|
|
40
|
+
> **Next recommended page:** [Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map).
|
|
41
|
+
|
|
42
|
+
## Why this page exists
|
|
43
|
+
|
|
44
|
+
The existing `ModelResource` pages already explain the owner pattern clearly:
|
|
45
|
+
|
|
46
|
+
- why selector identity matters
|
|
47
|
+
- why the model owns schema, permissions, queries, mutations, and invalidation
|
|
48
|
+
- how business modules should reuse the existing resource owner directly or through a thin facade
|
|
49
|
+
|
|
50
|
+
What those pages do **not** focus on is the larger module-level runtime around that owner:
|
|
51
|
+
|
|
52
|
+
- where the generic `/rest/resource/...` routes are declared
|
|
53
|
+
- how those routes become page-controller instances
|
|
54
|
+
- why the page controllers are intentionally thin
|
|
55
|
+
- how `rest.blocks` drives page assembly
|
|
56
|
+
- where the deeper list-page and entry-page CRUD runtime really lives
|
|
57
|
+
- how commands and other consumers reuse the same owner boundary
|
|
58
|
+
|
|
59
|
+
This page is that bridge.
|
|
60
|
+
|
|
61
|
+
## The shortest accurate runtime model
|
|
62
|
+
|
|
63
|
+
For a typical `rest-resource` page, the shortest accurate model is:
|
|
64
|
+
|
|
65
|
+
1. `routes.ts` declares one generic resource list route and two generic resource entry routes
|
|
66
|
+
2. generated `ZPage*` wrappers bind those route records to page-controller classes through `createZovaComponentPage(...)`
|
|
67
|
+
3. the page controller resolves a selector-backed `ModelResource` instance from the current `resource`
|
|
68
|
+
4. `ModelResource.__init__(resource)` bootstraps the resource metadata and resolves the final `resourceApi`
|
|
69
|
+
5. the model exposes resource-level computed surfaces such as permissions, form provider, and select/view/create/update schemas
|
|
70
|
+
6. the list shell reads `schemaRow.rest.blocks`, while the entry shell reads `formSchema.rest.blocks`
|
|
71
|
+
7. those blocks usually enter downstream generic runtimes such as `basic-page:blockPage` or `basic-pageentry:blockPageEntry`
|
|
72
|
+
8. those downstream runtimes resolve the same selector-backed `ModelResource` again and own the deeper list/form behavior
|
|
73
|
+
9. commands such as delete can also reuse the same model boundary instead of inventing page-local mutation logic
|
|
74
|
+
|
|
75
|
+
That is why `rest-resource` is not only one reusable model bean.
|
|
76
|
+
|
|
77
|
+
It is a **route-driven, schema-driven bridge** that connects:
|
|
78
|
+
|
|
79
|
+
- generic resource routes
|
|
80
|
+
- thin page-shell controllers
|
|
81
|
+
- generic Basic CRUD blocks
|
|
82
|
+
- one stable resource-owner model
|
|
83
|
+
|
|
84
|
+
## Runtime relationship map
|
|
85
|
+
|
|
86
|
+
Use this diagram when the question is:
|
|
87
|
+
|
|
88
|
+
- where does one `/rest/resource/...` route actually go?
|
|
89
|
+
- where does schema-driven block composition happen?
|
|
90
|
+
- where does the deeper CRUD runtime begin?
|
|
91
|
+
- which layer owns fetch, form, and mutation semantics?
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
Route record
|
|
95
|
+
└─ routes.ts
|
|
96
|
+
└─ ZPageResource / ZPageEntry / ZPageEntryCreate
|
|
97
|
+
└─ createZovaComponentPage(...)
|
|
98
|
+
└─ page-controller shell
|
|
99
|
+
├─ resolves current resource / id / formScene
|
|
100
|
+
├─ resolves selector-backed ModelResource
|
|
101
|
+
├─ autoloads top-level API schema surface
|
|
102
|
+
└─ reads schemaRow.rest.blocks or formSchema.rest.blocks
|
|
103
|
+
│
|
|
104
|
+
▼
|
|
105
|
+
schema-driven block composition
|
|
106
|
+
│
|
|
107
|
+
┌──────────────┴──────────────┐
|
|
108
|
+
▼ ▼
|
|
109
|
+
basic-page:blockPage basic-pageentry:blockPageEntry
|
|
110
|
+
│ │
|
|
111
|
+
├─ filter / pager / table ├─ formMeta / formData / submit
|
|
112
|
+
├─ query orchestration ├─ page-title / dirty-state sync
|
|
113
|
+
└─ deeper list runtime └─ deeper entry runtime
|
|
114
|
+
│
|
|
115
|
+
▼
|
|
116
|
+
selector-backed ModelResource
|
|
117
|
+
│
|
|
118
|
+
├─ bootstrap → resourceApi
|
|
119
|
+
├─ permissions / schemas / provider
|
|
120
|
+
├─ select / view queries
|
|
121
|
+
├─ create / update / delete mutations
|
|
122
|
+
└─ centralized invalidation
|
|
123
|
+
│
|
|
124
|
+
▼
|
|
125
|
+
OpenAPI bootstrap + fetch runtime
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Read this top-down:
|
|
129
|
+
|
|
130
|
+
- the route and page shell choose the scene
|
|
131
|
+
- schema metadata chooses the block composition
|
|
132
|
+
- generic Basic blocks own the richer CRUD page behavior
|
|
133
|
+
- `ModelResource` remains the stable owner of resource semantics underneath all of them
|
|
134
|
+
|
|
135
|
+
## A concrete source specimen
|
|
136
|
+
|
|
137
|
+
The smallest module-level source set is:
|
|
138
|
+
|
|
139
|
+
```text
|
|
140
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/routes.ts
|
|
141
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/resource/controller.tsx
|
|
142
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/entry/controller.tsx
|
|
143
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
A deeper runtime continuation is:
|
|
147
|
+
|
|
148
|
+
```text
|
|
149
|
+
zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx
|
|
150
|
+
zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx
|
|
151
|
+
zova/src/suite/cabloy-basic/modules/basic-commands/src/bean/command.delete.tsx
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Those files show the core architectural split clearly:
|
|
155
|
+
|
|
156
|
+
- `rest-resource` owns the module bridge and page shells
|
|
157
|
+
- `ModelResource` owns the resource boundary
|
|
158
|
+
- `basic-page` and `basic-pageentry` own the richer reusable CRUD block runtime
|
|
159
|
+
- command beans can reuse the same resource owner outside page rendering
|
|
160
|
+
|
|
161
|
+
## The core source-reading path
|
|
162
|
+
|
|
163
|
+
When you want to trace the full mechanism, read these files in order:
|
|
164
|
+
|
|
165
|
+
1. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/routes.ts`
|
|
166
|
+
2. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/page/resource.ts`
|
|
167
|
+
3. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/page/entry.ts`
|
|
168
|
+
4. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/page/entryCreate.ts`
|
|
169
|
+
5. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/resource/controller.tsx`
|
|
170
|
+
6. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/entry/controller.tsx`
|
|
171
|
+
7. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/entryCreate/controller.tsx`
|
|
172
|
+
8. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts`
|
|
173
|
+
9. `zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx`
|
|
174
|
+
10. `zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx`
|
|
175
|
+
11. `zova/src/suite/cabloy-basic/modules/basic-commands/src/bean/command.delete.tsx`
|
|
176
|
+
12. `zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/index.ts`
|
|
177
|
+
|
|
178
|
+
A compact role map is:
|
|
179
|
+
|
|
180
|
+
- `routes.ts` shows the public route surface
|
|
181
|
+
- `.metadata/page/*.ts` shows how route components enter `createZovaComponentPage(...)`
|
|
182
|
+
- `page/resource/controller.tsx` shows the list-page shell
|
|
183
|
+
- `page/entry/controller.tsx` shows the entry-page shell
|
|
184
|
+
- `page/entryCreate/controller.tsx` shows virtual create-route reuse
|
|
185
|
+
- `model/resource.ts` shows the owner core
|
|
186
|
+
- `blockPage/controller.tsx` shows the deeper list runtime
|
|
187
|
+
- `blockPageEntry/controller.tsx` shows the deeper form runtime
|
|
188
|
+
- `command.delete.tsx` shows non-page reuse of the same owner boundary
|
|
189
|
+
- `.metadata/index.ts` shows the generated bean/type registry surface
|
|
190
|
+
|
|
191
|
+
## Step-by-step runtime path
|
|
192
|
+
|
|
193
|
+
### 1. Generic resource routes define the public module surface
|
|
194
|
+
|
|
195
|
+
Start with:
|
|
196
|
+
|
|
197
|
+
```text
|
|
198
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/routes.ts
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
This file declares three routes:
|
|
202
|
+
|
|
203
|
+
- `:resource`
|
|
204
|
+
- `:resource/create`
|
|
205
|
+
- `:resource/:id/:formScene?`
|
|
206
|
+
|
|
207
|
+
That already reveals the module’s public role.
|
|
208
|
+
|
|
209
|
+
It is not a resource-specific module such as Student or Product.
|
|
210
|
+
|
|
211
|
+
It is a generic module whose runtime identity comes from the route params.
|
|
212
|
+
|
|
213
|
+
### Why the shared `tabKey` matters
|
|
214
|
+
|
|
215
|
+
All three routes use the same `tabKey(route)` shape:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
`/rest/resource/${encodeURIComponent(route.params.resource)}`;
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
This means the workspace identity is resource-level rather than row-level.
|
|
222
|
+
|
|
223
|
+
So the list page, create page, and entry page for one resource remain grouped under one resource-oriented tab boundary.
|
|
224
|
+
|
|
225
|
+
## 2. Generated page wrappers enter the normal Zova page-controller path
|
|
226
|
+
|
|
227
|
+
Read next:
|
|
228
|
+
|
|
229
|
+
- `src/.metadata/page/resource.ts`
|
|
230
|
+
- `src/.metadata/page/entry.ts`
|
|
231
|
+
- `src/.metadata/page/entryCreate.ts`
|
|
232
|
+
|
|
233
|
+
These files are intentionally thin.
|
|
234
|
+
|
|
235
|
+
They show that each route component is generated as a `ZPage*` wrapper through:
|
|
236
|
+
|
|
237
|
+
- `createZovaComponentPage(ControllerPageResource, ...)`
|
|
238
|
+
- `createZovaComponentPage(ControllerPageEntry, ...)`
|
|
239
|
+
- `createZovaComponentPage(ControllerPageEntryCreate, ...)`
|
|
240
|
+
|
|
241
|
+
They also surface the Zod-based params schemas for each page.
|
|
242
|
+
|
|
243
|
+
That means the route record does not jump straight into generic Vue page code.
|
|
244
|
+
|
|
245
|
+
It enters the normal Zova page-controller runtime with typed params.
|
|
246
|
+
|
|
247
|
+
## 3. The list page controller is a shell, not the full list runtime
|
|
248
|
+
|
|
249
|
+
Read:
|
|
250
|
+
|
|
251
|
+
```text
|
|
252
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/resource/controller.tsx
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
The main jobs of `ControllerPageResource` are:
|
|
256
|
+
|
|
257
|
+
1. resolve the selector-backed model from `this.$params.resource`
|
|
258
|
+
2. autoload the select API schema through `this.$$modelResource.apiSchemasSelect.sdk`
|
|
259
|
+
3. read `this.schemaRow?.rest?.blocks`
|
|
260
|
+
4. render those blocks through `ZovaJsx`
|
|
261
|
+
|
|
262
|
+
What is most important is what this controller does **not** own.
|
|
263
|
+
|
|
264
|
+
It does not directly own:
|
|
265
|
+
|
|
266
|
+
- filter state
|
|
267
|
+
- paged query state
|
|
268
|
+
- table refresh policy
|
|
269
|
+
- row-data fetching orchestration
|
|
270
|
+
- permission-sensitive table metadata refresh
|
|
271
|
+
|
|
272
|
+
Those deeper concerns usually appear later in the rendered block runtime, especially in `basic-page:blockPage`.
|
|
273
|
+
|
|
274
|
+
So the correct reading is:
|
|
275
|
+
|
|
276
|
+
> `ControllerPageResource` is the resource list **page shell**.
|
|
277
|
+
|
|
278
|
+
It resolves the current resource context, loads the schema surface, and lets metadata choose the block composition.
|
|
279
|
+
|
|
280
|
+
## 4. The entry page controller is also a shell
|
|
281
|
+
|
|
282
|
+
Read:
|
|
283
|
+
|
|
284
|
+
```text
|
|
285
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/entry/controller.tsx
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
The main jobs of `ControllerPageEntry` are:
|
|
289
|
+
|
|
290
|
+
- resolve `resource`, `id`, and `formScene`
|
|
291
|
+
- derive `formMeta`
|
|
292
|
+
- expose `formProvider` from the model
|
|
293
|
+
- expose `formSchema` from the model
|
|
294
|
+
- autoload the form API schemas
|
|
295
|
+
- read `formSchema?.rest?.blocks`
|
|
296
|
+
- render those blocks through `ZovaJsx`
|
|
297
|
+
|
|
298
|
+
Again, the deeper runtime is intentionally elsewhere.
|
|
299
|
+
|
|
300
|
+
This controller does **not** fully own:
|
|
301
|
+
|
|
302
|
+
- row-data loading for the business entry scene
|
|
303
|
+
- submit mutation execution for the full CRUD flow
|
|
304
|
+
- page-title/page-dirty synchronization
|
|
305
|
+
- the final reusable block-level form orchestration
|
|
306
|
+
|
|
307
|
+
Those concerns usually appear later in `basic-pageentry:blockPageEntry`.
|
|
308
|
+
|
|
309
|
+
So the correct reading is:
|
|
310
|
+
|
|
311
|
+
> `ControllerPageEntry` is the resource entry **page shell**.
|
|
312
|
+
|
|
313
|
+
It interprets the route and the form scene, then lets schema metadata choose the entry blocks.
|
|
314
|
+
|
|
315
|
+
## 5. Create-route reuse is handled through virtual subclassing
|
|
316
|
+
|
|
317
|
+
Read:
|
|
318
|
+
|
|
319
|
+
```text
|
|
320
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/page/entryCreate/controller.tsx
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
This file is intentionally tiny.
|
|
324
|
+
|
|
325
|
+
`ControllerPageEntryCreate` is a virtual subclass of `ControllerPageEntry`.
|
|
326
|
+
|
|
327
|
+
That means the create route does not get a second independently maintained runtime.
|
|
328
|
+
|
|
329
|
+
Instead, it reuses the same entry shell and lets route params plus form-scene logic choose the create branch.
|
|
330
|
+
|
|
331
|
+
This is an important Zova design clue:
|
|
332
|
+
|
|
333
|
+
- page identity can differ
|
|
334
|
+
- controller logic can still stay shared
|
|
335
|
+
|
|
336
|
+
## 6. `ModelResource` is the owner core behind both shells
|
|
337
|
+
|
|
338
|
+
Read:
|
|
339
|
+
|
|
340
|
+
```text
|
|
341
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
This file is the stable owner boundary behind the route shells.
|
|
345
|
+
|
|
346
|
+
At the module-runtime level, the most important steps are:
|
|
347
|
+
|
|
348
|
+
### 6.1 Selector-backed initialization
|
|
349
|
+
|
|
350
|
+
`ModelResource` is decorated with:
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
@Model({ enableSelector: true })
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
and initializes through:
|
|
357
|
+
|
|
358
|
+
```typescript
|
|
359
|
+
protected async __init__(resource: string)
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
That means one generic model class can serve many resources safely, because the runtime identity comes from the selector resource name.
|
|
363
|
+
|
|
364
|
+
### 6.2 Bootstrap resolves the final `resourceApi`
|
|
365
|
+
|
|
366
|
+
Inside initialization, `_bootstrap()` calls:
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
$QueryAutoLoad(() => this.$sdk.getBootstrap(this.resource));
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
and then resolves:
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
this.resourceApi = this.sys.util.parseResourceApi(this.resource, queryBootstrap.data.apiPath);
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
This is one of the most important architectural facts in the whole module.
|
|
379
|
+
|
|
380
|
+
The model does not assume a hardcoded final API path.
|
|
381
|
+
|
|
382
|
+
It bootstraps the resource metadata first, then derives the stable runtime API boundary from that metadata.
|
|
383
|
+
|
|
384
|
+
### 6.3 The model exposes resource-level metadata surfaces
|
|
385
|
+
|
|
386
|
+
Still inside initialization, the model creates computed surfaces for:
|
|
387
|
+
|
|
388
|
+
- `permissions`
|
|
389
|
+
- `formProvider`
|
|
390
|
+
- `schemaView`
|
|
391
|
+
- `schemaCreate`
|
|
392
|
+
- `schemaUpdate`
|
|
393
|
+
- `schemaFilter`
|
|
394
|
+
- `schemaRow`
|
|
395
|
+
- `schemaPages`
|
|
396
|
+
|
|
397
|
+
That is why the page shells can stay thin.
|
|
398
|
+
|
|
399
|
+
They do not need to invent schema or permission lookup rules locally, because the owner already exposes them.
|
|
400
|
+
|
|
401
|
+
### 6.4 The model owns query, mutation, and form semantics
|
|
402
|
+
|
|
403
|
+
The same owner also provides:
|
|
404
|
+
|
|
405
|
+
- `selectGeneral(...)`
|
|
406
|
+
- `select(...)`
|
|
407
|
+
- `queryItem(...)`
|
|
408
|
+
- `view(id)`
|
|
409
|
+
- `create()`
|
|
410
|
+
- `update(id)`
|
|
411
|
+
- `delete(id)`
|
|
412
|
+
- `mutationItem(...)`
|
|
413
|
+
- `getFormSchema(...)`
|
|
414
|
+
- `getFormApiSchemas(...)`
|
|
415
|
+
- `getFormMutationSubmit(...)`
|
|
416
|
+
- `getFormData(...)`
|
|
417
|
+
|
|
418
|
+
A practical reading takeaway is:
|
|
419
|
+
|
|
420
|
+
> routes and page shells give the module its outer shape, but `ModelResource` gives it its resource truth.
|
|
421
|
+
|
|
422
|
+
## 7. `basic-page:blockPage` is the deeper list runtime
|
|
423
|
+
|
|
424
|
+
Read:
|
|
425
|
+
|
|
426
|
+
```text
|
|
427
|
+
zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockPage/controller.tsx
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
This file shows where the richer list behavior really lives.
|
|
431
|
+
|
|
432
|
+
It resolves the same selector-backed model again, then owns:
|
|
433
|
+
|
|
434
|
+
- filter state
|
|
435
|
+
- paged query state
|
|
436
|
+
- combined `query`
|
|
437
|
+
- list loading through `this.$$modelResource.select(this.query)`
|
|
438
|
+
- permission-sensitive table-meta refresh
|
|
439
|
+
- page-scene JSX/CEL scope
|
|
440
|
+
- block rendering for filter/table/pager composition
|
|
441
|
+
|
|
442
|
+
This is the strongest runtime proof that `rest-resource` list pages are layered like this:
|
|
443
|
+
|
|
444
|
+
```text
|
|
445
|
+
rest-resource page shell
|
|
446
|
+
└─ schema-driven block composition
|
|
447
|
+
└─ basic-page:blockPage
|
|
448
|
+
└─ selector-backed ModelResource select(...) ownership
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
So if you are debugging list-page behavior such as paging, filtering, or table refresh, stopping at `ControllerPageResource` is usually too early.
|
|
452
|
+
|
|
453
|
+
## 8. `basic-pageentry:blockPageEntry` is the deeper form runtime
|
|
454
|
+
|
|
455
|
+
Read:
|
|
456
|
+
|
|
457
|
+
```text
|
|
458
|
+
zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
This file shows where the richer entry behavior really lives.
|
|
462
|
+
|
|
463
|
+
It resolves the same selector-backed model again, then owns:
|
|
464
|
+
|
|
465
|
+
- `formMeta`
|
|
466
|
+
- `formProvider`
|
|
467
|
+
- `formSchema`
|
|
468
|
+
- `formData`
|
|
469
|
+
- existing-row view-query loading
|
|
470
|
+
- form submission through `getFormMutationSubmit(...)`
|
|
471
|
+
- page-title/page-dirty synchronization
|
|
472
|
+
- page-entry JSX/CEL scope
|
|
473
|
+
- rendering of the actual form block composition
|
|
474
|
+
|
|
475
|
+
This is the strongest runtime proof that `rest-resource` entry pages are layered like this:
|
|
476
|
+
|
|
477
|
+
```text
|
|
478
|
+
rest-resource entry shell
|
|
479
|
+
└─ schema-driven block composition
|
|
480
|
+
└─ basic-pageentry:blockPageEntry
|
|
481
|
+
└─ selector-backed ModelResource form/query/mutation ownership
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
So if you are debugging entry-page behavior such as submit, title updates, or row-data loading, stopping at `ControllerPageEntry` is usually too early.
|
|
485
|
+
|
|
486
|
+
## 9. Commands can reuse the same owner boundary
|
|
487
|
+
|
|
488
|
+
Read:
|
|
489
|
+
|
|
490
|
+
```text
|
|
491
|
+
zova/src/suite/cabloy-basic/modules/basic-commands/src/bean/command.delete.tsx
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
This file shows an important architectural property of the module.
|
|
495
|
+
|
|
496
|
+
A command bean can resolve the same selector-backed `ModelResource` by resource name and call:
|
|
497
|
+
|
|
498
|
+
- `modelResource.delete(id)`
|
|
499
|
+
|
|
500
|
+
That means the resource owner is not tied to one page controller.
|
|
501
|
+
|
|
502
|
+
It is reusable across:
|
|
503
|
+
|
|
504
|
+
- page shells
|
|
505
|
+
- generic blocks
|
|
506
|
+
- commands
|
|
507
|
+
- business-facing thin facades
|
|
508
|
+
|
|
509
|
+
This is one reason the owner boundary is so valuable.
|
|
510
|
+
|
|
511
|
+
The mutation policy remains centralized even when the caller is not a page.
|
|
512
|
+
|
|
513
|
+
## 10. Generated metadata is a registry layer, not the main runtime layer
|
|
514
|
+
|
|
515
|
+
Read last:
|
|
516
|
+
|
|
517
|
+
```text
|
|
518
|
+
zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/index.ts
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
This file is still useful, but use it for a different purpose.
|
|
522
|
+
|
|
523
|
+
It is best read as the module registry map for:
|
|
524
|
+
|
|
525
|
+
- model bean registration
|
|
526
|
+
- controller bean registration
|
|
527
|
+
- page-path and page-name typing
|
|
528
|
+
- module scope typing
|
|
529
|
+
- generated module augmentation surfaces
|
|
530
|
+
|
|
531
|
+
It helps answer questions like:
|
|
532
|
+
|
|
533
|
+
- what is the bean full name?
|
|
534
|
+
- which page names and paths are registered?
|
|
535
|
+
- where does typed `$params` come from?
|
|
536
|
+
- which scope class represents this module?
|
|
537
|
+
|
|
538
|
+
But it is not the best first file for understanding the behavioral runtime flow.
|
|
539
|
+
|
|
540
|
+
## What `rest-resource` owns vs what downstream blocks own
|
|
541
|
+
|
|
542
|
+
This distinction is the single most useful debugging habit for this module.
|
|
543
|
+
|
|
544
|
+
### `rest-resource` mainly owns
|
|
545
|
+
|
|
546
|
+
- generic resource route surface
|
|
547
|
+
- page-shell controller layer
|
|
548
|
+
- resource-level schema/block entry surface
|
|
549
|
+
- selector-backed owner resolution
|
|
550
|
+
- reusable resource-owner model logic
|
|
551
|
+
|
|
552
|
+
### downstream generic Basic blocks mainly own
|
|
553
|
+
|
|
554
|
+
- filter/table/pager CRUD list behavior
|
|
555
|
+
- richer form-page orchestration
|
|
556
|
+
- page-title/page-dirty updates in entry scenes
|
|
557
|
+
- more complete list/query/form submit integration
|
|
558
|
+
|
|
559
|
+
When this distinction is clear, the module becomes much easier to extend without misplacing logic.
|
|
560
|
+
|
|
561
|
+
## The Zova-native explanation
|
|
562
|
+
|
|
563
|
+
The most accurate Zova-native description is:
|
|
564
|
+
|
|
565
|
+
- `rest-resource` is a **generic resource page module**
|
|
566
|
+
- `ModelResource` is a **selector-backed resource owner**
|
|
567
|
+
- `ControllerPageResource` and `ControllerPageEntry` are **schema-driven page shells**
|
|
568
|
+
- `basic-page:blockPage` and `basic-pageentry:blockPageEntry` are the **deeper reusable CRUD block runtimes**
|
|
569
|
+
|
|
570
|
+
An approximate Vue-style translation would be:
|
|
571
|
+
|
|
572
|
+
- this is not one page component with local fetch hooks
|
|
573
|
+
- it is closer to a route-driven controller shell that delegates into reusable model and block runtimes
|
|
574
|
+
|
|
575
|
+
That translation can help orientation, but the Zova meaning above is the authoritative one.
|
|
576
|
+
|
|
577
|
+
## What to read next after this page
|
|
578
|
+
|
|
579
|
+
Choose the next page by the question you actually have.
|
|
580
|
+
|
|
581
|
+
### If the next question is which files to read next
|
|
582
|
+
|
|
583
|
+
Continue with:
|
|
584
|
+
|
|
585
|
+
- [Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map)
|
|
586
|
+
|
|
587
|
+
### If the next question is how to reuse the owner in application code
|
|
588
|
+
|
|
589
|
+
Continue with:
|
|
590
|
+
|
|
591
|
+
- [Using `ModelResource` in Your Module](/frontend/model-resource-usage-guide)
|
|
592
|
+
- [Resource Model Cookbook](/frontend/model-resource-cookbook)
|
|
593
|
+
- [Resource Model Best Practices and Anti-Patterns](/frontend/model-resource-best-practices)
|
|
594
|
+
|
|
595
|
+
### If the next question is about list-page tables and resource list blocks
|
|
596
|
+
|
|
597
|
+
Continue with:
|
|
598
|
+
|
|
599
|
+
- [Table + Resource CRUD Cookbook](/frontend/table-resource-crud-cookbook)
|
|
600
|
+
- [Zova Table Under the Hood](/frontend/zova-table-under-the-hood)
|
|
601
|
+
- [Zova Table Source Reading Map](/frontend/zova-table-source-reading-map)
|
|
602
|
+
|
|
603
|
+
### If the next question is about entry pages and forms
|
|
604
|
+
|
|
605
|
+
Continue with:
|
|
606
|
+
|
|
607
|
+
- [Form Guide](/frontend/form-guide)
|
|
608
|
+
- [Zova Form Under the Hood](/frontend/zova-form-under-the-hood)
|
|
609
|
+
- [Zova Form Source Reading Map](/frontend/zova-form-source-reading-map)
|
|
610
|
+
|
|
611
|
+
## Final takeaway
|
|
612
|
+
|
|
613
|
+
The fastest accurate way to understand `rest-resource` is to stop reading it as only one reusable model file.
|
|
614
|
+
|
|
615
|
+
Read it as four cooperating layers:
|
|
616
|
+
|
|
617
|
+
1. generic resource routes
|
|
618
|
+
2. generated page wrappers
|
|
619
|
+
3. thin schema-driven page shells
|
|
620
|
+
4. one selector-backed resource owner reused by deeper CRUD block runtimes
|
|
621
|
+
|
|
622
|
+
Once those layers are clear, the module becomes much easier to debug, extend, and explain without collapsing Zova back into page-local CRUD code.
|