Cabloy Backend Scaffold
Use this skill when the user wants to add or extend a Vona backend feature thread.
Goals
- detect whether the active repository is Cabloy Basic or Cabloy Start
- stay backend-first unless the request clearly becomes a larger fullstack workflow
- prefer Vona CLI generation and CRUD tools over manual scaffolding
- always perform a backend follow-up review so migration, field indexes, DTO/OpenAPI contracts, and tests are not forgotten
- add a frontend-contract reminder only when the backend change likely affects OpenAPI consumers or generated SDK flows
- finish with verification guidance that matches the scope of the change
Step 1: Detect repo and task scope
Check the repository root for these marker files:
__CABLOY_BASIC__
__CABLOY_START__
Interpretation:
- only
__CABLOY_BASIC__ present → this is Cabloy Basic
- only
__CABLOY_START__ present → this is Cabloy Start
- both markers present → treat the repository as ambiguous or invalid and stop before making edition-specific assumptions
- neither marker present → inspect the owning package scripts and nearby repository structure, then ask before making an edition-specific assumption
Then classify the request:
- backend-only if the task is about Vona modules, beans, models, entities, DTOs, CRUD, migration, tests, or backend contracts
- fullstack only if the task clearly requires frontend SDK regeneration, frontend page/component work, or a broader cross-stack contract loop
Default to backend-first. Only escalate mentally to a broader fullstack workflow when the backend change obviously crosses the contract boundary.
If the user is still deciding a new business-domain boundary or suite/module naming, use the root cabloy-domain-planning skill before scaffolding.
If the task is really a broad cross-stack workflow, consider whether the root cabloy-workflow skill is the better primary router.
If the request is not ordinary standalone backend scaffolding but a parent-owned detail aggregation workflow, such as master-detail, nested-detail, aggregate-only detail, standalone-capable detail, or :tools:masterDetail, prefer the dedicated cabloy-master-detail skill first.
Step 2: Start from Vona CLI and repo entrypoints
Inspect these surfaces before proposing implementation:
- the repository or workspace
package.json that owns the scripts
npm run vona
- Vona command families such as
create:*, init:*, tools:*, and bin:*
repo-docs/backend/ for the relevant backend thread
For deeper reference material, read:
references/backend-thread-map.md
references/follow-up-checklist.md
Step 3: Choose the correct scaffolding path
Path A: create one backend bean or module piece
Use create:* when the user needs one structural piece such as:
- module
- bean
- controller
- service
- model
- entity
- dto
- test
Typical examples:
npm run vona :create:module ...
npm run vona :create:bean controller ...
npm run vona :create:bean dto ...
npm run vona :create:test ...
Path B: create a full CRUD thread
Use tools:* when the user needs a whole backend thread rather than one isolated file.
Typical example:
npm run vona :tools:crud ...
Choose this path when the user asks for a CRUD feature, an admin-style backend resource thread, or a connected set of controller/service/model/entity/dto/test files.
Path C: initialize supporting module resources
Use init:* when the task is really about module support files rather than business logic itself.
Typical areas include:
- config
- locale
- constant
- asset
- types
Step 4: Inspect the generated backend thread
After generation, inspect what the CLI created and keep it as the baseline.
Typical backend thread pieces include:
- controller
- service
- model
- entity
- dto
- migration/meta files
- locale files
- tests
Do not throw away the generated structure and rewrite it from scratch unless the generator clearly does not match the task.
Generated renderer decision
When refining generated entity fields, choose form and table controls from business semantics, not only from the primitive TypeScript type:
- keep ordinary Cabloy Basic text fields, such as generated
name and description, on the implicit default Input renderer; do not mechanically add basic-input:formFieldInput
- add explicit
ZovaRender.field(...) when semantics require a specialized control, such as an enum/select, resource relation, date/time, boolean choice, money, image, or file
- add
ZovaRender.cell(...) when that field also needs specialized table presentation
- reuse a shared renderer first, configure it with field-level options next, and create a custom renderer only when the shared surface cannot express the required behavior; follow
cabloy-resource-field-update for the edition-aware renderer branch
Step 5: Apply backend follow-up logic deliberately
Backend scaffolding is rarely complete after file generation alone. Treat this follow-up review as mandatory.
Check which of these concerns apply:
Contract and validation
Check whether the feature needs:
- request validation
- DTO design
- OpenAPI metadata
- inferred DTO generation
When the active edition and installed modules provide @Passport.rbac(...) and the task adds or changes a decorated action:
- verify the decorator, RBAC catalog, and any policy-catalog/editor consumer in the active source before making availability claims
- provide locale-aware
summary metadata at both the controller and action levels; these scopes are independent and must be authored explicitly
- add locale-aware
description metadata only when the business or administrative experience needs explanatory text
- keep action keys, controller bean names, action names, routes, and other authorization/integration identifiers stable and nonlocalized
- treat summary/description as presentation metadata, not authorization identity or enforcement
- verify the explicit server-side catalog/editor projection; do not assume OpenAPI metadata is automatically displayed by a policy editor
For the authoring example and metadata boundary, read Controller Guide and Controller AOP Guide.