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,52 @@
|
|
|
1
|
+
# SSR SEO Meta
|
|
2
|
+
|
|
3
|
+
This guide explains how SSR SEO metadata works in Zova within the Cabloy monorepo.
|
|
4
|
+
|
|
5
|
+
## What SEO meta covers
|
|
6
|
+
|
|
7
|
+
SEO meta is not only about the page title.
|
|
8
|
+
|
|
9
|
+
It can also control:
|
|
10
|
+
|
|
11
|
+
- `<meta>` tags
|
|
12
|
+
- `<html>` attributes
|
|
13
|
+
- `<body>` attributes
|
|
14
|
+
- `<style>` and `<script>` tags in the document head
|
|
15
|
+
- `<noscript>` tags
|
|
16
|
+
|
|
17
|
+
## `$useMeta`
|
|
18
|
+
|
|
19
|
+
Zova provides `$useMeta` on `BeanBase` so SSR-aware metadata can be declared in application code.
|
|
20
|
+
|
|
21
|
+
Representative shape:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
this.$useMeta({
|
|
25
|
+
title: 'Index Page',
|
|
26
|
+
titleTemplate: title => `${title} - My Website`,
|
|
27
|
+
meta: {
|
|
28
|
+
description: { name: 'description', content: 'Page 1' },
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Static and reactive metadata
|
|
34
|
+
|
|
35
|
+
Two useful modes are supported:
|
|
36
|
+
|
|
37
|
+
- **static meta** for values known at initialization time
|
|
38
|
+
- **reactive meta** for values that should update when bound state changes
|
|
39
|
+
|
|
40
|
+
That makes SEO metadata part of the reactive application model, not just a one-time page constant.
|
|
41
|
+
|
|
42
|
+
## Overwrite behavior
|
|
43
|
+
|
|
44
|
+
Calling `$useMeta` multiple times can overwrite earlier values for the same keys, so SSR metadata should be designed deliberately when multiple layers participate.
|
|
45
|
+
|
|
46
|
+
## Implementation checks for SSR SEO metadata changes
|
|
47
|
+
|
|
48
|
+
When adding or editing SEO behavior:
|
|
49
|
+
|
|
50
|
+
1. use `$useMeta` rather than inventing a parallel metadata system
|
|
51
|
+
2. decide whether the metadata is static or reactive
|
|
52
|
+
3. remember that SSR is what makes many SEO-related tags meaningful to crawlers and downstream consumers
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# System Startup Guide
|
|
2
|
+
|
|
3
|
+
## Why system startup matters
|
|
4
|
+
|
|
5
|
+
Zova separates system startup from application startup so system-level initialization can be reasoned about independently from request-scoped or app-instance-scoped behavior.
|
|
6
|
+
|
|
7
|
+
That matters especially in SSR scenarios, where application startup may happen per request while system startup does not.
|
|
8
|
+
|
|
9
|
+
## System startup vs app startup
|
|
10
|
+
|
|
11
|
+
The critical distinction is:
|
|
12
|
+
|
|
13
|
+
- **app startup** can be tied to individual application instances or requests
|
|
14
|
+
- **system startup** is not request-scoped
|
|
15
|
+
|
|
16
|
+
This separation makes it easier to place long-lived initialization logic in the correct lifecycle.
|
|
17
|
+
|
|
18
|
+
## System startup timings
|
|
19
|
+
|
|
20
|
+
Zova provides three main system startup timings:
|
|
21
|
+
|
|
22
|
+
- `sysInitialize`
|
|
23
|
+
- `sysInitialized`
|
|
24
|
+
- `sysReady`
|
|
25
|
+
|
|
26
|
+
These allow framework and project code to stage system-level initialization intentionally.
|
|
27
|
+
|
|
28
|
+
## System shutdown timing
|
|
29
|
+
|
|
30
|
+
System shutdown is represented by:
|
|
31
|
+
|
|
32
|
+
- `sysClose`
|
|
33
|
+
|
|
34
|
+
## Module load and config load timings
|
|
35
|
+
|
|
36
|
+
System-level lifecycle also includes:
|
|
37
|
+
|
|
38
|
+
- `moduleLoading`
|
|
39
|
+
- `moduleLoaded`
|
|
40
|
+
- `configLoaded`
|
|
41
|
+
|
|
42
|
+
These hooks are especially useful when module registration or config mutation must happen before the system is considered fully ready.
|
|
43
|
+
|
|
44
|
+
## Hook response scenarios
|
|
45
|
+
|
|
46
|
+
System startup hooks can be implemented in several places:
|
|
47
|
+
|
|
48
|
+
- **Module Main Sys**
|
|
49
|
+
- **Module Monkey Sys**
|
|
50
|
+
- **Sys Monkey**
|
|
51
|
+
|
|
52
|
+
This allows both module-level and project-level system initialization logic to participate in a structured way.
|
|
53
|
+
|
|
54
|
+
A compact mental model is:
|
|
55
|
+
|
|
56
|
+
- **Module Main Sys** handles a module’s own system-facing load/config lifecycle
|
|
57
|
+
- **Module Monkey Sys** lets a module participate in broader system-level hook timings
|
|
58
|
+
- **Sys Monkey** lets the project frontend config layer participate in the same system hook system
|
|
59
|
+
|
|
60
|
+
## Module Main Sys
|
|
61
|
+
|
|
62
|
+
A module can provide system-level main lifecycle entrypoints.
|
|
63
|
+
|
|
64
|
+
Representative creation command:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm run zova :init:mainSys demo-student
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Representative pattern:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
export class MainSys extends BeanSimple implements IModuleMainSys {
|
|
74
|
+
async moduleLoading() {}
|
|
75
|
+
async moduleLoaded() {}
|
|
76
|
+
async configLoaded(_config: any) {}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Module Monkey Sys
|
|
81
|
+
|
|
82
|
+
A module can also attach richer system lifecycle behavior through monkey-based hooks.
|
|
83
|
+
|
|
84
|
+
Representative creation command:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npm run zova :init:monkeySys demo-student
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Representative pattern:
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
export class MonkeySys
|
|
94
|
+
extends BeanSimple
|
|
95
|
+
implements
|
|
96
|
+
IMonkeyModuleSys,
|
|
97
|
+
IMonkeySysInitialize,
|
|
98
|
+
IMonkeySysInitialized,
|
|
99
|
+
IMonkeySysReady,
|
|
100
|
+
IMonkeySysClose
|
|
101
|
+
{
|
|
102
|
+
async moduleLoading(_module: IModule) {}
|
|
103
|
+
async moduleLoaded(_module: IModule) {}
|
|
104
|
+
async configLoaded(_module: IModule, _config: any) {}
|
|
105
|
+
async sysInitialize() {}
|
|
106
|
+
async sysInitialized() {}
|
|
107
|
+
async sysReady() {}
|
|
108
|
+
async sysClose() {}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Sys Monkey
|
|
113
|
+
|
|
114
|
+
Project-level system lifecycle customization can be placed in the frontend config area.
|
|
115
|
+
|
|
116
|
+
This is useful when the behavior belongs to the frontend runtime as a whole rather than to one module.
|
|
117
|
+
|
|
118
|
+
Representative creation command:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npm run zova :init:sysMonkey
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Representative file location:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
src/front/config/monkeySys.ts
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Practical interpretation of the phases
|
|
131
|
+
|
|
132
|
+
A representative lifecycle interpretation is:
|
|
133
|
+
|
|
134
|
+
- `moduleLoading` for early module registration work such as route-table contribution
|
|
135
|
+
- `moduleLoaded` once the module is available to the broader system
|
|
136
|
+
- `configLoaded` when module or project config still needs inspection or mutation before readiness
|
|
137
|
+
- `sysInitialize` for the earliest system-wide initialization
|
|
138
|
+
- `sysInitialized` when other modules should be able to react to initialized system state
|
|
139
|
+
- `sysReady` for long-lived runtime behavior that depends on the system being fully operational
|
|
140
|
+
- `sysClose` for teardown of system-level resources
|
|
141
|
+
|
|
142
|
+
## When to use system startup
|
|
143
|
+
|
|
144
|
+
Use system startup when:
|
|
145
|
+
|
|
146
|
+
- the behavior should not be repeated per app instance or per request
|
|
147
|
+
- config-loading order matters at the system level
|
|
148
|
+
- module registration or route-table wiring must happen before app startup flows begin
|
|
149
|
+
- the concern belongs to long-lived runtime setup rather than page/app initialization
|
|
150
|
+
|
|
151
|
+
## Relationship to environment/config selection
|
|
152
|
+
|
|
153
|
+
System startup behavior still runs under a selected mode, appMode, and flavor.
|
|
154
|
+
|
|
155
|
+
Read this guide together with [Environment and Config Guide](/frontend/environment-config-guide).
|
|
156
|
+
|
|
157
|
+
## Relationship to app startup
|
|
158
|
+
|
|
159
|
+
This guide is the first half of the frontend startup story, and the system-level companion to [App Startup Guide](/frontend/app-startup-guide).
|
|
160
|
+
|
|
161
|
+
Use this guide for long-lived runtime setup such as route-table and config wiring, then read the app guide for the router-readiness and first-screen behavior that runs after that system wiring is in place.
|
|
162
|
+
|
|
163
|
+
The legacy system-start docs used route registration as the clearest example boundary:
|
|
164
|
+
|
|
165
|
+
- `moduleLoading` as an early point for registering module routes into the system routing table
|
|
166
|
+
- app startup only after that lower-level system wiring is in place
|
|
167
|
+
|
|
168
|
+
That distinction is especially important in SSR-capable systems, where app lifecycles can repeat while system-level route and config wiring should not.
|
|
169
|
+
|
|
170
|
+
A practical reading sequence is:
|
|
171
|
+
|
|
172
|
+
1. [Environment and Config Guide](/frontend/environment-config-guide)
|
|
173
|
+
2. this page for system wiring
|
|
174
|
+
3. [App Startup Guide](/frontend/app-startup-guide) for router/guard readiness
|
|
175
|
+
4. [Page Route Guide](/frontend/page-route-guide) for shell/layout behavior
|
|
176
|
+
|
|
177
|
+
## Implementation checks for system-startup changes
|
|
178
|
+
|
|
179
|
+
When editing frontend lifecycle behavior, ask:
|
|
180
|
+
|
|
181
|
+
1. is this a system concern or an app concern?
|
|
182
|
+
2. does it need `configLoaded`, `moduleLoading`, or one of the `sys*` phases?
|
|
183
|
+
3. should the logic live in module mainSys, module monkeySys, or sys monkey?
|
|
184
|
+
4. does SSR change whether the code should be system-scoped instead of request-scoped?
|
|
185
|
+
|
|
186
|
+
That helps AI place lifecycle logic in the correct layer instead of mixing system and app startup behavior together.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Theme Guide
|
|
2
|
+
|
|
3
|
+
This guide explains how themes work in Zova within the Cabloy monorepo.
|
|
4
|
+
|
|
5
|
+
## Why Zova themes matter
|
|
6
|
+
|
|
7
|
+
Zova provides a theme system that is independent of any one UI library and supports theme switching out of the box.
|
|
8
|
+
|
|
9
|
+
This matters because Cabloy needs a frontend architecture that can survive across different edition-specific UI stacks.
|
|
10
|
+
|
|
11
|
+
## Two theme dimensions
|
|
12
|
+
|
|
13
|
+
Two major dimensions of theme switching are:
|
|
14
|
+
|
|
15
|
+
- **light/dark mode** with `light`, `dark`, and `auto`
|
|
16
|
+
- **brand style** changes, often centered on brand colors but not limited to them
|
|
17
|
+
|
|
18
|
+
This is an important design point: theming is not only dark-mode toggling. It is also a broader token and branding system.
|
|
19
|
+
|
|
20
|
+
## `$theme`
|
|
21
|
+
|
|
22
|
+
Zova injects `$theme` into `BeanBase`, so any bean instance can access theme state through `this.$theme`.
|
|
23
|
+
|
|
24
|
+
Important properties include:
|
|
25
|
+
|
|
26
|
+
- `name`
|
|
27
|
+
- `darkMode`
|
|
28
|
+
- `dark`
|
|
29
|
+
- `token`
|
|
30
|
+
|
|
31
|
+
Representative method:
|
|
32
|
+
|
|
33
|
+
- `toggleDark`
|
|
34
|
+
|
|
35
|
+
This is also why `$theme` and `$token` should be read together rather than as unrelated APIs.
|
|
36
|
+
|
|
37
|
+
## Tokens as the contract between style and theme
|
|
38
|
+
|
|
39
|
+
A token is the design-value layer that sits between CSS-in-JS styles and the active theme.
|
|
40
|
+
|
|
41
|
+
A practical split is:
|
|
42
|
+
|
|
43
|
+
- styles decide where values are consumed
|
|
44
|
+
- tokens define the reusable design vocabulary
|
|
45
|
+
- themes provide the concrete active token values
|
|
46
|
+
|
|
47
|
+
That is why token-driven styling scales better than scattering hardcoded values across many pages and components.
|
|
48
|
+
|
|
49
|
+
## Why token shape is shared in architecture but not fixed across UI libraries
|
|
50
|
+
|
|
51
|
+
The token architecture is shared across Cabloy Basic and Cabloy Start, but the exact token shape can still vary.
|
|
52
|
+
|
|
53
|
+
A practical distinction is:
|
|
54
|
+
|
|
55
|
+
- the idea of token-driven styling is shared
|
|
56
|
+
- the concrete token fields can still reflect the active UI library, component conventions, or project theme design
|
|
57
|
+
|
|
58
|
+
This matters because edition-sensitive UI differences should not be mistaken for a different styling architecture.
|
|
59
|
+
|
|
60
|
+
## Theme beans
|
|
61
|
+
|
|
62
|
+
Each UI library provides a default theme bean, and theme beans are responsible for returning token values and deeper theme customizations.
|
|
63
|
+
|
|
64
|
+
A practical lifecycle is:
|
|
65
|
+
|
|
66
|
+
- theme bean code defines the concrete token payload
|
|
67
|
+
- the active theme exposes that payload through `$theme.token`
|
|
68
|
+
- pages and components consume those values through `$token`
|
|
69
|
+
- runtime theme switching swaps the active token set without changing the broader styling architecture
|
|
70
|
+
|
|
71
|
+
Representative pattern:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
@Theme()
|
|
75
|
+
export class ThemeDefault implements IThemeBase {
|
|
76
|
+
async apply({ dark }: IThemeApplyParams) {
|
|
77
|
+
const token: ThemeToken = {
|
|
78
|
+
color: {
|
|
79
|
+
primary: '#1976d2',
|
|
80
|
+
},
|
|
81
|
+
var: {
|
|
82
|
+
borderColor: '#297acc',
|
|
83
|
+
},
|
|
84
|
+
component: {
|
|
85
|
+
page: {
|
|
86
|
+
background: dark ? '#121212' : '#fff',
|
|
87
|
+
color: dark ? '#fff' : '#000',
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
return { token };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Custom themes
|
|
97
|
+
|
|
98
|
+
Custom theme beans can also be created by following the same pattern.
|
|
99
|
+
|
|
100
|
+
That makes the theme system programmable rather than locked to a small fixed set of predefined skins.
|
|
101
|
+
|
|
102
|
+
## Consume tokens in pages and components
|
|
103
|
+
|
|
104
|
+
In practice, pages and components usually should not hardcode design values when those values belong to the theme vocabulary.
|
|
105
|
+
|
|
106
|
+
A practical rule is:
|
|
107
|
+
|
|
108
|
+
- use `$token` when a page or component is consuming theme-defined design values
|
|
109
|
+
- use `$theme` when code needs to inspect or switch the current theme state itself
|
|
110
|
+
|
|
111
|
+
This keeps token consumption separate from theme-state control while still letting both surfaces work together.
|
|
112
|
+
|
|
113
|
+
## Runtime theme switching
|
|
114
|
+
|
|
115
|
+
Representative usage pattern:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
this.$theme.name =
|
|
119
|
+
this.$theme.name === 'home-theme:default' ? 'home-theme:orange' : 'home-theme:default';
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
This illustrates that theme switching is an ordinary part of the application model and can be driven directly from code.
|
|
123
|
+
|
|
124
|
+
A useful distinction is:
|
|
125
|
+
|
|
126
|
+
- dark-mode switching changes the light/dark state of the active theme flow
|
|
127
|
+
- brand-theme switching changes which named theme provides the token set
|
|
128
|
+
- both still work through the same `$theme` and token architecture
|
|
129
|
+
|
|
130
|
+
## What stays shared across editions
|
|
131
|
+
|
|
132
|
+
Across Cabloy Basic and Cabloy Start, the core theme architecture remains shared:
|
|
133
|
+
|
|
134
|
+
- theme beans provide token values
|
|
135
|
+
- pages and components consume those values through `$token`
|
|
136
|
+
- runtime code can inspect or switch theme state through `$theme`
|
|
137
|
+
- dark mode and brand-theme switching stay part of the same model
|
|
138
|
+
|
|
139
|
+
What may still vary by edition or UI library is:
|
|
140
|
+
|
|
141
|
+
- the exact token shape
|
|
142
|
+
- concrete default token values
|
|
143
|
+
- integration details for a specific component library or visual system
|
|
144
|
+
|
|
145
|
+
## Implementation checks for theme-related changes
|
|
146
|
+
|
|
147
|
+
When changing theme behavior, ask:
|
|
148
|
+
|
|
149
|
+
1. should this change live in a theme bean instead of inlining colors into components?
|
|
150
|
+
2. is the change about dark mode, brand style, or both?
|
|
151
|
+
3. should the change be token-driven instead of component-specific?
|
|
152
|
+
4. does the active edition change the UI component library while preserving the same theme architecture?
|
|
153
|
+
|
|
154
|
+
That helps keep theme work scalable and edition-aware.
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Zod Guide
|
|
2
|
+
|
|
3
|
+
## Why Zod matters in Zova
|
|
4
|
+
|
|
5
|
+
Zova uses Zod as the schema foundation for typed page params, typed page query handling, and other frontend schema-driven behaviors.
|
|
6
|
+
|
|
7
|
+
That matters because route-driven data should not be handled as raw strings once the framework already provides a stronger schema model.
|
|
8
|
+
|
|
9
|
+
## Zova’s `z` wrapper
|
|
10
|
+
|
|
11
|
+
Zova encapsulates Zod and provides an enhanced `z` surface.
|
|
12
|
+
|
|
13
|
+
The goal is not only generic schema validation. The goal is schema validation that fits Zova’s routing and page-controller model.
|
|
14
|
+
|
|
15
|
+
## Basic schema usage
|
|
16
|
+
|
|
17
|
+
Representative examples include:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
const name = z.string();
|
|
21
|
+
const age = z.number();
|
|
22
|
+
const enabled = z.boolean();
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Optional values and defaults are also first-class:
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
const name = z.string().optional();
|
|
29
|
+
const title = z.string().optional().default('');
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Common object schemas
|
|
33
|
+
|
|
34
|
+
Representative object schema:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
const user = z.object({
|
|
38
|
+
name: z.string().optional(),
|
|
39
|
+
age: z.number().optional(),
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This is the foundation used by typed page params and page query support.
|
|
44
|
+
|
|
45
|
+
## Type coercion
|
|
46
|
+
|
|
47
|
+
One of the most important Zova enhancements is automatic coercion.
|
|
48
|
+
|
|
49
|
+
This matters because route params and query values often arrive as strings, while the page controller wants the final typed values.
|
|
50
|
+
|
|
51
|
+
That is why schemas such as:
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
z.number();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
can still support route-driven values more naturally than raw parsing code.
|
|
58
|
+
|
|
59
|
+
## Boolean coercion
|
|
60
|
+
|
|
61
|
+
Zova also applies special handling for boolean-like string values.
|
|
62
|
+
|
|
63
|
+
Representative false-like values include:
|
|
64
|
+
|
|
65
|
+
- `'false'`
|
|
66
|
+
- `'undefined'`
|
|
67
|
+
- `'null'`
|
|
68
|
+
- `'0'`
|
|
69
|
+
|
|
70
|
+
This makes route/query handling more practical in real app flows.
|
|
71
|
+
|
|
72
|
+
## JSON object support in query
|
|
73
|
+
|
|
74
|
+
Zova can support JSON-shaped data in query values.
|
|
75
|
+
|
|
76
|
+
Representative pattern:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
export const QuerySchema = z.object({
|
|
80
|
+
user: z
|
|
81
|
+
.object({
|
|
82
|
+
name: z.string(),
|
|
83
|
+
age: z.number(),
|
|
84
|
+
})
|
|
85
|
+
.optional(),
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
That allows page code to work with typed nested query objects instead of flattening everything into ad hoc string logic.
|
|
90
|
+
|
|
91
|
+
## Array support in query
|
|
92
|
+
|
|
93
|
+
Zova can also support array-shaped query values.
|
|
94
|
+
|
|
95
|
+
Representative pattern:
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
export const QuerySchema = z.object({
|
|
99
|
+
colors: z.array(z.string()).optional(),
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
This is especially useful for filter-like or multi-select page behavior.
|
|
104
|
+
|
|
105
|
+
## Representative page-oriented schemas
|
|
106
|
+
|
|
107
|
+
A page can combine param and query schemas so route-driven input stays typed end to end.
|
|
108
|
+
|
|
109
|
+
Representative patterns:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
export const ControllerPageCounterSchemaParams = z.object({
|
|
113
|
+
id: z.number().optional().default(0),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
export const ControllerPageCounterSchemaQuery = z.object({
|
|
117
|
+
user: z
|
|
118
|
+
.object({
|
|
119
|
+
name: z.string(),
|
|
120
|
+
age: z.number(),
|
|
121
|
+
})
|
|
122
|
+
.optional(),
|
|
123
|
+
colors: z.array(z.string()).optional(),
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Representative page access pattern:
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
class ControllerPageCounter {
|
|
131
|
+
render() {
|
|
132
|
+
return (
|
|
133
|
+
<div>
|
|
134
|
+
<div>id: {this.$params.id}</div>
|
|
135
|
+
<div>name: {this.$query.user?.name}</div>
|
|
136
|
+
<div>colors: {this.$query.colors?.join(',')}</div>
|
|
137
|
+
</div>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Relationship to page params and query
|
|
144
|
+
|
|
145
|
+
Zod is most often encountered in the frontend docs through:
|
|
146
|
+
|
|
147
|
+
- [Page Params Guide](/frontend/page-params-guide)
|
|
148
|
+
- [Page Query Guide](/frontend/page-query-guide)
|
|
149
|
+
|
|
150
|
+
Those guides explain how the schemas are attached to routing behavior, while this guide focuses on the schema model itself.
|
|
151
|
+
|
|
152
|
+
## Implementation checks for schema-driven route-state changes
|
|
153
|
+
|
|
154
|
+
When editing Zova route-driven page behavior, ask:
|
|
155
|
+
|
|
156
|
+
1. should this page value be expressed through a Zod schema instead of manual parsing?
|
|
157
|
+
2. does the schema need coercion, default values, nested objects, or arrays?
|
|
158
|
+
3. is this concern really page params, page query, or a broader reusable schema?
|
|
159
|
+
4. should the typed schema be shared rather than duplicated across pages?
|
|
160
|
+
|
|
161
|
+
That helps AI keep frontend routing behavior aligned with Zova’s schema-first page model.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Edition Differences in Fullstack Collaboration
|
|
2
|
+
|
|
3
|
+
This page makes the Basic/Start differences in the collaboration loop explicit.
|
|
4
|
+
|
|
5
|
+
## Why this page matters
|
|
6
|
+
|
|
7
|
+
Most Cabloy architecture can be explained once.
|
|
8
|
+
|
|
9
|
+
But the fullstack collaboration path becomes confusing if docs or AI systems silently reuse Cabloy Basic assumptions inside Cabloy Start workflows.
|
|
10
|
+
|
|
11
|
+
This page exists to keep those differences visible.
|
|
12
|
+
|
|
13
|
+
## Shared collaboration model
|
|
14
|
+
|
|
15
|
+
Both editions share the same broad collaboration loop:
|
|
16
|
+
|
|
17
|
+
- Vona provides backend runtime and OpenAPI-facing contract output
|
|
18
|
+
- Zova provides frontend application structure and generated metadata
|
|
19
|
+
- root scripts and CLI commands coordinate build, generation, and verification
|
|
20
|
+
|
|
21
|
+
## Where the editions diverge
|
|
22
|
+
|
|
23
|
+
The most important differences show up in:
|
|
24
|
+
|
|
25
|
+
- frontend UI stack assumptions
|
|
26
|
+
- frontend flavor names
|
|
27
|
+
- frontend module composition
|
|
28
|
+
- private value-add content in Cabloy Start
|
|
29
|
+
- potentially different generated output paths or integration details
|
|
30
|
+
|
|
31
|
+
## Cabloy Basic
|
|
32
|
+
|
|
33
|
+
In the current public monorepo, Basic examples commonly align with:
|
|
34
|
+
|
|
35
|
+
- DaisyUI + TailwindCSS oriented frontend assumptions
|
|
36
|
+
- Basic-specific Zova flavors such as `cabloyBasicAdmin` and `cabloyBasicWeb`
|
|
37
|
+
|
|
38
|
+
## Cabloy Start
|
|
39
|
+
|
|
40
|
+
In the sibling private repo, Start examples commonly align with:
|
|
41
|
+
|
|
42
|
+
- Vuetify-oriented frontend assumptions
|
|
43
|
+
- Start-specific Zova flavors such as `cabloyStartAdmin` and `cabloyStartWeb`
|
|
44
|
+
|
|
45
|
+
## Safe documentation and AI rule
|
|
46
|
+
|
|
47
|
+
When documenting or automating a fullstack collaboration flow:
|
|
48
|
+
|
|
49
|
+
1. explain the shared model once
|
|
50
|
+
2. detect the active edition
|
|
51
|
+
3. branch only where the workflow actually diverges
|
|
52
|
+
4. verify flavor names and generated output paths in the active repo
|
|
53
|
+
|
|
54
|
+
## Practical implications for edition-aware workflow decisions
|
|
55
|
+
|
|
56
|
+
This rule prevents a common failure mode:
|
|
57
|
+
|
|
58
|
+
- the model understands the shared architecture correctly
|
|
59
|
+
- but gives the wrong operational example because it assumes the wrong edition
|
|
60
|
+
|
|
61
|
+
That is exactly the kind of mistake good fullstack docs should prevent.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Frontend Metadata Back to Backend
|
|
2
|
+
|
|
3
|
+
This page documents the reverse direction of Cabloy’s fullstack collaboration loop: frontend-generated metadata that improves backend-side development and tooling.
|
|
4
|
+
|
|
5
|
+
## Why this path matters
|
|
6
|
+
|
|
7
|
+
The fullstack collaboration loop in Cabloy is not one-way.
|
|
8
|
+
|
|
9
|
+
For the forward contract-bridge direction from backend OpenAPI to frontend consumption, also see [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk).
|
|
10
|
+
|
|
11
|
+
The backend does not only feed the frontend through OpenAPI. The frontend also generates information that can improve backend-side type hints and integration confidence.
|
|
12
|
+
|
|
13
|
+
This is one of the unusual strengths of the Cabloy monorepo model.
|
|
14
|
+
|
|
15
|
+
## What the frontend can generate
|
|
16
|
+
|
|
17
|
+
The current script surface shows that Zova can generate metadata and type information for areas such as:
|
|
18
|
+
|
|
19
|
+
- routes
|
|
20
|
+
- components
|
|
21
|
+
- icons
|
|
22
|
+
- REST-related generated output
|
|
23
|
+
|
|
24
|
+
That generated information can then be consumed by backend-side fullstack workflows and developer tooling.
|
|
25
|
+
|
|
26
|
+
## Why this is valuable
|
|
27
|
+
|
|
28
|
+
In a separated-repo world, this information is often harder to share, easier to stale, and more annoying for AI to rediscover.
|
|
29
|
+
|
|
30
|
+
In the monorepo, the frontend-generated metadata can stay close to:
|
|
31
|
+
|
|
32
|
+
- the frontend source that produced it
|
|
33
|
+
- the backend workflows that consume or rely on it
|
|
34
|
+
- the docs and skills that explain the collaboration path
|
|
35
|
+
|
|
36
|
+
## Typical collaboration pattern
|
|
37
|
+
|
|
38
|
+
A practical collaboration loop often looks like this:
|
|
39
|
+
|
|
40
|
+
1. define or update frontend routes/components/icons
|
|
41
|
+
2. regenerate the relevant frontend metadata or REST/type output
|
|
42
|
+
3. let backend-side workflows, docs, or fullstack integration logic consume the generated information
|
|
43
|
+
4. verify the collaboration path still matches the active edition
|
|
44
|
+
|
|
45
|
+
## Edition awareness
|
|
46
|
+
|
|
47
|
+
This path is especially sensitive to edition differences because Basic and Start do not expose the same frontend module and UI shape.
|
|
48
|
+
|
|
49
|
+
So when AI reasons about frontend-generated metadata, it should verify:
|
|
50
|
+
|
|
51
|
+
- which repo is active
|
|
52
|
+
- which flavor is active
|
|
53
|
+
- which generated output belongs to that edition
|
|
54
|
+
|
|
55
|
+
## Implementation checks for frontend-metadata changes
|
|
56
|
+
|
|
57
|
+
When changing frontend structural resources such as routes or components, ask:
|
|
58
|
+
|
|
59
|
+
1. does metadata need regeneration?
|
|
60
|
+
2. does backend-side tooling or fullstack integration rely on that metadata?
|
|
61
|
+
3. is this a Basic-specific or Start-specific workflow?
|
|
62
|
+
4. should the next action be generation and verification rather than only source edits?
|
|
63
|
+
|
|
64
|
+
That keeps the reverse contract loop visible instead of accidental.
|