cabloy 5.1.60 → 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 (76) 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 +89 -16
  5. package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +102 -14
  6. package/.claude/skills/cabloy-contract-loop/references/resource-custom-state-pattern.md +4 -0
  7. package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +32 -14
  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 +7 -0
  12. package/.claude/skills/cabloy-zova-source-reading/SKILL.md +221 -0
  13. package/.claude/skills/cabloy-zova-source-reading/references/analysis-modes.md +91 -0
  14. package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +117 -0
  15. package/CHANGELOG.md +22 -0
  16. package/CLAUDE.md +10 -0
  17. package/cabloy-docs/.vitepress/config.mjs +50 -4
  18. package/cabloy-docs/ai/cli-to-skill-map.md +7 -0
  19. package/cabloy-docs/ai/docs-skills-rules-mapping.md +14 -0
  20. package/cabloy-docs/ai/future-skill-roadmap.md +10 -7
  21. package/cabloy-docs/ai/introduction.md +1 -0
  22. package/cabloy-docs/ai/playbook-backend-module.md +6 -0
  23. package/cabloy-docs/ai/playbook-module-removal.md +164 -0
  24. package/cabloy-docs/ai/skills.md +11 -0
  25. package/cabloy-docs/backend/dto-guide.md +6 -0
  26. package/cabloy-docs/backend/entity-guide.md +18 -0
  27. package/cabloy-docs/backend/introduction.md +2 -0
  28. package/cabloy-docs/backend/serialization-guide.md +10 -0
  29. package/cabloy-docs/backend/status-guide.md +271 -0
  30. package/cabloy-docs/frontend/api-guide.md +2 -0
  31. package/cabloy-docs/frontend/bean-scene-authoring.md +2 -0
  32. package/cabloy-docs/frontend/cli.md +12 -0
  33. package/cabloy-docs/frontend/command-scene-authoring.md +495 -0
  34. package/cabloy-docs/frontend/design-principles.md +6 -0
  35. package/cabloy-docs/frontend/fetch-interceptor-guide.md +440 -0
  36. package/cabloy-docs/frontend/form-guide.md +795 -0
  37. package/cabloy-docs/frontend/foundation.md +29 -0
  38. package/cabloy-docs/frontend/introduction.md +12 -1
  39. package/cabloy-docs/frontend/ioc-and-beans.md +6 -0
  40. package/cabloy-docs/frontend/mock-guide.md +1 -0
  41. package/cabloy-docs/frontend/model-architecture.md +252 -39
  42. package/cabloy-docs/frontend/model-resource-best-practices.md +379 -0
  43. package/cabloy-docs/frontend/model-resource-cookbook.md +505 -0
  44. package/cabloy-docs/frontend/model-resource-owner-pattern.md +382 -0
  45. package/cabloy-docs/frontend/model-resource-usage-guide.md +318 -0
  46. package/cabloy-docs/frontend/model-state-guide.md +366 -13
  47. package/cabloy-docs/frontend/openapi-sdk-guide.md +5 -2
  48. package/cabloy-docs/frontend/page-guide.md +6 -0
  49. package/cabloy-docs/frontend/quickstart.md +4 -0
  50. package/cabloy-docs/frontend/reading-zova-for-vue-developers.md +266 -0
  51. package/cabloy-docs/frontend/server-data.md +2 -0
  52. package/cabloy-docs/frontend/zova-form-source-reading-map.md +295 -0
  53. package/cabloy-docs/frontend/zova-form-under-the-hood.md +556 -0
  54. package/cabloy-docs/frontend/zova-reactivity-under-the-hood.md +320 -0
  55. package/cabloy-docs/frontend/zova-source-reading-map.md +327 -0
  56. package/cabloy-docs/frontend/zova-vs-vue3-comparison.md +308 -0
  57. package/cabloy-docs/fullstack/contract-loop-playbook.md +350 -0
  58. package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +44 -1
  59. package/cabloy-docs/fullstack/introduction.md +12 -1
  60. package/cabloy-docs/fullstack/openapi-to-sdk.md +19 -9
  61. package/cabloy-docs/fullstack/tutorial-3-frontend-metadata-sharing.md +2 -2
  62. package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +30 -5
  63. package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +9 -7
  64. package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +2 -0
  65. package/cabloy-docs/fullstack/tutorials-overview.md +16 -3
  66. package/cabloy-docs/reference/bean-scene-boilerplates.md +2 -0
  67. package/package.json +2 -1
  68. package/scripts/init.ts +2 -18
  69. package/scripts/initTestData.ts +25 -0
  70. package/scripts/upgrade.ts +17 -2
  71. package/vona/pnpm-lock.yaml +94 -4
  72. package/zova/packages-cli/cli/package.json +2 -2
  73. package/zova/packages-cli/cli-set-front/cli/templates/openapi/config/boilerplate/module/openapi.config.ts +6 -1
  74. package/zova/packages-cli/cli-set-front/package.json +1 -1
  75. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +34 -4
  76. package/zova/pnpm-lock.yaml +20 -20
