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
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Resource Custom State Pattern
|
|
2
|
+
|
|
3
|
+
Use this reference when a contract-loop task adds or refactors a custom API that still belongs to an existing resource.
|
|
4
|
+
|
|
5
|
+
This is a downstream consumer-alignment pattern for the forward chain. It applies after contract regeneration, not instead of contract generation.
|
|
6
|
+
|
|
7
|
+
Typical examples:
|
|
8
|
+
|
|
9
|
+
- `summary/:id`
|
|
10
|
+
- `restore/:id`
|
|
11
|
+
- `deleteForce/:id`
|
|
12
|
+
- `history/:id`
|
|
13
|
+
- any other row-scoped endpoint that should stay synchronized with standard resource list or entry flows
|
|
14
|
+
|
|
15
|
+
## The ownership rule
|
|
16
|
+
|
|
17
|
+
Prefer one owner for all resource-bound server state.
|
|
18
|
+
|
|
19
|
+
In this codebase, the preferred owner is:
|
|
20
|
+
|
|
21
|
+
- `rest-resource.model.resource`
|
|
22
|
+
|
|
23
|
+
Do not let a module-local model become a second state owner for the same resource rows unless the boundary is explicitly intentional.
|
|
24
|
+
|
|
25
|
+
## The split to avoid
|
|
26
|
+
|
|
27
|
+
Avoid this pattern:
|
|
28
|
+
|
|
29
|
+
1. standard resource list and entry pages consume `rest-resource.model.resource`
|
|
30
|
+
2. a module-local model introduces separate query or mutation state for the same rows
|
|
31
|
+
3. custom mutation success invalidates only the local model keys
|
|
32
|
+
4. the generic resource pages keep reading stale row or list state
|
|
33
|
+
|
|
34
|
+
This usually happens when a task starts with a module-local generated SDK wrapper and stops there. The pattern is generic and should not depend on any one demo module continuing to exist.
|
|
35
|
+
|
|
36
|
+
## Preferred pattern
|
|
37
|
+
|
|
38
|
+
Use this shape instead:
|
|
39
|
+
|
|
40
|
+
1. keep `ModelResource` as the single owner of resource-bound server state
|
|
41
|
+
2. add reusable resource-owned helpers for custom query and mutation state
|
|
42
|
+
3. keep module-local models only as thin semantic facades when the task still benefits from a business-local API surface
|
|
43
|
+
|
|
44
|
+
This is the forward-chain downstream rule in practice: regenerate the contract first, then keep the frontend follow-up thin and resource-owner-aware.
|
|
45
|
+
|
|
46
|
+
A good semantic facade may still expose methods such as:
|
|
47
|
+
|
|
48
|
+
- `summary(id)`
|
|
49
|
+
- `deleteForce(id)`
|
|
50
|
+
|
|
51
|
+
But those methods should delegate to `ModelResource`, not create a competing cache owner.
|
|
52
|
+
|
|
53
|
+
## Cache-key convention
|
|
54
|
+
|
|
55
|
+
For row-scoped state, group keys under the item identity.
|
|
56
|
+
|
|
57
|
+
Preferred structure:
|
|
58
|
+
|
|
59
|
+
- row root:
|
|
60
|
+
- `['item', id]`
|
|
61
|
+
- row query scenes:
|
|
62
|
+
- `['item', id, 'get']`
|
|
63
|
+
- `['item', id, 'summary']`
|
|
64
|
+
- `['item', id, 'history']`
|
|
65
|
+
- row mutation scenes may extend the same structure, for example:
|
|
66
|
+
- `['item', id, 'deleteForce', 'mutation']`
|
|
67
|
+
|
|
68
|
+
For list-scoped resource queries, keep the select-style grouping, for example:
|
|
69
|
+
|
|
70
|
+
- `['select', actionPath ?? '', hashkey(query)]`
|
|
71
|
+
|
|
72
|
+
## Invalidation rule
|
|
73
|
+
|
|
74
|
+
For a row-affecting mutation:
|
|
75
|
+
|
|
76
|
+
- invalidate `['item', id]`
|
|
77
|
+
|
|
78
|
+
For a list-affecting mutation:
|
|
79
|
+
|
|
80
|
+
- invalidate `['select']`
|
|
81
|
+
|
|
82
|
+
If both are affected:
|
|
83
|
+
|
|
84
|
+
- invalidate both
|
|
85
|
+
|
|
86
|
+
This is the key benefit of the grouped row-root convention: one invalidation clears all row-specific query scenes for the same item.
|
|
87
|
+
|
|
88
|
+
## Helper naming guidance
|
|
89
|
+
|
|
90
|
+
When adding reusable row-scoped helper options, prefer `action` over `scene` or `handler`.
|
|
91
|
+
|
|
92
|
+
Reason:
|
|
93
|
+
|
|
94
|
+
- `action` matches resource semantics such as `get`, `summary`, `deleteForce`
|
|
95
|
+
- `scene` already has stronger UI and form-scene meaning elsewhere in the codebase
|
|
96
|
+
- `handler` describes implementation shape rather than resource meaning
|
|
97
|
+
|
|
98
|
+
Preferred examples:
|
|
99
|
+
|
|
100
|
+
- `queryItem({ id, action: 'summary', ... })`
|
|
101
|
+
- `mutationItem({ id, action: 'deleteForce', ... })`
|
|
102
|
+
|
|
103
|
+
## Typed SDK guidance
|
|
104
|
+
|
|
105
|
+
Keep generated SDK calls typed and module-local.
|
|
106
|
+
|
|
107
|
+
Preferred split:
|
|
108
|
+
|
|
109
|
+
- module-local facade keeps the generated SDK call
|
|
110
|
+
- `ModelResource` owns the query or mutation state and invalidation policy
|
|
111
|
+
|
|
112
|
+
That means the facade passes typed closures into the generic helpers, conceptually like:
|
|
113
|
+
|
|
114
|
+
- `queryItem({ id, action: 'summary', queryFn: () => api.summary(...) })`
|
|
115
|
+
- `mutationItem({ id, action: 'deleteForce', mutationFn: () => api.deleteForce(...) })`
|
|
116
|
+
|
|
117
|
+
This preserves strong typing without duplicating state ownership.
|
|
118
|
+
|
|
119
|
+
## When to reuse this pattern
|
|
120
|
+
|
|
121
|
+
Reuse it when all of the following are true:
|
|
122
|
+
|
|
123
|
+
- the endpoint still belongs logically to an existing resource
|
|
124
|
+
- standard resource list or entry pages already consume that resource through `rest-resource.model.resource`
|
|
125
|
+
- stale row or list state would matter after the mutation or fetch
|
|
126
|
+
- the task needs a custom API shape beyond standard CRUD, but not a separate application-state subsystem
|
|
127
|
+
|
|
128
|
+
## When a separate owner may still be acceptable
|
|
129
|
+
|
|
130
|
+
A separate owner may still be fine when the data is not really part of the resource state surface, for example:
|
|
131
|
+
|
|
132
|
+
- unrelated dashboard data
|
|
133
|
+
- global application state
|
|
134
|
+
- purely local UI state
|
|
135
|
+
- intentionally unsynchronized auxiliary data
|
|
136
|
+
|
|
137
|
+
Even then, be explicit about the boundary.
|
|
138
|
+
|
|
139
|
+
## Quick checklist
|
|
140
|
+
|
|
141
|
+
1. confirm whether the resource pages already use `rest-resource.model.resource`
|
|
142
|
+
2. decide whether the custom endpoint is row-scoped or list-scoped
|
|
143
|
+
3. reuse or extend the generic resource helpers instead of creating a second owner
|
|
144
|
+
4. group row keys under `['item', id, action]`
|
|
145
|
+
5. invalidate `['item', id]` for row-affecting mutations
|
|
146
|
+
6. invalidate `['select']` for list-affecting mutations
|
|
147
|
+
7. keep module-local models semantic-only when possible
|
|
148
|
+
8. verify both standard resource flows and the new custom action flow
|
|
@@ -1,31 +1,67 @@
|
|
|
1
1
|
# Verification Checklist
|
|
2
2
|
|
|
3
|
-
After a contract-loop change,
|
|
3
|
+
After a contract-loop change, verify the branch that actually applies.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Edition verification
|
|
6
|
+
|
|
7
|
+
- Basic or Start marker confirmed
|
|
8
|
+
- affected flavor confirmed
|
|
9
|
+
- generation path matches the active edition
|
|
6
10
|
|
|
11
|
+
## Forward chain verification
|
|
12
|
+
|
|
13
|
+
- backend contract source is correct
|
|
7
14
|
- controller action contract is correct
|
|
8
15
|
- DTO and validation align
|
|
9
16
|
- OpenAPI output reflects the intended shape
|
|
10
|
-
-
|
|
11
|
-
-
|
|
17
|
+
- module ownership is constrained
|
|
18
|
+
- regeneration commands completed successfully
|
|
19
|
+
- generated SDK or schema outputs are updated
|
|
20
|
+
- thin model facades and downstream consumers still align with the regenerated contract
|
|
12
21
|
- `npm run tsc`
|
|
13
22
|
- `npm run build`
|
|
14
23
|
|
|
15
|
-
##
|
|
24
|
+
## Reverse chain verification
|
|
16
25
|
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
26
|
+
- frontend-owned source is correct
|
|
27
|
+
- metadata generation completed when applicable
|
|
28
|
+
- the relevant flavor build completed successfully
|
|
29
|
+
- `deps:vona` completed
|
|
30
|
+
- backend consumers can resolve the refreshed frontend-generated handoff
|
|
31
|
+
- prefer visible proof under `zova/src/**/.metadata/**` when it is available
|
|
32
|
+
- this repo does not rely on a contract-loop pre-commit gate; the active safeguard is the Claude hook layer
|
|
33
|
+
- if the change was a high-confidence Zova reverse-source edit through the Claude hook path, confirm whether the hook already auto-ran `npm run build:zova:admin` and `npm run deps:vona`
|
|
34
|
+
- if the change was consumer-side, low-confidence, outside the Claude hook path, or in another edition branch, run the reverse sync flow manually instead of assuming it already happened
|
|
35
|
+
- if the real handoff only appears in `.zova-rest`, treat the safeguard as conservative reminder/auto-sync assistance rather than strict proof
|
|
20
36
|
- `npm run tsc:zova`
|
|
21
|
-
- `npm run build:zova`
|
|
22
37
|
- relevant flavor-specific or route-specific checks
|
|
23
38
|
|
|
24
|
-
##
|
|
39
|
+
## Consumer drift verification
|
|
25
40
|
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
41
|
+
- source truth already looks correct
|
|
42
|
+
- generated output already looks correct
|
|
43
|
+
- the next consumer layer is the place that still looks stale
|
|
44
|
+
- do not patch source or generated artifacts again until the stale consumer path is identified
|
|
45
|
+
|
|
46
|
+
## Recovery rule for stale local file consumers
|
|
47
|
+
|
|
48
|
+
If all of these are true:
|
|
49
|
+
|
|
50
|
+
- generated `.zova-rest` or related generated consumer artifacts already contain the expected new keys or types
|
|
51
|
+
- the normal regeneration or sync flow already ran
|
|
52
|
+
- when relevant, the affected Zova flavor build already ran
|
|
53
|
+
- `deps:vona` already ran
|
|
54
|
+
- Vona still behaves as if old consumer types are installed
|
|
55
|
+
|
|
56
|
+
Then suspect a stale or unhealthy local installation state in `vona/node_modules`.
|
|
57
|
+
|
|
58
|
+
Recovery action:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
cd vona && rm -rf node_modules && pnpm install
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Use this as a recovery path when normal sync steps did not restore the local file-package installation state cleanly.
|
|
29
65
|
|
|
30
66
|
## Done rule
|
|
31
67
|
|
|
@@ -134,6 +134,16 @@ Check whether the feature needs:
|
|
|
134
134
|
- SSR init-data updates
|
|
135
135
|
- OpenAPI SDK regeneration
|
|
136
136
|
- schema-driven UI or `$apiSchema` review
|
|
137
|
+
- reverse fullstack handoff when newly added frontend resources will later be consumed by backend metadata or backend tooling
|
|
138
|
+
|
|
139
|
+
If the frontend change introduces resources such as a custom form-field renderer, table-cell renderer, or other generated metadata that backend `ZovaRender.field(...)` / `ZovaRender.cell(...)` will consume, do not treat the task as frontend-only cleanup.
|
|
140
|
+
|
|
141
|
+
In that case, surface this operational sequence:
|
|
142
|
+
|
|
143
|
+
1. refresh metadata when needed
|
|
144
|
+
2. build the affected flavor output
|
|
145
|
+
3. run `deps:vona`
|
|
146
|
+
4. if backend-side shared types still look stale, escalate to the contract-loop recovery path instead of continuing source-level debugging
|
|
137
147
|
|
|
138
148
|
### Component and interaction follow-up
|
|
139
149
|
|
|
@@ -173,6 +183,7 @@ Stay frontend-first, but if the frontend task clearly depends on backend contrac
|
|
|
173
183
|
- backend OpenAPI output may need refresh or inspection
|
|
174
184
|
- backend DTO/controller response shape may be the real source of truth
|
|
175
185
|
- frontend SDK or schema-driven layers should be regenerated from contract output rather than hand-patched
|
|
186
|
+
- newly added frontend resources that backend metadata will consume may require a reverse handoff through frontend build output and `deps:vona`
|
|
176
187
|
|
|
177
188
|
Do not turn the skill into a backend workflow. Only surface the reminder when the contract boundary is clearly involved.
|
|
178
189
|
|
|
@@ -15,6 +15,8 @@ After generating or extending a frontend thread, check which follow-up layers ap
|
|
|
15
15
|
- SSR init-data needs
|
|
16
16
|
- OpenAPI SDK or schema-driven layer impact
|
|
17
17
|
- backend contract reminder if frontend depends on generated backend contract output
|
|
18
|
+
- if backend metadata will consume newly added frontend render resources, run the relevant Zova build and then `deps:vona`
|
|
19
|
+
- if generated `.zova-rest` output is updated but backend still sees stale shared types, rebuild `vona/node_modules` and reinstall
|
|
18
20
|
|
|
19
21
|
## Interaction and UI follow-up
|
|
20
22
|
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cabloy-module-removal
|
|
3
|
+
description: Use this skill whenever the user wants to remove or delete an existing Cabloy module, retire a demo module, or cleanly take a backend, frontend, or fullstack module out of the monorepo. Trigger for requests such as remove module, delete module, retire module, remove demo module, or remove fullstack module, including equivalent requests in other languages. Prefer it when the task is about deletion order, generated-runtime cleanup, and verification rather than scaffolding or contract evolution.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cabloy Module Removal
|
|
7
|
+
|
|
8
|
+
Use this skill when the user wants to remove an existing module from the Cabloy monorepo.
|
|
9
|
+
|
|
10
|
+
Read the public [Module Removal Playbook](../../../cabloy-docs/ai/playbook-module-removal.md) for the canonical user/agent-facing workflow. This skill is the thinner orchestration layer: it should classify the removal path, choose the right cleanup branch, and point back to the playbook for the shared operational sequence.
|
|
11
|
+
|
|
12
|
+
## Goals
|
|
13
|
+
|
|
14
|
+
1. detect whether the active repository is Cabloy Basic or Cabloy Start
|
|
15
|
+
2. classify the removal scope as backend-only, frontend-only, or fullstack
|
|
16
|
+
3. keep the workflow source-first instead of debugging generated artifacts too early
|
|
17
|
+
4. make the stale-generated-runtime recovery branch explicit when needed
|
|
18
|
+
5. finish with verification guidance that proves the module is gone from the runtime/code graph
|
|
19
|
+
|
|
20
|
+
## Step 1: Detect repo and classify the removal branch
|
|
21
|
+
|
|
22
|
+
Check the repository root for these marker files:
|
|
23
|
+
|
|
24
|
+
- `__CABLOY_BASIC__`
|
|
25
|
+
- `__CABLOY_START__`
|
|
26
|
+
|
|
27
|
+
Interpretation:
|
|
28
|
+
|
|
29
|
+
- `__CABLOY_BASIC__` present → this is Cabloy Basic
|
|
30
|
+
- `__CABLOY_START__` present → this is Cabloy Start
|
|
31
|
+
- neither present → inspect nearby scripts and ask before making edition-specific assumptions
|
|
32
|
+
|
|
33
|
+
Then classify the request into one of three branches:
|
|
34
|
+
|
|
35
|
+
### Branch A: backend-only removal
|
|
36
|
+
|
|
37
|
+
Use this branch when the user is removing only Vona-side code such as:
|
|
38
|
+
|
|
39
|
+
- `vona/src/module/<module>`
|
|
40
|
+
- backend package references
|
|
41
|
+
- backend tests or metadata tied only to Vona
|
|
42
|
+
|
|
43
|
+
### Branch B: frontend-only removal
|
|
44
|
+
|
|
45
|
+
Use this branch when the user is removing only Zova-side code such as:
|
|
46
|
+
|
|
47
|
+
- `zova/src/module/<module>`
|
|
48
|
+
- frontend package references
|
|
49
|
+
- Zova-only API/model/component assets
|
|
50
|
+
|
|
51
|
+
### Branch C: fullstack removal
|
|
52
|
+
|
|
53
|
+
Use this branch when the module exists on both sides or the request affects both Vona and Zova.
|
|
54
|
+
|
|
55
|
+
This is the default branch for demo modules and shared business threads.
|
|
56
|
+
|
|
57
|
+
## Step 2: Inventory real source and direct references first
|
|
58
|
+
|
|
59
|
+
Before proposing or making cleanup steps, inspect the real module surfaces first:
|
|
60
|
+
|
|
61
|
+
- backend and frontend module roots
|
|
62
|
+
- `vona/package.json`
|
|
63
|
+
- `zova/package.json`
|
|
64
|
+
- generated registries or lockfiles that may need refresh
|
|
65
|
+
- tests tied to the module
|
|
66
|
+
- optional docs/examples only if the user explicitly wants a public scrub
|
|
67
|
+
|
|
68
|
+
Start from the shared root scripts first:
|
|
69
|
+
|
|
70
|
+
- `package.json`
|
|
71
|
+
- `npm run vona`
|
|
72
|
+
- `npm run zova`
|
|
73
|
+
|
|
74
|
+
Do not assume a module lives only in one path family until the actual repo layout has been inspected.
|
|
75
|
+
|
|
76
|
+
## Step 3: Keep the normal execution order source-first
|
|
77
|
+
|
|
78
|
+
Point the user or the main workflow to this order:
|
|
79
|
+
|
|
80
|
+
1. remove backend source if in scope
|
|
81
|
+
2. remove frontend source if in scope
|
|
82
|
+
3. remove direct workspace dependency references
|
|
83
|
+
4. run the repo-owned regeneration flow
|
|
84
|
+
5. verify no references remain
|
|
85
|
+
|
|
86
|
+
Important rule:
|
|
87
|
+
|
|
88
|
+
- do not start by hand-editing generated caches or type surfaces while the real source and dependency references still exist
|
|
89
|
+
|
|
90
|
+
Use the playbook for the full operational sequence and representative commands.
|
|
91
|
+
|
|
92
|
+
## Step 4: Use generated-runtime cleanup only as a recovery branch
|
|
93
|
+
|
|
94
|
+
When a module has already been removed from source and direct dependency references, but stale generated types or runtime entries still remain, treat generated runtime directories as disposable working state rather than source-of-truth files.
|
|
95
|
+
|
|
96
|
+
Primary recovery targets for this workflow are:
|
|
97
|
+
|
|
98
|
+
- `vona/.vona`
|
|
99
|
+
- `zova/.zova`
|
|
100
|
+
|
|
101
|
+
These directories are auto-generated by the Vona and Zova CLI flows and may survive when a service or build process does not stop cleanly.
|
|
102
|
+
|
|
103
|
+
This is a recovery branch, not the default first step.
|
|
104
|
+
|
|
105
|
+
After cleanup, rerun the normal build/deps/typecheck flow from the playbook.
|
|
106
|
+
|
|
107
|
+
## Step 5: Finish with branch-aware verification
|
|
108
|
+
|
|
109
|
+
Use the verification path that matches the branch:
|
|
110
|
+
|
|
111
|
+
- backend-only → backend deps/typecheck/tests as needed
|
|
112
|
+
- frontend-only → relevant Zova build/deps/typecheck path
|
|
113
|
+
- fullstack → fullstack regeneration order plus typecheck and targeted tests
|
|
114
|
+
|
|
115
|
+
Verification should prove:
|
|
116
|
+
|
|
117
|
+
- no direct workspace dependency entries remain
|
|
118
|
+
- no stale generated registrations remain
|
|
119
|
+
- no typecheck failures still point at the removed module
|
|
120
|
+
- no important runtime or test surfaces still import the removed module
|
|
121
|
+
|
|
122
|
+
## Step 6: Treat docs cleanup as a separate scope decision
|
|
123
|
+
|
|
124
|
+
Do not assume module deletion automatically means public docs cleanup.
|
|
125
|
+
|
|
126
|
+
Ask or confirm whether the task is:
|
|
127
|
+
|
|
128
|
+
- code/runtime removal only
|
|
129
|
+
- code/runtime removal plus docs/examples scrub
|
|
130
|
+
|
|
131
|
+
If docs cleanup is in scope, update `cabloy-docs/` separately from the runtime cleanup and keep maintainer rationale in `.docs-internal/`.
|
|
132
|
+
|
|
133
|
+
## Response pattern
|
|
134
|
+
|
|
135
|
+
When using this skill, structure the response around these points when helpful:
|
|
136
|
+
|
|
137
|
+
1. detected edition
|
|
138
|
+
2. detected removal scope
|
|
139
|
+
3. real module surfaces involved
|
|
140
|
+
4. recommended cleanup/regeneration branch
|
|
141
|
+
5. stale-generated-runtime recovery branch if needed
|
|
142
|
+
6. verification steps
|
|
143
|
+
|
|
144
|
+
Keep the response practical. The value of this skill is to choose the right removal branch quickly and keep generated working state in the correct role.
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cabloy-resource-field-update
|
|
3
|
+
description: Use this skill whenever the user wants to update a field on an existing Cabloy backend resource: add a new persisted field, refine validation, add enum-like constraints, attach or change ZovaRender.field / ZovaRender.cell metadata, decide whether vonaModule.fileVersion should change, or demonstrate a custom frontend renderer for a backend field. Trigger when the request is specifically about modifying an existing resource field thread rather than creating a new CRUD/resource thread. Prefer it for backend-first field-update work that may branch into renderer-aware frontend follow-up. Do not use it for initial backend scaffolding, generic frontend scaffolding, or stale generated contract diagnosis.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Cabloy Resource Field Update
|
|
7
|
+
|
|
8
|
+
Use this skill when the user wants to change a field on an existing Vona backend resource.
|
|
9
|
+
|
|
10
|
+
## Important recovery note for stale generated consumers
|
|
11
|
+
|
|
12
|
+
When generated `.zova-rest` output already contains the expected new keys or types but Vona still behaves as if old consumer types are installed, treat that first as a local file-dependency installation problem rather than a source-editing problem.
|
|
13
|
+
|
|
14
|
+
In that situation:
|
|
15
|
+
|
|
16
|
+
1. run the normal sync flow such as `deps:vona`
|
|
17
|
+
2. if the stale behavior remains, rebuild `vona/node_modules` and reinstall dependencies
|
|
18
|
+
|
|
19
|
+
Keep this recovery rule visible during renderer-aware or contract-loop follow-up work. Do not keep debugging source-level renderer registrations until the local file-package installation state is known to be healthy.
|
|
20
|
+
|
|
21
|
+
## Goals
|
|
22
|
+
|
|
23
|
+
1. detect whether the active repository is Cabloy Basic or Cabloy Start
|
|
24
|
+
2. classify the task as a new persisted field or a metadata-only field refinement
|
|
25
|
+
3. force the correct `fileVersion` decision before persistence edits
|
|
26
|
+
4. keep the workflow entity-first and inferred-DTO-first
|
|
27
|
+
5. prefer shared renderer reuse unless the task explicitly asks for a custom renderer demo
|
|
28
|
+
6. finish with verification guidance that matches backend and renderer follow-up scope
|
|
29
|
+
|
|
30
|
+
## Step 1: Detect repo and confirm existing-resource scope
|
|
31
|
+
|
|
32
|
+
Check the repository root for these marker files:
|
|
33
|
+
|
|
34
|
+
- `__CABLOY_BASIC__`
|
|
35
|
+
- `__CABLOY_START__`
|
|
36
|
+
|
|
37
|
+
Interpretation:
|
|
38
|
+
|
|
39
|
+
- `__CABLOY_BASIC__` present → this is Cabloy Basic
|
|
40
|
+
- `__CABLOY_START__` present → this is Cabloy Start
|
|
41
|
+
- neither present → inspect nearby scripts and ask before making edition-specific assumptions
|
|
42
|
+
|
|
43
|
+
Then confirm the request is about an **existing** resource field.
|
|
44
|
+
|
|
45
|
+
Use this skill for requests such as:
|
|
46
|
+
|
|
47
|
+
- add a field to an existing resource
|
|
48
|
+
- tighten validation for an existing field
|
|
49
|
+
- add enum-like constraints to an existing field
|
|
50
|
+
- add or change `ZovaRender.field(...)` / `ZovaRender.cell(...)`
|
|
51
|
+
- decide whether a persisted field change needs a new `fileVersion`
|
|
52
|
+
- demonstrate a custom renderer workflow for a backend field
|
|
53
|
+
|
|
54
|
+
Do **not** use this skill when the user is really asking to create a new module, bean, CRUD thread, page thread, or stale consumer diagnosis flow.
|
|
55
|
+
|
|
56
|
+
If the request is really about initial backend thread creation, prefer `cabloy-backend-scaffold`.
|
|
57
|
+
If the request is really about stale generated frontend/backend consumers, prefer `cabloy-contract-loop`.
|
|
58
|
+
If the request is mainly about choosing a workflow, prefer `cabloy-workflow`.
|
|
59
|
+
|
|
60
|
+
## Step 2: Classify the field change before editing
|
|
61
|
+
|
|
62
|
+
Branch the request into one of two cases.
|
|
63
|
+
|
|
64
|
+
### Case A: new persisted field
|
|
65
|
+
|
|
66
|
+
Examples:
|
|
67
|
+
|
|
68
|
+
- add `level: number`
|
|
69
|
+
- add `status: string`
|
|
70
|
+
- add a new stored relation key
|
|
71
|
+
|
|
72
|
+
This case affects persistence and versioning.
|
|
73
|
+
|
|
74
|
+
### Case B: metadata-only or validation/render-only refinement
|
|
75
|
+
|
|
76
|
+
Examples:
|
|
77
|
+
|
|
78
|
+
- add enum validation to an existing field
|
|
79
|
+
- add or change `ZovaRender.field(...)`
|
|
80
|
+
- add or change `ZovaRender.cell(...)`
|
|
81
|
+
- refine locale labels
|
|
82
|
+
- tighten validation without changing storage shape
|
|
83
|
+
|
|
84
|
+
This case usually does **not** require a `fileVersion` bump, because the persisted field already exists.
|
|
85
|
+
|
|
86
|
+
## Step 3: Force the `fileVersion` decision for new persisted fields
|
|
87
|
+
|
|
88
|
+
If the task is a new persisted field on an existing resource, ask whether `vonaModule.fileVersion` should be incremented **before** changing:
|
|
89
|
+
|
|
90
|
+
- `meta.version.ts`
|
|
91
|
+
- the module schema version path
|
|
92
|
+
- the module `package.json` `fileVersion`
|
|
93
|
+
|
|
94
|
+
### If the user says yes
|
|
95
|
+
|
|
96
|
+
Then:
|
|
97
|
+
|
|
98
|
+
1. bump `vonaModule.fileVersion`
|
|
99
|
+
2. add a new migration branch in `meta.version.ts`
|
|
100
|
+
3. preserve older version branches as historical snapshots
|
|
101
|
+
4. introduce the new persisted field in the new version branch
|
|
102
|
+
|
|
103
|
+
Important warning:
|
|
104
|
+
|
|
105
|
+
- do not add the same new column to an older create path and again to a new migration branch
|
|
106
|
+
- fresh install may run version branches sequentially
|
|
107
|
+
- that pattern can produce duplicate-column failures
|
|
108
|
+
|
|
109
|
+
### If the user says no
|
|
110
|
+
|
|
111
|
+
Then:
|
|
112
|
+
|
|
113
|
+
1. keep the current `fileVersion`
|
|
114
|
+
2. fold the schema change into the current version path
|
|
115
|
+
3. do not create a new migration branch
|
|
116
|
+
|
|
117
|
+
## Step 4: Inspect the current backend thread first
|
|
118
|
+
|
|
119
|
+
Before proposing or making edits, inspect the existing thread:
|
|
120
|
+
|
|
121
|
+
- entity
|
|
122
|
+
- model
|
|
123
|
+
- DTOs
|
|
124
|
+
- controller
|
|
125
|
+
- service
|
|
126
|
+
- `meta.version.ts`
|
|
127
|
+
- module `package.json`
|
|
128
|
+
- locale files
|
|
129
|
+
- tests
|
|
130
|
+
|
|
131
|
+
Also inspect the shared entrypoints first:
|
|
132
|
+
|
|
133
|
+
- root `package.json`
|
|
134
|
+
- `npm run vona`
|
|
135
|
+
- `npm run zova`
|
|
136
|
+
|
|
137
|
+
Use these references for compact support material:
|
|
138
|
+
|
|
139
|
+
- `references/field-update-decision-tree.md`
|
|
140
|
+
- `references/follow-up-checklist.md`
|
|
141
|
+
- `references/verification-checklist.md`
|
|
142
|
+
|
|
143
|
+
## Step 5: Update the entity first and reuse inferred DTO flow
|
|
144
|
+
|
|
145
|
+
Treat the entity as the primary field-definition surface.
|
|
146
|
+
|
|
147
|
+
Typical field-update changes belong here first:
|
|
148
|
+
|
|
149
|
+
- `@Api.field(...)`
|
|
150
|
+
- `v.required()` / `v.optional()`
|
|
151
|
+
- `v.title($locale(...))`
|
|
152
|
+
- `ZovaRender.order(...)`
|
|
153
|
+
- explicit zod schema for constrained values
|
|
154
|
+
|
|
155
|
+
For enum-like numeric or string values, prefer an explicit constrained schema such as:
|
|
156
|
+
|
|
157
|
+
- `z.union([z.literal(1), z.literal(2), z.literal(3)])`
|
|
158
|
+
|
|
159
|
+
Then check whether DTOs are already inferred through patterns such as:
|
|
160
|
+
|
|
161
|
+
- `$Dto.create(...)`
|
|
162
|
+
- `$Dto.update(...)`
|
|
163
|
+
- `$Dto.get(...)`
|
|
164
|
+
|
|
165
|
+
If the DTOs are inferred from the entity/model chain, let the entity change propagate. Do not hand-edit DTO field lists unless the source clearly requires it.
|
|
166
|
+
|
|
167
|
+
Important serialization reminder:
|
|
168
|
+
|
|
169
|
+
- if the returned field behavior depends on `v.serializerTransform(...)`, `v.serializerExclude()`, `v.serializerReplace(...)`, `v.serializerGetter(...)`, or `v.serializerCustom(...)`, do not assume those transforms run by default
|
|
170
|
+
- for performance reasons, Vona response serialization is opt-in per API action
|
|
171
|
+
- verify that the target controller action explicitly uses `@Core.serializer()` before concluding that serializer metadata is broken
|
|
172
|
+
|
|
173
|
+
## Step 6: Apply the renderer branch deliberately
|
|
174
|
+
|
|
175
|
+
### Default rule: prefer shared renderer reuse
|
|
176
|
+
|
|
177
|
+
If the field needs form or table rendering metadata, inspect shared renderers first.
|
|
178
|
+
|
|
179
|
+
Default preference order:
|
|
180
|
+
|
|
181
|
+
1. reuse an existing shared renderer
|
|
182
|
+
2. configure it with field-level options
|
|
183
|
+
3. only create a new custom renderer if the shared surface cannot express the needed behavior
|
|
184
|
+
|
|
185
|
+
For enum-like values, apply an edition-aware default.
|
|
186
|
+
|
|
187
|
+
In Cabloy Basic, the usual default is:
|
|
188
|
+
|
|
189
|
+
- `ZovaRender.field('basic-select:formFieldSelect', { items, placeholder })`
|
|
190
|
+
- `ZovaRender.cell('basic-select:select', { items })`
|
|
191
|
+
|
|
192
|
+
In Cabloy Start:
|
|
193
|
+
|
|
194
|
+
- do not assume the same renderer keys or placeholder behavior from Basic
|
|
195
|
+
- inspect the `start-select` wrapper and its underlying component semantics before choosing renderer keys or copying Basic-specific select logic
|
|
196
|
+
|
|
197
|
+
When using a field-rendering select component, default to providing a user-visible `placeholder` unless the UX clearly requires an always-preselected value.
|
|
198
|
+
|
|
199
|
+
In Cabloy Basic, prefer `placeholder` over artificial empty-item injection when the goal is to keep the select initially unchosen.
|
|
200
|
+
|
|
201
|
+
### Custom renderer demo rule
|
|
202
|
+
|
|
203
|
+
If the user explicitly wants to **demonstrate** the custom renderer workflow, branch into a frontend follow-up path.
|
|
204
|
+
|
|
205
|
+
Use these references:
|
|
206
|
+
|
|
207
|
+
- `references/custom-renderer-demo-checklist.md`
|
|
208
|
+
- `.docs-internal/architecture/backend-resource-field-workflow.md`
|
|
209
|
+
|
|
210
|
+
Recommended shape:
|
|
211
|
+
|
|
212
|
+
- module-local FormField component for backend field rendering
|
|
213
|
+
- module-local `@TableCell(...)` bean for backend table-cell rendering
|
|
214
|
+
- metadata regeneration
|
|
215
|
+
- frontend build
|
|
216
|
+
- `deps:vona`
|
|
217
|
+
- Vona-side typecheck and targeted backend test
|
|
218
|
+
|
|
219
|
+
Important warning:
|
|
220
|
+
|
|
221
|
+
- a plain frontend component alone is not enough for backend `ZovaRender.cell(...)`
|
|
222
|
+
- the backend table-cell render key should be backed by a registered `@TableCell(...)` bean
|
|
223
|
+
|
|
224
|
+
## Step 7: Always close the remaining layers
|
|
225
|
+
|
|
226
|
+
### Locale
|
|
227
|
+
|
|
228
|
+
If titles, enum labels, or helper text are user-visible, update locale files in the same task.
|
|
229
|
+
|
|
230
|
+
Typical additions:
|
|
231
|
+
|
|
232
|
+
- field title like `Level`
|
|
233
|
+
- enum labels like `LevelBeginner`, `LevelIntermediate`, `LevelAdvanced`
|
|
234
|
+
- custom renderer helper text when applicable
|
|
235
|
+
|
|
236
|
+
### Tests
|
|
237
|
+
|
|
238
|
+
Minimum expected backend coverage usually includes:
|
|
239
|
+
|
|
240
|
+
- create with the field
|
|
241
|
+
- select/list still works
|
|
242
|
+
- update persists the field
|
|
243
|
+
- get-by-id/view returns the field
|
|
244
|
+
- delete flow still works if relevant
|
|
245
|
+
|
|
246
|
+
For constrained enum-like fields, add a negative test such as:
|
|
247
|
+
|
|
248
|
+
- invalid value is rejected
|
|
249
|
+
|
|
250
|
+
### Verification
|
|
251
|
+
|
|
252
|
+
Always end with a verification path matched to the scope.
|
|
253
|
+
|
|
254
|
+
Typical checks include:
|
|
255
|
+
|
|
256
|
+
- `npm run test`
|
|
257
|
+
- `npm run tsc`
|
|
258
|
+
- `npm run build`
|
|
259
|
+
- narrow resource test runs
|
|
260
|
+
- when returned-field masking or exclusion uses `v.serializer*`, verify the action-level `@Core.serializer()` path with an API test, not only static field metadata inspection
|
|
261
|
+
- renderer/build/deps synchronization when custom frontend renderers are involved
|
|
262
|
+
|
|
263
|
+
## Response pattern
|
|
264
|
+
|
|
265
|
+
When helpful, structure the response around these points:
|
|
266
|
+
|
|
267
|
+
1. detected edition
|
|
268
|
+
2. persisted-field vs metadata-only classification
|
|
269
|
+
3. `fileVersion` decision if needed
|
|
270
|
+
4. backend thread surfaces to inspect or modify
|
|
271
|
+
5. shared-renderer reuse vs custom-renderer branch
|
|
272
|
+
6. verification steps
|
|
273
|
+
|
|
274
|
+
Keep the response practical. The value of this skill is turning existing-resource field updates into the correct Cabloy decision tree with the right backend and renderer follow-up, not writing a broad architecture essay.
|