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,308 @@
1
+ # Zova vs Vue 3 Comparison
2
+
3
+ This page compares **Zova’s frontend programming model** with the **default mental model many developers bring from Vue 3**.
4
+
5
+ The goal is not to argue that one replaces the other.
6
+
7
+ The goal is to explain two things clearly:
8
+
9
+ 1. **Zova still stands on top of Vue 3 runtime and reactivity foundations**
10
+ 2. **Zova deliberately changes the preferred authoring surface, architectural center, and code-organization habits built on top of those foundations**
11
+
12
+ Use this page together with:
13
+
14
+ - [Reading Zova for Vue Developers](/frontend/reading-zova-for-vue-developers)
15
+ - [Zova Reactivity Under the Hood](/frontend/zova-reactivity-under-the-hood)
16
+ - [Zova Source Reading Map](/frontend/zova-source-reading-map)
17
+
18
+ ## Why this page exists
19
+
20
+ A Vue developer can look at Zova code and ask questions like these:
21
+
22
+ - why is this state a plain class field instead of a `ref`?
23
+ - why is derived state wired in `__init__` instead of declared in `setup()`?
24
+ - why does route state appear on the controller instance instead of being pulled through `useRoute()`?
25
+ - why does the page grow into controller/render/style/service beans instead of only more composables and child components?
26
+
27
+ Those questions are reasonable.
28
+
29
+ This page answers them by comparing the two programming models across a few stable architectural dimensions.
30
+
31
+ ## The shortest accurate summary
32
+
33
+ If you only want the shortest answer, use this one:
34
+
35
+ > Vue 3 usually presents reactivity as explicit local primitives and composition-oriented setup logic, while Zova presents reactivity through framework-managed bean instances and controller-oriented architecture.
36
+
37
+ Under the surface, Zova still uses Vue runtime/reactivity capabilities.
38
+
39
+ The big difference is the **business-facing programming model**.
40
+
41
+ ## Side-by-side comparison table
42
+
43
+ | Dimension | Zova | Vue 3 default mental model |
44
+ | --- | --- | --- |
45
+ | Reactive host | controller or bean instance | local `ref` / `reactive` values inside `setup()` |
46
+ | Derived state | `$computed()` often assigned to instance fields | `computed()` usually assigned to local variables |
47
+ | Main wiring surface | `__init__` and bean lifecycle | `setup()` and composition hooks |
48
+ | Route state access | page-controller surface such as `$route`, `$params`, `$query` | composables such as `useRoute()` |
49
+ | Sharing model | IoC containers and bean scopes unify more sharing patterns | composables, props/emits, `provide/inject`, and store layers often coexist |
50
+ | Render organization | controller-oriented; render can stay in controller or move to render beans | component-oriented; template/render/setup stay the obvious center |
51
+ | Growth path | split into controller, render, style, service, model, or other beans | split into composables, child components, and store or helper layers |
52
+ | Architectural emphasis | explicit object roles, scope ownership, and runtime-managed surfaces | flexible local composition with more developer-managed assembly |
53
+
54
+ ## 1. Reactive host
55
+
56
+ ### Zova
57
+
58
+ Zova often makes the controller or bean instance the visible reactive surface.
59
+
60
+ That is why code can look like:
61
+
62
+ ```typescript
63
+ count: number = 0;
64
+
65
+ increment() {
66
+ this.count++;
67
+ }
68
+ ```
69
+
70
+ The important idea is not only shorter syntax.
71
+
72
+ The important idea is that the framework is making the bean instance itself the business-facing state host.
73
+
74
+ ### Vue 3
75
+
76
+ The default Vue mental model usually starts with explicit primitives:
77
+
78
+ ```typescript
79
+ const count = ref(0);
80
+
81
+ function increment() {
82
+ count.value++;
83
+ }
84
+ ```
85
+
86
+ ### Comparison takeaway
87
+
88
+ - Vue 3 teaches you to build reactivity from visible primitives
89
+ - Zova teaches you to work on top of a framework-managed reactive object
90
+
91
+ ## 2. Derived state
92
+
93
+ ### Zova
94
+
95
+ Derived state often looks like instance wiring:
96
+
97
+ ```typescript
98
+ protected async __init__() {
99
+ this.count2 = this.$computed(() => {
100
+ return `=== ${this.count} ===`;
101
+ });
102
+ }
103
+ ```
104
+
105
+ This makes derived state feel like part of object initialization and lifecycle wiring.
106
+
107
+ ### Vue 3
108
+
109
+ Derived state often looks like local reactive declaration:
110
+
111
+ ```typescript
112
+ const count2 = computed(() => `=== ${count.value} ===`);
113
+ ```
114
+
115
+ ### Comparison takeaway
116
+
117
+ - Vue 3 presents derived state as a local reactive value
118
+ - Zova often presents it as an instance-level property of a controller or bean
119
+
120
+ ## 3. Main wiring surface
121
+
122
+ ### Zova
123
+
124
+ Zova concentrates many setup concerns inside bean lifecycle methods such as:
125
+
126
+ - `__init__`
127
+ - `__dispose__`
128
+
129
+ That is where you often wire:
130
+
131
+ - computed values
132
+ - watchers
133
+ - derived state
134
+ - lifecycle cleanup
135
+
136
+ ### Vue 3
137
+
138
+ Vue 3 usually treats `setup()` as the main assembly point, then uses composition hooks around it.
139
+
140
+ ### Comparison takeaway
141
+
142
+ - Vue 3 is more obviously composition-function-centered
143
+ - Zova is more obviously lifecycle-and-object-centered
144
+
145
+ ## 4. Route state access
146
+
147
+ ### Zova
148
+
149
+ For page controllers, route-aware state is often part of the controller surface:
150
+
151
+ - `$route`
152
+ - `$params`
153
+ - `$query`
154
+
155
+ This keeps route-aware page logic close to the page controller itself.
156
+
157
+ ### Vue 3
158
+
159
+ Vue code more often pulls route state through:
160
+
161
+ - `useRoute()`
162
+ - `useRouter()`
163
+
164
+ ### Comparison takeaway
165
+
166
+ - Vue 3 usually pulls route state into local composition code
167
+ - Zova usually pushes route-aware state into the page-controller surface
168
+
169
+ ## 5. Sharing model
170
+
171
+ ### Zova
172
+
173
+ Zova uses IoC as a larger frontend architectural answer, not only as a small dependency-injection convenience.
174
+
175
+ That means questions often become:
176
+
177
+ - which bean owns this behavior?
178
+ - which scope should this bean live in?
179
+ - should this be resolved through injection or lookup?
180
+
181
+ ### Vue 3
182
+
183
+ Vue projects often combine several distinct sharing tools depending on the team and codebase:
184
+
185
+ - props and emits
186
+ - composables
187
+ - `provide/inject`
188
+ - store layers
189
+
190
+ ### Comparison takeaway
191
+
192
+ - Vue 3 gives a flexible base that can lead to multiple sharing styles in one codebase
193
+ - Zova tries to unify more of those patterns through bean and scope architecture
194
+
195
+ ## 6. Render organization
196
+
197
+ ### Zova
198
+
199
+ Zova treats render as part of a controller-oriented architecture.
200
+
201
+ A page can:
202
+
203
+ - render directly inside the controller
204
+ - later split render into a dedicated render bean
205
+ - also split style into a style bean
206
+ - later move additional state or behavior into service beans
207
+
208
+ ### Vue 3
209
+
210
+ Vue usually treats the component itself as the natural render center:
211
+
212
+ - template
213
+ - render function
214
+ - `setup()` locals feeding the component render
215
+
216
+ ### Comparison takeaway
217
+
218
+ - Vue 3 makes the component the obvious render center
219
+ - Zova makes the page or component controller architecture the larger center
220
+
221
+ ## 7. Growth path as complexity increases
222
+
223
+ ### Zova
224
+
225
+ A common Zova growth path is:
226
+
227
+ 1. start with one page controller
228
+ 2. split render into a render bean
229
+ 3. split style into a style bean
230
+ 4. extract state or logic into service or model beans when ownership becomes clearer
231
+
232
+ ### Vue 3
233
+
234
+ A common Vue growth path is:
235
+
236
+ 1. start with one component
237
+ 2. extract composables
238
+ 3. add child components
239
+ 4. introduce or extend store ownership where needed
240
+
241
+ ### Comparison takeaway
242
+
243
+ - Vue 3 complexity growth often feels more composition-first
244
+ - Zova complexity growth often feels more role-and-boundary-first
245
+
246
+ ## 8. Code-reading experience
247
+
248
+ ### Zova
249
+
250
+ When reading Zova, you often ask:
251
+
252
+ - which bean am I looking at?
253
+ - is this a page, component, service, model, render, or style role?
254
+ - what scope owns this bean?
255
+ - what runtime surface is being injected or refreshed onto it?
256
+
257
+ ### Vue 3
258
+
259
+ When reading Vue, you often ask:
260
+
261
+ - what lives in `setup()`?
262
+ - which composables are being used?
263
+ - which local refs/computeds feed the render?
264
+ - where does state ownership move to a store or parent component?
265
+
266
+ ### Comparison takeaway
267
+
268
+ The reading rhythm itself changes.
269
+
270
+ That is why a Vue expert can still feel unfamiliar inside Zova at first even though the lower-level reactive runtime is related.
271
+
272
+ ## What is the same underneath
273
+
274
+ Despite all the differences above, a few important foundations are still shared:
275
+
276
+ - Vue reactivity still matters underneath
277
+ - dependency tracking still matters underneath
278
+ - recomputation and rerender still matter underneath
279
+ - component runtime behavior still matters underneath
280
+
281
+ So the comparison is **not**:
282
+
283
+ - Zova versus Vue runtime
284
+
285
+ It is mostly:
286
+
287
+ - Zova’s architectural authoring model versus Vue’s default authoring habits
288
+
289
+ ## When to prefer this comparison page
290
+
291
+ Use this page when:
292
+
293
+ - you already know Vue and want a clean translation layer into Zova
294
+ - you want one page that summarizes the biggest architectural differences quickly
295
+ - you need to explain to another developer why Zova code should not be auto-refactored back toward generic Vue patterns
296
+
297
+ If you want the next level of detail after this page, continue with:
298
+
299
+ - [Zova Reactivity Under the Hood](/frontend/zova-reactivity-under-the-hood)
300
+ - [Zova Source Reading Map](/frontend/zova-source-reading-map)
301
+
302
+ ## Final takeaway
303
+
304
+ The most important comparison insight is simple:
305
+
306
+ > Vue 3 usually teaches explicit reactive primitives first and architectural composition second. Zova keeps the Vue runtime foundation but teaches explicit architectural roles first and hides more of the reactive primitive management behind framework-managed controller and bean surfaces.
307
+
308
+ Once that shift is clear, Zova code becomes much easier to read on its own terms.
@@ -0,0 +1,350 @@
1
+ # Contract Loop Playbook
2
+
3
+ This page is the canonical playbook for Cabloy’s bidirectional fullstack contract loop.
4
+
5
+ Use it when you need to decide:
6
+
7
+ - where source truth lives for a change
8
+ - which generated handoff should be refreshed
9
+ - which side is actually stale
10
+ - whether the problem is source drift, generated-output drift, consumer drift, or local dependency drift
11
+
12
+ ## Why this playbook exists
13
+
14
+ Cabloy’s fullstack collaboration is not only backend-to-frontend.
15
+
16
+ The same monorepo supports two symmetric chains:
17
+
18
+ - **forward chain** — backend contract emission and frontend consumption
19
+ - **reverse chain** — frontend metadata or resource handoff and backend consumption
20
+
21
+ The core model applies to both **Cabloy Basic** and **Cabloy Start**.
22
+
23
+ What changes by edition is not the model itself, but the operational branch:
24
+
25
+ - flavor names
26
+ - UI-resource examples
27
+ - generated-output paths
28
+ - build commands
29
+
30
+ So the first question is always:
31
+
32
+ 1. which chain am I in?
33
+ 2. which edition is active?
34
+
35
+ ## Shared vocabulary
36
+
37
+ Use these terms consistently:
38
+
39
+ - **contract loop** — the full bidirectional Vona↔Zova collaboration model
40
+ - **forward chain** — backend contract truth flows into generated frontend consumers
41
+ - **reverse chain** — frontend-owned metadata or resources flow into backend consumers
42
+ - **contract source** — the authored layer that currently owns truth
43
+ - **generated handoff** — the generated output that carries truth to the other side
44
+ - **consumer drift** — downstream consumers no longer match current truth
45
+ - **local dependency drift** — generated artifacts are already correct, but installed local file dependencies are still stale
46
+
47
+ ## The two chains
48
+
49
+ ### Forward chain
50
+
51
+ Use the forward chain when backend-authored contract surfaces changed.
52
+
53
+ Typical contract sources:
54
+
55
+ - controller request or response signatures
56
+ - DTOs
57
+ - entity field metadata
58
+ - validation rules
59
+ - OpenAPI metadata
60
+
61
+ Typical handoff:
62
+
63
+ - Swagger or OpenAPI output
64
+ - generated Zova SDK or schema-aware helpers
65
+ - flavor-built REST output when the workflow depends on it
66
+
67
+ Typical consumers:
68
+
69
+ - generated frontend API files
70
+ - thin frontend model facades
71
+ - schema-driven UI
72
+ - custom row or page actions
73
+
74
+ ### Reverse chain
75
+
76
+ Use the reverse chain when frontend-owned metadata or resources changed and backend-side tooling or metadata will consume them.
77
+
78
+ Typical contract sources:
79
+
80
+ - frontend routes
81
+ - frontend components
82
+ - frontend icons
83
+ - custom form-field or table-cell resources
84
+ - module metadata consumed by backend `ZovaRender.*(...)` references
85
+
86
+ Typical handoff:
87
+
88
+ - generated metadata
89
+ - flavor build output
90
+ - local file dependency sync into Vona
91
+
92
+ Typical consumers:
93
+
94
+ - backend metadata that references frontend resources
95
+ - backend-side tooling and type hints
96
+ - SSR or integration paths that depend on refreshed frontend output
97
+
98
+ ## Decision tree
99
+
100
+ Use this decision tree before editing or regenerating anything.
101
+
102
+ ### 1. Did backend contract truth change?
103
+
104
+ Examples:
105
+
106
+ - DTO shape changed
107
+ - controller request or response changed
108
+ - validation changed
109
+ - OpenAPI metadata changed
110
+
111
+ Then use the **forward chain**:
112
+
113
+ 1. change backend truth first
114
+ 2. prove emitted contract output is correct
115
+ 3. regenerate frontend consumers
116
+ 4. keep frontend follow-up thin
117
+ 5. verify consumer alignment
118
+
119
+ See [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk).
120
+
121
+ ### 2. Did frontend-owned metadata or resource truth change?
122
+
123
+ Examples:
124
+
125
+ - a custom table cell was added
126
+ - a custom form field was added
127
+ - routes, components, or icons changed
128
+ - backend metadata now references new frontend resources
129
+
130
+ Then use the **reverse chain**:
131
+
132
+ 1. change frontend source truth
133
+ 2. regenerate metadata when applicable
134
+ 3. build the relevant frontend flavor output
135
+ 4. run `npm run deps:vona`
136
+ 5. verify backend consumers can see the refreshed handoff
137
+
138
+ See [Frontend Metadata Back to Backend](/fullstack/frontend-metadata-to-backend).
139
+
140
+ ### 3. Do generated artifacts look stale?
141
+
142
+ Examples:
143
+
144
+ - generated SDK still reflects an old endpoint shape
145
+ - generated metadata is missing a new resource
146
+ - rest output did not pick up the latest source change
147
+
148
+ Then diagnose **generated-output drift**:
149
+
150
+ 1. confirm the source layer was changed in the right place
151
+ 2. confirm the correct generation path was used
152
+ 3. regenerate instead of hand-patching
153
+ 4. verify the generated output itself before debugging downstream code
154
+
155
+ ### 4. Do generated artifacts already look correct, but consumers still behave stale?
156
+
157
+ Examples:
158
+
159
+ - generated `.zova-rest` output already contains the new keys or types
160
+ - generated SDK already contains the new method
161
+ - backend or frontend still behaves as if old local file packages are installed
162
+
163
+ Then suspect **local dependency drift**:
164
+
165
+ 1. stop editing source files
166
+ 2. prove the generated handoff is already correct
167
+ 3. rerun the normal sync flow
168
+ 4. only then repair the local install state if consumers still look stale
169
+
170
+ ## Forward chain playbook
171
+
172
+ ### Stage 1: Backend contract source
173
+
174
+ Author the truth in Vona first.
175
+
176
+ Typical layers:
177
+
178
+ - controllers
179
+ - DTOs
180
+ - entities
181
+ - validation helpers
182
+ - OpenAPI annotations
183
+
184
+ Rule:
185
+
186
+ - do **not** patch generated frontend consumers first when the backend owns truth
187
+
188
+ ### Stage 2: Emitted contract proof
189
+
190
+ Before regeneration, verify the backend output is actually correct.
191
+
192
+ Typical checks:
193
+
194
+ - controller contract matches intent
195
+ - DTO and validation align
196
+ - OpenAPI output reflects the intended shape
197
+
198
+ If the emitted contract is wrong, regeneration will only spread the mistake.
199
+
200
+ ### Stage 3: Module ownership and generation
201
+
202
+ Regenerate the frontend consumer path deliberately.
203
+
204
+ Typical commands include:
205
+
206
+ ```bash
207
+ npm run zova :openapi:config <module-name>
208
+ npm run zova :openapi:generate <module-name>
209
+ ```
210
+
211
+ When the target is a module-local SDK, keep ownership constrained with `operations.match` so the module only generates the API surface it actually owns.
212
+
213
+ ### Stage 4: Thin frontend follow-up
214
+
215
+ After regeneration, keep frontend follow-up thin.
216
+
217
+ That means:
218
+
219
+ - prefer generated contract consumers over hand-written duplicates
220
+ - use **thin model facades** as semantic wrappers over generated APIs
221
+ - **reuse the existing resource-owner** when the custom API still belongs to an existing resource
222
+
223
+ For resource-bound custom endpoints, prefer `rest-resource.model.resource` as the state owner. A module-local model may still exist, but it should remain a semantic facade instead of becoming a second cache owner.
224
+
225
+ See the downstream pattern in `.claude/skills/cabloy-contract-loop/references/resource-custom-state-pattern.md`.
226
+
227
+ ### Stage 5: Consumer verification
228
+
229
+ Verify that generated output and frontend consumers agree.
230
+
231
+ Typical checks:
232
+
233
+ - generated API contains the intended methods
234
+ - model or schema consumers still typecheck
235
+ - UI behavior now matches the regenerated contract
236
+
237
+ ## Reverse chain playbook
238
+
239
+ ### Stage 1: Frontend-owned source truth
240
+
241
+ Start from the frontend resource or metadata that actually changed.
242
+
243
+ Typical layers:
244
+
245
+ - bean resources
246
+ - components
247
+ - metadata wrappers
248
+ - routes
249
+ - icons
250
+
251
+ Rule:
252
+
253
+ - do **not** treat a frontend-owned resource handoff as frontend-only cleanup if backend consumers depend on it
254
+
255
+ ### Stage 2: Generated handoff
256
+
257
+ Refresh the generated metadata or build output that carries the change across the boundary.
258
+
259
+ Typical commands may include:
260
+
261
+ ```bash
262
+ npm run zova :tools:metadata <module-name>
263
+ ```
264
+
265
+ and then the relevant build path for the active edition and flavor.
266
+
267
+ ### Stage 3: Vona sync handoff
268
+
269
+ After the frontend-generated handoff is ready, re-sync Vona’s local file dependencies.
270
+
271
+ For the current **Cabloy Basic Admin** branch, the representative sequence is:
272
+
273
+ ```bash
274
+ npm run build:zova:admin
275
+ npm run deps:vona
276
+ ```
277
+
278
+ If the same resource path must also be available to Web, also refresh the Web branch.
279
+
280
+ For **Cabloy Start**, use the same reverse-chain logic, but resolve the Start-specific flavor names and output paths from the active Start repo before recommending commands.
281
+
282
+ ### Stage 4: Consumer verification
283
+
284
+ Verify that backend consumers can now resolve the refreshed frontend-generated handoff.
285
+
286
+ Typical checks:
287
+
288
+ - backend metadata resolves the new frontend resource names
289
+ - generated shared types now appear in backend-side consumers
290
+ - SSR or integration behavior sees the refreshed output
291
+
292
+ ## Recovery path for local dependency drift
293
+
294
+ Use this branch only when all of these are already true:
295
+
296
+ - source truth was edited in the right place
297
+ - generation or build output already contains the intended change
298
+ - the normal sync flow already ran
299
+ - consumers still behave stale
300
+
301
+ Then treat the problem as **local dependency drift**.
302
+
303
+ Representative recovery path:
304
+
305
+ ```bash
306
+ cd vona && rm -rf node_modules && pnpm install
307
+ ```
308
+
309
+ This is a recovery step, not the first response.
310
+
311
+ ## Verification by branch
312
+
313
+ ### Forward chain
314
+
315
+ - backend source truth is correct
316
+ - emitted OpenAPI or contract output is correct
317
+ - module ownership is constrained
318
+ - generated frontend consumer output is refreshed
319
+ - frontend consumers and UI behavior align
320
+
321
+ ### Reverse chain
322
+
323
+ - frontend source truth is correct
324
+ - metadata or build output is refreshed
325
+ - Vona dependency sync completed
326
+ - backend consumers resolve the updated frontend-generated handoff
327
+
328
+ ### Local dependency drift
329
+
330
+ - generated artifacts already prove the change exists
331
+ - sync flow already ran
332
+ - reinstall is justified only because consumers still behave stale
333
+
334
+ ## Tutorial map
335
+
336
+ Use the tutorial series as examples of the two chains:
337
+
338
+ - [Tutorial 3: Frontend Metadata Sharing](/fullstack/tutorial-3-frontend-metadata-sharing) — reverse chain, built-in metadata branch
339
+ - [Tutorial 4: Custom Form/Table Renderers for Level](/fullstack/tutorial-4-custom-level-renderers) — reverse chain, custom resource handoff branch
340
+ - [Tutorial 5: Backend Contract Sharing](/fullstack/tutorial-5-backend-contract-sharing) — forward chain, backend-emitted contract branch
341
+ - [Tutorial 6: One Contract Surface, Four Uses](/fullstack/tutorial-6-one-contract-four-uses) — one field story spanning multiple contract surfaces
342
+
343
+ ## Related docs
344
+
345
+ - [Fullstack Introduction](/fullstack/introduction)
346
+ - [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk)
347
+ - [Frontend Metadata Back to Backend](/fullstack/frontend-metadata-to-backend)
348
+ - [Vona + Zova Integration](/fullstack/vona-zova-integration)
349
+ - [OpenAPI SDK Guide](/frontend/openapi-sdk-guide)
350
+ - [API Schema Guide](/frontend/api-schema-guide)