@@ -0,0 +1,117 @@
1
+ # Core Reading Paths
2
+
3
+ Use this reference to choose the shortest source path after the analysis mode is known.
4
+
5
+ ## Page controller and page reactivity
6
+
7
+ Read in this order:
8
+
9
+ 1. the concrete page controller source
10
+ 2. `zova-core/src/composables/useController.ts`
11
+ 3. `zova-core/src/bean/beanContainer.ts`
12
+ 4. `zova-core/src/bean/beanBase.ts`
13
+ 5. `zova-core/src/bean/beanControllerPageBase.ts`
14
+ 6. `zova-core/src/core/context/component.ts`
15
+ 7. router integration files such as `a-router/src/monkey.ts`
16
+
17
+ Use when the question is about:
18
+
19
+ - plain controller fields
20
+ - `$computed`
21
+ - `$params` / `$query`
22
+ - page render flow
23
+
24
+ ## Component controller and wrapper path
25
+
26
+ Read in this order:
27
+
28
+ 1. representative wrapper metadata under `src/.metadata/component/`
29
+ 2. `zova-core/src/composables/useController.ts`
30
+ 3. `zova-core/src/bean/beanControllerBase.ts`
31
+ 4. `zova-core/src/core/context/component.ts`
32
+ 5. the concrete component controller source
33
+
34
+ Use when the question is about:
35
+
36
+ - wrapper components
37
+ - `controllerRef`
38
+ - component-local controller behavior
39
+
40
+ ## Bean lifecycle and helper API path
41
+
42
+ Read in this order:
43
+
44
+ 1. `zova-core/src/bean/beanBase.ts`
45
+ 2. `zova-core/src/bean/beanBaseSimple.ts`
46
+ 3. `zova-core/src/bean/beanContainer.ts`
47
+ 4. `zova-core/src/core/context/util.ts`
48
+
49
+ Use when the question is about:
50
+
51
+ - `__init__`
52
+ - `__dispose__`
53
+ - `$watch`
54
+ - `$toRef`
55
+ - instance scope
56
+
57
+ ## Route and page-shell path
58
+
59
+ Read in this order:
60
+
61
+ 1. the local `routes.ts`
62
+ 2. `a-router/src/monkey.ts`
63
+ 3. router utility files
64
+ 4. page schema sources
65
+ 5. `BeanControllerPageBase`
66
+
67
+ Use when the question is about:
68
+
69
+ - route records
70
+ - params/query parsing
71
+ - layout shell implications
72
+ - route-aware controller state
73
+
74
+ ## Model/state ownership path
75
+
76
+ Read in this order:
77
+
78
+ 1. the relevant model bean
79
+ 2. framework model state helper files
80
+ 3. representative built-in model beans
81
+ 4. consuming page/controller/service code
82
+
83
+ Use when the question is about:
84
+
85
+ - model-owned state
86
+ - cache-oriented state
87
+ - async vs sync state ownership
88
+
89
+ ## Behavior path
90
+
91
+ Read in this order:
92
+
93
+ 1. the public behavior wrapper/controller path
94
+ 2. the concrete behavior bean
95
+ 3. the behavior composer/service files
96
+ 4. host-scoped injected dependencies
97
+
98
+ Use when the question is about:
99
+
100
+ - render-time interception
101
+ - behavior composition
102
+ - Behavior vs Component vs Helper
103
+
104
+ ## SSR runtime path
105
+
106
+ Read in this order:
107
+
108
+ 1. the SSR site or bundle entry
109
+ 2. SSR runtime/context files in `zova-core`
110
+ 3. relevant page/controller/model code
111
+ 4. Vona SSR handoff layer if needed
112
+
113
+ Use when the question is about:
114
+
115
+ - SSR entry
116
+ - hydration handoff
117
+ - whether the bug belongs to Vona or Zova
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.1.61
4
+
5
+ ### Features
6
+
7
+ - Enforce explicit OpenAPI operation filters.
8
+ - Remove the demo-student module and document the module-removal workflow.
9
+ - Add a mobile field to students and document serializer guidance.
10
+
11
+ ### Bug Fixes
12
+
13
+ - Decouple test data initialization from application initialization.
14
+ - Refresh the student summary after updates.
15
+
16
+ ### Improvements
17
+
18
+ - Migrate the contract-loop hook to TypeScript.
19
+ - Harden and simplify contract-loop guidance and gate behavior.
20
+ - Add Zova Form documentation and navigation.
21
+ - Refine ModelResource guidance and examples.
22
+ - Add Zova command scene, fetch interceptor, frontend reading, and Status architecture guides.
23
+ - Update backend contract-sharing tutorial and related skill documentation.
24
+
3
25
  ## 5.1.60
