cabloy 5.1.111 → 5.1.113
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/.cabloy-version +1 -1
- package/.claude/skills/cabloy-backend-scaffold/SKILL.md +31 -1
- package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +21 -0
- package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +3 -0
- package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +4 -0
- package/.claude/skills/cabloy-master-detail/SKILL.md +13 -2
- package/.github/workflows/playwright-e2e.yml +77 -0
- package/.github/workflows/vona-test-pg.yml +8 -0
- package/.gitignore +1 -0
- package/CHANGELOG.md +30 -0
- package/CLAUDE.md +6 -1
- package/README.md +8 -8
- package/cabloy-docs/backend/crud-workflow.md +10 -0
- package/cabloy-docs/backend/foundation.md +29 -4
- package/cabloy-docs/backend/introduction.md +1 -1
- package/cabloy-docs/backend/migration-and-changes.md +13 -9
- package/cabloy-docs/backend/model-guide.md +9 -11
- package/cabloy-docs/backend/multi-instance-and-instance-resolution.md +18 -0
- package/cabloy-docs/backend/service-guide.md +1 -1
- package/cabloy-docs/backend/unit-testing.md +25 -0
- package/cabloy-docs/frontend/a-router-guide.md +1 -1
- package/cabloy-docs/frontend/introduction.md +1 -1
- package/cabloy-docs/frontend/navigation-guards-guide.md +20 -11
- package/cabloy-docs/frontend/route-alias-guide.md +24 -0
- package/cabloy-docs/frontend/scripts.md +71 -24
- package/cabloy-docs/frontend/ssr-init-data.md +25 -0
- package/cabloy-docs/frontend/ssr-review-checklist.md +17 -7
- package/cabloy-docs/frontend/use-state-data-best-practices.md +4 -0
- package/cabloy-docs/frontend/zova-router-under-the-hood.md +4 -1
- package/cabloy-docs/fullstack/comparison-with-other-frameworks.md +19 -13
- package/cabloy-docs/fullstack/introduction.md +10 -10
- package/cabloy-docs/fullstack/quickstart.md +23 -1
- package/cabloy-docs/index.md +14 -14
- package/cabloy-docs/reference/package-map.md +11 -7
- package/cabloy-docs/reference/repo-scripts.md +108 -23
- package/e2e/scripts/e2e.ts +1 -1
- package/e2e/scripts/startE2eVona.ts +51 -13
- package/e2e/specs/a-commerce/commerce.spec.ts +125 -1
- package/e2e/specs/{a-basic → cabloy-basic}/basic.spec.ts +12 -7
- package/package.json +2 -1
- package/scripts/init.ts +6 -12
- package/scripts/upgrade.ts +3 -1
- package/vona/packages-cli/cli/package.json +1 -1
- package/vona/packages-cli/cli-set-api/package.json +1 -1
- package/vona/packages-cli/cli-set-api/src/lib/bean/cli.bin.test.ts +6 -9
- package/vona/packages-cli/cli-set-api/toolsIsolate/test.ts +50 -21
- package/vona/packages-vona/vona/package.json +1 -1
- package/vona/pnpm-lock.yaml +94 -163
- package/vona/src/backend/config/config/config.test.ts +1 -1
- package/vona/src/backend/config/config/config.ts +11 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/package.json +4 -2
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +732 -2
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/locales.ts +18 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/meta.index.ts +14 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/meta.version.ts +52 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/ssrMenu.category.ts +30 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/ssrMenu.product.ts +30 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/ssrMenu.sku.ts +30 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +19 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +19 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/controller/category.ts +65 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/controller/product.ts +86 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/controller/sku.ts +65 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categoryCreate.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categorySelectReq.tsx +25 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categorySelectRes.tsx +11 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categorySelectResItem.tsx +39 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categoryUpdate.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categoryView.tsx +25 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productCreate.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublic.tsx +38 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublicSelectReq.tsx +23 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublicSelectRes.tsx +11 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublicSku.tsx +25 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productSelectReq.tsx +25 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productSelectRes.tsx +11 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productSelectResItem.tsx +39 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productUpdate.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productView.tsx +25 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuCreate.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectReq.tsx +25 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectRes.tsx +11 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectResItem.tsx +39 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuUpdate.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuView.tsx +25 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/category.tsx +53 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/product.tsx +48 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/sku.tsx +66 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/index.ts +1 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/category.ts +15 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/product.ts +46 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/sku.ts +18 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/category.ts +47 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/product.ts +162 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/sku.ts +76 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/test/catalog.test.ts +592 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/test/category.test.ts +91 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/test/product.test.ts +154 -0
- package/vona/src/suite/a-commerce/modules/commerce-catalog/test/sku.test.ts +190 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/package.json +2 -1
- package/vona/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +342 -5
- package/vona/src/suite/a-commerce/modules/commerce-member/src/.metadata/locales.ts +18 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/bean/meta.index.ts +12 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/bean/meta.version.ts +31 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/config/locale/en-us.ts +12 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/config/locale/zh-cn.ts +12 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/controller/address.ts +59 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressCreate.tsx +39 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectReq.tsx +30 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectRes.tsx +11 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectResItem.tsx +53 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressUpdate.tsx +39 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressView.tsx +39 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/entity/address.tsx +76 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/index.ts +1 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/model/address.ts +10 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/src/service/address.ts +84 -0
- package/vona/src/suite/a-commerce/modules/commerce-member/test/addressOwnership.test.ts +203 -0
- package/vona/src/suite/a-commerce/modules/commerce-seed/package.json +52 -0
- package/vona/src/suite/a-commerce/modules/commerce-seed/src/.metadata/index.ts +55 -0
- package/vona/src/suite/a-commerce/modules/commerce-seed/src/.metadata/this.ts +2 -0
- package/vona/src/suite/a-commerce/modules/commerce-seed/src/bean/meta.version.ts +80 -0
- package/vona/src/suite/a-commerce/modules/commerce-seed/src/index.ts +1 -0
- package/vona/src/suite/a-commerce/modules/commerce-seed/tsconfig.build.json +11 -0
- package/vona/src/suite/a-commerce/modules/commerce-seed/tsconfig.json +7 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/package.json +4 -2
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/index.ts +192 -2
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/locales.ts +18 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/meta.version.ts +32 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/ssrMenu.home.ts +3 -1
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/ssrMenuGroup.catalog.ts +21 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/ssrMenuGroup.inventory.ts +21 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/en-us.ts +5 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/zh-cn.ts +5 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/controller/operator.ts +21 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/dto/operatorContext.ts +21 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/index.ts +1 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/service/operator.ts +18 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/meta.version.test.ts +44 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/operatorAccess.test.ts +55 -0
- package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/ssrMenu.test.ts +77 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/package.json +2 -1
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +773 -2
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/locales.ts +18 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/meta.index.ts +23 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/meta.version.ts +83 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/ssrMenu.stockAudit.ts +30 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/ssrMenu.stockBalance.ts +30 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +29 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +29 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/cart.ts +48 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/stockAudit.ts +38 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/stockBalance.ts +49 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartAddItem.tsx +19 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartItem.tsx +34 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartUpdateItem.tsx +15 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartView.tsx +18 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAdjust.tsx +32 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditCreate.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectReq.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectRes.tsx +11 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectResItem.tsx +33 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditUpdate.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditView.tsx +25 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceCreate.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectReq.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectRes.tsx +11 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectResItem.tsx +33 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceUpdate.tsx +28 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceView.tsx +25 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/cart.tsx +24 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/cartItem.tsx +30 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockAudit.tsx +118 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockBalance.tsx +53 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockReservation.tsx +63 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/index.ts +1 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/cart.ts +17 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/cartItem.ts +10 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/stockAudit.ts +10 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/stockBalance.ts +15 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/stockReservation.ts +10 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/cart.ts +152 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockAudit.ts +20 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockBalance.ts +342 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/test/cartOwnership.test.ts +174 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockAudit.test.ts +37 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockBalance.test.ts +389 -0
- package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockReservation.test.ts +457 -0
- package/vona/src/suite/a-commerce/package.json +1 -0
- package/vona/src/suite/a-commerce/tsconfig.json +3 -0
- package/vona/src/suite/a-home/modules/home-user/src/.metadata/index.ts +7 -1
- package/vona/src/suite/a-home/modules/home-user/test/role.test.ts +14 -23
- package/vona/src/suite/a-training/modules/training-record/src/.metadata/index.ts +10 -8
- package/vona/src/suite/a-training/modules/training-recordsubject/src/.metadata/index.ts +2 -0
- package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +3 -1
- package/vona/src/suite-vendor/a-auth/modules/a-auth/package.json +1 -1
- package/vona/src/suite-vendor/a-auth/modules/a-auth/src/.metadata/index.ts +7 -3
- package/vona/src/suite-vendor/a-auth/modules/auth-simple/package.json +1 -1
- package/vona/src/suite-vendor/a-auth/modules/auth-simple/src/.metadata/index.ts +2 -0
- package/vona/src/suite-vendor/a-auth/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/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-datasource/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-datasource/src/.metadata/index.ts +3 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-socket/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-socket/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/.metadata/index.ts +47 -47
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssrhmr/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-ssrhmr/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-status/package.json +1 -1
- package/vona/src/suite-vendor/a-cabloy/modules/a-status/src/.metadata/index.ts +2 -0
- 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/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-captcha/package.json +1 -1
- package/vona/src/suite-vendor/a-file/modules/a-file/package.json +1 -1
- package/vona/src/suite-vendor/a-file/modules/a-file/src/.metadata/index.ts +42 -38
- package/vona/src/suite-vendor/a-file/package.json +2 -2
- package/vona/src/suite-vendor/a-image/modules/a-image/package.json +1 -1
- package/vona/src/suite-vendor/a-image/modules/a-image/src/.metadata/index.ts +42 -38
- package/vona/src/suite-vendor/a-image/modules/image-cloudflare/package.json +1 -1
- package/vona/src/suite-vendor/a-image/modules/image-cloudflare/src/.metadata/index.ts +42 -27
- package/vona/src/suite-vendor/a-image/package.json +1 -1
- package/vona/src/suite-vendor/a-paypal/modules/a-paypal/package.json +1 -1
- package/vona/src/suite-vendor/a-paypal/modules/a-paypal/src/.metadata/index.ts +3 -1
- package/vona/src/suite-vendor/a-paypal/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-beanmutate/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-beanmutate/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-body/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-body/src/.metadata/index.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 +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-core/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-error/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-error/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-event/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-event/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-executor/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-executor/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-hmr/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-hmr/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-instance/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-instance/src/.metadata/index.ts +3 -1
- package/vona/src/suite-vendor/a-vona/modules/a-jwt/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-jwt/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-logger/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-logger/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-mail/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-mail/src/.metadata/index.ts +3 -1
- 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/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-onion/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-onion/src/.metadata/index.ts +1 -1
- 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/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-orm/cli/model/metadata/generate.ts +5 -11
- 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/lib/bean.model/bean.model_cache.ts +52 -0
- package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoGet.ts +4 -10
- package/vona/src/suite-vendor/a-vona/modules/a-redis/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-redis/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-security/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-security/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-serialization/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-serialization/src/.metadata/index.ts +1 -1
- 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/service/startup.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-user/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-user/src/.metadata/index.ts +4 -5
- package/vona/src/suite-vendor/a-vona/modules/a-validation/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-validation/src/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-version/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-version/src/.metadata/index.ts +6 -0
- package/vona/src/suite-vendor/a-vona/modules/a-version/src/service/version.ts +12 -12
- package/vona/src/suite-vendor/a-vona/modules/a-version/src/types/version.ts +4 -4
- package/vona/src/suite-vendor/a-vona/modules/a-web/package.json +1 -1
- package/vona/src/suite-vendor/a-vona/modules/a-web/src/.metadata/index.ts +1 -1
- 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/.metadata/index.ts +1 -1
- package/vona/src/suite-vendor/a-vona/package.json +1 -1
- package/zova/packages-cli/cli/package.json +2 -2
- package/zova/packages-cli/cli-set-front/package.json +1 -1
- package/zova/packages-cli/cli-set-front/src/lib/bean/toolsMetadata/generateScope.ts +1 -1
- package/zova/packages-zova/zova/package.json +2 -2
- package/zova/pnpm-lock.yaml +9 -9
- package/zova/src/front/config/config/config.cabloyCommerce.ts +5 -1
- package/zova/src/front/config/config/config.cabloyCommerceAdmin.ts +2 -1
- package/zova/src/suite/a-commerce/modules/commerce-catalog/cli/openapi.config.ts +9 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/package.json +2 -1
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +202 -3
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/locales.ts +7 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/page/catalogue.ts +23 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/page/product.ts +19 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/commerceCatalogProduct.ts +52 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/baseURL.ts +5 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/index.ts +3 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/schemas.ts +412 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/types.ts +7159 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/apiSchema/commerceCatalogProduct.ts +20 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +8 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +8 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/index.ts +1 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/model/catalogue.ts +38 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/page/catalogue/controller.tsx +71 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/page/product/controller.tsx +107 -0
- package/zova/src/suite/a-commerce/modules/commerce-catalog/src/routes.ts +19 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/cli/openapi.config.ts +9 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/package.json +2 -1
- package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +182 -3
- package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/locales.ts +7 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/page/address.ts +19 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/api/commerceMemberAddress.ts +111 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/baseURL.ts +5 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/index.ts +3 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/schemas.ts +432 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/types.ts +7445 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/apiSchema/commerceMemberAddress.ts +35 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/config/locale/en-us.ts +17 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/config/locale/zh-cn.ts +17 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/index.ts +1 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/model/address.ts +38 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/page/address/controller.tsx +194 -0
- package/zova/src/suite/a-commerce/modules/commerce-member/src/routes.ts +12 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/cli/openapi.config.ts +9 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/package.json +2 -1
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/index.ts +175 -3
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/locales.ts +7 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/page/dashboard.ts +9 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/commerceSiteadminOperator.ts +25 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/baseURL.ts +5 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/index.ts +3 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/schemas.ts +304 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/types.ts +5710 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/apiSchema/commerceSiteadminOperator.ts +13 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/en-us.ts +5 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/zh-cn.ts +5 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/index.ts +1 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/model/operator.ts +17 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/page/dashboard/controller.tsx +34 -0
- package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/routes.ts +5 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/cli/openapi.config.ts +15 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/package.json +2 -1
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +182 -3
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/locales.ts +7 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/page/cart.ts +19 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/commerceTradeCart.ts +99 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/baseURL.ts +5 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/index.ts +3 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/schemas.ts +446 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/types.ts +7651 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/apiSchema/commerceTradeCart.ts +35 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +8 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +8 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/index.ts +1 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/cart.ts +78 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/cart/controller.tsx +108 -0
- package/zova/src/suite/a-commerce/modules/commerce-trade/src/routes.ts +12 -0
- package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/index.ts +5 -5
- package/zova/src/suite/a-demo/modules/demo-todo/src/.metadata/index.ts +2 -2
- package/zova/src/suite/a-home/modules/home-base/src/service/routerGuards.ts +18 -10
- package/zova/src/suite/a-home/modules/home-indexweb/src/.metadata/index.ts +2 -2
- package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/controller.tsx +17 -7
- package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.header.tsx +1 -1
- package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/controller.tsx +17 -7
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/index.ts +4 -4
- package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +1 -0
- package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-bean/cli/controller/metadata/generateMetaPage.ts +3 -1
- package/zova/src/suite-vendor/a-zova/modules/a-bean/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-fetch/package.json +2 -2
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
- package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +3 -1
- 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 +35 -8
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkeySys.ts +28 -12
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/service/routerGuards.ts +6 -8
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/router.ts +14 -2
- package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/utils.ts +4 -1
- package/zova/src/suite-vendor/a-zova/package.json +5 -5
- package/CLAUDE.local.md +0 -4
|
@@ -16,34 +16,39 @@ Typical uses include:
|
|
|
16
16
|
|
|
17
17
|
The `home-base` module provides a router-guard service hook where custom logic can be added.
|
|
18
18
|
|
|
19
|
+
Use the pure `app.$getPagePath(...)` family to construct a guard destination. Use the imperative `app.$gotoPage(...)` family from event handlers or workflows that intentionally start navigation. Do not call `$gotoLogin()` or `$gotoAccessDenied()` from a `beforeEach` guard and then return `false`: Client-side `$goto...()` starts a nested navigation while `false` aborts the navigation currently being guarded.
|
|
20
|
+
|
|
19
21
|
Representative shape:
|
|
20
22
|
|
|
21
23
|
```typescript
|
|
22
24
|
class ServiceRouterGuards {
|
|
23
25
|
protected onRouterGuards(router: BeanRouter) {
|
|
24
26
|
router.beforeEach(async to => {
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const [_res, err] = await catchError(() => {
|
|
31
|
-
return this.$passport.ensurePassport();
|
|
32
|
-
});
|
|
27
|
+
if (to.meta.requiresAuth === false) return;
|
|
28
|
+
if (this.sys.config.ssr.cookieDisabledOnServer) return;
|
|
29
|
+
|
|
30
|
+
if (!this.$passport.isAuthenticated) {
|
|
31
|
+
const [_res, err] = await catchError(() => this.$passport.ensurePassport());
|
|
33
32
|
if (err) {
|
|
34
33
|
this.$errorHandler(err, 'onRouterGuards');
|
|
35
34
|
return false;
|
|
36
35
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!this.$passport.isAuthenticated) {
|
|
39
|
+
const pagePath = this.app.$getPagePathLogin(to.fullPath);
|
|
40
|
+
if (process.env.SERVER) {
|
|
41
|
+
this.app.$redirect(pagePath);
|
|
40
42
|
}
|
|
43
|
+
return pagePath;
|
|
41
44
|
}
|
|
42
45
|
});
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
```
|
|
46
49
|
|
|
50
|
+
`$getPagePathLogin(to.fullPath)` preserves the protected destination as `returnTo` without starting navigation. On the Client, returning that path lets Vue Router redirect the current navigation atomically. On the Server, `$redirect(...)` preserves the SSR HTTP redirect flow.
|
|
51
|
+
|
|
47
52
|
## Why route meta matters here
|
|
48
53
|
|
|
49
54
|
The example makes a key architectural point: navigation guards are tightly coupled to route metadata such as `requiresAuth`.
|
|
@@ -54,6 +59,10 @@ That means route configuration and guard behavior should be read together, not a
|
|
|
54
59
|
|
|
55
60
|
The example also references SSR-related configuration such as cookie handling on the server side.
|
|
56
61
|
|
|
62
|
+
When `SSR_COOKIE=false`, `cookieDisabledOnServer` is true only during server rendering. The guard deliberately allows the protected route's neutral SSR entry, then the browser restores Passport state and applies the same admission policy after hydration. This preserves equivalent server and hydration-time initial rendering without weakening Client-side protection.
|
|
63
|
+
|
|
64
|
+
For cookie-enabled SSR, a rejected request must still use `$redirect(...)` so the SSR layer returns its HTTP redirect response. On the Client, return a route path or route-location object from the guard instead of using an imperative `$goto...()` helper.
|
|
65
|
+
|
|
57
66
|
So guards are not purely a client-side router concern. In Cabloy/Zova, they can also intersect with SSR behavior.
|
|
58
67
|
|
|
59
68
|
## Implementation checks for navigation-guard changes
|
|
@@ -50,6 +50,30 @@ The distinction matters:
|
|
|
50
50
|
- use `routes.path` for normal path-based aliases
|
|
51
51
|
- use `routes.name` when the route depends on params-aware naming
|
|
52
52
|
|
|
53
|
+
## Generate a configured alias path
|
|
54
|
+
|
|
55
|
+
When application code needs a user-facing URL for a named route, use the canonical route name with `$router.getAliasPath(...)`:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const path = this.$router.getAliasPath('demo-todo:item', {
|
|
59
|
+
params: {
|
|
60
|
+
id: '42',
|
|
61
|
+
locale: true,
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
const absoluteUrl = this.$router.getAliasPath(
|
|
65
|
+
'demo-todo:item',
|
|
66
|
+
{ params: { id: '42', locale: true } },
|
|
67
|
+
true,
|
|
68
|
+
);
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The helper returns the configured alias path, such as `/zh-cn/todo/42`, or `undefined` when that route name has no configured alias. Pass `true` as the third argument when an absolute URL is required; it uses the same host and public-path conversion as `$router.getPagePath(..., true)`. `locale: true` uses the active locale and omits the configured default locale from an optional locale segment.
|
|
72
|
+
|
|
73
|
+
Use the canonical generated route name. Do not construct `$alias:<name>` or strip `/__alias__` in application code: those are private router implementation details.
|
|
74
|
+
|
|
75
|
+
Use `$router.getPagePath(...)` for a known canonical path template, `$router.getAliasPath(...)` for a configured public alias by canonical route name, and `$router.resolveName(...)` for canonical named-route resolution. Do not add alias behavior to `getPagePath(...)`, because aliases are configured against route names rather than page-path templates.
|
|
76
|
+
|
|
53
77
|
## Implementation checks for route-alias changes
|
|
54
78
|
|
|
55
79
|
When changing user-facing routes, ask:
|
|
@@ -20,15 +20,17 @@ For the edition-detection workflow, also see [Edition Detection](/editions/detec
|
|
|
20
20
|
|
|
21
21
|
## Cabloy Basic root wrappers
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Cabloy Basic exposes these default Web and Admin wrappers:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
npm run dev:zova:admin
|
|
27
27
|
npm run dev:zova:web
|
|
28
28
|
npm run build:zova
|
|
29
|
+
npm run build:zova:admin
|
|
30
|
+
npm run build:zova:web
|
|
29
31
|
```
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
They map to the `cabloyBasicAdmin` and `cabloyBasicWeb` flavors. Basic also includes the Commerce aggregate-and-surface wrappers:
|
|
32
34
|
|
|
33
35
|
```bash
|
|
34
36
|
# Customer Web or Operator Admin development server
|
|
@@ -41,11 +43,13 @@ npm run build:zova:commerce:web
|
|
|
41
43
|
npm run build:zova:commerce:admin
|
|
42
44
|
```
|
|
43
45
|
|
|
46
|
+
`npm run build:zova:all` sequentially runs the focused Basic and Commerce batch builds. `npm run init` uses it to prepare every shipped Cabloy Basic SSR/REST flavor before Vona is initialized. For normal frontend work, continue to use `build:zova` or `build:zova:commerce` when only that suite's artifacts changed.
|
|
47
|
+
|
|
44
48
|
## Basic SSR browser acceptance
|
|
45
49
|
|
|
46
|
-
The default Basic Web and Admin sites have browser smoke commands that exercise Vona SSR dispatch at `7102`, not a standalone Zova development-server port.
|
|
50
|
+
The default Basic Web and Admin sites have browser smoke commands that exercise Vona SSR dispatch at port `7102`, not a standalone Zova development-server port.
|
|
47
51
|
|
|
48
|
-
Prepare current artifacts explicitly when
|
|
52
|
+
Prepare current SSR and REST artifacts explicitly when frontend output has changed:
|
|
49
53
|
|
|
50
54
|
```bash
|
|
51
55
|
# Web only
|
|
@@ -54,40 +58,77 @@ npm run build:zova:web
|
|
|
54
58
|
# Admin only
|
|
55
59
|
npm run build:zova:admin
|
|
56
60
|
|
|
57
|
-
# Both default Basic sites
|
|
61
|
+
# Both default Basic sites, then a managed local run
|
|
58
62
|
npm run build:zova
|
|
59
63
|
npm run deps:vona
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Then use the managed clean local acceptance command:
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
64
|
npm run test:e2e:basic:clean
|
|
66
65
|
```
|
|
67
66
|
|
|
68
|
-
|
|
67
|
+
The managed clean command resets Vona-managed test data and the local Redis namespace, starts one development Vona worker, and runs the complete suite by default. Browser commands consume already-built artifacts; they do not rebuild them.
|
|
69
68
|
|
|
70
|
-
The
|
|
69
|
+
The Basic and Commerce suite families use the same command shape:
|
|
71
70
|
|
|
72
71
|
```text
|
|
73
72
|
test:e2e:<suite> complete suite
|
|
74
73
|
test:e2e:<suite>:web all @web surface scenarios
|
|
75
74
|
test:e2e:<suite>:admin all @admin surface scenarios
|
|
76
|
-
test:e2e:<suite>:clean
|
|
75
|
+
test:e2e:<suite>:clean managed clean local suite run
|
|
77
76
|
```
|
|
78
77
|
|
|
79
|
-
Use Playwright tags after npm's argument delimiter for
|
|
78
|
+
Use Playwright tags after npm's argument delimiter for scenario selection instead of adding one root script per scenario:
|
|
80
79
|
|
|
81
80
|
```bash
|
|
82
81
|
npm run test:e2e:basic:clean -- --grep @flow
|
|
83
82
|
npm run test:e2e:basic -- --grep ATP-BASIC-FLOW-01
|
|
84
83
|
```
|
|
85
84
|
|
|
86
|
-
For the complete tag vocabulary, managed-runner argument boundaries, and externally managed-target examples, see [Repo Scripts](/reference/repo-scripts#ssr-browser-checks). For a separately managed Basic target, set `BASIC_E2E_BASE_URL`;
|
|
85
|
+
For the complete tag vocabulary, managed-runner argument boundaries, and externally managed-target examples, see [Repo Scripts](/reference/repo-scripts#ssr-browser-checks). For a separately managed Basic target, set `BASIC_E2E_BASE_URL`; Commerce commands use `COMMERCE_E2E_BASE_URL`. The caller owns external-target data, cache, and artifact freshness.
|
|
86
|
+
|
|
87
|
+
## Cabloy Start root wrappers
|
|
88
|
+
|
|
89
|
+
Cabloy Start is the licensed private edition. Its default root wrappers use the `cabloyStartAdmin` and `cabloyStartWeb` flavors:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npm run dev:zova:admin
|
|
93
|
+
npm run dev:zova:web
|
|
94
|
+
npm run build:zova
|
|
95
|
+
npm run build:zova:admin
|
|
96
|
+
npm run build:zova:web
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Cabloy Start does not expose the Basic Commerce wrapper family.
|
|
100
|
+
|
|
101
|
+
## Start SSR browser acceptance
|
|
102
|
+
|
|
103
|
+
The Start Web and Admin browser baseline also exercises Vona SSR dispatch at port `7102`. Prepare current SSR and REST artifacts, then use the managed local command:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm run build:zova
|
|
107
|
+
npm run deps:vona
|
|
108
|
+
npm run test:e2e:start:clean
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The Start command family is:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
test:e2e:start complete suite
|
|
115
|
+
test:e2e:start:web all @web surface scenarios
|
|
116
|
+
test:e2e:start:admin all @admin surface scenarios
|
|
117
|
+
test:e2e:start:clean managed clean local suite run
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Start scenarios currently use `@web`, `@admin`, and `@smoke`. Select a scenario or surface with Playwright arguments:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npm run test:e2e:start:clean -- --grep @web
|
|
124
|
+
npm run test:e2e:start -- --grep ATP-START-FLOW-01
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
For a separately managed Start target, set `START_E2E_BASE_URL`. The target owner is responsible for data, cache, and artifact freshness.
|
|
87
128
|
|
|
88
129
|
## Zova script model
|
|
89
130
|
|
|
90
|
-
The underlying Zova package
|
|
131
|
+
The underlying Zova package organizes scripts around app mode and flavor.
|
|
91
132
|
|
|
92
133
|
Examples from the current source include:
|
|
93
134
|
|
|
@@ -100,18 +141,18 @@ Examples from the current source include:
|
|
|
100
141
|
- `dev:ssr:cabloyBasicAdmin`
|
|
101
142
|
- `build:ssr:cabloyBasicAdmin`
|
|
102
143
|
- `build:rest:cabloyBasicAdmin`
|
|
103
|
-
- `dev:ssr:
|
|
104
|
-
- `build:ssr:
|
|
105
|
-
- `build:rest:
|
|
144
|
+
- `dev:ssr:cabloyStartAdmin`
|
|
145
|
+
- `build:ssr:cabloyStartAdmin`
|
|
146
|
+
- `build:rest:cabloyStartAdmin`
|
|
106
147
|
|
|
107
148
|
## Cabloy Basic
|
|
108
149
|
|
|
109
|
-
The
|
|
150
|
+
The public repository supports Basic-specific flavors:
|
|
110
151
|
|
|
111
152
|
- `cabloyBasicAdmin`
|
|
112
153
|
- `cabloyBasicWeb`
|
|
113
154
|
|
|
114
|
-
Representative Zova commands
|
|
155
|
+
Representative Zova commands are:
|
|
115
156
|
|
|
116
157
|
```bash
|
|
117
158
|
cd zova && npm run dev:ssr:cabloyBasicAdmin
|
|
@@ -121,18 +162,24 @@ cd zova && npm run build:rest:cabloyBasicAdmin
|
|
|
121
162
|
|
|
122
163
|
## Cabloy Start
|
|
123
164
|
|
|
124
|
-
The
|
|
165
|
+
The licensed private repository supports Start-specific flavors:
|
|
125
166
|
|
|
126
167
|
- `cabloyStartAdmin`
|
|
127
168
|
- `cabloyStartWeb`
|
|
128
169
|
|
|
129
|
-
|
|
170
|
+
Representative Zova commands are:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
cd zova && npm run dev:ssr:cabloyStartAdmin
|
|
174
|
+
cd zova && npm run build:ssr:cabloyStartAdmin
|
|
175
|
+
cd zova && npm run build:rest:cabloyStartAdmin
|
|
176
|
+
```
|
|
130
177
|
|
|
131
178
|
## Workflow guidance
|
|
132
179
|
|
|
133
180
|
When documenting or automating frontend scripts:
|
|
134
181
|
|
|
135
|
-
- start from root wrappers for
|
|
182
|
+
- start from the root wrappers for the detected edition
|
|
136
183
|
- detect the edition before choosing flavor-specific examples
|
|
137
184
|
- verify the exact flavor before writing edition-specific examples
|
|
138
185
|
- use REST/type generation commands deliberately when backend integration depends on them
|
|
@@ -44,6 +44,31 @@ Client reuse requires the model call to resolve to the same effective query key:
|
|
|
44
44
|
|
|
45
45
|
For helper selection and the complete passport flow, read [Model State Guide](/frontend/model-state-guide). For the dehydration filter and QueryClient lifecycle, read [A-Model Under the Hood](/frontend/a-model-under-the-hood).
|
|
46
46
|
|
|
47
|
+
## Hydration-equivalent initial render
|
|
48
|
+
|
|
49
|
+
The server-rendered HTML and the client's hydration-time initial render must be equivalent. Compare the server response with the first client render that hydrates it, not with the browser UI after later client work completes.
|
|
50
|
+
|
|
51
|
+
Choose one of these strategies for each render-driving state:
|
|
52
|
+
|
|
53
|
+
### State required in SSR output
|
|
54
|
+
|
|
55
|
+
Use the model-owned query on both sides, prepare it in the server-capable initialization path, and let the client reuse the transferred state through the same effective Model, selector, and logical query key. This is the normal approach for public data that must appear in the initial HTML.
|
|
56
|
+
|
|
57
|
+
### State intentionally omitted from SSR
|
|
58
|
+
|
|
59
|
+
For private, cookie-unavailable, or browser-only state, render the same neutral shell or placeholder on the server and during the client's hydration-time initial render. Begin the query, loading state, and private rendered branch only at an explicit client boundary, such as `onHydrated`, `ClientOnly`, completed route admission, a mounted client lifecycle, or user interaction.
|
|
60
|
+
|
|
61
|
+
A `process.env.CLIENT` branch is not sufficient when it changes the first hydration tree. A state transition after hydration is valid; a different hydration-time initial tree is not.
|
|
62
|
+
|
|
63
|
+
### Query helper roles
|
|
64
|
+
|
|
65
|
+
- `$useStateData(...)` owns the query identity, state, cache lifecycle, and hydration reuse.
|
|
66
|
+
- `disableSuspenseOnInit: true` skips only `$useStateData(...)`'s automatic first-creation `query.suspense()` kick. It does not prevent query creation, restore, mounted/no-data fetches, or later refetches.
|
|
67
|
+
- `$QueryEnsureLoaded(...)` is an awaited availability gate: it waits only while `query.data === undefined`. Use it at a deliberate boundary that needs loaded data, not to suppress a query during hydration.
|
|
68
|
+
- If a boundary requires domain-valid data rather than merely loaded data, choose `$QueryGetFresh(...)` or `$QueryEnsureFresh(...)` with the model's freshness rule.
|
|
69
|
+
|
|
70
|
+
For the detailed state-helper semantics, read [Use State Data Best Practices](/frontend/use-state-data-best-practices). For browser-only rendering, read [SSR ClientOnly](/frontend/ssr-client-only).
|
|
71
|
+
|
|
47
72
|
## Implementation checks for SSR data-loading changes
|
|
48
73
|
|
|
49
74
|
When changing SSR pages, avoid inventing parallel data-loading patterns unless there is a real reason.
|
|
@@ -79,6 +79,9 @@ Review these questions when the change affects route resolution, server-side dat
|
|
|
79
79
|
|
|
80
80
|
- [ ] Is the initial server-rendered HTML still correct before hydration begins?
|
|
81
81
|
- [ ] If data is involved, is it prepared through the intended SSR/model/controller flow?
|
|
82
|
+
- [ ] Does the server HTML match the client's hydration-time initial render in structure, visible state, and render-driving data?
|
|
83
|
+
- [ ] For SSR-required data, does the client reuse the transferred state through the same effective query key instead of producing a separate first-screen result?
|
|
84
|
+
- [ ] For private, cookie-unavailable, or browser-only data intentionally omitted by SSR, does the server and hydration-time client render keep the same neutral shell or placeholder?
|
|
82
85
|
- [ ] If metadata is involved, is it still produced through the intended SSR-aware meta path?
|
|
83
86
|
- [ ] If the change touches SSR-only behavior, did I verify it at the server-render stage rather than only after client boot?
|
|
84
87
|
|
|
@@ -92,10 +95,12 @@ Read together:
|
|
|
92
95
|
|
|
93
96
|
Review these questions when the change affects browser-only behavior, first paint, or client takeover after SSR.
|
|
94
97
|
|
|
95
|
-
- [ ] Is the client reusing server-provided state rather than recomputing a different
|
|
96
|
-
- [ ] If
|
|
98
|
+
- [ ] Is the client reusing server-provided state rather than recomputing a different hydration-time initial result?
|
|
99
|
+
- [ ] If state was intentionally omitted by SSR, is its query/load/render branch deferred until an explicit post-hydration, admission, mounted, or interaction boundary?
|
|
100
|
+
- [ ] If browser-only behavior is involved, should part of the UI be isolated with `ClientOnly` and a hydration-equivalent placeholder?
|
|
101
|
+
- [ ] Is `disableSuspenseOnInit` being used only to skip its init-time suspense kick, rather than as an assumed no-fetch or hydration-deferral mechanism?
|
|
97
102
|
- [ ] Did I separate a hydration issue from a server-render issue before changing code?
|
|
98
|
-
- [ ] If the
|
|
103
|
+
- [ ] If the browser UI later differs from the server output, does that change begin after hydration through an expected framework-supported boundary?
|
|
99
104
|
|
|
100
105
|
Read together:
|
|
101
106
|
|
|
@@ -135,6 +140,8 @@ Flag the change for follow-up when any of these are true:
|
|
|
135
140
|
- the change assumes one edition's theme/UI behavior applies universally
|
|
136
141
|
- the change was validated only in dev even though the failure is deploy- or build-sensitive
|
|
137
142
|
- the review never identified which SSR layer was actually changing
|
|
143
|
+
- private or browser-only state omitted by SSR appears or starts loading during the client's hydration-time initial render
|
|
144
|
+
- `disableSuspenseOnInit` is presented as proof that a query cannot fetch or affect hydration
|
|
138
145
|
|
|
139
146
|
## Reviewer template
|
|
140
147
|
|
|
@@ -156,10 +163,13 @@ Review this change with the Cabloy SSR checklist in mind.
|
|
|
156
163
|
|
|
157
164
|
1. Identify which SSR layer the change touches: Vona SSR orchestration, frontend build output, Zova SSR server render, or client hydration.
|
|
158
165
|
2. Separate server-render correctness from hydration correctness.
|
|
159
|
-
3.
|
|
160
|
-
4.
|
|
161
|
-
5.
|
|
162
|
-
6.
|
|
166
|
+
3. Compare server HTML with the client's hydration-time initial render, not with later post-hydration browser state.
|
|
167
|
+
4. Verify whether SSR-required state reuses the intended transferred query state and whether deliberately omitted private/browser-only state remains absent until an explicit client boundary.
|
|
168
|
+
5. Do not accept `disableSuspenseOnInit` as evidence that a query cannot fetch or change hydration behavior.
|
|
169
|
+
6. Verify whether the change reuses the intended framework abstraction instead of adding a parallel workaround.
|
|
170
|
+
7. Check whether the change needs built-mode validation rather than only dev-mode validation.
|
|
171
|
+
8. Review edition-sensitive UI/theme assumptions when the change touches first paint, tokens, dark mode, or SSR env behavior.
|
|
172
|
+
9. Flag any change whose review never identifies the failing or affected SSR layer.
|
|
163
173
|
```
|
|
164
174
|
|
|
165
175
|
## Read together
|
|
@@ -98,6 +98,10 @@ A controller renders as though the interaction is ready, but clicking the button
|
|
|
98
98
|
|
|
99
99
|
That is a sign that a query-state concern may have been pushed too far into imperative interaction code.
|
|
100
100
|
|
|
101
|
+
### SSR exception: intentionally omitted state
|
|
102
|
+
|
|
103
|
+
For state intentionally omitted from SSR, hydration equivalence takes priority over the normal render-time default. Keep the same neutral shell or placeholder in the server output and the client's hydration-time initial render, then establish or load the private/client-only branch only after an explicit client boundary. Read [SSR Init Data](/frontend/ssr-init-data) before applying this exception.
|
|
104
|
+
|
|
101
105
|
## Practical rule 3: `disableSuspenseOnInit: true` disables the init-time `query.suspense()` kick, not the query itself
|
|
102
106
|
|
|
103
107
|
This point needs precise wording.
|
|
@@ -263,6 +263,8 @@ This detail is important because:
|
|
|
263
263
|
- the runtime can still preserve named-route identity and params-aware resolution
|
|
264
264
|
- alias handling remains a router concern instead of leaking into page code
|
|
265
265
|
|
|
266
|
+
`$alias:<name>` and `/__alias__` are private runtime machinery. Application code should use `$router.getAliasPath('module:page', { params, query }, absolute?)`, which accepts the canonical route name and returns the configured public alias path (or `undefined` when no alias is configured). Its optional `absolute` argument uses the same origin and public-path conversion as `getPagePath(...)`.
|
|
267
|
+
|
|
266
268
|
#### Layout wrapping
|
|
267
269
|
|
|
268
270
|
If `meta.layout !== false`, the runtime does not register the page component alone.
|
|
@@ -289,11 +291,12 @@ This helper:
|
|
|
289
291
|
- handles locale-specific param normalization
|
|
290
292
|
- can return a relative page path or an absolute URL
|
|
291
293
|
|
|
292
|
-
Zova also exposes named-route resolution through `resolveName(...)
|
|
294
|
+
Zova also exposes canonical named-route resolution through `resolveName(...)` and configured public alias-path generation through `getAliasPath(...)`. Like `getPagePath(...)`, `getAliasPath(...)` can return either a relative path or an absolute URL. These helpers preserve the module-aware naming/path model rather than asking every caller to manually build URLs.
|
|
293
295
|
|
|
294
296
|
That is why the recommended page-navigation surface stays framework-native:
|
|
295
297
|
|
|
296
298
|
- `this.$router.getPagePath(...)`
|
|
299
|
+
- `this.$router.getAliasPath(...)`
|
|
297
300
|
- `this.app.$gotoPage(...)`
|
|
298
301
|
- `this.app.$gotoHome(...)`
|
|
299
302
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# Comparison with Other Frameworks
|
|
2
2
|
|
|
3
|
-
This page shows how **Cabloy** differs from several common framework choices,
|
|
3
|
+
This page shows how **Cabloy** differs from several common framework choices, focusing on its one fullstack system for AI vibe coding: bidirectional type sync, CLI-first workflows, and source-grounded docs and skills. It also distinguishes strengths of the fullstack system from those of the backend layer provided by **Vona**.
|
|
4
4
|
|
|
5
5
|
## What is being compared
|
|
6
6
|
|
|
7
7
|
Cabloy is a **Node.js fullstack framework system**.
|
|
8
8
|
|
|
9
|
-
That means the comparison is not only about a backend runtime or
|
|
9
|
+
That means the comparison is not only about a backend runtime or a frontend stack. It is about a unified system where **Vona** and **Zova** support bidirectional type sync, CLI-first workflows, and reusable docs and skills, alongside shared conventions, SSR-aware delivery modes, and cross-stack generation workflows.
|
|
10
10
|
|
|
11
11
|
For the broader Cabloy model, start with these pages:
|
|
12
12
|
|
|
@@ -23,17 +23,19 @@ The sections below use the same comparison lens each time:
|
|
|
23
23
|
- **System center** — what the framework treats as the main architectural center
|
|
24
24
|
- **Backend model** — how much backend structure and infrastructure the framework provides by default
|
|
25
25
|
- **Frontend and admin model** — how the UI side is expected to evolve
|
|
26
|
-
- **Cross-stack workflow** — how
|
|
26
|
+
- **Cross-stack workflow** — how bidirectional type sync, contracts, and generation workflows stay aligned
|
|
27
|
+
- **Guidance and automation** — how CLI-first workflows, docs, and skills make repository conventions reusable
|
|
27
28
|
- **Best fit** — the kind of team or project the framework fits most naturally
|
|
28
29
|
|
|
29
30
|
## Cabloy vs Next.js
|
|
30
31
|
|
|
31
32
|
| Perspective | Cabloy | Next.js |
|
|
32
33
|
| ------------------------ | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
33
|
-
| System center | One
|
|
34
|
+
| System center | One fullstack system, with Vona and Zova as aligned backend and frontend layers | Frontend-centric fullstack framework |
|
|
34
35
|
| Backend model | Dedicated backend framework with its own runtime, contracts, infrastructure, and CLI workflows | Backend capabilities are typically centered around the web app runtime |
|
|
35
36
|
| Frontend and admin model | Shared conventions across SSR, SPA, Web, and Admin applications | Strong fit for React-based web application delivery |
|
|
36
|
-
| Cross-stack workflow |
|
|
37
|
+
| Cross-stack workflow | Bidirectional type sync through OpenAPI, SDK generation, and metadata feedback loops | Usually chosen per project or ecosystem tooling |
|
|
38
|
+
| Guidance and automation | CLI-first workflows plus source-grounded docs and skills | Usually chosen per project or ecosystem tooling |
|
|
37
39
|
| Best fit | Teams that want a coordinated fullstack system with a stronger dedicated backend layer | Teams that want a React-centered fullstack web application path |
|
|
38
40
|
|
|
39
41
|
Cabloy and Next.js both target fullstack application development, but they organize the stack differently.
|
|
@@ -43,8 +45,9 @@ Cabloy keeps the backend and frontend as **separate but coordinated framework la
|
|
|
43
45
|
Representative Cabloy strengths in this comparison include:
|
|
44
46
|
|
|
45
47
|
- a clear backend/frontend collaboration model rather than a single frontend-centered runtime
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
+
- bidirectional type sync through backend OpenAPI output, frontend SDK generation, and frontend metadata feedback loops
|
|
49
|
+
- CLI-first workflows for scaffolding, generation, refactors, and verification
|
|
50
|
+
- source-grounded docs and skills that make repository conventions reusable for people and AI agents
|
|
48
51
|
- shared delivery conventions for SSR, SPA, Web, and Admin applications
|
|
49
52
|
|
|
50
53
|
If your main goal is a React-centered fullstack web app, Next.js may feel more direct. If your main goal is a **coordinated fullstack framework system** with a stronger backend layer and explicit cross-stack workflows, Cabloy is the better fit.
|
|
@@ -53,10 +56,11 @@ If your main goal is a React-centered fullstack web app, Next.js may feel more d
|
|
|
53
56
|
|
|
54
57
|
| Perspective | Cabloy | NestJS |
|
|
55
58
|
| ------------------------ | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
56
|
-
| System center |
|
|
59
|
+
| System center | One fullstack system | Backend framework |
|
|
57
60
|
| Backend model | Vona provides backend runtime, contracts, infrastructure, and CLI workflows | NestJS focuses on backend application structure |
|
|
58
61
|
| Frontend and admin model | Frontend collaboration is built into the broader Cabloy system through Zova and shared docs/workflows | Usually paired with a separate frontend choice |
|
|
59
|
-
| Cross-stack workflow |
|
|
62
|
+
| Cross-stack workflow | Bidirectional type sync connects backend contracts, frontend SDKs, and metadata feedback | Typically assembled from separate backend and frontend tooling choices |
|
|
63
|
+
| Guidance and automation | CLI-first workflows plus source-grounded docs and skills | Usually chosen per project or ecosystem tooling |
|
|
60
64
|
| Best fit | Teams that want backend strength inside a shared fullstack system | Teams that want a backend-first framework and will choose the frontend stack separately |
|
|
61
65
|
|
|
62
66
|
The most important difference here is **scope**.
|
|
@@ -77,10 +81,11 @@ If a team only needs a backend framework and wants to choose the frontend stack
|
|
|
77
81
|
|
|
78
82
|
| Perspective | Cabloy | Django Admin |
|
|
79
83
|
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
80
|
-
| System center | Typed Node.js fullstack
|
|
84
|
+
| System center | Typed Node.js fullstack system with aligned backend and frontend layers | Python server-centered admin framework experience |
|
|
81
85
|
| Backend model | Dedicated backend runtime and infrastructure through Vona | Django backend conventions centered on the admin stack |
|
|
82
86
|
| Frontend and admin model | Modern frontend layer through Zova with SSR, SPA, Web, and Admin delivery modes | Admin experience is centered on server-rendered templates and built-in admin conventions |
|
|
83
|
-
| Cross-stack workflow |
|
|
87
|
+
| Cross-stack workflow | Bidirectional type sync through generated contracts, metadata, and shared workflows | The default model is more tightly centered on the server-side admin stack |
|
|
88
|
+
| Guidance and automation | CLI-first workflows plus source-grounded docs and skills | Usually centered on Django conventions and ecosystem tooling |
|
|
84
89
|
| Best fit | Teams that want rapid admin development in Node.js without giving up typed frontend flexibility and richer UI interaction | Teams that want a fast server-centered admin path in the Python ecosystem |
|
|
85
90
|
|
|
86
91
|
This comparison is worth keeping even though the language ecosystems are different.
|
|
@@ -110,9 +115,10 @@ For Cabloy’s frontend/runtime side of this comparison, see:
|
|
|
110
115
|
These comparisons are most useful when your decision depends on questions like:
|
|
111
116
|
|
|
112
117
|
- do you want one coordinated framework system instead of stitching backend and frontend frameworks together?
|
|
118
|
+
- do you need bidirectional type sync through an explicit contract loop?
|
|
119
|
+
- do you want CLI-first workflows, source-grounded docs, and skills that make repository conventions reusable?
|
|
113
120
|
- do you need a stronger dedicated backend layer inside a fullstack architecture?
|
|
114
|
-
- do you want explicit contract-loop workflows between backend and frontend?
|
|
115
121
|
- do you need shared conventions across SSR, SPA, Web, and Admin delivery modes?
|
|
116
122
|
- do you want Django-Admin-like rapid admin development inside the Node.js ecosystem, but with a more modern frontend and interaction model?
|
|
117
123
|
|
|
118
|
-
If those questions matter, Cabloy’s value is not just one isolated feature. It is the way **Vona**, **Zova**, shared scripts, and cross-stack workflows stay aligned as one
|
|
124
|
+
If those questions matter, Cabloy’s value is not just one isolated feature. It is the way **Vona**, **Zova**, shared scripts, docs, skills, and cross-stack workflows stay aligned as one fullstack system.
|
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
Cabloy is a Node.js fullstack framework for AI vibe coding.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**One fullstack system for AI vibe coding—bidirectional type sync, CLI-first workflows, docs, and skills.**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Instead of stitching separate backend and frontend stacks together, Cabloy keeps their contracts, tooling, and guidance connected in one repository. Vona, Zova, and suite-based modules are the aligned architecture behind that workflow.
|
|
8
8
|
|
|
9
9
|
## What Cabloy emphasizes
|
|
10
10
|
|
|
11
|
-
- **One
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **
|
|
11
|
+
- **One fullstack system** — build backend and frontend together instead of assembling separate stacks
|
|
12
|
+
- **Bidirectional type sync** — use the contract loop to keep backend contracts and frontend metadata aligned in both directions
|
|
13
|
+
- **CLI-first workflows** — use explicit commands for scaffolding, generation, refactors, and verification
|
|
14
|
+
- **Docs and skills** — give people and AI agents reusable, source-grounded guidance for the current repository
|
|
15
|
+
- **Vona + Zova** — use aligned backend and frontend layers for code sharing and cross-stack consistency
|
|
16
|
+
- **Modular delivery** — organize capabilities as suites and modules, then deliver SSR, SPA, Web, and Admin applications with shared conventions
|
|
17
17
|
|
|
18
18
|
## How to approach fullstack work
|
|
19
19
|
|
|
@@ -84,9 +84,9 @@ In earlier standalone-repo explanations, this was often described as placing the
|
|
|
84
84
|
|
|
85
85
|
For the integration workflow and current monorepo shape, see [Vona + Zova Integration](/fullstack/vona-zova-integration) and [SSR Overview](/frontend/ssr-overview).
|
|
86
86
|
|
|
87
|
-
### 2.
|
|
87
|
+
### 2. Bidirectional type sync through the contract loop
|
|
88
88
|
|
|
89
|
-
Cabloy does not treat type sharing as backend-to-frontend only. The collaboration loop
|
|
89
|
+
Cabloy does not treat type sharing as backend-to-frontend only. The collaboration loop provides bidirectional type sync:
|
|
90
90
|
|
|
91
91
|
- **Backend → Frontend**: Vona emits Swagger/OpenAPI contracts that Zova uses to generate frontend SDKs and related schema-aware helpers
|
|
92
92
|
- **Frontend → Backend**: Zova generates structural metadata and types such as routes, components, and icons, which can be reflected back into backend-side tooling and type hints
|
|
@@ -114,12 +114,34 @@ In Cabloy Basic, upgrade synchronizes the framework-owned SSR browser E2E baseli
|
|
|
114
114
|
```text
|
|
115
115
|
e2e/config/
|
|
116
116
|
e2e/scripts/
|
|
117
|
-
e2e/specs/
|
|
117
|
+
e2e/specs/cabloy-basic/
|
|
118
118
|
e2e/specs/a-commerce/
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
Keep project-owned browser tests outside those reserved paths, for example under `e2e/specs/my-project/`; upgrade overlays framework files without deleting project test paths. Projects whose previous upgrader predates this E2E synchronization may need to run `npm run upgrade` once more: the updated upgrader recognizes an incomplete Basic E2E baseline even when the version marker is already current.
|
|
122
122
|
|
|
123
|
+
### Cabloy Start repository baseline
|
|
124
|
+
|
|
125
|
+
Cabloy Start is checked out from the licensed private repository rather than created through `npm create cabloy`. Its E2E baseline is maintained in that repository:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
e2e/config/
|
|
129
|
+
e2e/scripts/
|
|
130
|
+
e2e/specs/cabloy-start/
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The public Cabloy upgrade flow does not synchronize or repair those Start E2E files, the `test:e2e:start*` scripts, or `@playwright/test`. Keep project-owned browser scenarios outside the baseline paths, for example under `e2e/specs/my-project/`.
|
|
134
|
+
|
|
135
|
+
Prepare and run the managed Start baseline locally with:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npm run build:zova
|
|
139
|
+
npm run deps:vona
|
|
140
|
+
npm run test:e2e:start:clean
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The managed command requires port `7102` to be available and owns the local reset and Vona worker lifecycle. For a separately managed target, set `START_E2E_BASE_URL` and use `test:e2e:start`, `test:e2e:start:web`, or `test:e2e:start:admin`; those commands do not reset, build, start, or stop the target. Install Chromium once when needed with `npx playwright install chromium`. See [Repo Scripts](/reference/repo-scripts#ssr-browser-checks) for the complete command variants.
|
|
144
|
+
|
|
123
145
|
## 7. Next steps for framework-aware development
|
|
124
146
|
|
|
125
147
|
If you are contributing to framework-aware workflows or using Cabloy CLI generation directly, prefer CLI-backed generation over manual scaffolding.
|
package/cabloy-docs/index.md
CHANGED
|
@@ -4,7 +4,7 @@ layout: home
|
|
|
4
4
|
hero:
|
|
5
5
|
name: 'Cabloy'
|
|
6
6
|
text: 'Node.js fullstack framework for AI vibe coding'
|
|
7
|
-
tagline:
|
|
7
|
+
tagline: One fullstack system for AI vibe coding—bidirectional type sync, CLI-first workflows, docs, and skills.
|
|
8
8
|
actions:
|
|
9
9
|
- theme: brand
|
|
10
10
|
text: Get Started
|
|
@@ -17,25 +17,25 @@ hero:
|
|
|
17
17
|
link: /ai/introduction
|
|
18
18
|
|
|
19
19
|
features:
|
|
20
|
-
- title: One
|
|
21
|
-
details: Build backend and frontend
|
|
20
|
+
- title: One fullstack system
|
|
21
|
+
details: Build backend and frontend together instead of assembling separate stacks.
|
|
22
|
+
- title: Bidirectional type sync
|
|
23
|
+
details: Keep backend contracts and frontend metadata aligned through a two-way contract loop.
|
|
24
|
+
- title: CLI-first workflows
|
|
25
|
+
details: Use explicit commands for scaffolding, generation, refactors, and verification.
|
|
26
|
+
- title: Docs and skills
|
|
27
|
+
details: Give people and AI agents reusable, source-grounded guidance for the current repository.
|
|
22
28
|
- title: Vona + Zova
|
|
23
|
-
details: Use aligned backend and frontend
|
|
24
|
-
- title:
|
|
25
|
-
details: Organize capabilities as suites and modules
|
|
26
|
-
- title: Multiple delivery modes
|
|
27
|
-
details: Deliver SSR, SPA, Web, and Admin applications with shared conventions across the stack.
|
|
28
|
-
- title: CLI-first workflows for AI vibe coding
|
|
29
|
-
details: Turn scaffolding, metadata, refactors, and verification into explicit commands for faster, more accurate AI vibe coding.
|
|
30
|
-
- title: Monorepo-native development
|
|
31
|
-
details: Keep framework source, docs, and tooling aligned in one monorepo workflow.
|
|
29
|
+
details: Use aligned backend and frontend layers for code sharing and cross-stack consistency.
|
|
30
|
+
- title: Modular delivery
|
|
31
|
+
details: Organize capabilities as suites and modules, then deliver SSR, SPA, Web, and Admin applications with shared conventions.
|
|
32
32
|
---
|
|
33
33
|
|
|
34
34
|
# Cabloy Documentation
|
|
35
35
|
|
|
36
|
-
Cabloy is a Node.js fullstack framework for AI vibe coding.
|
|
36
|
+
Cabloy is a Node.js fullstack framework for AI vibe coding. It brings backend and frontend work into one system, with bidirectional type sync, CLI-first workflows, and source-grounded docs and skills for people and AI agents.
|
|
37
37
|
|
|
38
|
-
Start
|
|
38
|
+
Start with the [Contract Loop Playbook](/fullstack/contract-loop-playbook) to understand bidirectional type sync, then use the [Fullstack CLI](/fullstack/cli) and [AI Development](/ai/introduction) guides to follow the current repository. Vona, Zova, and suite-based modules provide the aligned architecture behind that workflow, while Cabloy Basic and Cabloy Start share the same fullstack core but diverge by edition.
|
|
39
39
|
|
|
40
40
|
## What you can do here
|
|
41
41
|
|