cabloy 5.1.59 → 5.1.61
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/references/follow-up-checklist.md +1 -0
- package/.claude/skills/cabloy-contract-loop/SKILL.md +103 -14
- package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +126 -12
- package/.claude/skills/cabloy-contract-loop/references/resource-custom-state-pattern.md +148 -0
- package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +49 -13
- package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +11 -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 +274 -0
- package/.claude/skills/cabloy-resource-field-update/evals/evals.json +53 -0
- package/.claude/skills/cabloy-resource-field-update/references/custom-renderer-demo-checklist.md +102 -0
- package/.claude/skills/cabloy-resource-field-update/references/field-update-decision-tree.md +120 -0
- package/.claude/skills/cabloy-resource-field-update/references/follow-up-checklist.md +80 -0
- package/.claude/skills/cabloy-resource-field-update/references/verification-checklist.md +97 -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/.github/workflows/docs-pages.yml +2 -0
- package/.github/workflows/vona-cov-pg.yml +2 -0
- package/.github/workflows/vona-test-crud.yml +4 -2
- package/.github/workflows/vona-test-mysql.yml +2 -0
- package/.github/workflows/vona-test-pg.yml +2 -0
- package/.github/workflows/vona-test-sqlite3.yml +2 -0
- package/.github/workflows/vona-tsc.yml +2 -0
- package/.github/workflows/zova-ui.yml +2 -0
- package/.gitignore +0 -4
- package/CHANGELOG.md +52 -0
- package/CLAUDE.md +12 -0
- package/README.md +15 -0
- package/cabloy-docs/.vitepress/config.mjs +89 -0
- package/cabloy-docs/ai/class-placement-rule.md +2 -0
- package/cabloy-docs/ai/cli-to-skill-map.md +14 -0
- package/cabloy-docs/ai/docs-skills-rules-mapping.md +14 -0
- package/cabloy-docs/ai/future-skill-roadmap.md +27 -9
- 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 +11 -0
- package/cabloy-docs/backend/bean-scene-authoring.md +350 -0
- package/cabloy-docs/backend/cli.md +26 -1
- package/cabloy-docs/backend/dto-guide.md +6 -0
- package/cabloy-docs/backend/entity-guide.md +18 -0
- package/cabloy-docs/backend/foundation.md +28 -3
- package/cabloy-docs/backend/introduction.md +10 -0
- package/cabloy-docs/backend/serialization-guide.md +10 -0
- package/cabloy-docs/backend/service-guide.md +2 -0
- package/cabloy-docs/backend/status-guide.md +271 -0
- package/cabloy-docs/backend/websocket-call-flow.md +435 -0
- package/cabloy-docs/backend/websocket-guide.md +455 -0
- package/cabloy-docs/backend/websocket-protocol-guide.md +381 -0
- package/cabloy-docs/backend/websocket-usage-guide.md +356 -0
- package/cabloy-docs/frontend/api-guide.md +2 -0
- package/cabloy-docs/frontend/bean-scene-authoring.md +374 -0
- package/cabloy-docs/frontend/behavior-guide.md +449 -0
- package/cabloy-docs/frontend/cli.md +24 -0
- package/cabloy-docs/frontend/command-scene-authoring.md +495 -0
- package/cabloy-docs/frontend/design-principles.md +6 -0
- package/cabloy-docs/frontend/fetch-interceptor-guide.md +440 -0
- package/cabloy-docs/frontend/form-guide.md +795 -0
- package/cabloy-docs/frontend/foundation.md +29 -0
- package/cabloy-docs/frontend/introduction.md +17 -1
- package/cabloy-docs/frontend/ioc-and-beans.md +16 -9
- package/cabloy-docs/frontend/mock-guide.md +1 -0
- package/cabloy-docs/frontend/model-architecture.md +252 -39
- package/cabloy-docs/frontend/model-resource-best-practices.md +379 -0
- package/cabloy-docs/frontend/model-resource-cookbook.md +505 -0
- package/cabloy-docs/frontend/model-resource-owner-pattern.md +382 -0
- package/cabloy-docs/frontend/model-resource-usage-guide.md +318 -0
- package/cabloy-docs/frontend/model-state-guide.md +366 -13
- package/cabloy-docs/frontend/openapi-sdk-guide.md +5 -2
- package/cabloy-docs/frontend/page-guide.md +6 -0
- package/cabloy-docs/frontend/quickstart.md +4 -0
- package/cabloy-docs/frontend/reading-zova-for-vue-developers.md +266 -0
- package/cabloy-docs/frontend/router-tabs-admin-web-comparison.md +206 -0
- package/cabloy-docs/frontend/router-tabs-introduction.md +106 -0
- package/cabloy-docs/frontend/router-tabs-mechanism.md +469 -0
- package/cabloy-docs/frontend/router-tabs-overview.md +227 -0
- package/cabloy-docs/frontend/router-tabs-route-meta-cookbook.md +343 -0
- package/cabloy-docs/frontend/server-data.md +2 -0
- package/cabloy-docs/frontend/ssr-architecture-overview.md +211 -0
- package/cabloy-docs/frontend/ssr-build-deploy-guide.md +308 -0
- package/cabloy-docs/frontend/ssr-review-checklist.md +184 -0
- package/cabloy-docs/frontend/ssr-troubleshooting-guide.md +301 -0
- package/cabloy-docs/frontend/zova-form-source-reading-map.md +295 -0
- package/cabloy-docs/frontend/zova-form-under-the-hood.md +556 -0
- package/cabloy-docs/frontend/zova-reactivity-under-the-hood.md +320 -0
- package/cabloy-docs/frontend/zova-source-reading-map.md +327 -0
- package/cabloy-docs/frontend/zova-vs-vue3-comparison.md +308 -0
- package/cabloy-docs/fullstack/contract-loop-playbook.md +350 -0
- package/cabloy-docs/fullstack/framework-performance.md +3 -3
- package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +44 -1
- package/cabloy-docs/fullstack/introduction.md +40 -0
- package/cabloy-docs/fullstack/openapi-to-sdk.md +19 -9
- package/cabloy-docs/fullstack/quickstart.md +7 -1
- package/cabloy-docs/fullstack/tutorial-1-first-module.md +111 -0
- package/cabloy-docs/fullstack/tutorial-2-first-crud.md +122 -0
- package/cabloy-docs/fullstack/tutorial-3-frontend-metadata-sharing.md +131 -0
- package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +144 -0
- package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +146 -0
- package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +170 -0
- package/cabloy-docs/fullstack/tutorials-overview.md +192 -0
- package/cabloy-docs/index.md +4 -3
- package/cabloy-docs/reference/bean-scene-boilerplates.md +75 -0
- package/cabloy-docs/reference/cli-reference.md +2 -0
- package/package.json +7 -2
- package/scripts/initTestData.ts +25 -0
- package/scripts/upgrade.ts +17 -2
- package/vona/packages-cli/cabloy-cli/package.json +2 -2
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli-set-api/package.json +1 -1
- package/vona/packages-cli/cli-set-api/src/lib/bean/cli.create.module.ts +4 -0
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/pnpm-lock.yaml +226 -1091
- package/vona/pnpm-workspace.yaml +0 -1
- package/vona/src/suite-vendor/a-vona/modules/a-core/assets/static/img/vona.svg +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-upload/package.json +2 -2
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/package.original.json +1 -1
- package/zova/packages-cli/cli/package.json +3 -3
- package/zova/packages-cli/cli-set-front/cli/templates/init/icon/boilerplate/icons/default/zova.svg +1 -1
- 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 +3 -3
- package/zova/packages-cli/cli-set-front/src/lib/bean/cli.create.module.ts +4 -0
- package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +34 -4
- package/zova/packages-cli/cli-set-front/src/lib/command/create.bean.ts +5 -1
- package/zova/packages-utils/zova-vite/package.json +2 -2
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +282 -1311
- package/zova/pnpm-workspace.yaml +0 -1
- package/zova/src/suite/a-home/modules/home-icon/icons/social/cabloy.svg +1 -1
- package/zova/src/suite/a-home/modules/home-icon/icons/social/vona.svg +1 -1
- package/zova/src/suite/a-home/modules/home-icon/icons/social/zova.svg +1 -1
- package/zova/src/suite/a-home/modules/home-icon/src/.metadata/icons/groups/social.svg +3 -3
- package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +9 -0
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +66 -16
- package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-routertabs/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts +60 -18
- package/zova/src/suite-vendor/a-zova/modules/a-table/cli/tableActionRow/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
- package/zova/src/suite-vendor/a-zova/modules/a-table/cli/tableCell/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
- package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/package.json +4 -4
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# Frontend Metadata Back to Backend
|
|
2
2
|
|
|
3
|
-
This page
|
|
3
|
+
This page is the **reverse chain** deep dive for Cabloy’s bidirectional contract loop: frontend-generated metadata that improves backend-side development and tooling.
|
|
4
4
|
|
|
5
5
|
## Why this path matters
|
|
6
6
|
|
|
7
7
|
The fullstack collaboration loop in Cabloy is not one-way.
|
|
8
8
|
|
|
9
|
+
In the bidirectional [Contract Loop Playbook](/fullstack/contract-loop-playbook), this page covers the **reverse chain**.
|
|
10
|
+
|
|
9
11
|
For the forward contract-bridge direction from backend OpenAPI to frontend consumption, also see [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk).
|
|
10
12
|
|
|
11
13
|
The backend does not only feed the frontend through OpenAPI. The frontend also generates information that can improve backend-side type hints and integration confidence.
|
|
@@ -44,6 +46,8 @@ A practical collaboration loop often looks like this:
|
|
|
44
46
|
|
|
45
47
|
## Edition awareness
|
|
46
48
|
|
|
49
|
+
The reverse-chain mental model applies to both Cabloy Basic and Cabloy Start.
|
|
50
|
+
|
|
47
51
|
This path is especially sensitive to edition differences because Basic and Start do not expose the same frontend module and UI shape.
|
|
48
52
|
|
|
49
53
|
So when AI reasons about frontend-generated metadata, it should verify:
|
|
@@ -51,6 +55,7 @@ So when AI reasons about frontend-generated metadata, it should verify:
|
|
|
51
55
|
- which repo is active
|
|
52
56
|
- which flavor is active
|
|
53
57
|
- which generated output belongs to that edition
|
|
58
|
+
- which concrete build and sync commands belong to that edition
|
|
54
59
|
|
|
55
60
|
## Implementation checks for frontend-metadata changes
|
|
56
61
|
|
|
@@ -62,3 +67,41 @@ When changing frontend structural resources such as routes or components, ask:
|
|
|
62
67
|
4. should the next action be generation and verification rather than only source edits?
|
|
63
68
|
|
|
64
69
|
That keeps the reverse contract loop visible instead of accidental.
|
|
70
|
+
|
|
71
|
+
## When backend consumes newly added frontend resources
|
|
72
|
+
|
|
73
|
+
This reverse handoff matters most when you create or change frontend resources that backend-side workflows will later consume, such as:
|
|
74
|
+
|
|
75
|
+
- custom form-field renderers
|
|
76
|
+
- custom table-cell renderers
|
|
77
|
+
- other generated frontend metadata that backend `ZovaRender.*(...)` references depend on
|
|
78
|
+
|
|
79
|
+
In that case, do not stop after source edits alone. Use this representative sequence:
|
|
80
|
+
|
|
81
|
+
1. regenerate frontend metadata when applicable
|
|
82
|
+
2. build the relevant frontend flavor output so the shared REST/type surface is refreshed
|
|
83
|
+
3. run `npm run deps:vona` so Vona re-syncs its local file dependencies
|
|
84
|
+
4. if generated `.zova-rest` output already contains the expected new keys or types but backend-side consumers still look stale, rebuild `vona/node_modules` and reinstall dependencies
|
|
85
|
+
|
|
86
|
+
For the current Cabloy Basic admin flow, the representative commands are:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npm run zova :tools:metadata <module-name>
|
|
90
|
+
npm run build:zova:admin
|
|
91
|
+
npm run deps:vona
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If the same resource path must also be available for Web, add:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npm run build:zova:web
|
|
98
|
+
npm run deps:vona
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
If Vona still cannot see the refreshed shared types after the normal sync flow, use this recovery path:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
cd vona && rm -rf node_modules && pnpm install
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The key rule is simple: if frontend-generated resources are later consumed by backend tooling or backend metadata, treat the work as a reverse fullstack handoff, not as frontend-only cleanup.
|
|
@@ -62,6 +62,46 @@ Use this path when the task depends on edition boundaries, UI assumptions, or cr
|
|
|
62
62
|
|
|
63
63
|
This combination keeps backend and frontend development close enough for code sharing, workflow reuse, and AI vibe coding workflows.
|
|
64
64
|
|
|
65
|
+
## Cabloy fullstack framework principles
|
|
66
|
+
|
|
67
|
+
Cabloy’s fullstack model can be understood through two core principles.
|
|
68
|
+
|
|
69
|
+
### 1. Frontend build output participates directly in backend SSR
|
|
70
|
+
|
|
71
|
+
Zova owns the frontend application, but its build output is not treated as a completely separate artifact that the backend ignores.
|
|
72
|
+
|
|
73
|
+
In Cabloy’s fullstack flow:
|
|
74
|
+
|
|
75
|
+
- the frontend is built from Zova source
|
|
76
|
+
- the generated bundle and related SSR output are consumed by the Vona-side SSR runtime
|
|
77
|
+
- backend rendering and frontend hydration stay in one coordinated SSR path rather than two unrelated systems
|
|
78
|
+
|
|
79
|
+
In earlier standalone-repo explanations, this was often described as placing the frontend bundle into the backend for direct SSR rendering. In the current monorepo, the important principle stays the same while the workflow is cleaner: shared scripts and integrated repository structure let frontend build artifacts flow into the backend-side SSR process.
|
|
80
|
+
|
|
81
|
+
For the integration workflow and current monorepo shape, see [Vona + Zova Integration](/fullstack/vona-zova-integration) and [SSR Overview](/frontend/ssr-overview).
|
|
82
|
+
|
|
83
|
+
### 2. Type information flows in both directions
|
|
84
|
+
|
|
85
|
+
Cabloy does not treat type sharing as backend-to-frontend only. The collaboration loop is bidirectional:
|
|
86
|
+
|
|
87
|
+
- **Backend → Frontend**: Vona emits Swagger/OpenAPI contracts that Zova uses to generate frontend SDKs and related schema-aware helpers
|
|
88
|
+
- **Frontend → Backend**: Zova generates structural metadata and types such as routes, components, and icons, which can be reflected back into backend-side tooling and type hints
|
|
89
|
+
|
|
90
|
+
This two-way contract loop reduces duplicate declarations and lets backend and frontend evolve from generated source truth instead of hand-maintained memory.
|
|
91
|
+
|
|
92
|
+
Start with the canonical [Contract Loop Playbook](/fullstack/contract-loop-playbook), then use the directional deep dives [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk) and [Frontend Metadata Back to Backend](/fullstack/frontend-metadata-to-backend).
|
|
93
|
+
|
|
94
|
+
Use the playbook to distinguish four cases clearly:
|
|
95
|
+
|
|
96
|
+
- forward chain
|
|
97
|
+
- reverse chain
|
|
98
|
+
- consumer drift
|
|
99
|
+
- local dependency drift
|
|
100
|
+
|
|
101
|
+
The contract-loop model is shared across Cabloy Basic and Cabloy Start. Detect the edition to choose concrete flavor commands and generated-output paths, not to redefine the workflow model.
|
|
102
|
+
|
|
103
|
+
When the reverse direction involves newly added frontend resources that backend tooling or backend metadata will consume, treat that as an operational handoff rather than a conceptual one: refresh generated frontend output, run the relevant flavor build, run `npm run deps:vona`, and if Vona still sees stale shared types, rebuild `vona/node_modules` and reinstall dependencies.
|
|
104
|
+
|
|
65
105
|
## How the fullstack system stays connected
|
|
66
106
|
|
|
67
107
|
At the repository level, shared scripts, shared terminology, and CLI-first workflows keep Vona and Zova aligned as one framework system.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Backend OpenAPI to Frontend SDK
|
|
2
2
|
|
|
3
|
-
This page
|
|
3
|
+
This page is the **forward chain** deep dive for Cabloy’s bidirectional contract loop.
|
|
4
4
|
|
|
5
5
|
## Why this path matters
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
In the bidirectional [Contract Loop Playbook](/fullstack/contract-loop-playbook), this page covers the **forward chain**:
|
|
8
8
|
|
|
9
9
|
1. Vona emits backend API metadata through Swagger/OpenAPI
|
|
10
10
|
2. Zova consumes that metadata to generate frontend SDKs and schema-aware helpers
|
|
@@ -12,7 +12,7 @@ Cabloy’s fullstack productivity depends heavily on a contract loop:
|
|
|
12
12
|
|
|
13
13
|
This is one of the strongest AI-leverage paths in the repo because it reduces duplicated type work and keeps backend/frontend coordination closer to source truth.
|
|
14
14
|
|
|
15
|
-
## The
|
|
15
|
+
## The forward chain in practical terms
|
|
16
16
|
|
|
17
17
|
A useful split is:
|
|
18
18
|
|
|
@@ -20,7 +20,9 @@ A useful split is:
|
|
|
20
20
|
- fullstack docs define the bridge from emitted contract to generated SDK
|
|
21
21
|
- frontend docs define the consumption side of the generated contract
|
|
22
22
|
|
|
23
|
-
That means this page is the
|
|
23
|
+
That means this page is the forward-chain bridge page, not the backend authoring page and not the frontend usage page.
|
|
24
|
+
|
|
25
|
+
If the changed source is actually a frontend-owned resource that backend consumers later depend on, switch to the reverse-chain guide: [Frontend Metadata Back to Backend](/fullstack/frontend-metadata-to-backend).
|
|
24
26
|
|
|
25
27
|
## Backend side: Vona emits the contract
|
|
26
28
|
|
|
@@ -70,23 +72,31 @@ cd zova && npm run build:rest:cabloyBasicAdmin
|
|
|
70
72
|
cd zova && npm run build:rest:cabloyBasicWeb
|
|
71
73
|
```
|
|
72
74
|
|
|
73
|
-
A practical
|
|
75
|
+
A practical forward-chain sequence is:
|
|
74
76
|
|
|
75
77
|
1. author or change the backend contract
|
|
76
78
|
2. emit or inspect backend OpenAPI output
|
|
77
|
-
3.
|
|
78
|
-
4.
|
|
79
|
-
5.
|
|
80
|
-
6.
|
|
79
|
+
3. if the frontend generator reads from a local Swagger endpoint, start the backend service first so the endpoint is reachable — in this repo, `npm run dev` is the normal path and exposes Swagger at `http://localhost:7102/swagger/json?version=V31`
|
|
80
|
+
4. configure frontend module ownership if needed
|
|
81
|
+
5. generate module-level OpenAPI SDK output
|
|
82
|
+
6. run the rest build for the active flavor when needed
|
|
83
|
+
7. consume the generated contract from frontend code instead of re-declaring it manually
|
|
84
|
+
8. keep frontend follow-up thin by wrapping generated consumers with semantic facades instead of re-declaring the contract
|
|
85
|
+
9. when the custom API still belongs to an existing resource, reuse the existing resource-owner instead of creating a competing cache owner
|
|
81
86
|
|
|
82
87
|
A practical responsibility split is:
|
|
83
88
|
|
|
84
89
|
- project-level OpenAPI config decides where the backend Swagger/OpenAPI source comes from
|
|
85
90
|
- module-level OpenAPI config decides which generated contract slice belongs to which frontend module
|
|
91
|
+
- module-level ownership should be declared explicitly with `operations.match` or `operations.ignore`
|
|
92
|
+
|
|
93
|
+
If both `operations.match` and `operations.ignore` are empty, frontend SDK generation should fail fast instead of generating a large unrelated contract surface for the module. That fail-fast behavior helps both developers and AI agents notice the missing ownership boundary immediately and repair the config before the wrong SDK slice is generated.
|
|
86
94
|
|
|
87
95
|
A practical regeneration rule is:
|
|
88
96
|
|
|
89
97
|
- if the backend contract changed, prefer regenerating the SDK/rest layer before hand-editing frontend request code
|
|
98
|
+
- if `npm run zova :openapi:generate ...` fails because the local Swagger source is unavailable, first start the backend service and confirm `http://localhost:7102/swagger/json?version=V31` is reachable before treating generation as broken
|
|
99
|
+
- if the generated consumer path is already correct, but frontend behavior still looks stale, stop patching generated files and diagnose consumer drift or local dependency drift instead
|
|
90
100
|
|
|
91
101
|
## Cabloy Start workflow
|
|
92
102
|
|
|
@@ -92,7 +92,13 @@ npm run zova :create
|
|
|
92
92
|
|
|
93
93
|
Then narrow into the specific command family you need.
|
|
94
94
|
|
|
95
|
-
## 8.
|
|
95
|
+
## 8. Next step: follow the quick start tutorials
|
|
96
|
+
|
|
97
|
+
If you want a beginner-friendly path that connects modules, CRUD, bidirectional contract sharing, and schema-driven workflows into one story, continue with:
|
|
98
|
+
|
|
99
|
+
- [Fullstack Quick Start Tutorials](/fullstack/tutorials-overview)
|
|
100
|
+
|
|
101
|
+
## 9. Shared verification commands for deeper workflow checks
|
|
96
102
|
|
|
97
103
|
If you are validating framework-aware changes or a broader workflow, use the shared project scripts before declaring a workflow correct:
|
|
98
104
|
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Tutorial 1: Create Your First Module
|
|
2
|
+
|
|
3
|
+
<Badge type="info" text="Basic" />
|
|
4
|
+
|
|
5
|
+
In this tutorial, one prompt lets AI create the first backend and frontend module skeleton for the **Student Training Center** story through a CLI-first workflow.
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
By the end of this tutorial, you will understand:
|
|
10
|
+
|
|
11
|
+
- when to use Vona and when to use Zova
|
|
12
|
+
- how to inspect the CLI before creating files
|
|
13
|
+
- how a Cabloy business capability starts as a module on both sides of the stack
|
|
14
|
+
|
|
15
|
+
## AI Prompt
|
|
16
|
+
|
|
17
|
+
Give AI a prompt like this:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
I'm building a Student Training Center project. Please create a demo-student module for both the backend and frontend.
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Why this step matters
|
|
24
|
+
|
|
25
|
+
This is the right first step because Cabloy treats the module as the unit that owns business code, metadata, generated assets, and docs.
|
|
26
|
+
|
|
27
|
+
If AI jumps directly into CRUD, contracts, or rendering before the module boundary exists, the work loses its natural owner. This step keeps the rest of the Student Training Center story aligned from the start.
|
|
28
|
+
|
|
29
|
+
## CLI commands to inspect/use
|
|
30
|
+
|
|
31
|
+
Work from the repo root, not from `vona/` or `zova/` directly.
|
|
32
|
+
|
|
33
|
+
Inspect the CLI surface first:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm run vona :
|
|
37
|
+
npm run zova :
|
|
38
|
+
|
|
39
|
+
npm run vona :create
|
|
40
|
+
npm run zova :create
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Representative module-generation commands:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm run vona :create:module demo-student -- --suite=
|
|
47
|
+
npm run zova :create:module demo-student -- --suite=
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Usage notes:
|
|
51
|
+
|
|
52
|
+
- use `npm run vona :create:module` for the backend module boundary
|
|
53
|
+
- use `npm run zova :create:module` for the frontend module boundary
|
|
54
|
+
- use an empty `--suite=` when you want an independent module rather than a suite-owned module
|
|
55
|
+
- rerun `npm run dev` after module creation so the local workflow picks up the new modules cleanly
|
|
56
|
+
|
|
57
|
+
## Generated or affected files
|
|
58
|
+
|
|
59
|
+
After both generators run, inspect the generated module roots before editing anything else.
|
|
60
|
+
|
|
61
|
+
Typical paths in this repo are:
|
|
62
|
+
|
|
63
|
+
- backend module root: `vona/src/module/<module>/`
|
|
64
|
+
- frontend module root without suite placement: `zova/src/module/<module>/`
|
|
65
|
+
- frontend module root with suite placement: `zova/src/suite/<suite>/modules/<module>/`
|
|
66
|
+
|
|
67
|
+
In this series, the target module roots are:
|
|
68
|
+
|
|
69
|
+
- `vona/src/module/demo-student/`
|
|
70
|
+
- `zova/src/module/demo-student/`
|
|
71
|
+
|
|
72
|
+
A minimal frontend module usually starts with files like:
|
|
73
|
+
|
|
74
|
+
- `zova/src/module/demo-student/package.json`
|
|
75
|
+
- `zova/src/module/demo-student/src/index.ts`
|
|
76
|
+
- `zova/src/module/demo-student/src/.metadata/index.ts`
|
|
77
|
+
|
|
78
|
+
## What those files mean in the business thread
|
|
79
|
+
|
|
80
|
+
At this stage, the key idea is ownership, not business logic yet.
|
|
81
|
+
|
|
82
|
+
- the backend module root is where the Student resource, entity, DTOs, controller, tests, and backend metadata will live later
|
|
83
|
+
- the frontend module root is where generated OpenAPI output, model helpers, render resources, and frontend metadata will live later
|
|
84
|
+
- the frontend `.metadata` entrypoint is part of how the module exposes its local registration surface
|
|
85
|
+
|
|
86
|
+
A good beginner rule is: do not rush into editing business logic until you can explain which module roots were created and why they will own the next tutorials.
|
|
87
|
+
|
|
88
|
+
## Verification
|
|
89
|
+
|
|
90
|
+
1. make sure the local dev workflow is running:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npm run dev
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
2. confirm that both module roots now exist
|
|
97
|
+
3. inspect the generated files before editing them
|
|
98
|
+
4. confirm that the generated module roots match the target paths for this series:
|
|
99
|
+
- `vona/src/module/demo-student/`
|
|
100
|
+
- `zova/src/module/demo-student/`
|
|
101
|
+
|
|
102
|
+
## Read more
|
|
103
|
+
|
|
104
|
+
- [Fullstack CLI](/fullstack/cli)
|
|
105
|
+
- [CLI Reference](/reference/cli-reference)
|
|
106
|
+
- [Backend Quickstart](/backend/quickstart)
|
|
107
|
+
- [Frontend Quickstart](/frontend/quickstart)
|
|
108
|
+
|
|
109
|
+
## Next step
|
|
110
|
+
|
|
111
|
+
Continue to [Tutorial 2: Create Your First CRUD](/fullstack/tutorial-2-first-crud).
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Tutorial 2: Create Your First CRUD
|
|
2
|
+
|
|
3
|
+
<Badge type="info" text="Basic" />
|
|
4
|
+
|
|
5
|
+
In this tutorial, one prompt lets AI turn the new module into its first real business thread by generating a `student` CRUD workflow.
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
By the end of this tutorial, you will understand:
|
|
10
|
+
|
|
11
|
+
- why Cabloy prefers CRUD generation over hand-written boilerplate
|
|
12
|
+
- what the generated backend thread usually includes
|
|
13
|
+
- how the generated entity and DTO surface becomes the contract foundation for later tutorials
|
|
14
|
+
- why this step does not generate any frontend code, but already gives you a complete CRUD admin page through Cabloy’s existing schema-driven surface
|
|
15
|
+
|
|
16
|
+
## AI Prompt
|
|
17
|
+
|
|
18
|
+
Give AI a prompt like this:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
Please generate the first CRUD flow for the Student resource.
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Why this step matters
|
|
25
|
+
|
|
26
|
+
Once the module exists, this is the next useful step because the prompt can drive the CRUD generator instead of hand-building controller, service, model, entity, DTO, metadata, locale, and tests one by one.
|
|
27
|
+
|
|
28
|
+
That keeps the conversation focused on the generated business thread rather than on repetitive scaffolding details.
|
|
29
|
+
|
|
30
|
+
## CLI commands to inspect/use
|
|
31
|
+
|
|
32
|
+
Inspect the CRUD family first:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm run vona :tools
|
|
36
|
+
npm run vona :tools:crud --help
|
|
37
|
+
npm run vona :tools:crudBasic --help
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Generate the `student` CRUD thread:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm run vona :tools:crud student -- --module=demo-student
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Equivalent Basic-specific entrypoint:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm run vona :tools:crudBasic student -- --module=demo-student
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Usage notes:
|
|
53
|
+
|
|
54
|
+
- `:tools:crud` is the public entrypoint beginners should prefer
|
|
55
|
+
- `:tools:crudBasic` is useful when you want to inspect the Basic-specific underlying path directly
|
|
56
|
+
- after generation, verify the result from the admin UI instead of stopping at file inspection
|
|
57
|
+
|
|
58
|
+
## Generated or affected files
|
|
59
|
+
|
|
60
|
+
After generation, inspect the resulting backend thread before refining anything.
|
|
61
|
+
|
|
62
|
+
By the end of this tutorial, your `demo-student` backend thread should have a representative shape under `vona/src/module/demo-student/src/`:
|
|
63
|
+
|
|
64
|
+
- `controller/student.ts`
|
|
65
|
+
- `service/student.ts`
|
|
66
|
+
- `model/student.ts`
|
|
67
|
+
- `entity/student.tsx`
|
|
68
|
+
- `dto/studentCreate.tsx`
|
|
69
|
+
- `dto/studentUpdate.tsx`
|
|
70
|
+
- `dto/studentView.tsx`
|
|
71
|
+
- `dto/studentSelectReq.tsx`
|
|
72
|
+
- `dto/studentSelectRes.tsx`
|
|
73
|
+
- `dto/studentSelectResItem.tsx`
|
|
74
|
+
- `bean/meta.version.ts`
|
|
75
|
+
|
|
76
|
+
There is also a test anchor at:
|
|
77
|
+
|
|
78
|
+
- `vona/src/module/demo-student/test/student.test.ts`
|
|
79
|
+
|
|
80
|
+
## What those files mean in the business thread
|
|
81
|
+
|
|
82
|
+
As you inspect the generated files, pay attention to the division of responsibility:
|
|
83
|
+
|
|
84
|
+
1. `controller/student.ts` exposes the HTTP contract
|
|
85
|
+
2. `service/student.ts` owns orchestration
|
|
86
|
+
3. `model/student.ts` owns persistence behavior
|
|
87
|
+
4. `entity/student.tsx` defines the field-oriented contract surface
|
|
88
|
+
5. the DTO files define operation-specific request and response contracts
|
|
89
|
+
6. `bean/meta.version.ts` anchors the module schema/version thread
|
|
90
|
+
7. `test/student.test.ts` gives you a verification anchor for the generated backend flow
|
|
91
|
+
|
|
92
|
+
This is the backend contract thread that later tutorials will extend with `level`, `mobile`, render metadata, OpenAPI output, and row actions.
|
|
93
|
+
|
|
94
|
+
## Verification
|
|
95
|
+
|
|
96
|
+
1. make sure the local dev workflow is running:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npm run dev
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
2. open `http://localhost:7102/admin/`
|
|
103
|
+
3. enter the **Student** list page from the **Student** menu
|
|
104
|
+
4. trigger create, read, update, and delete operations from the page
|
|
105
|
+
5. inspect the generated backend files and confirm that the CRUD layers are present:
|
|
106
|
+
- `vona/src/module/demo-student/src/entity/student.tsx`
|
|
107
|
+
- `vona/src/module/demo-student/src/controller/student.ts`
|
|
108
|
+
- `vona/src/module/demo-student/src/dto/studentSelectResItem.tsx`
|
|
109
|
+
|
|
110
|
+
## Read more
|
|
111
|
+
|
|
112
|
+
- [CRUD Workflow](/backend/crud-workflow)
|
|
113
|
+
- [Controller Guide](/backend/controller-guide)
|
|
114
|
+
- [Service Guide](/backend/service-guide)
|
|
115
|
+
- [Model Guide](/backend/model-guide)
|
|
116
|
+
- [Entity Guide](/backend/entity-guide)
|
|
117
|
+
- [DTO Guide](/backend/dto-guide)
|
|
118
|
+
- [Validation Guide](/backend/validation-guide)
|
|
119
|
+
|
|
120
|
+
## Next step
|
|
121
|
+
|
|
122
|
+
Continue to [Tutorial 3: Frontend Metadata Sharing](/fullstack/tutorial-3-frontend-metadata-sharing).
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Tutorial 3: Frontend Metadata Sharing
|
|
2
|
+
|
|
3
|
+
<Badge type="info" text="Basic" />
|
|
4
|
+
|
|
5
|
+
In this tutorial, one prompt lets AI show the **reverse chain** of Cabloy’s fullstack contract loop: backend field metadata can reference frontend render resources.
|
|
6
|
+
|
|
7
|
+
You start with the simplest path first: reuse the existing built-in rendering resources for the `level` field.
|
|
8
|
+
|
|
9
|
+
## Goal
|
|
10
|
+
|
|
11
|
+
By the end of this tutorial, you will understand:
|
|
12
|
+
|
|
13
|
+
- why Cabloy fullstack sharing is bidirectional
|
|
14
|
+
- how a backend field can reuse frontend rendering resources through metadata
|
|
15
|
+
- how one `level` field can participate in schema-driven form and table behavior without a custom component yet
|
|
16
|
+
|
|
17
|
+
## AI Prompt
|
|
18
|
+
|
|
19
|
+
Give AI a prompt like this:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
Please add a level field to the Student resource. It should be a required number field with these enum values:
|
|
23
|
+
|
|
24
|
+
- 1: beginner
|
|
25
|
+
- 2: intermediate
|
|
26
|
+
- 3: advanced
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Why this step matters
|
|
30
|
+
|
|
31
|
+
This is the right step because it teaches one very specific Cabloy distinction.
|
|
32
|
+
|
|
33
|
+
The goal is not to make backend and frontend share arbitrary component code. The goal is to keep the backend field contract in charge while letting that contract reference frontend render resources through metadata.
|
|
34
|
+
|
|
35
|
+
In other words, this step is about **frontend metadata sharing**: the backend field contract references frontend render resources through metadata.
|
|
36
|
+
|
|
37
|
+
## CLI commands to inspect/use
|
|
38
|
+
|
|
39
|
+
This tutorial is mainly a contract-refinement step, so the most important habit is inspection before editing.
|
|
40
|
+
|
|
41
|
+
Useful discovery commands from the repo root:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npm run vona :
|
|
45
|
+
npm run zova :
|
|
46
|
+
npm run zova :create
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
You usually do **not** need to generate a custom bean in this tutorial.
|
|
50
|
+
|
|
51
|
+
Instead, inspect the current contract surfaces first:
|
|
52
|
+
|
|
53
|
+
- `vona/src/module/demo-student/src/entity/student.tsx`
|
|
54
|
+
- `vona/src/module/demo-student/src/dto/studentSelectReq.tsx`
|
|
55
|
+
|
|
56
|
+
Usage notes:
|
|
57
|
+
|
|
58
|
+
- keep the backend entity as the main source of truth for the `level` field
|
|
59
|
+
- prefer built-in frontend render resources first
|
|
60
|
+
- delay custom renderer authoring to the next tutorial
|
|
61
|
+
|
|
62
|
+
## Generated or affected files
|
|
63
|
+
|
|
64
|
+
The key backend contract anchor is:
|
|
65
|
+
|
|
66
|
+
- `vona/src/module/demo-student/src/entity/student.tsx`
|
|
67
|
+
|
|
68
|
+
By the end of this tutorial, the `level` field should follow a built-in path like this:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
@Api.field(
|
|
72
|
+
v.title($locale('Level')),
|
|
73
|
+
v.required(),
|
|
74
|
+
ZovaRender.order(3),
|
|
75
|
+
ZovaRender.field('basic-select:formFieldSelect', {
|
|
76
|
+
items: levelItems,
|
|
77
|
+
placeholder: $locale('LevelPlaceholder'),
|
|
78
|
+
}),
|
|
79
|
+
ZovaRender.cell('basic-select:select', { items: levelItems }),
|
|
80
|
+
levelSchema,
|
|
81
|
+
)
|
|
82
|
+
level: number;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
A related DTO anchor is:
|
|
86
|
+
|
|
87
|
+
- `vona/src/module/demo-student/src/dto/studentSelectReq.tsx`
|
|
88
|
+
|
|
89
|
+
That DTO already shows how filter-side field metadata can also participate in schema-driven UI.
|
|
90
|
+
|
|
91
|
+
## What those files mean in the business thread
|
|
92
|
+
|
|
93
|
+
This tutorial teaches one core mental model:
|
|
94
|
+
|
|
95
|
+
- the backend still owns the business field contract
|
|
96
|
+
- the frontend still owns the render resources
|
|
97
|
+
- metadata is the bridge between them
|
|
98
|
+
|
|
99
|
+
Concretely:
|
|
100
|
+
|
|
101
|
+
- `entity/student.tsx` defines `level` as a real business field
|
|
102
|
+
- `levelItems` gives that field a stable set of business options
|
|
103
|
+
- `ZovaRender.field('basic-select:formFieldSelect', ...)` makes the form side schema-aware
|
|
104
|
+
- `ZovaRender.cell('basic-select:select', ...)` makes the table side schema-aware
|
|
105
|
+
- `dto/studentSelectReq.tsx` reminds you that filter-side metadata is also part of the same contract story
|
|
106
|
+
|
|
107
|
+
At this stage, you do not need a custom frontend component to understand the reverse-sharing model.
|
|
108
|
+
|
|
109
|
+
## Verification
|
|
110
|
+
|
|
111
|
+
1. make sure the local dev workflow is running:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npm run dev
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
2. open `http://localhost:7102/admin/`
|
|
118
|
+
3. enter the **Student** list page from the **Student** menu
|
|
119
|
+
4. verify that the `level` field appears with select-style behavior in the relevant schema-driven surfaces
|
|
120
|
+
5. inspect `vona/src/module/demo-student/src/entity/student.tsx` and confirm that the backend field contract now points to built-in frontend render resources instead of page-local hard-coded UI logic
|
|
121
|
+
|
|
122
|
+
## Read more
|
|
123
|
+
|
|
124
|
+
- [Frontend Metadata Back to Backend](/fullstack/frontend-metadata-to-backend)
|
|
125
|
+
- [API Schema Guide](/frontend/api-schema-guide)
|
|
126
|
+
- [Server Data](/frontend/server-data)
|
|
127
|
+
- [Frontend CLI](/frontend/cli)
|
|
128
|
+
|
|
129
|
+
## Next step
|
|
130
|
+
|
|
131
|
+
Continue to [Tutorial 4: Custom Form/Table Renderers for Level](/fullstack/tutorial-4-custom-level-renderers).
|