cabloy 5.1.49 → 5.1.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/cabloy-backend-scaffold/SKILL.md +207 -0
- package/.claude/skills/cabloy-backend-scaffold/evals/evals.json +29 -0
- package/.claude/skills/cabloy-backend-scaffold/references/backend-thread-map.md +52 -0
- package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +39 -0
- package/.claude/skills/cabloy-contract-loop/SKILL.md +201 -0
- package/.claude/skills/cabloy-contract-loop/evals/evals.json +29 -0
- package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +47 -0
- package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +32 -0
- package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +230 -0
- package/.claude/skills/cabloy-frontend-scaffold/evals/evals.json +35 -0
- package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +41 -0
- package/.claude/skills/cabloy-frontend-scaffold/references/frontend-thread-map.md +54 -0
- package/.claude/skills/cabloy-workflow/SKILL.md +288 -0
- package/.claude/skills/cabloy-workflow/evals/evals.json +35 -0
- package/.claude/skills/cabloy-workflow/references/cli-strategy.md +39 -0
- package/.claude/skills/cabloy-workflow/references/edition-detection.md +29 -0
- package/.github/workflows/docs-pages.yml +54 -0
- package/.gitignore +1 -0
- package/CHANGELOG.md +46 -0
- package/CLAUDE.md +59 -0
- package/README.md +137 -0
- package/cabloy-docs/.vitepress/config.mjs +222 -0
- package/cabloy-docs/.vitepress/public/CNAME +1 -0
- package/cabloy-docs/.vitepress/theme/custom.css +64 -0
- package/cabloy-docs/.vitepress/theme/edition-badges.md +5 -0
- package/cabloy-docs/.vitepress/theme/index.js +5 -0
- package/cabloy-docs/ai/class-placement-rule.md +138 -0
- package/cabloy-docs/ai/cli-for-agents.md +56 -0
- package/cabloy-docs/ai/cli-to-skill-map.md +165 -0
- package/cabloy-docs/ai/docs-skills-rules-mapping.md +167 -0
- package/cabloy-docs/ai/edition-detection.md +30 -0
- package/cabloy-docs/ai/future-skill-roadmap.md +135 -0
- package/cabloy-docs/ai/global-bean-lookup.md +157 -0
- package/cabloy-docs/ai/introduction.md +62 -0
- package/cabloy-docs/ai/playbook-backend-module.md +111 -0
- package/cabloy-docs/ai/playbook-contract-regeneration.md +100 -0
- package/cabloy-docs/ai/playbook-frontend-page.md +99 -0
- package/cabloy-docs/ai/playbook-metadata-refresh.md +67 -0
- package/cabloy-docs/ai/repo-guidance.md +58 -0
- package/cabloy-docs/ai/rules-and-config.md +29 -0
- package/cabloy-docs/ai/skills.md +35 -0
- package/cabloy-docs/ai/verification.md +30 -0
- package/cabloy-docs/backend/aop-overview.md +128 -0
- package/cabloy-docs/backend/auth-guide.md +151 -0
- package/cabloy-docs/backend/backend-essentials.md +128 -0
- package/cabloy-docs/backend/broadcast-guide.md +138 -0
- package/cabloy-docs/backend/cache-guide.md +70 -0
- package/cabloy-docs/backend/captcha-guide.md +162 -0
- package/cabloy-docs/backend/cli.md +173 -0
- package/cabloy-docs/backend/config-guide.md +249 -0
- package/cabloy-docs/backend/controller-aop-guide.md +270 -0
- package/cabloy-docs/backend/controller-guide.md +347 -0
- package/cabloy-docs/backend/crud-workflow.md +118 -0
- package/cabloy-docs/backend/dto-guide.md +161 -0
- package/cabloy-docs/backend/dto-infer-generation.md +153 -0
- package/cabloy-docs/backend/dynamic-datasource-guide.md +70 -0
- package/cabloy-docs/backend/election-guide.md +141 -0
- package/cabloy-docs/backend/entity-guide.md +150 -0
- package/cabloy-docs/backend/error-guide.md +108 -0
- package/cabloy-docs/backend/event-guide.md +183 -0
- package/cabloy-docs/backend/external-aop-guide.md +149 -0
- package/cabloy-docs/backend/field-indexes.md +79 -0
- package/cabloy-docs/backend/foundation.md +281 -0
- package/cabloy-docs/backend/i18n-guide.md +211 -0
- package/cabloy-docs/backend/internal-aop-guide.md +181 -0
- package/cabloy-docs/backend/introduction.md +95 -0
- package/cabloy-docs/backend/jwt-guide.md +276 -0
- package/cabloy-docs/backend/logger-guide.md +223 -0
- package/cabloy-docs/backend/mail-guide.md +189 -0
- package/cabloy-docs/backend/menu-guide.md +80 -0
- package/cabloy-docs/backend/migration-and-changes.md +192 -0
- package/cabloy-docs/backend/model-guide.md +274 -0
- package/cabloy-docs/backend/multi-database-datasource.md +171 -0
- package/cabloy-docs/backend/multi-instance-and-instance-resolution.md +196 -0
- package/cabloy-docs/backend/openapi-guide.md +118 -0
- package/cabloy-docs/backend/orm-aggregate-group-guide.md +210 -0
- package/cabloy-docs/backend/orm-configuration-guide.md +165 -0
- package/cabloy-docs/backend/orm-guide.md +109 -0
- package/cabloy-docs/backend/orm-mutation-guide.md +195 -0
- package/cabloy-docs/backend/orm-select-guide.md +243 -0
- package/cabloy-docs/backend/queue-guide.md +271 -0
- package/cabloy-docs/backend/quickstart.md +141 -0
- package/cabloy-docs/backend/redis-guide.md +70 -0
- package/cabloy-docs/backend/redlock-guide.md +60 -0
- package/cabloy-docs/backend/relations-guide.md +250 -0
- package/cabloy-docs/backend/runtime-and-flavors.md +304 -0
- package/cabloy-docs/backend/schedule-guide.md +81 -0
- package/cabloy-docs/backend/scripts.md +116 -0
- package/cabloy-docs/backend/serialization-guide.md +192 -0
- package/cabloy-docs/backend/service-guide.md +166 -0
- package/cabloy-docs/backend/sharding-guide.md +49 -0
- package/cabloy-docs/backend/startup-guide.md +326 -0
- package/cabloy-docs/backend/transaction-guide.md +82 -0
- package/cabloy-docs/backend/unit-testing.md +209 -0
- package/cabloy-docs/backend/upload-guide.md +160 -0
- package/cabloy-docs/backend/user-access-guide.md +157 -0
- package/cabloy-docs/backend/validation-guide.md +80 -0
- package/cabloy-docs/backend/worker-guide.md +59 -0
- package/cabloy-docs/editions/cabloy-basic.md +25 -0
- package/cabloy-docs/editions/cabloy-start.md +24 -0
- package/cabloy-docs/editions/detection.md +31 -0
- package/cabloy-docs/editions/overview.md +44 -0
- package/cabloy-docs/frontend/api-guide.md +93 -0
- package/cabloy-docs/frontend/api-schema-guide.md +43 -0
- package/cabloy-docs/frontend/app-startup-guide.md +185 -0
- package/cabloy-docs/frontend/cli.md +78 -0
- package/cabloy-docs/frontend/component-guide.md +105 -0
- package/cabloy-docs/frontend/component-props-guide.md +97 -0
- package/cabloy-docs/frontend/component-v-model-guide.md +110 -0
- package/cabloy-docs/frontend/css-in-js-guide.md +151 -0
- package/cabloy-docs/frontend/design-principles.md +55 -0
- package/cabloy-docs/frontend/environment-config-guide.md +250 -0
- package/cabloy-docs/frontend/foundation.md +57 -0
- package/cabloy-docs/frontend/generic-component-guide.md +35 -0
- package/cabloy-docs/frontend/icon-engine-guide.md +88 -0
- package/cabloy-docs/frontend/introduction.md +32 -0
- package/cabloy-docs/frontend/ioc-and-beans.md +211 -0
- package/cabloy-docs/frontend/mock-guide.md +109 -0
- package/cabloy-docs/frontend/model-architecture.md +87 -0
- package/cabloy-docs/frontend/model-state-guide.md +70 -0
- package/cabloy-docs/frontend/module-scope.md +168 -0
- package/cabloy-docs/frontend/modules-and-suites.md +179 -0
- package/cabloy-docs/frontend/navigation-guards-guide.md +68 -0
- package/cabloy-docs/frontend/openapi-sdk-guide.md +102 -0
- package/cabloy-docs/frontend/page-guide.md +223 -0
- package/cabloy-docs/frontend/page-params-guide.md +87 -0
- package/cabloy-docs/frontend/page-query-guide.md +96 -0
- package/cabloy-docs/frontend/page-route-guide.md +147 -0
- package/cabloy-docs/frontend/quickstart.md +201 -0
- package/cabloy-docs/frontend/route-alias-guide.md +61 -0
- package/cabloy-docs/frontend/scripts.md +86 -0
- package/cabloy-docs/frontend/sdk-guide.md +45 -0
- package/cabloy-docs/frontend/server-data.md +74 -0
- package/cabloy-docs/frontend/ssr-client-only.md +40 -0
- package/cabloy-docs/frontend/ssr-env.md +51 -0
- package/cabloy-docs/frontend/ssr-init-data.md +46 -0
- package/cabloy-docs/frontend/ssr-overview.md +48 -0
- package/cabloy-docs/frontend/ssr-seo-meta.md +52 -0
- package/cabloy-docs/frontend/system-startup-guide.md +186 -0
- package/cabloy-docs/frontend/theme-guide.md +154 -0
- package/cabloy-docs/frontend/zod-guide.md +161 -0
- package/cabloy-docs/fullstack/edition-collaboration-differences.md +61 -0
- package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +64 -0
- package/cabloy-docs/fullstack/introduction.md +69 -0
- package/cabloy-docs/fullstack/openapi-to-sdk.md +116 -0
- package/cabloy-docs/fullstack/quickstart.md +86 -0
- package/cabloy-docs/fullstack/vona-zova-integration.md +86 -0
- package/cabloy-docs/index.md +73 -0
- package/cabloy-docs/package.json +16 -0
- package/cabloy-docs/pnpm-lock.yaml +1607 -0
- package/cabloy-docs/reference/backend-directory-structure.md +88 -0
- package/cabloy-docs/reference/cli-reference.md +49 -0
- package/cabloy-docs/reference/glossary.md +38 -0
- package/cabloy-docs/reference/package-map.md +105 -0
- package/cabloy-docs/reference/repo-scripts.md +36 -0
- package/package.json +4 -1
- package/scripts/init.ts +12 -0
- package/scripts/upgrade.ts +31 -3
- package/vona/README.md +3 -3
- package/vona/README.zh-CN.md +4 -4
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-datasharding/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-datasharding/src/bean/summerCache.datasourceWrite.ts +2 -2
- package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
- package/vona/src/suite-vendor/a-captcha/modules/a-captcha/package.json +1 -1
- package/vona/src/suite-vendor/a-captcha/modules/a-captcha/src/bean/cacheRedis.captcha.ts +2 -2
- package/vona/src/suite-vendor/a-captcha/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-bean/cli/bean/metadata/generate.ts +5 -6
- package/vona/src/suite-vendor/a-vona/modules/a-bean/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-cache/cli/cacheMem/boilerplate/{{sceneName}}.{{beanName}}.ts_ +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-cache/cli/cacheRedis/boilerplate/{{sceneName}}.{{beanName}}.ts_ +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-cache/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-cache/src/.metadata/index.ts +13 -2
- package/vona/src/suite-vendor/a-vona/modules/a-cache/src/bean/bean.cache.ts +6 -7
- package/vona/src/suite-vendor/a-vona/modules/a-cache/src/{bean/bean.cacheMemBase.ts → service/cacheMemBase_.ts} +3 -3
- package/vona/src/suite-vendor/a-vona/modules/a-cache/src/{bean/bean.cacheRedisBase.ts → service/cacheRedisBase_.ts} +3 -3
- package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/bean/cacheRedis.emailConfirm.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/bean/cacheRedis.passwordReset.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-openapi/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-openapi/src/bean/summerCache.json.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-orm/cli/databaseDialect/boilerplate/{{sceneName}}.{{beanName}}.ts_ +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-orm/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/.metadata/index.ts +4 -3
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/bean/bean.database.ts +3 -3
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/bean/bean.model.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/bean/schedule.softDeletionPrune.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/common/utils.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_cache.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_meta.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.modelBase.ts +0 -5
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoAggregate.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoCreate.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoGet.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoGroup.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoMutate.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoSelectAndCount.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoUpdate.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/index.ts +1 -0
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/modelCacheBase.ts +3 -3
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/relations.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/relationsDynamic.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/relationsMutate.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/relationsStatic.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/cacheEntity_.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/cacheQuery_.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/database.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean/bean.databaseDialectBase.ts → service/databaseDialectBase_.ts} +38 -41
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/db_.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/relations_.ts +3 -3
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/database.ts +0 -5
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/dto/dtoGet.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/dto/dtoMutate.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/dto/dtoSelectAndCount.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/model.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/modelAggr.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/modelCount.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/modelGeneral.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/modelGroup.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/modelIncrement.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relations.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsColumns.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsDef.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsDefDynamic.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsDefMutate.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsMutate.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsTables.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/bean/databaseDialect.betterSqlite3.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/bean/databaseDialect.mysql.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/bean/databaseDialect.pg.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +109 -40
- package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/summerCache.permission.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-startup/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-startup/src/bean/cacheRedis.startupDebounce.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-summer/cli/boilerplate/{{sceneName}}.{{beanName}}.ts_ +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-summer/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-summer/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-summer/src/bean/bean.summer.ts +3 -3
- package/vona/src/suite-vendor/a-vona/modules/a-summer/src/service/localMem_.ts +3 -3
- package/vona/src/suite-vendor/a-vona/modules/a-summer/src/service/localRedis_.ts +3 -3
- package/vona/src/suite-vendor/a-vona/modules/a-summer/src/{bean/bean.summerCacheBase.ts → service/summerCacheBase_.ts} +3 -3
- package/vona/src/suite-vendor/a-vona/modules/a-swagger/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-swagger/src/bean/summerCache.rapidoc.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-swagger/src/bean/summerCache.swagger.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/bean/cacheRedis.authToken.ts +2 -2
- package/vona/src/suite-vendor/a-vona/modules/a-worker/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-worker/src/bean/cacheRedis.workerAlive.ts +2 -2
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/README.md +4 -4
- package/zova/README.zh-CN.md +4 -4
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/src/suite/a-demo/modules/demo-basic/src/page/toolTwo/controller.tsx +0 -2
- package/zova/src/suite/a-home/modules/home-base/src/config/locale/en-us.ts +1 -0
- package/zova/src/suite/a-home/modules/home-base/src/config/locale/zh-cn.ts +1 -0
- package/zova/src/suite/a-home/modules/home-base/src/page/errorNotFound/controller.tsx +8 -2
- package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/controller.tsx +1 -1
- package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.header.tsx +1 -1
- package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.locale.tsx +2 -5
- package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.tabs.tsx +1 -4
- package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/bean/sys.router.ts +28 -6
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkeySys.ts +15 -3
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/router.ts +1 -0
- package/zova/src/suite-vendor/a-zova/modules/a-routertabs/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts +4 -0
- package/zova/src/suite-vendor/a-zova/package.json +3 -3
- /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_crud.ts +0 -0
- /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_crud_inner.ts +0 -0
- /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_crud_table.ts +0 -0
- /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_knex.ts +0 -0
- /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_utils.ts +0 -0
- /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_view.ts +0 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# Runtime Environments and Flavors
|
|
2
|
+
|
|
3
|
+
This guide explains how runtime environments and flavors work in Vona within the Cabloy monorepo.
|
|
4
|
+
|
|
5
|
+
## Why this model exists
|
|
6
|
+
|
|
7
|
+
Vona does not treat backend runtime selection as a single switch.
|
|
8
|
+
|
|
9
|
+
In practice, backend behavior is chosen by combining:
|
|
10
|
+
|
|
11
|
+
- **runtime environment**
|
|
12
|
+
- **flavor**
|
|
13
|
+
|
|
14
|
+
That gives Cabloy enough room for development, testing, Playground, Docker, CI, and deployment-specific behavior without flattening everything into one axis.
|
|
15
|
+
|
|
16
|
+
## Runtime environments
|
|
17
|
+
|
|
18
|
+
Vona provides three main runtime environments:
|
|
19
|
+
|
|
20
|
+
| Name | Description |
|
|
21
|
+
| ------ | ----------------------- |
|
|
22
|
+
| `test` | testing environment |
|
|
23
|
+
| `dev` | development environment |
|
|
24
|
+
| `prod` | production environment |
|
|
25
|
+
|
|
26
|
+
## How runtime environment is activated in the current repo
|
|
27
|
+
|
|
28
|
+
In Cabloy Basic, the active mode is usually implied by which command you run.
|
|
29
|
+
|
|
30
|
+
### Root-level contributor workflow
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm run dev
|
|
34
|
+
npm run test
|
|
35
|
+
npm run build
|
|
36
|
+
npm run start
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
These root scripts delegate to the backend or frontend layer as needed, so they are the preferred monorepo-facing entrypoints.
|
|
40
|
+
|
|
41
|
+
### Direct Vona workflow
|
|
42
|
+
|
|
43
|
+
Representative backend-side scripts include:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
cd vona && npm run dev
|
|
47
|
+
cd vona && npm run dev:one
|
|
48
|
+
cd vona && npm run test
|
|
49
|
+
cd vona && npm run cov
|
|
50
|
+
cd vona && npm run db:reset
|
|
51
|
+
cd vona && npm run build
|
|
52
|
+
cd vona && npm run build:docker
|
|
53
|
+
cd vona && npm run start
|
|
54
|
+
cd vona && npm run start:one
|
|
55
|
+
cd vona && npm run start:docker
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
In the current repo, those scripts map naturally to:
|
|
59
|
+
|
|
60
|
+
- `dev` commands -> development mode
|
|
61
|
+
- `test` / `cov` / `db:reset` -> test mode
|
|
62
|
+
- `build` / `start` -> production mode
|
|
63
|
+
|
|
64
|
+
## Flavors
|
|
65
|
+
|
|
66
|
+
For more specific scenarios, Vona adds the `flavor` dimension.
|
|
67
|
+
|
|
68
|
+
The combination of runtime environment and flavor lets the framework support more precise operational contexts without inventing a separate environment for every case.
|
|
69
|
+
|
|
70
|
+
### Built-in flavors used in this repo
|
|
71
|
+
|
|
72
|
+
| Name | Description |
|
|
73
|
+
| -------- | --------------------------------------------- |
|
|
74
|
+
| `normal` | default contributor/runtime flavor |
|
|
75
|
+
| `play` | used by the Playground workflow |
|
|
76
|
+
| `docker` | used for Docker-oriented build/runtime output |
|
|
77
|
+
| `ci` | used for CI-oriented production variants |
|
|
78
|
+
|
|
79
|
+
Representative current scripts include:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
cd vona && npm run play
|
|
83
|
+
cd vona && npm run build
|
|
84
|
+
cd vona && npm run build:docker
|
|
85
|
+
cd vona && npm run start
|
|
86
|
+
cd vona && npm run start:docker
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
These scripts show that the same `prod` mode can still branch into different output/runtime shapes through flavor.
|
|
90
|
+
|
|
91
|
+
## What the CLI injects automatically
|
|
92
|
+
|
|
93
|
+
The current Vona CLI does not only read env files. It also injects key meta variables for the running process.
|
|
94
|
+
|
|
95
|
+
The important ones are:
|
|
96
|
+
|
|
97
|
+
- `NODE_ENV`
|
|
98
|
+
- `META_MODE`
|
|
99
|
+
- `META_FLAVOR`
|
|
100
|
+
- `SERVER_WORKERS`
|
|
101
|
+
|
|
102
|
+
A practical interpretation is:
|
|
103
|
+
|
|
104
|
+
- `META_MODE` is the backend runtime mode source of truth
|
|
105
|
+
- `META_FLAVOR` carries the flavor dimension
|
|
106
|
+
- `NODE_ENV` is derived from mode (`test`, `development`, or `production`)
|
|
107
|
+
- `SERVER_WORKERS` is normalized so the runtime always has an explicit worker count
|
|
108
|
+
|
|
109
|
+
In the current CLI behavior:
|
|
110
|
+
|
|
111
|
+
- prod defaults `SERVER_WORKERS` to CPU count when not provided
|
|
112
|
+
- non-prod defaults `SERVER_WORKERS` to `1`
|
|
113
|
+
|
|
114
|
+
## Curated built-in env variable catalog
|
|
115
|
+
|
|
116
|
+
The current repo uses many env variables, but these are the most important ones for understanding the runtime/config family.
|
|
117
|
+
|
|
118
|
+
| Variable family | Representative variables | Why it matters |
|
|
119
|
+
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
120
|
+
| Runtime meta | `META_MODE`, `META_FLAVOR`, `NODE_ENV` | chooses the active runtime and flavor shape |
|
|
121
|
+
| Worker/runtime process | `SERVER_WORKERS` | controls worker count and is normalized by the CLI/bootstrap path |
|
|
122
|
+
| HTTP server | `SERVER_LISTEN_HOSTNAME`, `SERVER_LISTEN_PORT`, `SERVER_LISTEN_DISABLE`, `SERVER_SERVE_PROTOCOL`, `SERVER_SERVE_HOST`, `SERVER_GLOBALPREFIX` | controls listen/serve behavior and URL shaping |
|
|
123
|
+
| Database | `DATABASE_DEFAULT_CLIENT`, `DATABASE_CLIENT_SQLITE3_FILENAME`, `DATABASE_CLIENT_PG_*`, `DATABASE_CLIENT_MYSQL_*` | controls datasource defaults and concrete client connection settings |
|
|
124
|
+
| Redis | `REDIS_DEFAULT_HOST`, `REDIS_DEFAULT_PORT`, `REDIS_DEFAULT_DB` | controls the backend Redis baseline used by queue, cache, broadcast, and related capabilities |
|
|
125
|
+
| Logger | `LOGGER_DIR`, `LOGGER_ROTATE_*` | controls log path and rotation behavior |
|
|
126
|
+
|
|
127
|
+
Use this page as the runtime-facing overview, then inspect the current app config when you need to see how those values are translated into backend config.
|
|
128
|
+
|
|
129
|
+
## How to determine runtime metadata in code
|
|
130
|
+
|
|
131
|
+
### Via environment variables
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
process.env.META_MODE === 'test';
|
|
135
|
+
process.env.META_MODE === 'dev';
|
|
136
|
+
process.env.META_MODE === 'prod';
|
|
137
|
+
|
|
138
|
+
process.env.META_FLAVOR === 'normal';
|
|
139
|
+
process.env.META_FLAVOR === 'docker';
|
|
140
|
+
process.env.META_FLAVOR === 'ci';
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Using environment variables is especially useful when behavior needs to participate in build-time replacement or tree-shaking.
|
|
144
|
+
|
|
145
|
+
### Via config
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
app.config.meta.mode === 'test';
|
|
149
|
+
app.config.meta.mode === 'dev';
|
|
150
|
+
app.config.meta.mode === 'prod';
|
|
151
|
+
|
|
152
|
+
app.config.meta.flavor === 'normal';
|
|
153
|
+
app.config.meta.flavor === 'docker';
|
|
154
|
+
app.config.meta.flavor === 'ci';
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Via simplified helpers
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
app.meta.isTest;
|
|
161
|
+
app.meta.isDev;
|
|
162
|
+
app.meta.isProd;
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
A practical rule is:
|
|
166
|
+
|
|
167
|
+
- use `process.env` when the logic is environment-driven and may affect bundling or compile-time replacement
|
|
168
|
+
- use `app.config.meta` or `app.meta` when the logic belongs to normal runtime behavior inside the running backend
|
|
169
|
+
|
|
170
|
+
## Env-file resolution and precedence
|
|
171
|
+
|
|
172
|
+
This page owns the env-file and mode/flavor precedence view. For config surfaces and config layering, see [Config Guide](/backend/config-guide). For the fuller instance-aware merge view used by request-scoped behavior, see [Multi-Instance and Instance Resolution](/backend/multi-instance-and-instance-resolution).
|
|
173
|
+
|
|
174
|
+
In the current repo, env values are loaded from the `vona/env/` directory.
|
|
175
|
+
|
|
176
|
+
Representative files include:
|
|
177
|
+
|
|
178
|
+
- `.env`
|
|
179
|
+
- `.env.dev`
|
|
180
|
+
- `.env.dev.play`
|
|
181
|
+
- `.env.test`
|
|
182
|
+
- `.env.prod`
|
|
183
|
+
- `.env.prod.ci`
|
|
184
|
+
- `.env.prod.docker`
|
|
185
|
+
- `.env.local`
|
|
186
|
+
- `.env.prod.local`
|
|
187
|
+
- `.env.prod.docker.local`
|
|
188
|
+
- `.env.prod.normal.local`
|
|
189
|
+
|
|
190
|
+
The current loader builds the env-file chain from runtime metadata shaped like:
|
|
191
|
+
|
|
192
|
+
- `mode`
|
|
193
|
+
- `flavor`
|
|
194
|
+
- `local`
|
|
195
|
+
|
|
196
|
+
That means the loader can cascade from general files to more specific files such as:
|
|
197
|
+
|
|
198
|
+
1. `.env`
|
|
199
|
+
2. `.env.prod`
|
|
200
|
+
3. `.env.prod.docker`
|
|
201
|
+
4. `.env.prod.docker.local`
|
|
202
|
+
|
|
203
|
+
The important rule is:
|
|
204
|
+
|
|
205
|
+
- `.local` variants are treated as highest-priority local overrides
|
|
206
|
+
|
|
207
|
+
Representative effective chains in the current repo look like this:
|
|
208
|
+
|
|
209
|
+
- `dev + normal` -> `.env` -> `.env.dev` -> `.env.local`
|
|
210
|
+
- `dev + play` -> `.env` -> `.env.dev` -> `.env.dev.play` -> `.env.local`
|
|
211
|
+
- `prod + docker + local` -> `.env` -> `.env.prod` -> `.env.prod.docker` -> `.env.local` -> `.env.prod.local` -> `.env.prod.docker.local`
|
|
212
|
+
|
|
213
|
+
One more practical detail matters during bootstrap:
|
|
214
|
+
|
|
215
|
+
- after the env files are prepared, already-present `process.env` values still win when the runtime assembles the final env object
|
|
216
|
+
|
|
217
|
+
So when you document or debug backend configuration, do not assume one flat `.env` file. Inspect the active `mode`, `flavor`, local override files, and any externally injected environment variables together.
|
|
218
|
+
|
|
219
|
+
## Custom flavors
|
|
220
|
+
|
|
221
|
+
Flavors are not limited to the built-in ones. You can introduce your own flavor for needs such as:
|
|
222
|
+
|
|
223
|
+
- customer-specific behavior
|
|
224
|
+
- deployment-specific behavior
|
|
225
|
+
- project-specific behavior
|
|
226
|
+
- organization-specific behavior
|
|
227
|
+
|
|
228
|
+
Example:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
npm run dev -- --flavor=customA
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
And in code:
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
process.env.META_FLAVOR === 'customA';
|
|
238
|
+
app.config.meta.flavor === 'customA';
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## Type support for custom flavors
|
|
242
|
+
|
|
243
|
+
Custom flavor names can also be added to type definitions for better editor support.
|
|
244
|
+
|
|
245
|
+
Representative pattern:
|
|
246
|
+
|
|
247
|
+
```typescript
|
|
248
|
+
declare module '@cabloy/module-info' {
|
|
249
|
+
export interface VonaMetaFlavorExtend {
|
|
250
|
+
customA: never;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## How runtime metadata becomes backend config
|
|
256
|
+
|
|
257
|
+
Runtime env values do not stop at `process.env`.
|
|
258
|
+
|
|
259
|
+
In the current Vona app config, they are folded into config such as:
|
|
260
|
+
|
|
261
|
+
- `config.meta.mode`
|
|
262
|
+
- `config.meta.flavor`
|
|
263
|
+
- `config.server.*`
|
|
264
|
+
- `config.database.defaultClient`
|
|
265
|
+
- `config.logger.*`
|
|
266
|
+
- `config.redis.*`
|
|
267
|
+
|
|
268
|
+
This is why runtime environment and config should be read together, not as separate concerns.
|
|
269
|
+
|
|
270
|
+
For the config-layering view, also see [Config Guide](/backend/config-guide).
|
|
271
|
+
|
|
272
|
+
## Relationship to startup, instance, and datasource behavior
|
|
273
|
+
|
|
274
|
+
Runtime environment and flavor are not only configuration concerns. They also shape:
|
|
275
|
+
|
|
276
|
+
- startup enable/disable rules
|
|
277
|
+
- startup hook behavior in different modes
|
|
278
|
+
- distributed capability activation
|
|
279
|
+
- datasource defaults
|
|
280
|
+
- local-vs-prod operational differences
|
|
281
|
+
|
|
282
|
+
Read this guide together with:
|
|
283
|
+
|
|
284
|
+
- [Config Guide](/backend/config-guide)
|
|
285
|
+
- [Backend Startup Guide](/backend/startup-guide)
|
|
286
|
+
- [Model Guide](/backend/model-guide)
|
|
287
|
+
- [Multi-Database and Datasource Guide](/backend/multi-database-datasource)
|
|
288
|
+
- [Queue Guide](/backend/queue-guide)
|
|
289
|
+
- [Schedule Guide](/backend/schedule-guide)
|
|
290
|
+
- [Broadcast Guide](/backend/broadcast-guide)
|
|
291
|
+
|
|
292
|
+
## Implementation checks for runtime and flavor changes
|
|
293
|
+
|
|
294
|
+
When evaluating backend runtime or configuration guidance, do not assume that `dev/test/prod` is the whole story.
|
|
295
|
+
|
|
296
|
+
Also inspect:
|
|
297
|
+
|
|
298
|
+
1. which repo command actually drives the workflow
|
|
299
|
+
2. whether the active behavior depends on flavor
|
|
300
|
+
3. whether `.local` overrides may be changing the effective env values
|
|
301
|
+
4. whether the runtime check should use `process.env`, `app.config.meta`, or `app.meta`
|
|
302
|
+
5. whether a datasource, startup, or distributed feature is mode- or flavor-sensitive
|
|
303
|
+
|
|
304
|
+
These environment differences also matter for operational concerns such as log directories, log levels, worker count, and runtime output layout; see [Logger Guide](/backend/logger-guide).
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Schedule Guide
|
|
2
|
+
|
|
3
|
+
This guide explains how schedules work in Vona within the Cabloy monorepo.
|
|
4
|
+
|
|
5
|
+
## Why schedules matter
|
|
6
|
+
|
|
7
|
+
Vona provides schedules on top of BullMQ, treating schedule as a specialized queue-driven execution path.
|
|
8
|
+
|
|
9
|
+
This matters because recurring work is modeled with the same broader distributed-execution vocabulary rather than as an isolated timer hack.
|
|
10
|
+
|
|
11
|
+
## Create a schedule
|
|
12
|
+
|
|
13
|
+
Example: create a schedule named `log` in module `demo-student`.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm run vona :create:bean schedule log -- --module=demo-student
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Schedule definition
|
|
20
|
+
|
|
21
|
+
Representative shape:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
@Schedule({ repeat: { every: 3000 } })
|
|
25
|
+
export class ScheduleLog extends BeanBase implements IScheduleExecute {
|
|
26
|
+
async execute() {
|
|
27
|
+
console.log(Date.now());
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The important point is that recurring execution is declared explicitly through schedule metadata.
|
|
33
|
+
|
|
34
|
+
## Repeat configuration
|
|
35
|
+
|
|
36
|
+
Two main repeat modes are supported:
|
|
37
|
+
|
|
38
|
+
- interval-based repetition with `every`
|
|
39
|
+
- cron-style repetition with `pattern`
|
|
40
|
+
|
|
41
|
+
A practical distinction is:
|
|
42
|
+
|
|
43
|
+
- use `every` when the schedule should repeat by a fixed interval
|
|
44
|
+
- use `pattern` when the schedule should follow a cron-style calendar expression
|
|
45
|
+
|
|
46
|
+
That gives schedules a flexible operational model without leaving the framework abstraction.
|
|
47
|
+
|
|
48
|
+
## Queue and transaction interaction
|
|
49
|
+
|
|
50
|
+
Schedule parameters can also include:
|
|
51
|
+
|
|
52
|
+
- which queue to use
|
|
53
|
+
- repeat options
|
|
54
|
+
- template options
|
|
55
|
+
- datasource context
|
|
56
|
+
- whether to enable transaction behavior
|
|
57
|
+
|
|
58
|
+
This matters because recurring jobs often have the same consistency concerns as ordinary queue jobs.
|
|
59
|
+
|
|
60
|
+
## Enable/disable and environment scoping
|
|
61
|
+
|
|
62
|
+
Like queues, schedules can be enabled or disabled and scoped to flavor or mode.
|
|
63
|
+
|
|
64
|
+
That is important in Cabloy because recurring behavior is often environment-sensitive.
|
|
65
|
+
|
|
66
|
+
## Load behavior and inspection
|
|
67
|
+
|
|
68
|
+
Enabled schedules are loaded through the broader runtime/onion startup flow, and changed or disabled schedule definitions should be understood through that effective runtime context rather than as isolated timer state.
|
|
69
|
+
|
|
70
|
+
The effective schedule list can be inspected, which helps operational debugging and understanding of what is actually active.
|
|
71
|
+
|
|
72
|
+
## Implementation checks for scheduled backend changes
|
|
73
|
+
|
|
74
|
+
When asked to add recurring backend behavior, ask:
|
|
75
|
+
|
|
76
|
+
1. is this better modeled as a schedule rather than an ad hoc loop?
|
|
77
|
+
2. should it repeat by interval or by cron pattern?
|
|
78
|
+
3. does it need transaction behavior?
|
|
79
|
+
4. should it be active in all modes and flavors or only specific ones?
|
|
80
|
+
|
|
81
|
+
That keeps recurring backend work aligned with Vona’s distributed model.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Backend Scripts
|
|
2
|
+
|
|
3
|
+
This guide explains the main Vona script workflows in the Cabloy monorepo.
|
|
4
|
+
|
|
5
|
+
## Shared rule
|
|
6
|
+
|
|
7
|
+
Even though the underlying backend scripts still live in `vona/package.json`, contributors should usually start from the root scripts in the monorepo because they are the shared workflow surface.
|
|
8
|
+
|
|
9
|
+
## Root scripts vs Vona CLI
|
|
10
|
+
|
|
11
|
+
A practical distinction is:
|
|
12
|
+
|
|
13
|
+
- use root scripts for normal runtime workflows such as install, dev, build, start, test, and typecheck
|
|
14
|
+
- use `npm run vona ...` when you need backend command discovery, generation, initialization, or backend-specific tool flows
|
|
15
|
+
|
|
16
|
+
That means [Backend CLI](/backend/cli) and this page are complementary, not redundant.
|
|
17
|
+
|
|
18
|
+
## Development
|
|
19
|
+
|
|
20
|
+
Start the backend in the root repository:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm run dev
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The underlying Vona package also distinguishes multi-worker and single-worker development modes:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd vona && npm run dev
|
|
30
|
+
cd vona && npm run dev:one
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Build
|
|
34
|
+
|
|
35
|
+
From the root repository:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm run build
|
|
39
|
+
npm run build:docker
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The backend-side build behavior is driven by Vona scripts such as:
|
|
43
|
+
|
|
44
|
+
- `build`
|
|
45
|
+
- `build:docker`
|
|
46
|
+
|
|
47
|
+
## Start
|
|
48
|
+
|
|
49
|
+
From the root repository:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm run start
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Vona also supports single-process and docker-oriented start modes inside its own package:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cd vona && npm run start
|
|
59
|
+
cd vona && npm run start:one
|
|
60
|
+
cd vona && npm run start:docker
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Test and typecheck
|
|
64
|
+
|
|
65
|
+
From the root repository:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm run test
|
|
69
|
+
npm run tsc
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The backend-specific script surface also includes:
|
|
73
|
+
|
|
74
|
+
- `cov`
|
|
75
|
+
- `db:reset`
|
|
76
|
+
- `play`
|
|
77
|
+
|
|
78
|
+
## Playground
|
|
79
|
+
|
|
80
|
+
The Playground remains a high-value verification path for fast backend checks.
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cd vona && npm run play
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Or through the CLI wrapper:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
npm run vona :bin:play -- --flavor=play --dummy
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Database reset
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
cd vona && npm run db:reset
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Relationship to backend essentials
|
|
99
|
+
|
|
100
|
+
These scripts are part of the backend essentials workflow because they define how contributors actually enter the backend runtime.
|
|
101
|
+
|
|
102
|
+
A useful split is:
|
|
103
|
+
|
|
104
|
+
- scripts answer how the monorepo runs backend workflows
|
|
105
|
+
- the CLI answers how backend resources are discovered and generated
|
|
106
|
+
- modules and suites answer where generated resources belong
|
|
107
|
+
|
|
108
|
+
For the structural side of that story, also see [Backend Essentials](/backend/backend-essentials) and [Package Map](/reference/package-map).
|
|
109
|
+
|
|
110
|
+
## Guidance
|
|
111
|
+
|
|
112
|
+
When documenting or automating backend scripts:
|
|
113
|
+
|
|
114
|
+
- prefer root scripts for normal contributor workflows
|
|
115
|
+
- drop to `vona/package.json` only when you need backend-specific detail
|
|
116
|
+
- verify commands against current scripts before publishing examples
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Serialization Guide
|
|
2
|
+
|
|
3
|
+
## Why serialization matters in Vona
|
|
4
|
+
|
|
5
|
+
Vona provides serialization so backend APIs can transform response data before it leaves the request path.
|
|
6
|
+
|
|
7
|
+
That matters because response shaping often needs to do more than return raw entity fields. Real systems frequently need to:
|
|
8
|
+
|
|
9
|
+
- exclude sensitive fields
|
|
10
|
+
- mask values such as email or mobile data
|
|
11
|
+
- derive new output fields
|
|
12
|
+
- apply custom transforms to response values
|
|
13
|
+
|
|
14
|
+
## Core serialization model
|
|
15
|
+
|
|
16
|
+
Serialization in Vona is built around two layers:
|
|
17
|
+
|
|
18
|
+
- enabling serialization for an API
|
|
19
|
+
- attaching serializer behavior to fields through metadata helpers
|
|
20
|
+
|
|
21
|
+
The framework can then transform response data using typed, reusable rules instead of ad hoc post-processing logic.
|
|
22
|
+
|
|
23
|
+
## Enabling serialization for an API
|
|
24
|
+
|
|
25
|
+
Serialization is enabled per API with:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
@Core.serializer()
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Representative pattern:
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
@Web.get(':id')
|
|
35
|
+
@Api.body(v.optional(), v.object(EntityStudent))
|
|
36
|
+
@Core.serializer()
|
|
37
|
+
async findOne(id) {
|
|
38
|
+
return await this.scope.service.student.findOne(id);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This makes serialization an explicit request-path capability rather than an invisible response-side convention.
|
|
43
|
+
|
|
44
|
+
## Serializer transforms
|
|
45
|
+
|
|
46
|
+
Vona supports custom serializer transforms through `@SerializerTransform(...)`.
|
|
47
|
+
|
|
48
|
+
Representative generation workflow:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm run vona :create:bean serializerTransform upper -- --module=demo-student
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Representative pattern:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
@SerializerTransform<ISerializerTransformOptionsUpper>()
|
|
58
|
+
export class SerializerTransformUpper {
|
|
59
|
+
async transform(value: string) {
|
|
60
|
+
return value.toUpperCase();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
A transform can define:
|
|
66
|
+
|
|
67
|
+
- input value type
|
|
68
|
+
- parent data type
|
|
69
|
+
- result type
|
|
70
|
+
- transform options
|
|
71
|
+
|
|
72
|
+
This makes serializer behavior reusable and typed.
|
|
73
|
+
|
|
74
|
+
## Applying a serializer transform
|
|
75
|
+
|
|
76
|
+
Field-level serialization is attached through `@Api.field(...)` metadata helpers.
|
|
77
|
+
|
|
78
|
+
Representative pattern:
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
@Api.field(v.serializerTransform('demo-student:upper'))
|
|
82
|
+
name: string;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This means response transformation is part of the same field-oriented contract model used for validation and OpenAPI metadata.
|
|
86
|
+
|
|
87
|
+
## Filtered serializer execution
|
|
88
|
+
|
|
89
|
+
A serializer transform can include a filter function so the transform only runs when the filter allows it.
|
|
90
|
+
|
|
91
|
+
This is useful when serialization behavior depends on the current user, request context, or other runtime conditions.
|
|
92
|
+
|
|
93
|
+
## Serializer transform parameters
|
|
94
|
+
|
|
95
|
+
Serializer transforms can define options with:
|
|
96
|
+
|
|
97
|
+
- default values
|
|
98
|
+
- per-usage overrides
|
|
99
|
+
- app-config overrides
|
|
100
|
+
|
|
101
|
+
This lets projects tune serializer behavior without rewriting the transform implementation each time.
|
|
102
|
+
|
|
103
|
+
A representative precedence model is:
|
|
104
|
+
|
|
105
|
+
- usage-site override in `v.serializerTransform(...)`
|
|
106
|
+
- then `config.onions.serializerTransform`
|
|
107
|
+
- then decorator default values
|
|
108
|
+
|
|
109
|
+
## Serializer helper tools
|
|
110
|
+
|
|
111
|
+
Vona also provides a set of serializer-oriented helpers under the `v` helper surface.
|
|
112
|
+
|
|
113
|
+
Representative helpers include:
|
|
114
|
+
|
|
115
|
+
- `v.serializerTransform(...)`
|
|
116
|
+
- `v.serializerExclude()`
|
|
117
|
+
- `v.serializerReplace(...)`
|
|
118
|
+
- `v.serializerGetter(...)`
|
|
119
|
+
- `v.serializerCustom(...)`
|
|
120
|
+
|
|
121
|
+
## `v.serializerExclude()`
|
|
122
|
+
|
|
123
|
+
Use this to remove a field from serialized output.
|
|
124
|
+
|
|
125
|
+
This is useful for fields that should exist in the backend model but should not appear in API responses.
|
|
126
|
+
|
|
127
|
+
## `v.serializerReplace(...)`
|
|
128
|
+
|
|
129
|
+
Use this to mask or rewrite a field value.
|
|
130
|
+
|
|
131
|
+
A representative use case is partially masking a string such as an email, mobile number, or other sensitive value.
|
|
132
|
+
|
|
133
|
+
## `v.serializerGetter(...)`
|
|
134
|
+
|
|
135
|
+
Use this to derive a new serialized field value from the parent object.
|
|
136
|
+
|
|
137
|
+
This is useful for fields such as `fullName` that are better expressed as output-only computed values.
|
|
138
|
+
|
|
139
|
+
## `v.serializerCustom(...)`
|
|
140
|
+
|
|
141
|
+
Use this when the transformation should be expressed inline as a custom function rather than through a named reusable transform bean.
|
|
142
|
+
|
|
143
|
+
## App-config override patterns
|
|
144
|
+
|
|
145
|
+
Serializer metadata can also be adjusted through app config, including field-level metadata updates for entities.
|
|
146
|
+
|
|
147
|
+
That means serialization participates in the broader backend metadata and schema configuration system instead of being locked into only one code location.
|
|
148
|
+
|
|
149
|
+
Representative patterns include:
|
|
150
|
+
|
|
151
|
+
- direct metadata replacement with `$makeMetadata(...)`
|
|
152
|
+
- schema reconstruction with `$makeSchema(...)`
|
|
153
|
+
|
|
154
|
+
That choice matters because sometimes you only want to swap serialization metadata, while other times you want to rebuild the field schema surface more explicitly.
|
|
155
|
+
|
|
156
|
+
## Relationship to DTOs, entities, validation, and OpenAPI
|
|
157
|
+
|
|
158
|
+
Serialization should be read together with:
|
|
159
|
+
|
|
160
|
+
- [DTO Guide](/backend/dto-guide)
|
|
161
|
+
- [Entity Guide](/backend/entity-guide)
|
|
162
|
+
- [Validation Guide](/backend/validation-guide)
|
|
163
|
+
- [OpenAPI Guide](/backend/openapi-guide)
|
|
164
|
+
|
|
165
|
+
These guides explain the same field-oriented metadata system from the perspectives of contract design, persistence shape, validation, and machine-readable API output.
|
|
166
|
+
|
|
167
|
+
## When to use serialization instead of service-layer mutation
|
|
168
|
+
|
|
169
|
+
Use serialization when:
|
|
170
|
+
|
|
171
|
+
- the underlying backend object should remain unchanged
|
|
172
|
+
- the output should vary by API response needs
|
|
173
|
+
- the transformation belongs to response presentation or exposure policy
|
|
174
|
+
|
|
175
|
+
Use service- or model-layer mutation when the underlying business data itself should change.
|
|
176
|
+
|
|
177
|
+
A useful rule of thumb is:
|
|
178
|
+
|
|
179
|
+
- choose a named serializer transform when the rule should be reusable across fields or entities
|
|
180
|
+
- choose `v.serializerCustom(...)` when the rule is local to one field and does not deserve its own bean
|
|
181
|
+
- choose `v.serializerExclude`, `v.serializerReplace`, or `v.serializerGetter` when the intent is one of those standard output policies
|
|
182
|
+
|
|
183
|
+
## Implementation checks for backend serialization changes
|
|
184
|
+
|
|
185
|
+
When changing backend response behavior, ask:
|
|
186
|
+
|
|
187
|
+
1. should this be a serialization concern instead of modifying the underlying entity or service result?
|
|
188
|
+
2. is a reusable named serializer transform better than an inline custom transform?
|
|
189
|
+
3. should the field be excluded, masked, derived, or otherwise transformed through `v.serializer*` helpers?
|
|
190
|
+
4. does the same field metadata also interact with validation, DTO design, or OpenAPI output?
|
|
191
|
+
|
|
192
|
+
That helps AI keep response shaping aligned with Vona’s contract and metadata model.
|