4
26
 
5
27
  ### Features
package/CLAUDE.md CHANGED
@@ -42,8 +42,18 @@ Before inventing a custom implementation path:
42
42
  ## AI development rules
43
43
 
44
44
  - Prefer CLI-backed workflows over manual scaffolding whenever Vona or Zova already provides a generator, refactor, metadata, or verification command.
45
+ - The Cabloy contract-loop model applies to both Cabloy Basic and Cabloy Start; detect the edition to choose commands and output paths, not to redefine the workflow model.
46
+ - Treat contract-loop work as one of four branches: forward chain, reverse chain, consumer drift, or local dependency drift.
47
+ - For the forward chain, change backend contract truth first and regenerate frontend consumers rather than hand-patching them.
48
+ - After forward regeneration, keep frontend follow-up thin: prefer semantic model facades and reuse the existing resource-owner when the custom API still belongs to the same resource.
49
+ - For the reverse chain, when Vona consumes newly added or changed Zova Admin render/action/metadata, always run `npm run build:zova:admin` before `npm run deps:vona`. Do not treat `build:rest:cabloyBasicAdmin` alone as sufficient, because the Admin JS bundle and rest output must move together.
50
+ - If generated artifacts already contain the expected changes but consumers still behave stale, suspect local dependency drift before making more source edits.
51
+ - For Cabloy Start, apply the same reverse-chain logic but resolve the Start-specific flavor names and generated-output paths from the active Start repo before recommending commands.
45
52
  - Treat legacy docs as input material, not as unquestioned truth. When docs conflict with source code, prefer current source code.
46
53
  - For frontend work, assume Cabloy Basic and Cabloy Start share a frontend engineering layer but may diverge in UI layer, frontend flavors, suite/module availability, SSR site baselines, project assets, and generated outputs.
54
+ - For Zova frontend analysis, do not default to generic Vue reinterpretation first. Read the code through Zova’s controller / bean / IoC architecture before mapping it to Vue concepts.
55
+ - For Zova source-reading or Vue-vs-Zova explanation tasks, start from the frontend reading guides and source-reading map in `cabloy-docs/frontend/` before doing framework-neutral reinterpretation.
56
+ - Keep repo-wide AI rules in `CLAUDE.md` short and durable; put branching Zova analysis workflows in `.claude/skills/`.
47
57
  - For SSR theme-sensitive frontend work, detect the active edition marker and UI library before making assumptions. Cabloy Basic currently means DaisyUI + Tailwind CSS assumptions; Cabloy Start currently means Vuetify assumptions.
48
58
  - In Web SSR without cookie-backed theme resolution, do not treat server reads of `$theme.dark`, `$theme.darkMode`, or `$token` as final browser truth. Keep theme-sensitive SSR branching hydration-tolerant or defer final theme-sensitive decisions to the client.
49
59
  - Do not assume Cabloy Basic and Cabloy Start use the same adapter-level SSR theme handoff. Verify the active theme handler and client hydration path before changing SSR theme behavior.
