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.
Files changed (149) hide show
  1. package/.claude/hooks/contract-loop-gate.ts +296 -0
  2. package/.claude/settings.json +16 -0
  3. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +1 -0
  4. package/.claude/skills/cabloy-contract-loop/SKILL.md +103 -14
  5. package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +126 -12
  6. package/.claude/skills/cabloy-contract-loop/references/resource-custom-state-pattern.md +148 -0
  7. package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +49 -13
  8. package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +11 -0
  9. package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +2 -0
  10. package/.claude/skills/cabloy-module-removal/SKILL.md +144 -0
  11. package/.claude/skills/cabloy-resource-field-update/SKILL.md +274 -0
  12. package/.claude/skills/cabloy-resource-field-update/evals/evals.json +53 -0
  13. package/.claude/skills/cabloy-resource-field-update/references/custom-renderer-demo-checklist.md +102 -0
  14. package/.claude/skills/cabloy-resource-field-update/references/field-update-decision-tree.md +120 -0
  15. package/.claude/skills/cabloy-resource-field-update/references/follow-up-checklist.md +80 -0
  16. package/.claude/skills/cabloy-resource-field-update/references/verification-checklist.md +97 -0
  17. package/.claude/skills/cabloy-zova-source-reading/SKILL.md +221 -0
  18. package/.claude/skills/cabloy-zova-source-reading/references/analysis-modes.md +91 -0
  19. package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +117 -0
  20. package/.github/workflows/docs-pages.yml +2 -0
  21. package/.github/workflows/vona-cov-pg.yml +2 -0
  22. package/.github/workflows/vona-test-crud.yml +4 -2
  23. package/.github/workflows/vona-test-mysql.yml +2 -0
  24. package/.github/workflows/vona-test-pg.yml +2 -0
  25. package/.github/workflows/vona-test-sqlite3.yml +2 -0
  26. package/.github/workflows/vona-tsc.yml +2 -0
  27. package/.github/workflows/zova-ui.yml +2 -0
  28. package/.gitignore +0 -4
  29. package/CHANGELOG.md +52 -0
  30. package/CLAUDE.md +12 -0
  31. package/README.md +15 -0
  32. package/cabloy-docs/.vitepress/config.mjs +89 -0
  33. package/cabloy-docs/ai/class-placement-rule.md +2 -0
  34. package/cabloy-docs/ai/cli-to-skill-map.md +14 -0
  35. package/cabloy-docs/ai/docs-skills-rules-mapping.md +14 -0
  36. package/cabloy-docs/ai/future-skill-roadmap.md +27 -9
  37. package/cabloy-docs/ai/introduction.md +1 -0
  38. package/cabloy-docs/ai/playbook-backend-module.md +6 -0
  39. package/cabloy-docs/ai/playbook-module-removal.md +164 -0
  40. package/cabloy-docs/ai/skills.md +11 -0
  41. package/cabloy-docs/backend/bean-scene-authoring.md +350 -0
  42. package/cabloy-docs/backend/cli.md +26 -1
  43. package/cabloy-docs/backend/dto-guide.md +6 -0
  44. package/cabloy-docs/backend/entity-guide.md +18 -0
  45. package/cabloy-docs/backend/foundation.md +28 -3
  46. package/cabloy-docs/backend/introduction.md +10 -0
  47. package/cabloy-docs/backend/serialization-guide.md +10 -0
  48. package/cabloy-docs/backend/service-guide.md +2 -0
  49. package/cabloy-docs/backend/status-guide.md +271 -0
  50. package/cabloy-docs/backend/websocket-call-flow.md +435 -0
  51. package/cabloy-docs/backend/websocket-guide.md +455 -0
  52. package/cabloy-docs/backend/websocket-protocol-guide.md +381 -0
  53. package/cabloy-docs/backend/websocket-usage-guide.md +356 -0
  54. package/cabloy-docs/frontend/api-guide.md +2 -0
  55. package/cabloy-docs/frontend/bean-scene-authoring.md +374 -0
  56. package/cabloy-docs/frontend/behavior-guide.md +449 -0
  57. package/cabloy-docs/frontend/cli.md +24 -0
  58. package/cabloy-docs/frontend/command-scene-authoring.md +495 -0
  59. package/cabloy-docs/frontend/design-principles.md +6 -0
  60. package/cabloy-docs/frontend/fetch-interceptor-guide.md +440 -0
  61. package/cabloy-docs/frontend/form-guide.md +795 -0
  62. package/cabloy-docs/frontend/foundation.md +29 -0
  63. package/cabloy-docs/frontend/introduction.md +17 -1
  64. package/cabloy-docs/frontend/ioc-and-beans.md +16 -9
  65. package/cabloy-docs/frontend/mock-guide.md +1 -0
  66. package/cabloy-docs/frontend/model-architecture.md +252 -39
  67. package/cabloy-docs/frontend/model-resource-best-practices.md +379 -0
  68. package/cabloy-docs/frontend/model-resource-cookbook.md +505 -0
  69. package/cabloy-docs/frontend/model-resource-owner-pattern.md +382 -0
  70. package/cabloy-docs/frontend/model-resource-usage-guide.md +318 -0
  71. package/cabloy-docs/frontend/model-state-guide.md +366 -13
  72. package/cabloy-docs/frontend/openapi-sdk-guide.md +5 -2
  73. package/cabloy-docs/frontend/page-guide.md +6 -0
  74. package/cabloy-docs/frontend/quickstart.md +4 -0
  75. package/cabloy-docs/frontend/reading-zova-for-vue-developers.md +266 -0
  76. package/cabloy-docs/frontend/router-tabs-admin-web-comparison.md +206 -0
  77. package/cabloy-docs/frontend/router-tabs-introduction.md +106 -0
  78. package/cabloy-docs/frontend/router-tabs-mechanism.md +469 -0
  79. package/cabloy-docs/frontend/router-tabs-overview.md +227 -0
  80. package/cabloy-docs/frontend/router-tabs-route-meta-cookbook.md +343 -0
  81. package/cabloy-docs/frontend/server-data.md +2 -0
  82. package/cabloy-docs/frontend/ssr-architecture-overview.md +211 -0
  83. package/cabloy-docs/frontend/ssr-build-deploy-guide.md +308 -0
  84. package/cabloy-docs/frontend/ssr-review-checklist.md +184 -0
  85. package/cabloy-docs/frontend/ssr-troubleshooting-guide.md +301 -0
  86. package/cabloy-docs/frontend/zova-form-source-reading-map.md +295 -0
  87. package/cabloy-docs/frontend/zova-form-under-the-hood.md +556 -0
  88. package/cabloy-docs/frontend/zova-reactivity-under-the-hood.md +320 -0
  89. package/cabloy-docs/frontend/zova-source-reading-map.md +327 -0
  90. package/cabloy-docs/frontend/zova-vs-vue3-comparison.md +308 -0
  91. package/cabloy-docs/fullstack/contract-loop-playbook.md +350 -0
  92. package/cabloy-docs/fullstack/framework-performance.md +3 -3
  93. package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +44 -1
  94. package/cabloy-docs/fullstack/introduction.md +40 -0
  95. package/cabloy-docs/fullstack/openapi-to-sdk.md +19 -9
  96. package/cabloy-docs/fullstack/quickstart.md +7 -1
  97. package/cabloy-docs/fullstack/tutorial-1-first-module.md +111 -0
  98. package/cabloy-docs/fullstack/tutorial-2-first-crud.md +122 -0
  99. package/cabloy-docs/fullstack/tutorial-3-frontend-metadata-sharing.md +131 -0
  100. package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +144 -0
  101. package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +146 -0
  102. package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +170 -0
  103. package/cabloy-docs/fullstack/tutorials-overview.md +192 -0
  104. package/cabloy-docs/index.md +4 -3
  105. package/cabloy-docs/reference/bean-scene-boilerplates.md +75 -0
  106. package/cabloy-docs/reference/cli-reference.md +2 -0
  107. package/package.json +7 -2
  108. package/scripts/initTestData.ts +25 -0
  109. package/scripts/upgrade.ts +17 -2
  110. package/vona/packages-cli/cabloy-cli/package.json +2 -2
  111. package/vona/packages-cli/cli/package.json +1 -1
  112. package/vona/packages-cli/cli-set-api/package.json +1 -1
  113. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.create.module.ts +4 -0
  114. package/vona/packages-vona/vona/package.json +1 -1
  115. package/vona/pnpm-lock.yaml +226 -1091
  116. package/vona/pnpm-workspace.yaml +0 -1
  117. package/vona/src/suite-vendor/a-vona/modules/a-core/assets/static/img/vona.svg +1 -1
  118. package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
  119. package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
  120. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +1 -1
  121. package/vona/src/suite-vendor/a-vona/modules/a-upload/package.json +2 -2
  122. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  123. package/zova/package.original.json +1 -1
  124. package/zova/packages-cli/cli/package.json +3 -3
  125. package/zova/packages-cli/cli-set-front/cli/templates/init/icon/boilerplate/icons/default/zova.svg +1 -1
  126. package/zova/packages-cli/cli-set-front/cli/templates/openapi/config/boilerplate/module/openapi.config.ts +6 -1
  127. package/zova/packages-cli/cli-set-front/package.json +3 -3
  128. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.create.module.ts +4 -0
  129. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +34 -4
  130. package/zova/packages-cli/cli-set-front/src/lib/command/create.bean.ts +5 -1
  131. package/zova/packages-utils/zova-vite/package.json +2 -2
  132. package/zova/packages-zova/zova/package.json +2 -2
  133. package/zova/pnpm-lock.yaml +282 -1311
  134. package/zova/pnpm-workspace.yaml +0 -1
  135. package/zova/src/suite/a-home/modules/home-icon/icons/social/cabloy.svg +1 -1
  136. package/zova/src/suite/a-home/modules/home-icon/icons/social/vona.svg +1 -1
  137. package/zova/src/suite/a-home/modules/home-icon/icons/social/zova.svg +1 -1
  138. package/zova/src/suite/a-home/modules/home-icon/src/.metadata/icons/groups/social.svg +3 -3
  139. package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +9 -0
  140. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  141. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +66 -16
  142. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  143. package/zova/src/suite-vendor/a-zova/modules/a-routertabs/package.json +1 -1
  144. package/zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts +60 -18
  145. package/zova/src/suite-vendor/a-zova/modules/a-table/cli/tableActionRow/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
  146. package/zova/src/suite-vendor/a-zova/modules/a-table/cli/tableCell/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
  147. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
  148. package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
  149. 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, check both sides.
3
+ After a contract-loop change, verify the branch that actually applies.
4
4
 
5
- ## Backend verification
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
- - backend tests pass
11
- - `npm run test`
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
- ## Frontend verification
24
+ ## Reverse chain verification
16
25
 
17
- - regeneration commands completed successfully
18
- - generated SDK/schema outputs are updated
19
- - API/model/page/component consumers still typecheck
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
- ## Edition verification
39
+ ## Consumer drift verification
25
40
 
26
- - Basic or Start marker confirmed
27
- - affected flavor confirmed
28
- - generation path matches the active edition
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.