cabloy 5.1.60 → 5.1.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/hooks/contract-loop-gate.ts +296 -0
- package/.claude/settings.json +16 -0
- package/.claude/skills/cabloy-backend-scaffold/SKILL.md +2 -0
- package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -0
- package/.claude/skills/cabloy-contract-loop/SKILL.md +89 -16
- package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +102 -14
- package/.claude/skills/cabloy-contract-loop/references/resource-custom-state-pattern.md +4 -0
- package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +32 -14
- package/.claude/skills/cabloy-domain-planning/SKILL.md +212 -0
- package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +13 -0
- package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +2 -0
- package/.claude/skills/cabloy-module-removal/SKILL.md +144 -0
- package/.claude/skills/cabloy-resource-field-update/SKILL.md +7 -0
- package/.claude/skills/cabloy-zova-source-reading/SKILL.md +221 -0
- package/.claude/skills/cabloy-zova-source-reading/references/analysis-modes.md +91 -0
- package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +117 -0
- package/CHANGELOG.md +64 -0
- package/CLAUDE.md +11 -0
- package/cabloy-docs/.vitepress/config.mjs +197 -5
- package/cabloy-docs/ai/cli-to-skill-map.md +7 -0
- package/cabloy-docs/ai/docs-skills-rules-mapping.md +22 -0
- package/cabloy-docs/ai/future-skill-roadmap.md +12 -7
- package/cabloy-docs/ai/introduction.md +1 -0
- package/cabloy-docs/ai/playbook-backend-module.md +6 -0
- package/cabloy-docs/ai/playbook-module-removal.md +164 -0
- package/cabloy-docs/ai/skills.md +12 -0
- package/cabloy-docs/backend/backend-contract-emission-output-inspection.md +189 -0
- package/cabloy-docs/backend/backend-contract-emission-source-reading-map.md +160 -0
- package/cabloy-docs/backend/backend-contract-emission-specimen.md +170 -0
- package/cabloy-docs/backend/backend-resource-module-contract-chain.md +323 -0
- package/cabloy-docs/backend/backend-source-reading-debug-checklist.md +173 -0
- package/cabloy-docs/backend/backend-source-reading-roadmap.md +129 -0
- package/cabloy-docs/backend/backend-source-reading-verify-playbook.md +166 -0
- package/cabloy-docs/backend/bean-scene-authoring.md +4 -4
- package/cabloy-docs/backend/broadcast-guide.md +3 -3
- package/cabloy-docs/backend/cli.md +20 -11
- package/cabloy-docs/backend/config-guide.md +4 -4
- package/cabloy-docs/backend/controller-aop-guide.md +10 -10
- package/cabloy-docs/backend/controller-guide.md +12 -2
- package/cabloy-docs/backend/crud-workflow.md +7 -3
- package/cabloy-docs/backend/dto-guide.md +18 -2
- package/cabloy-docs/backend/dto-infer-generation.md +201 -25
- package/cabloy-docs/backend/election-guide.md +2 -2
- package/cabloy-docs/backend/entity-guide.md +30 -3
- package/cabloy-docs/backend/error-guide.md +3 -3
- package/cabloy-docs/backend/event-guide.md +4 -4
- package/cabloy-docs/backend/external-aop-guide.md +2 -2
- package/cabloy-docs/backend/field-indexes.md +9 -3
- package/cabloy-docs/backend/foundation.md +8 -8
- package/cabloy-docs/backend/i18n-guide.md +6 -6
- package/cabloy-docs/backend/internal-aop-guide.md +2 -2
- package/cabloy-docs/backend/introduction.md +15 -0
- package/cabloy-docs/backend/migration-and-changes.md +3 -3
- package/cabloy-docs/backend/model-guide.md +16 -6
- package/cabloy-docs/backend/openapi-guide.md +3 -0
- package/cabloy-docs/backend/queue-guide.md +3 -3
- package/cabloy-docs/backend/redlock-guide.md +2 -2
- package/cabloy-docs/backend/schedule-guide.md +2 -2
- package/cabloy-docs/backend/scripts.md +8 -0
- package/cabloy-docs/backend/serialization-guide.md +12 -2
- package/cabloy-docs/backend/service-guide.md +18 -9
- package/cabloy-docs/backend/startup-guide.md +5 -5
- package/cabloy-docs/backend/status-guide.md +271 -0
- package/cabloy-docs/backend/unit-testing.md +3 -3
- package/cabloy-docs/backend/vona-source-reading-map.md +157 -0
- package/cabloy-docs/backend/websocket-protocol-guide.md +5 -5
- package/cabloy-docs/backend/websocket-usage-guide.md +15 -8
- package/cabloy-docs/frontend/a-model-under-the-hood.md +281 -0
- package/cabloy-docs/frontend/a-openapi-under-the-hood.md +248 -0
- package/cabloy-docs/frontend/a-router-guide.md +307 -0
- package/cabloy-docs/frontend/api-guide.md +6 -4
- package/cabloy-docs/frontend/api-schema-guide.md +1 -0
- package/cabloy-docs/frontend/app-startup-guide.md +7 -4
- package/cabloy-docs/frontend/bean-scene-authoring.md +3 -1
- package/cabloy-docs/frontend/behavior-guide.md +16 -16
- package/cabloy-docs/frontend/cli.md +14 -2
- package/cabloy-docs/frontend/command-scene-authoring.md +504 -0
- package/cabloy-docs/frontend/component-guide.md +5 -5
- package/cabloy-docs/frontend/component-props-guide.md +1 -1
- package/cabloy-docs/frontend/component-v-model-guide.md +2 -2
- package/cabloy-docs/frontend/design-principles.md +6 -0
- package/cabloy-docs/frontend/fetch-interceptor-guide.md +440 -0
- package/cabloy-docs/frontend/filter-query-select-data-flow-guide.md +260 -0
- package/cabloy-docs/frontend/form-guide.md +786 -0
- package/cabloy-docs/frontend/form-scene-to-page-meta-guide.md +303 -0
- package/cabloy-docs/frontend/foundation.md +33 -0
- package/cabloy-docs/frontend/frontend-source-reading-roadmap.md +249 -0
- package/cabloy-docs/frontend/generated-contract-consumption-debug-checklist.md +190 -0
- package/cabloy-docs/frontend/generated-contract-consumption-entry-branch.md +205 -0
- package/cabloy-docs/frontend/generated-contract-consumption-list-branch.md +157 -0
- package/cabloy-docs/frontend/generated-contract-consumption-specimen.md +203 -0
- package/cabloy-docs/frontend/generated-contract-consumption-verify-playbook.md +189 -0
- package/cabloy-docs/frontend/generic-component-guide.md +1 -1
- package/cabloy-docs/frontend/introduction.md +38 -5
- package/cabloy-docs/frontend/ioc-and-beans.md +6 -0
- package/cabloy-docs/frontend/mock-guide.md +1 -0
- package/cabloy-docs/frontend/model-architecture.md +288 -39
- package/cabloy-docs/frontend/model-resource-best-practices.md +379 -0
- package/cabloy-docs/frontend/model-resource-cookbook.md +508 -0
- package/cabloy-docs/frontend/model-resource-internals-deep-dive.md +238 -0
- package/cabloy-docs/frontend/model-resource-owner-pattern.md +402 -0
- package/cabloy-docs/frontend/model-resource-usage-guide.md +334 -0
- package/cabloy-docs/frontend/model-state-guide.md +371 -15
- package/cabloy-docs/frontend/module-scope.md +8 -8
- package/cabloy-docs/frontend/modules-and-suites.md +2 -1
- package/cabloy-docs/frontend/navigation-guards-guide.md +7 -0
- package/cabloy-docs/frontend/openapi-sdk-guide.md +17 -6
- package/cabloy-docs/frontend/page-guide.md +15 -9
- package/cabloy-docs/frontend/page-meta-guide.md +466 -0
- package/cabloy-docs/frontend/page-params-guide.md +3 -3
- package/cabloy-docs/frontend/page-query-guide.md +2 -2
- package/cabloy-docs/frontend/page-route-guide.md +6 -0
- package/cabloy-docs/frontend/permission-formscene-action-visibility-guide.md +263 -0
- package/cabloy-docs/frontend/quickstart.md +18 -2
- package/cabloy-docs/frontend/reading-zova-for-vue-developers.md +266 -0
- package/cabloy-docs/frontend/resource-entry-page-deep-dive.md +271 -0
- package/cabloy-docs/frontend/resource-list-page-deep-dive.md +279 -0
- package/cabloy-docs/frontend/rest-resource-source-reading-map.md +522 -0
- package/cabloy-docs/frontend/rest-resource-under-the-hood.md +622 -0
- package/cabloy-docs/frontend/root-behaviors-guide.md +282 -0
- package/cabloy-docs/frontend/route-alias-guide.md +6 -0
- package/cabloy-docs/frontend/router-stack-guide.md +229 -0
- package/cabloy-docs/frontend/router-tabs-introduction.md +26 -3
- package/cabloy-docs/frontend/router-tabs-layout-integration.md +367 -0
- package/cabloy-docs/frontend/router-tabs-mechanism.md +6 -0
- package/cabloy-docs/frontend/router-tabs-route-meta-cookbook.md +7 -0
- package/cabloy-docs/frontend/router-tabs-vs-stack.md +167 -0
- package/cabloy-docs/frontend/router-view-hosts-guide.md +450 -0
- package/cabloy-docs/frontend/server-data.md +4 -1
- package/cabloy-docs/frontend/system-startup-guide.md +2 -2
- package/cabloy-docs/frontend/table-action-visibility-permission-flow-guide.md +263 -0
- package/cabloy-docs/frontend/table-cell-cookbook.md +568 -0
- package/cabloy-docs/frontend/table-guide.md +373 -0
- package/cabloy-docs/frontend/table-resource-crud-cookbook.md +496 -0
- package/cabloy-docs/frontend/zova-app-guide.md +251 -0
- package/cabloy-docs/frontend/zova-form-source-reading-map.md +293 -0
- package/cabloy-docs/frontend/zova-form-under-the-hood.md +561 -0
- package/cabloy-docs/frontend/zova-reactivity-under-the-hood.md +320 -0
- package/cabloy-docs/frontend/zova-router-under-the-hood.md +561 -0
- package/cabloy-docs/frontend/zova-source-reading-map.md +421 -0
- package/cabloy-docs/frontend/zova-table-controller-render-supplement.md +225 -0
- package/cabloy-docs/frontend/zova-table-source-reading-map.md +317 -0
- package/cabloy-docs/frontend/zova-table-under-the-hood.md +532 -0
- package/cabloy-docs/frontend/zova-vs-vue3-comparison.md +308 -0
- package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-debug-checklist.md +245 -0
- package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-source-reading-map.md +139 -0
- package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions-verify-playbook.md +248 -0
- package/cabloy-docs/fullstack/backend-metadata-to-frontend-table-actions.md +511 -0
- package/cabloy-docs/fullstack/contract-loop-playbook.md +356 -0
- package/cabloy-docs/fullstack/edition-collaboration-differences.md +6 -0
- package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +199 -23
- package/cabloy-docs/fullstack/introduction.md +15 -1
- package/cabloy-docs/fullstack/openapi-to-sdk.md +135 -11
- package/cabloy-docs/fullstack/suites-and-modules.md +333 -0
- package/cabloy-docs/fullstack/tutorial-1-first-module.md +3 -0
- package/cabloy-docs/fullstack/tutorial-2-first-crud.md +4 -0
- package/cabloy-docs/fullstack/tutorial-3-frontend-metadata-sharing.md +6 -2
- package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +60 -23
- package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +14 -7
- package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +6 -0
- package/cabloy-docs/fullstack/tutorials-overview.md +17 -4
- package/cabloy-docs/reference/bean-scene-boilerplates.md +15 -13
- package/cabloy-docs/reference/package-map.md +4 -3
- package/package.json +2 -1
- package/scripts/init.ts +2 -18
- package/scripts/initTestData.ts +25 -0
- package/scripts/upgrade.ts +17 -2
- package/vona/pnpm-lock.yaml +48 -194
- package/vona/src/suite/a-training/modules/training-student/package.json +53 -0
- package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +400 -0
- package/vona/src/suite/a-training/modules/training-student/src/.metadata/locales.ts +18 -0
- package/vona/src/suite/a-training/modules/training-student/src/.metadata/this.ts +2 -0
- package/vona/src/suite/a-training/modules/training-student/src/bean/meta.index.ts +12 -0
- package/vona/src/suite/a-training/modules/training-student/src/bean/meta.version.ts +21 -0
- package/vona/src/suite/a-training/modules/training-student/src/bean/ssrMenu.student.ts +29 -0
- package/vona/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +15 -0
- package/vona/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +15 -0
- package/vona/src/suite/a-training/modules/training-student/src/controller/student.ts +74 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentCreate.tsx +28 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectReq.tsx +44 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectRes.tsx +11 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +45 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentSummary.tsx +42 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentUpdate.tsx +28 -0
- package/vona/src/suite/a-training/modules/training-student/src/dto/studentView.tsx +25 -0
- package/vona/src/suite/a-training/modules/training-student/src/entity/student.tsx +84 -0
- package/vona/src/suite/a-training/modules/training-student/src/index.ts +2 -0
- package/vona/src/suite/a-training/modules/training-student/src/model/student.ts +10 -0
- package/vona/src/suite/a-training/modules/training-student/src/service/student.ts +57 -0
- package/vona/src/suite/a-training/modules/training-student/test/student.test.ts +173 -0
- package/vona/src/suite/a-training/modules/training-student/tsconfig.build.json +11 -0
- package/vona/src/suite/a-training/modules/training-student/tsconfig.json +7 -0
- package/vona/src/suite/a-training/package.json +12 -0
- package/vona/src/suite/a-training/tsconfig.base.json +4 -0
- package/vona/src/suite/a-training/tsconfig.json +10 -0
- package/zova/packages-cli/cli/package.json +2 -2
- package/zova/packages-cli/cli-set-front/cli/templates/openapi/config/boilerplate/module/openapi.config.ts +6 -1
- package/zova/packages-cli/cli-set-front/package.json +1 -1
- package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +34 -4
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +416 -690
- package/zova/src/suite/a-training/modules/training-student/cli/openapi.config.ts +9 -0
- package/zova/src/suite/a-training/modules/training-student/package.json +52 -0
- package/zova/src/suite/a-training/modules/training-student/src/.metadata/component/formFieldLevel.ts +31 -0
- package/zova/src/suite/a-training/modules/training-student/src/.metadata/index.ts +258 -0
- package/zova/src/suite/a-training/modules/training-student/src/.metadata/locales.ts +7 -0
- package/zova/src/suite/a-training/modules/training-student/src/.metadata/this.ts +2 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/baseURL.ts +5 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/index.ts +3 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +196 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +4146 -0
- package/zova/src/suite/a-training/modules/training-student/src/api/trainingStudent.ts +151 -0
- package/zova/src/suite/a-training/modules/training-student/src/apiSchema/trainingStudent.ts +43 -0
- package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionDeleteForce.tsx +51 -0
- package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionSummary.tsx +56 -0
- package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.level.tsx +63 -0
- package/zova/src/suite/a-training/modules/training-student/src/component/formFieldLevel/controller.tsx +117 -0
- package/zova/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +9 -0
- package/zova/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +9 -0
- package/zova/src/suite/a-training/modules/training-student/src/index.ts +2 -0
- package/zova/src/suite/a-training/modules/training-student/src/model/student.ts +42 -0
- package/zova/src/suite/a-training/modules/training-student/tsconfig.build.json +13 -0
- package/zova/src/suite/a-training/modules/training-student/tsconfig.json +5 -0
- package/zova/src/suite/a-training/package.json +12 -0
- package/zova/src/suite/a-training/tsconfig.base.json +4 -0
- package/zova/src/suite/a-training/tsconfig.json +4 -0
- package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +29 -7
- package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/select/controller.tsx +34 -11
- package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/component/table/controller.tsx +3 -3
- package/zova/src/suite-vendor/a-zova/modules/a-table/src/lib/tableCell.ts +1 -1
- package/zova/src/suite-vendor/a-zova/package.json +2 -2
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
# Zova Form Under the Hood
|
|
2
|
+
|
|
3
|
+
This guide explains the source-level runtime path behind Zova Form.
|
|
4
|
+
|
|
5
|
+
Use this page together with:
|
|
6
|
+
|
|
7
|
+
- [Form Guide](/frontend/form-guide)
|
|
8
|
+
- [Rest Resource Under the Hood](/frontend/rest-resource-under-the-hood)
|
|
9
|
+
- [Rest Resource Source Reading Map](/frontend/rest-resource-source-reading-map)
|
|
10
|
+
- [Zova Form Source Reading Map](/frontend/zova-form-source-reading-map)
|
|
11
|
+
- [Zova Reactivity Under the Hood](/frontend/zova-reactivity-under-the-hood)
|
|
12
|
+
- [Behavior Guide](/frontend/behavior-guide)
|
|
13
|
+
- [API Schema Guide](/frontend/api-schema-guide)
|
|
14
|
+
|
|
15
|
+
Use this page after [Form Guide](/frontend/form-guide) when you want to move from the public authoring surface to the internal cooperation among form controllers, field controllers, schema metadata, provider config, behaviors, and CRUD integration.
|
|
16
|
+
|
|
17
|
+
If your next question is not “how does this runtime work?” but “which files should I read next?”, continue with [Zova Form Source Reading Map](/frontend/zova-form-source-reading-map).
|
|
18
|
+
|
|
19
|
+
If your next question is specifically how `formScene` flows into `formMeta`, then `pageMeta`, and finally shell/tab state, continue with [Form Scene to Page Meta Guide](/frontend/form-scene-to-page-meta-guide).
|
|
20
|
+
|
|
21
|
+
> [!TIP]
|
|
22
|
+
> **Zova Form docs path**
|
|
23
|
+
>
|
|
24
|
+
> 1. **[Form Guide](/frontend/form-guide)** — learn the public authoring surface
|
|
25
|
+
> 2. **[Zova Form Under the Hood](/frontend/zova-form-under-the-hood)** — learn how the runtime pieces cooperate
|
|
26
|
+
> 3. **[Zova Form Source Reading Map](/frontend/zova-form-source-reading-map)** — learn which files to read next
|
|
27
|
+
>
|
|
28
|
+
> **You are here:** step 2.
|
|
29
|
+
> **Previous page:** [Form Guide](/frontend/form-guide).
|
|
30
|
+
> **Next recommended page:** [Zova Form Source Reading Map](/frontend/zova-form-source-reading-map).
|
|
31
|
+
|
|
32
|
+
## Why this page exists
|
|
33
|
+
|
|
34
|
+
The public form guide already explains the authoring surface:
|
|
35
|
+
|
|
36
|
+
- `ZForm`
|
|
37
|
+
- `ZFormFieldPreset`
|
|
38
|
+
- `ZFormField`
|
|
39
|
+
- `ZFormFieldBlank`
|
|
40
|
+
- `formMeta`
|
|
41
|
+
- `formProvider`
|
|
42
|
+
|
|
43
|
+
The source-reading map already explains where to look when you need a targeted code path.
|
|
44
|
+
|
|
45
|
+
What many contributors and AI workflows still want next is the implementation bridge:
|
|
46
|
+
|
|
47
|
+
- where the TanStack form instance is created
|
|
48
|
+
- where one field becomes a TanStack field binding
|
|
49
|
+
- how schema metadata becomes field props
|
|
50
|
+
- how layout, provider config, and behaviors merge into final rendering
|
|
51
|
+
- how validation and server errors flow back into the form state
|
|
52
|
+
- how CRUD pages feed resource-driven schema and data into `ZForm`
|
|
53
|
+
|
|
54
|
+
This page is that bridge.
|
|
55
|
+
|
|
56
|
+
## The shortest accurate runtime model
|
|
57
|
+
|
|
58
|
+
For a typical Zova form, the shortest accurate model is:
|
|
59
|
+
|
|
60
|
+
1. the `ZForm` wrapper creates a form controller bean through the normal Zova controller path
|
|
61
|
+
2. the form controller creates a TanStack form instance through Zova’s `$useForm(...)` wrapper
|
|
62
|
+
3. the form controller computes provider config, schema, Zod schema, and rendered properties
|
|
63
|
+
4. if the form body is not manually overridden, the form render bean turns schema properties into field children
|
|
64
|
+
5. each field controller creates its own TanStack field binding with `useField(...)`
|
|
65
|
+
6. field props merge from schema metadata, field props, layout options, provider config, and readonly rules
|
|
66
|
+
7. provider behaviors wrap the field render path before the final renderer is invoked
|
|
67
|
+
8. submit and validation flow through TanStack and Zod, then Zova normalizes invalid-submit and 422 server errors back into form state
|
|
68
|
+
9. resource-driven CRUD pages feed `formMeta`, `formSchema`, `formData`, and `formProvider` into the same runtime
|
|
69
|
+
|
|
70
|
+
That is why Zova Form is not only a thin wrapper around TanStack Form. The business-facing runtime surface is still Zova-native.
|
|
71
|
+
|
|
72
|
+
## A concrete source specimen
|
|
73
|
+
|
|
74
|
+
A small public example that shows several form patterns clearly is:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
zova/src/suite/a-demo/modules/demo-basic/src/page/toolOne/render.tsx
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
That specimen is useful because it shows both:
|
|
81
|
+
|
|
82
|
+
- schema-driven rendering
|
|
83
|
+
- manual field rendering through `ZFormField`
|
|
84
|
+
|
|
85
|
+
A more business-facing specimen is:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
zova/src/suite/a-home/modules/home-login/src/page/login/render.tsx
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
That page shows:
|
|
92
|
+
|
|
93
|
+
- preset-based field rendering
|
|
94
|
+
- a provider-level layout behavior override
|
|
95
|
+
- a blank row used for action controls
|
|
96
|
+
|
|
97
|
+
The rest of this page explains how those public authoring shapes become real runtime behavior.
|
|
98
|
+
|
|
99
|
+
## The core source-reading path
|
|
100
|
+
|
|
101
|
+
When you want to trace the full mechanism, read these files in order:
|
|
102
|
+
|
|
103
|
+
1. `zova/src/suite-vendor/a-zova/modules/a-form/src/component/form/controller.tsx`
|
|
104
|
+
2. `zova/src/suite-vendor/a-zova/modules/a-form/src/lib/beanControllerFormBase.ts`
|
|
105
|
+
3. `zova/src/suite-vendor/a-zova/modules/a-form/src/component/form/render.tsx`
|
|
106
|
+
4. `zova/src/suite-vendor/a-zova/modules/a-form/src/component/formField/controller.tsx`
|
|
107
|
+
5. `zova/src/suite-vendor/a-zova/modules/a-form/src/component/formField/render.tsx`
|
|
108
|
+
6. `zova/src/suite-vendor/a-zova/modules/a-openapi/src/lib/schema.ts`
|
|
109
|
+
7. `zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx`
|
|
110
|
+
|
|
111
|
+
A compact role map is:
|
|
112
|
+
|
|
113
|
+
- `form/controller.tsx` owns form runtime creation, schema state, submit flow, and error normalization
|
|
114
|
+
- `beanControllerFormBase.ts` shows the Zova wrapper around TanStack `useForm(...)`
|
|
115
|
+
- `form/render.tsx` shows automatic schema-driven field iteration and form-level submit wiring
|
|
116
|
+
- `formField/controller.tsx` owns field runtime creation, props merge, validation setup, and behavior selection
|
|
117
|
+
- `formField/render.tsx` shows the final behavior-wrapped render handoff
|
|
118
|
+
- `schema.ts` shows schema-property loading and Zod conversion
|
|
119
|
+
- `blockPageEntry/controller.tsx` shows how a resource-driven CRUD page feeds schema and data into `ZForm`
|
|
120
|
+
|
|
121
|
+
## Step-by-step runtime path
|
|
122
|
+
|
|
123
|
+
### 1. `ZForm` creates the form controller bean
|
|
124
|
+
|
|
125
|
+
The public wrapper enters the normal Zova controller path through the generated metadata wrapper:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/.metadata/component/form.ts
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
That wrapper calls `useController(...)`, which means the form runtime begins as a controller bean, not as a page-local ad hoc object.
|
|
132
|
+
|
|
133
|
+
A practical reading takeaway is:
|
|
134
|
+
|
|
135
|
+
- **the visible wrapper component is thin**
|
|
136
|
+
- **the controller bean is the real runtime owner**
|
|
137
|
+
|
|
138
|
+
## 2. The form controller creates the TanStack form bridge
|
|
139
|
+
|
|
140
|
+
The main runtime owner is:
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/component/form/controller.tsx
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Inside `ControllerForm.__init__()` the controller:
|
|
147
|
+
|
|
148
|
+
- registers itself as `$$form`
|
|
149
|
+
- creates the form instance with `_createForm()`
|
|
150
|
+
- creates `formState` with `useStore(this.form.store, ...)`
|
|
151
|
+
- computes `formProvider`
|
|
152
|
+
- computes `schema`
|
|
153
|
+
- computes `zodSchema`
|
|
154
|
+
- computes rendered `properties`
|
|
155
|
+
- creates the field CEL environment
|
|
156
|
+
- creates `zovaJsx`
|
|
157
|
+
- watches incoming `data` and resets the form when it changes
|
|
158
|
+
|
|
159
|
+
This is one of the most important source-level facts about Zova Form.
|
|
160
|
+
|
|
161
|
+
The form controller is not only coordinating submit. It is the central bridge among:
|
|
162
|
+
|
|
163
|
+
- TanStack form state
|
|
164
|
+
- schema-driven field metadata
|
|
165
|
+
- provider-driven renderer lookup
|
|
166
|
+
- Zova field render context
|
|
167
|
+
|
|
168
|
+
## 3. Why `$useForm(...)` exists
|
|
169
|
+
|
|
170
|
+
The shared wrapper lives in:
|
|
171
|
+
|
|
172
|
+
```text
|
|
173
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/lib/beanControllerFormBase.ts
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
and the page-controller variant lives in:
|
|
177
|
+
|
|
178
|
+
```text
|
|
179
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/lib/beanControllerPageFormBase.ts
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The important runtime detail is that `$useForm(...)` wraps TanStack `useForm(...)` like this:
|
|
183
|
+
|
|
184
|
+
- run it inside `ctx.util.instanceScope(...)`
|
|
185
|
+
- then `markRaw(...)` the returned TanStack object
|
|
186
|
+
|
|
187
|
+
That matters because:
|
|
188
|
+
|
|
189
|
+
- Zova wants the controller bean to stay the business-facing reactive host
|
|
190
|
+
- the underlying TanStack object still needs to be created in the right Zova instance scope
|
|
191
|
+
- the raw TanStack API should not itself become the main reactive authoring object
|
|
192
|
+
|
|
193
|
+
A practical reading takeaway is:
|
|
194
|
+
|
|
195
|
+
- **Zova does not replace TanStack Form**
|
|
196
|
+
- **Zova relocates the business-facing ownership into controller beans**
|
|
197
|
+
|
|
198
|
+
## 4. How schema becomes rendered fields
|
|
199
|
+
|
|
200
|
+
The form controller computes two related surfaces:
|
|
201
|
+
|
|
202
|
+
- `zodSchema`
|
|
203
|
+
- `properties`
|
|
204
|
+
|
|
205
|
+
The relevant source files are:
|
|
206
|
+
|
|
207
|
+
```text
|
|
208
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/component/form/controller.tsx
|
|
209
|
+
zova/src/suite-vendor/a-zova/modules/a-openapi/src/lib/schema.ts
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
The important runtime path is:
|
|
213
|
+
|
|
214
|
+
1. the form receives `schema`
|
|
215
|
+
2. `_getZodSchema()` either reuses `props.zodSchema` or converts the schema with `schemaToZodSchema(...)`
|
|
216
|
+
3. `loadSchemaProperties(...)` resolves fields for the current schema scene
|
|
217
|
+
4. each property carries field-level metadata such as render, order, and scene-specific `rest` overrides
|
|
218
|
+
|
|
219
|
+
`loadSchemaProperties(...)` is especially important because it does more than list object keys.
|
|
220
|
+
|
|
221
|
+
It also:
|
|
222
|
+
|
|
223
|
+
- resolves `$ref`
|
|
224
|
+
- applies scene-specific metadata overlays such as `form`, `form-view`, `form-create`, and `filter`
|
|
225
|
+
- sorts fields by `rest.order`
|
|
226
|
+
|
|
227
|
+
A practical reading takeaway is:
|
|
228
|
+
|
|
229
|
+
- **schema is not only validation truth**
|
|
230
|
+
- **schema also drives ordering, render metadata, and scene-specific field behavior**
|
|
231
|
+
|
|
232
|
+
## 5. The form controller creates the field render context
|
|
233
|
+
|
|
234
|
+
Still inside `form/controller.tsx`, the form controller prepares the field runtime support used later by every field:
|
|
235
|
+
|
|
236
|
+
- `getFieldValue(...)`
|
|
237
|
+
- `setFieldValue(...)`
|
|
238
|
+
- `getFieldProperty(...)`
|
|
239
|
+
- `getFieldZodSchema(...)`
|
|
240
|
+
- `getFieldScope(...)`
|
|
241
|
+
- `getFieldJsxRenderContext(...)`
|
|
242
|
+
- `getFieldComponentPropsTop(...)`
|
|
243
|
+
|
|
244
|
+
These methods matter because they separate responsibilities clearly:
|
|
245
|
+
|
|
246
|
+
- the form controller owns cross-field knowledge
|
|
247
|
+
- the field controller owns one field’s runtime binding
|
|
248
|
+
|
|
249
|
+
This is why a field can ask the parent form for:
|
|
250
|
+
|
|
251
|
+
- its current value
|
|
252
|
+
- its schema property metadata
|
|
253
|
+
- its field-level Zod schema
|
|
254
|
+
- the JSX/CEL scope used for rendering expressions
|
|
255
|
+
|
|
256
|
+
## 6. One field becomes a TanStack field binding
|
|
257
|
+
|
|
258
|
+
The field runtime owner is:
|
|
259
|
+
|
|
260
|
+
```text
|
|
261
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/component/formField/controller.tsx
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Inside `ControllerFormField.__init__()` the field controller:
|
|
265
|
+
|
|
266
|
+
- verifies it is inside a form
|
|
267
|
+
- registers itself as `$$formField`
|
|
268
|
+
- creates the field with `_createField()`
|
|
269
|
+
- computes `propsBucket`
|
|
270
|
+
- watches schema-property changes and updates the TanStack field options
|
|
271
|
+
- initializes the behavior holder
|
|
272
|
+
|
|
273
|
+
The key bridge is `_createField()`:
|
|
274
|
+
|
|
275
|
+
- call `useField(options as any)`
|
|
276
|
+
- `markRaw(...)` the field object
|
|
277
|
+
- create reactive `fieldState` with `useStore(field.api.store, ...)`
|
|
278
|
+
|
|
279
|
+
This is the field-level equivalent of the form controller’s TanStack bridge.
|
|
280
|
+
|
|
281
|
+
A practical reading takeaway is:
|
|
282
|
+
|
|
283
|
+
- **the form owns the cross-field runtime**
|
|
284
|
+
- **each field controller owns one field’s TanStack binding and render context**
|
|
285
|
+
|
|
286
|
+
## 7. How one field is configured
|
|
287
|
+
|
|
288
|
+
The field controller builds its runtime configuration mainly through:
|
|
289
|
+
|
|
290
|
+
- `_getPropsBucket()`
|
|
291
|
+
- `_getFormFieldOptions()`
|
|
292
|
+
- `_getFormFieldOptionsValidators()`
|
|
293
|
+
|
|
294
|
+
### `_getPropsBucket()`
|
|
295
|
+
|
|
296
|
+
This is one of the most important methods in the entire module.
|
|
297
|
+
|
|
298
|
+
Its job is to merge the final field-facing props from several sources:
|
|
299
|
+
|
|
300
|
+
1. default field render assumptions
|
|
301
|
+
2. local field props
|
|
302
|
+
3. top-level schema-derived props from the parent form
|
|
303
|
+
4. computed layout options
|
|
304
|
+
5. computed renderer options
|
|
305
|
+
6. readonly normalization
|
|
306
|
+
7. final render-provider resolution
|
|
307
|
+
|
|
308
|
+
That means the final field render is not decided by one layer only.
|
|
309
|
+
|
|
310
|
+
It is the result of several layers cooperating.
|
|
311
|
+
|
|
312
|
+
### `_getFormFieldOptions()`
|
|
313
|
+
|
|
314
|
+
This method builds the TanStack field options by combining:
|
|
315
|
+
|
|
316
|
+
- current form value
|
|
317
|
+
- default value from system options or schema property defaults
|
|
318
|
+
- form reference
|
|
319
|
+
- validators
|
|
320
|
+
|
|
321
|
+
### `_getFormFieldOptionsValidators()`
|
|
322
|
+
|
|
323
|
+
This method chooses the validation surface for `onDynamic`, `onBlur`, and `onChange`.
|
|
324
|
+
|
|
325
|
+
Its important behavior is:
|
|
326
|
+
|
|
327
|
+
- if a validator flag is `true`, use the field’s Zod schema
|
|
328
|
+
- if a validator is an explicit Zod validator, use that
|
|
329
|
+
- if no field-specific validator is given, default dynamic validation can still be enabled
|
|
330
|
+
|
|
331
|
+
A practical reading takeaway is:
|
|
332
|
+
|
|
333
|
+
- **field validation is not hard-coded in one place**
|
|
334
|
+
- **it is derived from either explicit field options or the field’s schema-driven Zod contract**
|
|
335
|
+
|
|
336
|
+
## 8. The prop/provider/behavior merge pipeline
|
|
337
|
+
|
|
338
|
+
The most useful durable mental model for field rendering is:
|
|
339
|
+
|
|
340
|
+
```text
|
|
341
|
+
schema/rest + field props + layout + provider config -> behavior wrapping -> final renderer
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
The relevant sources are:
|
|
345
|
+
|
|
346
|
+
```text
|
|
347
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/component/formField/controller.tsx
|
|
348
|
+
zova/src/suite/cabloy-basic/modules/basic-adapter/src/config/config.ts
|
|
349
|
+
zova/src/suite/cabloy-basic/modules/basic-form/src/bean/behavior.formField.ts
|
|
350
|
+
zova/src/suite/cabloy-basic/modules/basic-form/src/bean/behavior.formFieldLayout.tsx
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Provider defaults
|
|
354
|
+
|
|
355
|
+
In Cabloy Basic, the default provider config maps:
|
|
356
|
+
|
|
357
|
+
- `FormField` -> `basic-form:formField`
|
|
358
|
+
- `FormFieldLayout` -> `basic-form:formFieldLayout`
|
|
359
|
+
- `Input` -> `basic-input:formFieldInput`
|
|
360
|
+
|
|
361
|
+
That means the field runtime is provider-driven even before a page overrides anything.
|
|
362
|
+
|
|
363
|
+
### Behavior merge
|
|
364
|
+
|
|
365
|
+
`_getFieldBehaviors()` merges:
|
|
366
|
+
|
|
367
|
+
- explicit field `behaviors`
|
|
368
|
+
- provider-level `FormField`
|
|
369
|
+
- provider-level `FormFieldLayout`
|
|
370
|
+
|
|
371
|
+
Then `RenderFormField.render()` passes rendering through:
|
|
372
|
+
|
|
373
|
+
- `$$beanBehaviorsHolder.render(...)`
|
|
374
|
+
|
|
375
|
+
In the Basic defaults:
|
|
376
|
+
|
|
377
|
+
- `BehaviorFormField` is a pass-through behavior
|
|
378
|
+
- `BehaviorFormFieldLayout` decides inline vs block layout and renders validation errors in the wrapper
|
|
379
|
+
|
|
380
|
+
A practical reading takeaway is:
|
|
381
|
+
|
|
382
|
+
- **field rendering is provider-driven and behavior-wrapped**
|
|
383
|
+
- **`a-form` does not hard-code one final Basic UI layout by itself**
|
|
384
|
+
|
|
385
|
+
## 9. Render flow for form and field
|
|
386
|
+
|
|
387
|
+
The form render bean lives in:
|
|
388
|
+
|
|
389
|
+
```text
|
|
390
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/component/form/render.tsx
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
The field render bean lives in:
|
|
394
|
+
|
|
395
|
+
```text
|
|
396
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/component/formField/render.tsx
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Form render path
|
|
400
|
+
|
|
401
|
+
`RenderForm` does three important jobs:
|
|
402
|
+
|
|
403
|
+
- iterate schema properties when the form body is not manually overridden
|
|
404
|
+
- create structural slots like header/body/footer/wrapper
|
|
405
|
+
- wire native form submit to `submit()` unless `onFormSubmit` is supplied
|
|
406
|
+
|
|
407
|
+
That means automatic schema-driven rendering is not happening magically in the wrapper component. It is happening in the render bean.
|
|
408
|
+
|
|
409
|
+
### Field render path
|
|
410
|
+
|
|
411
|
+
`RenderFormField` does two important jobs:
|
|
412
|
+
|
|
413
|
+
- pass the field render context through the behavior pipeline
|
|
414
|
+
- if no custom slot is given, call `$$form.zovaJsx.render(...)`
|
|
415
|
+
|
|
416
|
+
That means the final renderer is reached only after:
|
|
417
|
+
|
|
418
|
+
- field controller preparation
|
|
419
|
+
- props merge
|
|
420
|
+
- behavior wrapping
|
|
421
|
+
|
|
422
|
+
## 10. Validation and server error round-trip
|
|
423
|
+
|
|
424
|
+
The main submit and error path lives in:
|
|
425
|
+
|
|
426
|
+
```text
|
|
427
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/component/form/controller.tsx
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
The short version is:
|
|
431
|
+
|
|
432
|
+
- `submit()` delegates to `this.form.handleSubmit(...)`
|
|
433
|
+
- `_createForm()` wires `onSubmitInvalid` and `onSubmit`
|
|
434
|
+
- `onSubmit` calls user `onSubmitData`
|
|
435
|
+
- if the backend returns a 422 validation error, Zova normalizes it back into TanStack field/form error state
|
|
436
|
+
- other errors can flow to `onShowError`
|
|
437
|
+
|
|
438
|
+
### Why 422 handling matters
|
|
439
|
+
|
|
440
|
+
Without this step, server validation would stay outside the form runtime and feel disconnected from field state.
|
|
441
|
+
|
|
442
|
+
Instead, `_handleError422(...)` parses the server payload and pushes normalized errors back into TanStack’s error maps.
|
|
443
|
+
|
|
444
|
+
That is one of the strongest reasons the module feels like a real form runtime rather than only a submit helper.
|
|
445
|
+
|
|
446
|
+
A practical reading takeaway is:
|
|
447
|
+
|
|
448
|
+
- **Zova does not treat server validation as an unrelated external concern**
|
|
449
|
+
- **it feeds server validation back into the same field/form state model**
|
|
450
|
+
|
|
451
|
+
## 11. CRUD and filter integration path
|
|
452
|
+
|
|
453
|
+
Zova Form is also used as part of Cabloy Basic’s resource-driven page runtime.
|
|
454
|
+
|
|
455
|
+
The strongest source specimens are:
|
|
456
|
+
|
|
457
|
+
```text
|
|
458
|
+
zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockPageEntry/controller.tsx
|
|
459
|
+
zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockForm/controller.tsx
|
|
460
|
+
zova/src/suite/cabloy-basic/modules/basic-page/src/component/blockFilter/controller.tsx
|
|
461
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/lib/utils.ts
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
### Resource entry page path
|
|
465
|
+
|
|
466
|
+
`blockPageEntry` computes:
|
|
467
|
+
|
|
468
|
+
- `formMeta`
|
|
469
|
+
- `formProvider`
|
|
470
|
+
- `formSchema`
|
|
471
|
+
- `formData`
|
|
472
|
+
|
|
473
|
+
from the resource model.
|
|
474
|
+
|
|
475
|
+
Then `blockForm` passes those into `ZForm`.
|
|
476
|
+
|
|
477
|
+
So in resource CRUD pages, `ZForm` is not expected to discover business data by itself. The page/resource layer prepares the form inputs first.
|
|
478
|
+
|
|
479
|
+
### Filter-form path
|
|
480
|
+
|
|
481
|
+
`blockFilter` shows the lighter filter branch:
|
|
482
|
+
|
|
483
|
+
- `formMeta = { formMode: 'edit' }`
|
|
484
|
+
- `schemaScene="filter"`
|
|
485
|
+
- inline field layout
|
|
486
|
+
- reset and submit reuse the same form runtime
|
|
487
|
+
|
|
488
|
+
This is a useful reminder that the same form module supports more than create/edit/view pages.
|
|
489
|
+
|
|
490
|
+
## 12. Type contracts worth knowing
|
|
491
|
+
|
|
492
|
+
If you want the compact type surface, do not skip these files:
|
|
493
|
+
|
|
494
|
+
```text
|
|
495
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/types/form.ts
|
|
496
|
+
zova/src/suite-vendor/a-zova/modules/a-form/src/types/formField.ts
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
The most useful contracts to notice are:
|
|
500
|
+
|
|
501
|
+
- `TypeForm`
|
|
502
|
+
- `TypeFormField`
|
|
503
|
+
- `TypeFormOnSubmitData`
|
|
504
|
+
- `TypeFormOnSubmitInvalid`
|
|
505
|
+
- `TypeFormOnShowError`
|
|
506
|
+
- `IFormFieldRenderContext`
|
|
507
|
+
- `IJsxRenderContextFormField`
|
|
508
|
+
- `constFieldProps`
|
|
509
|
+
|
|
510
|
+
These types show where the runtime contracts are formalized for:
|
|
511
|
+
|
|
512
|
+
- submit payloads
|
|
513
|
+
- field render context
|
|
514
|
+
- form events
|
|
515
|
+
- field-level slot signatures
|
|
516
|
+
|
|
517
|
+
## 13. Compact call-flow sketch
|
|
518
|
+
|
|
519
|
+
When in doubt, use this short call flow:
|
|
520
|
+
|
|
521
|
+
1. `ZForm` wrapper enters the normal Zova controller path
|
|
522
|
+
2. `ControllerForm.__init__()` creates the TanStack form bridge
|
|
523
|
+
3. form controller computes provider/schema/Zod/properties
|
|
524
|
+
4. `RenderForm` either auto-renders schema fields or uses custom slots
|
|
525
|
+
5. each `ControllerFormField` creates a TanStack `useField(...)` binding
|
|
526
|
+
6. field props merge from schema metadata, field props, layout, provider config, and readonly rules
|
|
527
|
+
7. `RenderFormField` sends the field through the behavior pipeline
|
|
528
|
+
8. final field rendering reaches `zovaJsx.render(...)` or a custom slot
|
|
529
|
+
9. submit flows through TanStack, then Zova normalizes invalid-submit and server-side validation back into form state
|
|
530
|
+
10. resource CRUD pages prepare `formMeta`, `formSchema`, `formData`, and `formProvider` before entering the same runtime
|
|
531
|
+
|
|
532
|
+
That is the shortest end-to-end explanation of how the module cooperates.
|
|
533
|
+
|
|
534
|
+
## Final takeaway
|
|
535
|
+
|
|
536
|
+
Zova Form is not just TanStack Form plus JSX wrappers.
|
|
537
|
+
|
|
538
|
+
It moves form ownership into:
|
|
539
|
+
|
|
540
|
+
- Zova controller beans
|
|
541
|
+
- schema metadata
|
|
542
|
+
- provider-driven renderer lookup
|
|
543
|
+
- behavior-based field wrapping
|
|
544
|
+
- resource-driven CRUD integration
|
|
545
|
+
|
|
546
|
+
TanStack Form and Zod are still important underlying engines, but the business-facing runtime model is Zova-native.
|
|
547
|
+
|
|
548
|
+
## Verification checklist
|
|
549
|
+
|
|
550
|
+
When documenting or changing this area, verify in this order:
|
|
551
|
+
|
|
552
|
+
1. confirm the runtime claims against the current `a-form` source
|
|
553
|
+
2. confirm the Basic provider defaults still match current `basic-adapter` and `basic-form` wiring
|
|
554
|
+
3. confirm CRUD integration claims still match `blockPageEntry`, `blockForm`, and `blockFilter`
|
|
555
|
+
4. build the docs site:
|
|
556
|
+
|
|
557
|
+
```bash
|
|
558
|
+
npm run docs:build
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
5. verify the page is reachable from the frontend sidebar and related form docs
|