@@ -23,6 +23,7 @@ const aiItems = [
23
23
  { text: 'Playbook: Backend Module', link: '/ai/playbook-backend-module' },
24
24
  { text: 'Playbook: Frontend Page', link: '/ai/playbook-frontend-page' },
25
25
  { text: 'Playbook: Contract Regeneration', link: '/ai/playbook-contract-regeneration' },
26
+ { text: 'Playbook: Module Removal', link: '/ai/playbook-module-removal' },
26
27
  { text: 'Playbook: Metadata Refresh', link: '/ai/playbook-metadata-refresh' },
27
28
  { text: 'CLI for Agents', link: '/ai/cli-for-agents' },
28
29
  { text: 'Rules and Config', link: '/ai/rules-and-config' },
@@ -50,12 +51,16 @@ const fullstackGroups = [
50
51
  link: '/fullstack/tutorial-3-frontend-metadata-sharing',
51
52
  },
52
53
  {
53
- text: 'Tutorial 4: Backend Contract Sharing',
54
- link: '/fullstack/tutorial-4-backend-contract-sharing',
54
+ text: 'Tutorial 4: Custom Form/Table Renderers for Level',
55
+ link: '/fullstack/tutorial-4-custom-level-renderers',
55
56
  },
56
57
  {
57
- text: 'Tutorial 5: One Contract Surface, Four Uses',
58
- link: '/fullstack/tutorial-5-one-contract-four-uses',
58
+ text: 'Tutorial 5: Backend Contract Sharing',
59
+ link: '/fullstack/tutorial-5-backend-contract-sharing',
60
+ },
61
+ {
62
+ text: 'Tutorial 6: One Contract Surface, Four Uses',
63
+ link: '/fullstack/tutorial-6-one-contract-four-uses',
59
64
  },
60
65
  ],
61
66
  },
@@ -75,6 +80,7 @@ const fullstackGroups = [
75
80
  },
76
81
  { text: 'Framework Performance', link: '/fullstack/framework-performance' },
77
82
  { text: 'Vona + Zova Integration', link: '/fullstack/vona-zova-integration' },
83
+ { text: 'Contract Loop Playbook', link: '/fullstack/contract-loop-playbook' },
78
84
  { text: 'Backend OpenAPI to Frontend SDK', link: '/fullstack/openapi-to-sdk' },
79
85
  {
80
86
  text: 'Frontend Metadata Back to Backend',
@@ -243,6 +249,7 @@ export default defineConfig({
243
249
  { text: 'Queue Guide', link: '/backend/queue-guide' },
244
250
  { text: 'Election Guide', link: '/backend/election-guide' },
245
251
  { text: 'Schedule Guide', link: '/backend/schedule-guide' },
252
+ { text: 'Status Guide', link: '/backend/status-guide' },
246
253
  { text: 'Worker Guide', link: '/backend/worker-guide' },
247
254
  { text: 'Broadcast Guide', link: '/backend/broadcast-guide' },
248
255
  { text: 'Web Socket Guide', link: '/backend/websocket-guide' },
@@ -268,6 +275,22 @@ export default defineConfig({
268
275
  { text: 'Introduction', link: '/frontend/introduction' },
269
276
  { text: 'Quickstart', link: '/frontend/quickstart' },
270
277
  { text: 'Foundation', link: '/frontend/foundation' },
278
+ {
279
+ text: 'Reading Zova for Vue Developers',
280
+ link: '/frontend/reading-zova-for-vue-developers',
281
+ },
282
+ {
283
+ text: 'Zova vs Vue 3 Comparison',
284
+ link: '/frontend/zova-vs-vue3-comparison',
285
+ },
286
+ {
287
+ text: 'Zova Reactivity Under the Hood',
288
+ link: '/frontend/zova-reactivity-under-the-hood',
289
+ },
290
+ {
291
+ text: 'Zova Source Reading Map',
292
+ link: '/frontend/zova-source-reading-map',
293
+ },
271
294
  ],
272
295
  },
273
296
  {
@@ -324,6 +347,15 @@ export default defineConfig({
324
347
  text: 'Components & UI',
325
348
  items: [
326
349
  { text: 'Component Guide', link: '/frontend/component-guide' },
350
+ { text: 'Form Guide', link: '/frontend/form-guide' },
351
+ {
352
+ text: 'Zova Form Under the Hood',
353
+ link: '/frontend/zova-form-under-the-hood',
354
+ },
355
+ {
356
+ text: 'Zova Form Source Reading Map',
357
+ link: '/frontend/zova-form-source-reading-map',
358
+ },
327
359
  { text: 'Component Props Guide', link: '/frontend/component-props-guide' },
328
360
  { text: 'Component v-model Guide', link: '/frontend/component-v-model-guide' },
329
361
  { text: 'Generic Component Guide', link: '/frontend/generic-component-guide' },
@@ -336,9 +368,23 @@ export default defineConfig({
336
368
  text: 'Data & State',
337
369
  items: [
338
370
  { text: 'Server Data', link: '/frontend/server-data' },
371
+ { text: 'Fetch Interceptor Guide', link: '/frontend/fetch-interceptor-guide' },
339
372
  { text: 'API Guide', link: '/frontend/api-guide' },
340
373
  { text: 'Model Architecture', link: '/frontend/model-architecture' },
341
374
  { text: 'Model State Guide', link: '/frontend/model-state-guide' },
375
+ { text: 'Model Resource Owner Pattern', link: '/frontend/model-resource-owner-pattern' },
376
+ {
377
+ text: 'Using ModelResource in Your Module',
378
+ link: '/frontend/model-resource-usage-guide',
379
+ },
380
+ {
381
+ text: 'Resource Model Best Practices',
382
+ link: '/frontend/model-resource-best-practices',
383
+ },
384
+ {
385
+ text: 'Resource Model Cookbook',
386
+ link: '/frontend/model-resource-cookbook',
387
+ },
342
388
  ],
343
389
  },
344
390
  {
@@ -152,6 +152,13 @@ Typical skill role:
152
152
  - likely CLI path: Vona persistence verification plus Zova metadata/build flows only if renderer follow-up is required
153
153
  - skill then verifies entity, locale, tests, `fileVersion` logic, and renderer/build/deps follow-up when applicable
154
154
 
155
+ ### Example: “Remove an existing module cleanly”
156
+
157
+ - skill decides this is a module-removal workflow rather than scaffolding or contract evolution
158
+ - skill classifies backend-only vs frontend-only vs fullstack removal
159
+ - likely CLI path: root build/deps/typecheck scripts such as `npm run build:zova:admin`, `npm run deps:vona`, `npm run deps:zova`, and `npm run tsc`
160
+ - skill then verifies that source, package references, generated registrations, and stale runtime directories are handled in the correct order
161
+
155
162
  ## Anti-patterns
156
163
 
157
164
  Avoid these mistakes in skills:
@@ -143,6 +143,20 @@ Use this quick rule:
143
143
  - full explanation → [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk)
144
144
  - workflow steering → skill and rules can point to the docs and choose the right CLI path
145
145
 
146
+ ### Example: “How should AI remove an existing module cleanly?”
147
+
148
+ - public operational explanation → [Playbook: Module Removal](/ai/playbook-module-removal)
149
+ - maintainer rationale and pitfalls → `.docs-internal/architecture/module-removal-workflow.md`
150
+ - avoid putting the full workflow in `CLAUDE.md` because the task needs branching, cleanup order, generated-runtime recovery, and verification
151
+ - procedural decision workflow → `cabloy-module-removal` skill
152
+
153
+ ### Example: “What `@Api.field(...)` ordering rule should AI preserve when mixing helpers and zod?”
154
+
155
+ - full explanation → [Entity Guide](/backend/entity-guide) and [DTO Guide](/backend/dto-guide)
156
+ - AI workflow reminder → [Playbook: Add a Backend Module](/ai/playbook-backend-module)
157
+ - procedural checklist reminder → backend scaffold skill references
158
+ - avoid putting the full explanation only in `CLAUDE.md` because this is a framework-specific authoring rule, not a short global behavior rule
159
+
146
160
  ## Anti-patterns to avoid
147
161
 
148
162
  Avoid these mistakes:
@@ -10,18 +10,21 @@ A roadmap helps convert that documented knowledge into a focused set of high-val
10
10
 
11
11
  ## What already exists
12
12
 
13
- Current root skill:
13
+ Current root skills include:
14
14
 
15
15
  - `cabloy-workflow`
16
+ - `cabloy-contract-loop`
17
+ - `cabloy-resource-field-update`
18
+ - `cabloy-module-removal`
16
19
 
17
- Its current role is broad workflow selection:
20
+ Their current roles are:
18
21
 
19
- - detect Basic vs Start
20
- - classify backend/frontend/fullstack/docs work
21
- - prefer CLI-first behavior
22
- - suggest verification
22
+ - `cabloy-workflow` broad workflow selection, edition detection, CLI-first routing, and verification framing
23
+ - `cabloy-contract-loop` backend/frontend contract regeneration, reverse-chain handling, and drift diagnosis
24
+ - `cabloy-resource-field-update` → existing backend resource-field changes with `fileVersion` and renderer-aware follow-up
25
+ - `cabloy-module-removal` → backend/frontend/fullstack module deletion order, generated-runtime cleanup, and verification
23
26
 
24
- This is a strong foundation skill, but it is intentionally general.
27
+ This is now a stronger foundation skill set, but it still leaves several useful workflow families for future specialization.
25
28
 
26
29
  ## Recommended next skill families
27
30
 
@@ -75,6 +75,7 @@ Use this path when the task is about implementing or reviewing Cabloy code with
75
75
  - [Playbook: Backend Module](/ai/playbook-backend-module)
76
76
  - [Playbook: Frontend Page](/ai/playbook-frontend-page)
77
77
  - [Playbook: Contract Regeneration](/ai/playbook-contract-regeneration)
78
+ - [Playbook: Module Removal](/ai/playbook-module-removal)
78
79
  - [Playbook: Metadata Refresh](/ai/playbook-metadata-refresh)
79
80
 
80
81
  ### Verification and roadmap path
@@ -66,6 +66,12 @@ Depending on the feature, extend the generated code with the right framework-lev
66
66
  - migration and changes
67
67
  - field indexes
68
68
 
69
+ When refining entity or DTO fields that use `@Api.field(...)`, apply this framework-specific guardrail:
70
+
71
+ - if you include an explicit zod schema such as `z.number().int().min(1)`, place it as the **last argument**
72
+ - keep helper metadata such as `v.xxx(...)` and `ZovaRender.xxx(...)` before the zod schema
73
+ - otherwise helpers written after the zod schema may stop taking effect
74
+
69
75
  Relevant docs:
70
76
 
71
77
  - [Controller Guide](/backend/controller-guide)
@@ -0,0 +1,164 @@
1
+ # Playbook: Remove a Cabloy Module
2
+
3
+ This playbook turns Cabloy module deletion into a repeatable AI-friendly workflow.
4
+
5
+ ## When to use this playbook
6
+
7
+ Use this playbook when the goal is to remove an existing module from the Cabloy monorepo.
8
+
9
+ Typical triggers include:
10
+
11
+ - delete a demo module
12
+ - retire a backend module
13
+ - remove a frontend module
14
+ - remove a fullstack module that exists in both Vona and Zova
15
+ - clean up stale generated runtime or type residues after a module was removed
16
+
17
+ ## Step 1: Detect the repo and scope
18
+
19
+ Before deleting anything:
20
+
21
+ 1. detect whether the active repo is Cabloy Basic or Cabloy Start
22
+ 2. confirm whether the module is backend-only, frontend-only, or fullstack
23
+ 3. inspect the root `package.json`
24
+ 4. inspect `npm run vona` and `npm run zova`
25
+
26
+ This avoids deleting the wrong surfaces or using the wrong edition-specific assumptions.
27
+
28
+ ## Step 2: Inventory the real module surfaces
29
+
30
+ Inspect the real source and direct dependency surfaces first.
31
+
32
+ Typical locations include:
33
+
34
+ - `vona/src/module/<module>` or suite-based backend module roots
35
+ - `zova/src/module/<module>` or suite-based frontend module roots
36
+ - `vona/package.json`
37
+ - `zova/package.json`
38
+ - generated registries and lockfiles
39
+ - tests that still target the module
40
+
41
+ If the user asked for a public scrub, also inspect `cabloy-docs/`. Otherwise, treat docs cleanup as a separate scope decision.
42
+
43
+ ## Step 3: Remove source and direct references first
44
+
45
+ Start by removing the real source and direct workspace package references.
46
+
47
+ Typical order:
48
+
49
+ 1. remove backend module source if in scope
50
+ 2. remove frontend module source if in scope
51
+ 3. remove direct workspace dependency entries from the relevant `package.json` files
52
+ 4. refresh or clean generated registrations only after source removal
53
+
54
+ Do not start by hand-editing generated caches while the real module source or package references still exist.
55
+
56
+ ## Step 4: Regenerate with the repo-owned workflow
57
+
58
+ After source cleanup, use the existing root scripts to refresh generated outputs.
59
+
60
+ Representative root commands in Cabloy Basic include:
61
+
62
+ ```bash
63
+ npm run build:zova:admin
64
+ npm run deps:vona
65
+ npm run deps:zova
66
+ npm run tsc
67
+ npm run test
68
+ ```
69
+
70
+ ### Fullstack default sequence
71
+
72
+ When the module exists on both the Vona and Zova sides, the usual sequence is:
73
+
74
+ 1. `npm run build:zova:admin`
75
+ 2. `npm run deps:vona`
76
+ 3. `npm run deps:zova`
77
+ 4. `npm run tsc`
78
+
79
+ This keeps the Zova Admin JS bundle and rest output aligned before Vona consumes downstream artifacts.
80
+
81
+ ### Narrower branches
82
+
83
+ For backend-only removal, prefer the narrowest meaningful verification first:
84
+
85
+ - `npm run deps:vona`
86
+ - `npm run tsc`
87
+ - `npm run test` when runtime/test coupling is likely
88
+
89
+ For frontend-only removal, use the relevant Zova build/deps path first, then typecheck.
90
+
91
+ ## Step 5: Clean generated runtime directories when residues remain stale
92
+
93
+ If stale module types or runtime entries still remain after the normal cleanup and regeneration flow, treat generated runtime directories as disposable working state.
94
+
95
+ In particular, the primary recovery targets for this workflow are:
96
+
97
+ - `vona/.vona`
98
+ - `zova/.zova`
99
+
100
+ These are not necessarily the only generated working directories in the repo, but they are the main stale-runtime targets for normal module-removal recovery.
101
+
102
+ Why this is safe:
103
+
104
+ - these directories are generated by the Vona and Zova CLI flows
105
+ - they are ignored by the repo because they are not source-of-truth files
106
+ - they may survive when a service or build process does not stop cleanly
107
+
108
+ After deleting them, rerun the normal regeneration flow and typecheck again.
109
+
110
+ ## Step 6: Verify that the module is really gone
111
+
112
+ Search for remaining references to:
113
+
114
+ - the module relative name
115
+ - the backend workspace package name
116
+ - the frontend workspace package name
117
+ - route or resource names if applicable
118
+
119
+ Then verify with the narrowest meaningful commands first, followed by broader checks when needed.
120
+
121
+ Typical verification commands:
122
+
123
+ ```bash
124
+ npm run build:zova:admin
125
+ npm run deps:vona
126
+ npm run deps:zova
127
+ npm run tsc
128
+ npm run test
129
+ ```
130
+
131
+ The expected result is:
132
+
133
+ - no direct workspace dependency entries remain
134
+ - no generated registry still points at the removed module
135
+ - no stale typecheck failures still reference the module
136
+ - no important runtime or test surfaces still import it
137
+
138
+ ## Step 7: Treat docs cleanup as an explicit second scope
139
+
140
+ Removing code/runtime surfaces does not automatically mean public docs should be rewritten.
141
+
142
+ Make this an explicit scope decision:
143
+
144
+ - code/runtime removal only
145
+ - code/runtime removal plus docs/examples scrub
146
+
147
+ If docs cleanup is in scope, update `cabloy-docs/` as a separate pass after runtime cleanup is stable.
148
+
149
+ ## AI rule of thumb
150
+
151
+ A good Cabloy module-removal workflow is usually:
152
+
153
+ 1. detect edition and scope
154
+ 2. inventory real module surfaces
155
+ 3. remove source and direct references
156
+ 4. regenerate with repo entrypoints
157
+ 5. clean generated runtime dirs only when stale residues remain
158
+ 6. verify the module is really gone
159
+
160
+ Not:
161
+
162
+ 1. delete a few generated files first
163
+ 2. guess which paths matter
164
+ 3. leave workspace dependencies or generated registrations stale
@@ -35,3 +35,14 @@ A strong Cabloy skill usually includes:
35
35
  When a skill needs to apply an architectural rule such as backend class placement, prefer a branching decision tree that points back to durable docs instead of embedding the full architecture rationale inside the skill itself.
36
36
 
37
37
  For edition-aware skills, use [Edition Detection for AI Workflows](/ai/edition-detection) and [Edition Consistency Checklist](/ai/edition-consistency-checklist) as the durable review surfaces before expanding edition-specific branches.
38
+
39
+ ## Example workflow skills in this repo
40
+
41
+ Current examples include:
42
+
43
+ - `cabloy-workflow` for choosing the correct Cabloy work path before implementation
44
+ - `cabloy-contract-loop` for backend/frontend contract regeneration and drift diagnosis
45
+ - `cabloy-resource-field-update` for updating an existing backend resource field thread
46
+ - `cabloy-module-removal` for removing a backend, frontend, or fullstack module cleanly, including generated-runtime cleanup, stale-residue recovery, and verification
47
+
48
+ The module-removal workflow is a good example of why skills belong in `.claude/skills/` instead of `CLAUDE.md`: the task needs branching, cleanup order, recovery guidance for generated runtime directories such as `vona/.vona` and `zova/.zova`, and a verification checklist that would be too large for a short repo-wide rule.
@@ -73,6 +73,12 @@ class DtoStudentCreate {
73
73
  }
74
74
  ```
75
75
 
76
+ When mixing helper metadata and an explicit zod schema in `@Api.field(...)`, apply the same ordering rule used by entities:
77
+
78
+ - place `z.xxx(...)` as the **last argument** because it returns the zod schema instance
79
+ - keep helper metadata such as `v.xxx(...)` and `ZovaRender.xxx(...)` before the zod schema
80
+ - otherwise helpers written after the zod schema may stop taking effect
81
+
76
82
  For query-oriented DTOs, another important distinction is optional vs nullable:
77
83
 
78
84
  - `v.optional()` means the field may be omitted
@@ -103,6 +103,24 @@ Representative examples include:
103
103
  - helpers such as `v.default`, `v.optional`, `v.array`
104
104
  - OpenAPI metadata such as `v.title`, `v.description`, `v.example`, `v.openapi`
105
105
 
106
+ When mixing helper metadata and an explicit zod schema in `@Api.field(...)`, keep a small but important ordering rule:
107
+
108
+ - `z.xxx(...)` returns the zod schema instance, so place it as the **last argument**
109
+ - put helper metadata such as `v.xxx(...)` and `ZovaRender.xxx(...)` before the zod schema
110
+ - otherwise helpers written after the zod schema may stop taking effect
111
+
112
+ Representative pattern:
113
+
114
+ ```typescript
115
+ @Api.field(
116
+ v.title($locale('Level')),
117
+ ZovaRender.order(3),
118
+ ZovaRender.field('basic-select:formFieldSelect', { items: levelItems }),
119
+ z.number().int().min(1).max(3),
120
+ )
121
+ level: number;
122
+ ```
123
+
106
124
  A practical rule is:
107
125
 
108
126
  - use inference for straightforward fields
@@ -60,6 +60,7 @@ Use this path when the task is about runtime shape, startup, instances, workers,
60
60
  - [Worker Guide](/backend/worker-guide)
61
61
  - [Election Guide](/backend/election-guide)
62
62
  - [Queue Guide](/backend/queue-guide)
63
+ - [Status Guide](/backend/status-guide)
63
64
  - [Broadcast Guide](/backend/broadcast-guide)
64
65
  - [Web Socket Guide](/backend/websocket-guide)
65
66
  - [Web Socket Usage Guide](/backend/websocket-usage-guide)
@@ -94,6 +95,7 @@ If your task is already inside the runtime and distributed family, read these gu
94
95
  - [Worker Guide](/backend/worker-guide)
95
96
  - [Election Guide](/backend/election-guide)
96
97
  - [Queue Guide](/backend/queue-guide)
98
+ - [Status Guide](/backend/status-guide)
97
99
  - [Broadcast Guide](/backend/broadcast-guide)
98
100
  - [Web Socket Guide](/backend/websocket-guide)
99
101
  - [Web Socket Usage Guide](/backend/websocket-usage-guide)
@@ -41,6 +41,16 @@ async findOne(id) {
41
41
 
42
42
  This makes serialization an explicit request-path capability rather than an invisible response-side convention.
43
43
 
44
+ Important operational rule:
45
+
46
+ - for performance reasons, serialization is **not enabled by default**
47
+ - `v.serializerTransform(...)`, `v.serializerExclude()`, `v.serializerReplace(...)`, `v.serializerGetter(...)`, and `v.serializerCustom(...)` only declare field-level transform metadata
48
+ - those transforms do **not** run unless the target API explicitly enables serialization with `@Core.serializer()`
49
+
50
+ A practical debugging rule is:
51
+
52
+ - if a field-level serializer appears correct but the response still returns the raw value, first check whether the controller action uses `@Core.serializer()`
53
+
44
54
  ## Serializer transforms
45
55
 
46
56
  Vona supports custom serializer transforms through `@SerializerTransform(...)`.