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.
Files changed (385) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/skills/cabloy-backend-scaffold/SKILL.md +31 -1
  3. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +21 -0
  4. package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +3 -0
  5. package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +4 -0
  6. package/.claude/skills/cabloy-master-detail/SKILL.md +13 -2
  7. package/.github/workflows/playwright-e2e.yml +77 -0
  8. package/.github/workflows/vona-test-pg.yml +8 -0
  9. package/.gitignore +1 -0
  10. package/CHANGELOG.md +30 -0
  11. package/CLAUDE.md +6 -1
  12. package/README.md +8 -8
  13. package/cabloy-docs/backend/crud-workflow.md +10 -0
  14. package/cabloy-docs/backend/foundation.md +29 -4
  15. package/cabloy-docs/backend/introduction.md +1 -1
  16. package/cabloy-docs/backend/migration-and-changes.md +13 -9
  17. package/cabloy-docs/backend/model-guide.md +9 -11
  18. package/cabloy-docs/backend/multi-instance-and-instance-resolution.md +18 -0
  19. package/cabloy-docs/backend/service-guide.md +1 -1
  20. package/cabloy-docs/backend/unit-testing.md +25 -0
  21. package/cabloy-docs/frontend/a-router-guide.md +1 -1
  22. package/cabloy-docs/frontend/introduction.md +1 -1
  23. package/cabloy-docs/frontend/navigation-guards-guide.md +20 -11
  24. package/cabloy-docs/frontend/route-alias-guide.md +24 -0
  25. package/cabloy-docs/frontend/scripts.md +71 -24
  26. package/cabloy-docs/frontend/ssr-init-data.md +25 -0
  27. package/cabloy-docs/frontend/ssr-review-checklist.md +17 -7
  28. package/cabloy-docs/frontend/use-state-data-best-practices.md +4 -0
  29. package/cabloy-docs/frontend/zova-router-under-the-hood.md +4 -1
  30. package/cabloy-docs/fullstack/comparison-with-other-frameworks.md +19 -13
  31. package/cabloy-docs/fullstack/introduction.md +10 -10
  32. package/cabloy-docs/fullstack/quickstart.md +23 -1
  33. package/cabloy-docs/index.md +14 -14
  34. package/cabloy-docs/reference/package-map.md +11 -7
  35. package/cabloy-docs/reference/repo-scripts.md +108 -23
  36. package/e2e/scripts/e2e.ts +1 -1
  37. package/e2e/scripts/startE2eVona.ts +51 -13
  38. package/e2e/specs/a-commerce/commerce.spec.ts +125 -1
  39. package/e2e/specs/{a-basic → cabloy-basic}/basic.spec.ts +12 -7
  40. package/package.json +2 -1
  41. package/scripts/init.ts +6 -12
  42. package/scripts/upgrade.ts +3 -1
  43. package/vona/packages-cli/cli/package.json +1 -1
  44. package/vona/packages-cli/cli-set-api/package.json +1 -1
  45. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.bin.test.ts +6 -9
  46. package/vona/packages-cli/cli-set-api/toolsIsolate/test.ts +50 -21
  47. package/vona/packages-vona/vona/package.json +1 -1
  48. package/vona/pnpm-lock.yaml +94 -163
  49. package/vona/src/backend/config/config/config.test.ts +1 -1
  50. package/vona/src/backend/config/config/config.ts +11 -0
  51. package/vona/src/suite/a-commerce/modules/commerce-catalog/package.json +4 -2
  52. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +732 -2
  53. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/locales.ts +18 -0
  54. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/meta.index.ts +14 -0
  55. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/meta.version.ts +52 -0
  56. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/ssrMenu.category.ts +30 -0
  57. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/ssrMenu.product.ts +30 -0
  58. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/ssrMenu.sku.ts +30 -0
  59. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +19 -0
  60. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +19 -0
  61. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/controller/category.ts +65 -0
  62. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/controller/product.ts +86 -0
  63. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/controller/sku.ts +65 -0
  64. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categoryCreate.tsx +28 -0
  65. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categorySelectReq.tsx +25 -0
  66. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categorySelectRes.tsx +11 -0
  67. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categorySelectResItem.tsx +39 -0
  68. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categoryUpdate.tsx +28 -0
  69. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categoryView.tsx +25 -0
  70. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productCreate.tsx +28 -0
  71. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublic.tsx +38 -0
  72. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublicSelectReq.tsx +23 -0
  73. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublicSelectRes.tsx +11 -0
  74. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublicSku.tsx +25 -0
  75. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productSelectReq.tsx +25 -0
  76. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productSelectRes.tsx +11 -0
  77. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productSelectResItem.tsx +39 -0
  78. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productUpdate.tsx +28 -0
  79. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productView.tsx +25 -0
  80. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuCreate.tsx +28 -0
  81. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectReq.tsx +25 -0
  82. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectRes.tsx +11 -0
  83. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectResItem.tsx +39 -0
  84. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuUpdate.tsx +28 -0
  85. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuView.tsx +25 -0
  86. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/category.tsx +53 -0
  87. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/product.tsx +48 -0
  88. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/sku.tsx +66 -0
  89. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/index.ts +1 -0
  90. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/category.ts +15 -0
  91. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/product.ts +46 -0
  92. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/sku.ts +18 -0
  93. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/category.ts +47 -0
  94. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/product.ts +162 -0
  95. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/sku.ts +76 -0
  96. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/catalog.test.ts +592 -0
  97. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/category.test.ts +91 -0
  98. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/product.test.ts +154 -0
  99. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/sku.test.ts +190 -0
  100. package/vona/src/suite/a-commerce/modules/commerce-member/package.json +2 -1
  101. package/vona/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +342 -5
  102. package/vona/src/suite/a-commerce/modules/commerce-member/src/.metadata/locales.ts +18 -0
  103. package/vona/src/suite/a-commerce/modules/commerce-member/src/bean/meta.index.ts +12 -0
  104. package/vona/src/suite/a-commerce/modules/commerce-member/src/bean/meta.version.ts +31 -0
  105. package/vona/src/suite/a-commerce/modules/commerce-member/src/config/locale/en-us.ts +12 -0
  106. package/vona/src/suite/a-commerce/modules/commerce-member/src/config/locale/zh-cn.ts +12 -0
  107. package/vona/src/suite/a-commerce/modules/commerce-member/src/controller/address.ts +59 -0
  108. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressCreate.tsx +39 -0
  109. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectReq.tsx +30 -0
  110. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectRes.tsx +11 -0
  111. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectResItem.tsx +53 -0
  112. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressUpdate.tsx +39 -0
  113. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressView.tsx +39 -0
  114. package/vona/src/suite/a-commerce/modules/commerce-member/src/entity/address.tsx +76 -0
  115. package/vona/src/suite/a-commerce/modules/commerce-member/src/index.ts +1 -0
  116. package/vona/src/suite/a-commerce/modules/commerce-member/src/model/address.ts +10 -0
  117. package/vona/src/suite/a-commerce/modules/commerce-member/src/service/address.ts +84 -0
  118. package/vona/src/suite/a-commerce/modules/commerce-member/test/addressOwnership.test.ts +203 -0
  119. package/vona/src/suite/a-commerce/modules/commerce-seed/package.json +52 -0
  120. package/vona/src/suite/a-commerce/modules/commerce-seed/src/.metadata/index.ts +55 -0
  121. package/vona/src/suite/a-commerce/modules/commerce-seed/src/.metadata/this.ts +2 -0
  122. package/vona/src/suite/a-commerce/modules/commerce-seed/src/bean/meta.version.ts +80 -0
  123. package/vona/src/suite/a-commerce/modules/commerce-seed/src/index.ts +1 -0
  124. package/vona/src/suite/a-commerce/modules/commerce-seed/tsconfig.build.json +11 -0
  125. package/vona/src/suite/a-commerce/modules/commerce-seed/tsconfig.json +7 -0
  126. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/package.json +4 -2
  127. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/index.ts +192 -2
  128. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/locales.ts +18 -0
  129. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/meta.version.ts +32 -0
  130. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/ssrMenu.home.ts +3 -1
  131. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/ssrMenuGroup.catalog.ts +21 -0
  132. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/ssrMenuGroup.inventory.ts +21 -0
  133. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/en-us.ts +5 -0
  134. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/zh-cn.ts +5 -0
  135. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/controller/operator.ts +21 -0
  136. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/dto/operatorContext.ts +21 -0
  137. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/index.ts +1 -0
  138. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/service/operator.ts +18 -0
  139. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/meta.version.test.ts +44 -0
  140. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/operatorAccess.test.ts +55 -0
  141. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/ssrMenu.test.ts +77 -0
  142. package/vona/src/suite/a-commerce/modules/commerce-trade/package.json +2 -1
  143. package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +773 -2
  144. package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/locales.ts +18 -0
  145. package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/meta.index.ts +23 -0
  146. package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/meta.version.ts +83 -0
  147. package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/ssrMenu.stockAudit.ts +30 -0
  148. package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/ssrMenu.stockBalance.ts +30 -0
  149. package/vona/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +29 -0
  150. package/vona/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +29 -0
  151. package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/cart.ts +48 -0
  152. package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/stockAudit.ts +38 -0
  153. package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/stockBalance.ts +49 -0
  154. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartAddItem.tsx +19 -0
  155. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartItem.tsx +34 -0
  156. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartUpdateItem.tsx +15 -0
  157. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartView.tsx +18 -0
  158. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAdjust.tsx +32 -0
  159. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditCreate.tsx +28 -0
  160. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectReq.tsx +28 -0
  161. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectRes.tsx +11 -0
  162. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectResItem.tsx +33 -0
  163. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditUpdate.tsx +28 -0
  164. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditView.tsx +25 -0
  165. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceCreate.tsx +28 -0
  166. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectReq.tsx +28 -0
  167. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectRes.tsx +11 -0
  168. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectResItem.tsx +33 -0
  169. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceUpdate.tsx +28 -0
  170. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceView.tsx +25 -0
  171. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/cart.tsx +24 -0
  172. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/cartItem.tsx +30 -0
  173. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockAudit.tsx +118 -0
  174. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockBalance.tsx +53 -0
  175. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockReservation.tsx +63 -0
  176. package/vona/src/suite/a-commerce/modules/commerce-trade/src/index.ts +1 -0
  177. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/cart.ts +17 -0
  178. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/cartItem.ts +10 -0
  179. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/stockAudit.ts +10 -0
  180. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/stockBalance.ts +15 -0
  181. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/stockReservation.ts +10 -0
  182. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/cart.ts +152 -0
  183. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockAudit.ts +20 -0
  184. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockBalance.ts +342 -0
  185. package/vona/src/suite/a-commerce/modules/commerce-trade/test/cartOwnership.test.ts +174 -0
  186. package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockAudit.test.ts +37 -0
  187. package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockBalance.test.ts +389 -0
  188. package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockReservation.test.ts +457 -0
  189. package/vona/src/suite/a-commerce/package.json +1 -0
  190. package/vona/src/suite/a-commerce/tsconfig.json +3 -0
  191. package/vona/src/suite/a-home/modules/home-user/src/.metadata/index.ts +7 -1
  192. package/vona/src/suite/a-home/modules/home-user/test/role.test.ts +14 -23
  193. package/vona/src/suite/a-training/modules/training-record/src/.metadata/index.ts +10 -8
  194. package/vona/src/suite/a-training/modules/training-recordsubject/src/.metadata/index.ts +2 -0
  195. package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +3 -1
  196. package/vona/src/suite-vendor/a-auth/modules/a-auth/package.json +1 -1
  197. package/vona/src/suite-vendor/a-auth/modules/a-auth/src/.metadata/index.ts +7 -3
  198. package/vona/src/suite-vendor/a-auth/modules/auth-simple/package.json +1 -1
  199. package/vona/src/suite-vendor/a-auth/modules/auth-simple/src/.metadata/index.ts +2 -0
  200. package/vona/src/suite-vendor/a-auth/package.json +1 -1
  201. package/vona/src/suite-vendor/a-cabloy/modules/a-datasharding/package.json +1 -1
  202. package/vona/src/suite-vendor/a-cabloy/modules/a-datasharding/src/.metadata/index.ts +1 -1
  203. package/vona/src/suite-vendor/a-cabloy/modules/a-datasource/package.json +1 -1
  204. package/vona/src/suite-vendor/a-cabloy/modules/a-datasource/src/.metadata/index.ts +3 -1
  205. package/vona/src/suite-vendor/a-cabloy/modules/a-socket/package.json +1 -1
  206. package/vona/src/suite-vendor/a-cabloy/modules/a-socket/src/.metadata/index.ts +1 -1
  207. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
  208. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/.metadata/index.ts +47 -47
  209. package/vona/src/suite-vendor/a-cabloy/modules/a-ssrhmr/package.json +1 -1
  210. package/vona/src/suite-vendor/a-cabloy/modules/a-ssrhmr/src/.metadata/index.ts +1 -1
  211. package/vona/src/suite-vendor/a-cabloy/modules/a-status/package.json +1 -1
  212. package/vona/src/suite-vendor/a-cabloy/modules/a-status/src/.metadata/index.ts +2 -0
  213. package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
  214. package/vona/src/suite-vendor/a-captcha/modules/a-captcha/package.json +1 -1
  215. package/vona/src/suite-vendor/a-captcha/modules/a-captcha/src/.metadata/index.ts +1 -1
  216. package/vona/src/suite-vendor/a-captcha/package.json +1 -1
  217. package/vona/src/suite-vendor/a-file/modules/a-file/package.json +1 -1
  218. package/vona/src/suite-vendor/a-file/modules/a-file/src/.metadata/index.ts +42 -38
  219. package/vona/src/suite-vendor/a-file/package.json +2 -2
  220. package/vona/src/suite-vendor/a-image/modules/a-image/package.json +1 -1
  221. package/vona/src/suite-vendor/a-image/modules/a-image/src/.metadata/index.ts +42 -38
  222. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/package.json +1 -1
  223. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/src/.metadata/index.ts +42 -27
  224. package/vona/src/suite-vendor/a-image/package.json +1 -1
  225. package/vona/src/suite-vendor/a-paypal/modules/a-paypal/package.json +1 -1
  226. package/vona/src/suite-vendor/a-paypal/modules/a-paypal/src/.metadata/index.ts +3 -1
  227. package/vona/src/suite-vendor/a-paypal/package.json +1 -1
  228. package/vona/src/suite-vendor/a-vona/modules/a-beanmutate/package.json +1 -1
  229. package/vona/src/suite-vendor/a-vona/modules/a-beanmutate/src/.metadata/index.ts +1 -1
  230. package/vona/src/suite-vendor/a-vona/modules/a-body/package.json +1 -1
  231. package/vona/src/suite-vendor/a-vona/modules/a-body/src/.metadata/index.ts +2 -2
  232. package/vona/src/suite-vendor/a-vona/modules/a-cache/package.json +1 -1
  233. package/vona/src/suite-vendor/a-vona/modules/a-cache/src/.metadata/index.ts +1 -1
  234. package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
  235. package/vona/src/suite-vendor/a-vona/modules/a-core/src/.metadata/index.ts +1 -1
  236. package/vona/src/suite-vendor/a-vona/modules/a-error/package.json +1 -1
  237. package/vona/src/suite-vendor/a-vona/modules/a-error/src/.metadata/index.ts +1 -1
  238. package/vona/src/suite-vendor/a-vona/modules/a-event/package.json +1 -1
  239. package/vona/src/suite-vendor/a-vona/modules/a-event/src/.metadata/index.ts +1 -1
  240. package/vona/src/suite-vendor/a-vona/modules/a-executor/package.json +1 -1
  241. package/vona/src/suite-vendor/a-vona/modules/a-executor/src/.metadata/index.ts +1 -1
  242. package/vona/src/suite-vendor/a-vona/modules/a-hmr/package.json +1 -1
  243. package/vona/src/suite-vendor/a-vona/modules/a-hmr/src/.metadata/index.ts +1 -1
  244. package/vona/src/suite-vendor/a-vona/modules/a-instance/package.json +1 -1
  245. package/vona/src/suite-vendor/a-vona/modules/a-instance/src/.metadata/index.ts +3 -1
  246. package/vona/src/suite-vendor/a-vona/modules/a-jwt/package.json +1 -1
  247. package/vona/src/suite-vendor/a-vona/modules/a-jwt/src/.metadata/index.ts +1 -1
  248. package/vona/src/suite-vendor/a-vona/modules/a-logger/package.json +1 -1
  249. package/vona/src/suite-vendor/a-vona/modules/a-logger/src/.metadata/index.ts +1 -1
  250. package/vona/src/suite-vendor/a-vona/modules/a-mail/package.json +1 -1
  251. package/vona/src/suite-vendor/a-vona/modules/a-mail/src/.metadata/index.ts +3 -1
  252. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/package.json +1 -1
  253. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/.metadata/index.ts +1 -1
  254. package/vona/src/suite-vendor/a-vona/modules/a-onion/package.json +1 -1
  255. package/vona/src/suite-vendor/a-vona/modules/a-onion/src/.metadata/index.ts +1 -1
  256. package/vona/src/suite-vendor/a-vona/modules/a-openapi/package.json +1 -1
  257. package/vona/src/suite-vendor/a-vona/modules/a-openapi/src/.metadata/index.ts +1 -1
  258. package/vona/src/suite-vendor/a-vona/modules/a-orm/cli/model/metadata/generate.ts +5 -11
  259. package/vona/src/suite-vendor/a-vona/modules/a-orm/package.json +1 -1
  260. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/bean.model/bean.model_cache.ts +52 -0
  261. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoGet.ts +4 -10
  262. package/vona/src/suite-vendor/a-vona/modules/a-redis/package.json +1 -1
  263. package/vona/src/suite-vendor/a-vona/modules/a-redis/src/.metadata/index.ts +1 -1
  264. package/vona/src/suite-vendor/a-vona/modules/a-security/package.json +1 -1
  265. package/vona/src/suite-vendor/a-vona/modules/a-security/src/.metadata/index.ts +1 -1
  266. package/vona/src/suite-vendor/a-vona/modules/a-serialization/package.json +1 -1
  267. package/vona/src/suite-vendor/a-vona/modules/a-serialization/src/.metadata/index.ts +1 -1
  268. package/vona/src/suite-vendor/a-vona/modules/a-startup/package.json +1 -1
  269. package/vona/src/suite-vendor/a-vona/modules/a-startup/src/service/startup.ts +2 -2
  270. package/vona/src/suite-vendor/a-vona/modules/a-summer/package.json +1 -1
  271. package/vona/src/suite-vendor/a-vona/modules/a-summer/src/.metadata/index.ts +1 -1
  272. package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
  273. package/vona/src/suite-vendor/a-vona/modules/a-user/src/.metadata/index.ts +4 -5
  274. package/vona/src/suite-vendor/a-vona/modules/a-validation/package.json +1 -1
  275. package/vona/src/suite-vendor/a-vona/modules/a-validation/src/.metadata/index.ts +1 -1
  276. package/vona/src/suite-vendor/a-vona/modules/a-version/package.json +1 -1
  277. package/vona/src/suite-vendor/a-vona/modules/a-version/src/.metadata/index.ts +6 -0
  278. package/vona/src/suite-vendor/a-vona/modules/a-version/src/service/version.ts +12 -12
  279. package/vona/src/suite-vendor/a-vona/modules/a-version/src/types/version.ts +4 -4
  280. package/vona/src/suite-vendor/a-vona/modules/a-web/package.json +1 -1
  281. package/vona/src/suite-vendor/a-vona/modules/a-web/src/.metadata/index.ts +1 -1
  282. package/vona/src/suite-vendor/a-vona/modules/a-worker/package.json +1 -1
  283. package/vona/src/suite-vendor/a-vona/modules/a-worker/src/.metadata/index.ts +1 -1
  284. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  285. package/zova/packages-cli/cli/package.json +2 -2
  286. package/zova/packages-cli/cli-set-front/package.json +1 -1
  287. package/zova/packages-cli/cli-set-front/src/lib/bean/toolsMetadata/generateScope.ts +1 -1
  288. package/zova/packages-zova/zova/package.json +2 -2
  289. package/zova/pnpm-lock.yaml +9 -9
  290. package/zova/src/front/config/config/config.cabloyCommerce.ts +5 -1
  291. package/zova/src/front/config/config/config.cabloyCommerceAdmin.ts +2 -1
  292. package/zova/src/suite/a-commerce/modules/commerce-catalog/cli/openapi.config.ts +9 -0
  293. package/zova/src/suite/a-commerce/modules/commerce-catalog/package.json +2 -1
  294. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +202 -3
  295. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/locales.ts +7 -0
  296. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/page/catalogue.ts +23 -0
  297. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/page/product.ts +19 -0
  298. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/commerceCatalogProduct.ts +52 -0
  299. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/baseURL.ts +5 -0
  300. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/index.ts +3 -0
  301. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/schemas.ts +412 -0
  302. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/types.ts +7159 -0
  303. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/apiSchema/commerceCatalogProduct.ts +20 -0
  304. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +8 -0
  305. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +8 -0
  306. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/index.ts +1 -0
  307. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/model/catalogue.ts +38 -0
  308. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/page/catalogue/controller.tsx +71 -0
  309. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/page/product/controller.tsx +107 -0
  310. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/routes.ts +19 -0
  311. package/zova/src/suite/a-commerce/modules/commerce-member/cli/openapi.config.ts +9 -0
  312. package/zova/src/suite/a-commerce/modules/commerce-member/package.json +2 -1
  313. package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +182 -3
  314. package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/locales.ts +7 -0
  315. package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/page/address.ts +19 -0
  316. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/commerceMemberAddress.ts +111 -0
  317. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/baseURL.ts +5 -0
  318. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/index.ts +3 -0
  319. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/schemas.ts +432 -0
  320. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/types.ts +7445 -0
  321. package/zova/src/suite/a-commerce/modules/commerce-member/src/apiSchema/commerceMemberAddress.ts +35 -0
  322. package/zova/src/suite/a-commerce/modules/commerce-member/src/config/locale/en-us.ts +17 -0
  323. package/zova/src/suite/a-commerce/modules/commerce-member/src/config/locale/zh-cn.ts +17 -0
  324. package/zova/src/suite/a-commerce/modules/commerce-member/src/index.ts +1 -0
  325. package/zova/src/suite/a-commerce/modules/commerce-member/src/model/address.ts +38 -0
  326. package/zova/src/suite/a-commerce/modules/commerce-member/src/page/address/controller.tsx +194 -0
  327. package/zova/src/suite/a-commerce/modules/commerce-member/src/routes.ts +12 -0
  328. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/cli/openapi.config.ts +9 -0
  329. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/package.json +2 -1
  330. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/index.ts +175 -3
  331. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/locales.ts +7 -0
  332. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/page/dashboard.ts +9 -0
  333. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/commerceSiteadminOperator.ts +25 -0
  334. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/baseURL.ts +5 -0
  335. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/index.ts +3 -0
  336. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/schemas.ts +304 -0
  337. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/types.ts +5710 -0
  338. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/apiSchema/commerceSiteadminOperator.ts +13 -0
  339. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/en-us.ts +5 -0
  340. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/zh-cn.ts +5 -0
  341. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/index.ts +1 -0
  342. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/model/operator.ts +17 -0
  343. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/page/dashboard/controller.tsx +34 -0
  344. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/routes.ts +5 -0
  345. package/zova/src/suite/a-commerce/modules/commerce-trade/cli/openapi.config.ts +15 -0
  346. package/zova/src/suite/a-commerce/modules/commerce-trade/package.json +2 -1
  347. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +182 -3
  348. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/locales.ts +7 -0
  349. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/page/cart.ts +19 -0
  350. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/commerceTradeCart.ts +99 -0
  351. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/baseURL.ts +5 -0
  352. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/index.ts +3 -0
  353. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/schemas.ts +446 -0
  354. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/types.ts +7651 -0
  355. package/zova/src/suite/a-commerce/modules/commerce-trade/src/apiSchema/commerceTradeCart.ts +35 -0
  356. package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +8 -0
  357. package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +8 -0
  358. package/zova/src/suite/a-commerce/modules/commerce-trade/src/index.ts +1 -0
  359. package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/cart.ts +78 -0
  360. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/cart/controller.tsx +108 -0
  361. package/zova/src/suite/a-commerce/modules/commerce-trade/src/routes.ts +12 -0
  362. package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/index.ts +5 -5
  363. package/zova/src/suite/a-demo/modules/demo-todo/src/.metadata/index.ts +2 -2
  364. package/zova/src/suite/a-home/modules/home-base/src/service/routerGuards.ts +18 -10
  365. package/zova/src/suite/a-home/modules/home-indexweb/src/.metadata/index.ts +2 -2
  366. package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/controller.tsx +17 -7
  367. package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.header.tsx +1 -1
  368. package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/controller.tsx +17 -7
  369. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  370. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/index.ts +4 -4
  371. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +1 -0
  372. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  373. package/zova/src/suite-vendor/a-zova/modules/a-bean/cli/controller/metadata/generateMetaPage.ts +3 -1
  374. package/zova/src/suite-vendor/a-zova/modules/a-bean/package.json +1 -1
  375. package/zova/src/suite-vendor/a-zova/modules/a-fetch/package.json +2 -2
  376. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  377. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +3 -1
  378. package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
  379. package/zova/src/suite-vendor/a-zova/modules/a-router/src/bean/sys.router.ts +35 -8
  380. package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkeySys.ts +28 -12
  381. package/zova/src/suite-vendor/a-zova/modules/a-router/src/service/routerGuards.ts +6 -8
  382. package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/router.ts +14 -2
  383. package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/utils.ts +4 -1
  384. package/zova/src/suite-vendor/a-zova/package.json +5 -5
  385. package/CLAUDE.local.md +0 -4
@@ -36,7 +36,7 @@ Example: `vona/src/suite/a-training/modules/training-student/package.json`
36
36
 
37
37
  - package name: `vona-module-training-student`
38
38
  - title: `training-student`
39
- - `vonaModule.dependencies` records module-level framework dependencies
39
+ - `vonaModule.dependencies` records genuine module availability, dependency-first ordering, and minimum-version requirements
40
40
 
41
41
  ### Suite package
42
42
 
@@ -58,17 +58,21 @@ This matters because Vona modularization is not just folder layout. Package meta
58
58
 
59
59
  ## Practical modularization edge table
60
60
 
61
- | Unit | Main role | Where dependency intent is usually expressed |
62
- | ------- | ------------------------------------- | -------------------------------------------------------------------- |
63
- | Package | metadata and publication unit | package-level `dependencies`, scripts, exports, and release metadata |
64
- | Module | main backend capability unit | `vonaModule.dependencies` for framework/module dependency intent |
65
- | Suite | composition unit for multiple modules | normal package `dependencies` that compose module packages |
61
+ | Surface | Main role |
62
+ | -------------------------------- | ------------------------------------------------------------------------------------------------------- |
63
+ | Package | metadata, publication, and ordinary package imports/dependencies |
64
+ | Suite package `dependencies` | compose the module packages that the suite includes |
65
+ | Module `vonaModule.dependencies` | declare genuine target-module availability, dependency-first ordering, and minimum-version requirements |
66
+ | Scope lookup | resolve resources from an already application-composed module without creating a module dependency edge |
66
67
 
67
68
  A practical comparison is:
68
69
 
69
- - a standalone module package still uses `vonaModule.dependencies` to describe backend framework/module dependency intent
70
+ - a standalone module package uses `vonaModule.dependencies` when its feature truly requires another module to be available, ordered first, or at a minimum compatible version
70
71
  - a suite package uses ordinary package `dependencies` to compose the module packages it contains or depends on
71
72
  - a suite-contained module still remains a module package with its own `vonaModule.dependencies`
73
+ - `this.$scope.<module>` and `app.scope(...)` perform runtime lookup of an already composed module; cross-module service, model, config, locale, or other resource lookup alone is not a reason to add `vonaModule.dependencies`
74
+
75
+ Do not add speculative module dependency declarations merely to document a scope lookup or avoid an assumed circular dependency. Lookup creates no module-order edge. Conversely, scope lookup cannot make an absent module available: declare a module dependency when the feature genuinely requires the target module's availability, ordering, or minimum version.
72
76
 
73
77
  ## How this relates to backend docs
74
78
 
@@ -1,12 +1,14 @@
1
1
  # Repo Scripts
2
2
 
3
- Use this page when you need the compact lookup surface for the shared root scripts exposed by the Cabloy Basic monorepo.
3
+ Use this page as the compact lookup surface for root scripts in Cabloy Basic and Cabloy Start.
4
4
 
5
5
  For the broader Reference landing page, see [Reference Introduction](/reference/introduction).
6
6
 
7
- The root `package.json` is the first reference point for shared monorepo workflows.
7
+ Always start with the active repository's root `package.json`. Cabloy Basic is the public generated-project baseline; Cabloy Start is the licensed private repository and has its own root command surface.
8
8
 
9
- ## Current shared entrypoints in Cabloy Basic
9
+ ## Cabloy Basic entrypoints
10
+
11
+ Cabloy Basic exposes these shared root scripts:
10
12
 
11
13
  - `npm run init`
12
14
  - `npm run upgrade`
@@ -14,17 +16,23 @@ The root `package.json` is the first reference point for shared monorepo workflo
14
16
  - `npm run vona`
15
17
  - `npm run zova`
16
18
  - `npm run dev`
19
+ - `npm run dev:one`
17
20
  - `npm run dev:zova:admin`
18
21
  - `npm run dev:zova:web`
19
22
  - `npm run dev:zova:commerce:web`
20
23
  - `npm run dev:zova:commerce:admin`
21
24
  - `npm run build`
22
25
  - `npm run build:zova`
26
+ - `npm run build:zova:all`
27
+ - `npm run build:zova:admin`
28
+ - `npm run build:zova:web`
23
29
  - `npm run build:zova:commerce`
24
30
  - `npm run build:zova:commerce:web`
25
31
  - `npm run build:zova:commerce:admin`
26
32
  - `npm run start`
33
+ - `npm run start:one`
27
34
  - `npm run test`
35
+ - `npm run db:reset`
28
36
  - `npm run test:e2e:basic`
29
37
  - `npm run test:e2e:basic:web`
30
38
  - `npm run test:e2e:basic:admin`
@@ -38,21 +46,87 @@ The root `package.json` is the first reference point for shared monorepo workflo
38
46
  - `npm run docs:build`
39
47
  - `npm run docs:preview`
40
48
 
49
+ `npm run init` prepares all Cabloy Basic SSR and REST artifacts with `npm run build:zova:all`, which sequentially builds the Basic and Commerce flavor batches before Vona initialization. Use `build:zova` or `build:zova:commerce` for focused artifact refreshes; use `build:zova:all` only when every shipped Basic flavor must be prepared.
50
+
51
+ ## Cabloy Start entrypoints
52
+
53
+ Cabloy Start exposes the equivalent Start repository surface:
54
+
55
+ - `npm run init`
56
+ - `npm run upgrade`
57
+ - `npm run upgrade:dry-run`
58
+ - `npm run vona`
59
+ - `npm run zova`
60
+ - `npm run dev`
61
+ - `npm run dev:one`
62
+ - `npm run dev:zova:admin`
63
+ - `npm run dev:zova:web`
64
+ - `npm run build`
65
+ - `npm run build:zova`
66
+ - `npm run build:zova:admin`
67
+ - `npm run build:zova:web`
68
+ - `npm run start`
69
+ - `npm run start:one`
70
+ - `npm run test`
71
+ - `npm run db:reset`
72
+ - `npm run test:e2e:start`
73
+ - `npm run test:e2e:start:web`
74
+ - `npm run test:e2e:start:admin`
75
+ - `npm run test:e2e:start:clean`
76
+ - `npm run tsc`
77
+
78
+ Cabloy Start does not expose Basic Commerce or root documentation wrappers.
79
+
41
80
  ## Upgrade
42
81
 
43
- Run `npm run upgrade:dry-run` before `npm run upgrade` to inspect the framework files and root manifest entries that an upgrade would synchronize. In Cabloy Basic, the upgrade owns `e2e/config/`, `e2e/scripts/`, `e2e/specs/a-basic/`, and `e2e/specs/a-commerce/`, together with the framework `test:e2e:*` scripts and `@playwright/test` development dependency. Keep project browser tests outside those reserved paths; see [Fullstack Quickstart](/fullstack/quickstart) for the upgrade bootstrap behavior.
82
+ Run `npm run upgrade:dry-run` before `npm run upgrade` to inspect framework files and root manifest entries that an upgrade would synchronize.
83
+
84
+ ### Cabloy Basic public projects
85
+
86
+ Basic upgrade owns these browser baseline paths:
87
+
88
+ ```text
89
+ e2e/config/
90
+ e2e/scripts/
91
+ e2e/specs/cabloy-basic/
92
+ e2e/specs/a-commerce/
93
+ ```
94
+
95
+ It also reconciles the framework Basic and Commerce `test:e2e:*` scripts and `@playwright/test` development dependency. Keep project browser tests outside those reserved paths. The upgrader merges framework baseline directories without deleting project-owned paths and can repair an incomplete Basic E2E baseline even when the framework version marker is already current.
96
+
97
+ ### Cabloy Start private repository
98
+
99
+ The Start E2E baseline is maintained in the private repository:
100
+
101
+ ```text
102
+ e2e/config/
103
+ e2e/scripts/
104
+ e2e/specs/cabloy-start/
105
+ ```
106
+
107
+ The public-package upgrade flow does not source or reconcile the Start baseline, its `test:e2e:start*` scripts, or `@playwright/test`. Keep project browser tests outside the baseline paths, for example under `e2e/specs/my-project/`.
44
108
 
45
109
  ## SSR browser checks
46
110
 
47
- Both E2E families use the same command structure:
111
+ The suites use this command family:
48
112
 
49
113
  - `test:e2e:<suite>` runs every browser scenario in the suite.
50
- - `test:e2e:<suite>:web` and `test:e2e:<suite>:admin` are durable surface shortcuts that select `@web` and `@admin` tests.
51
- - `test:e2e:<suite>:clean` resets managed local test state, starts one development Vona worker, then runs the suite or a Playwright-filtered subset.
114
+ - `test:e2e:<suite>:web` and `test:e2e:<suite>:admin` select `@web` and `@admin` scenarios.
115
+ - `test:e2e:<suite>:clean` resets managed local state, starts one development Vona worker, then runs the suite or a Playwright-filtered subset.
116
+
117
+ The managed `:clean` runner requires port `7102` to be available. It owns the suite config and local lifecycle: it resets the database, and Playwright starts and stops `npm run dev:one`. It accepts normal Playwright selection and reporting options, but rejects external base URLs, `--config`, and positional spec paths. Use `--grep` or `--grep-invert` to narrow the run.
118
+
119
+ Pass Playwright options after npm's `--` delimiter. `@web` and `@admin` are stable surface tags. Purpose tags depend on the suite: current scenarios use `@smoke`, while the Basic suite also uses `@flow`. ATP IDs remain in titles for exact evidence and failure reruns.
52
120
 
53
- Use native Playwright tags for scenario categories rather than adding a root script for each feature. Every framework scenario uses one surface tag (`@web` or `@admin`) and one purpose tag when applicable (`@smoke` or `@flow`). ATP IDs remain in titles for exact evidence and failure reruns.
121
+ ### Cabloy Basic and Commerce
54
122
 
55
- Pass Playwright options after npm's `--` delimiter:
123
+ The Basic suite exercises Web at `/` and Admin at `/admin` through Vona's SSR dispatcher. Prepare fresh SSR and REST artifacts explicitly when frontend output has changed:
124
+
125
+ ```bash
126
+ npm run build:zova
127
+ npm run deps:vona
128
+ npm run test:e2e:basic:clean
129
+ ```
56
130
 
57
131
  ```bash
58
132
  # Exact acceptance scenario
@@ -66,16 +140,6 @@ npm run test:e2e:basic:clean -- --grep @admin
66
140
  npm run test:e2e:basic:clean -- --grep '(?=.*@admin)(?=.*@flow)'
67
141
  ```
68
142
 
69
- The managed `:clean` runner owns its suite config and local lifecycle. It accepts normal Playwright selection and reporting options, but does not accept `--config` or positional spec paths. Use `--grep` or `--grep-invert` to narrow the run. It rejects an external base URL rather than resetting or starting an externally managed target.
70
-
71
- The Basic suite exercises Web at `/` and Admin at `/admin` through Vona's SSR dispatcher. Prepare fresh Basic SSR artifacts explicitly when frontend SSR output has changed:
72
-
73
- ```bash
74
- npm run build:zova
75
- npm run deps:vona
76
- npm run test:e2e:basic:clean
77
- ```
78
-
79
143
  For an externally managed Basic target, set `BASIC_E2E_BASE_URL` and use aggregate, surface, or forwarded-tag commands. These commands do not reset, start, stop, or rebuild the target:
80
144
 
81
145
  ```bash
@@ -100,13 +164,34 @@ COMMERCE_E2E_BASE_URL=http://127.0.0.1:7102 npm run test:e2e:commerce:web
100
164
  COMMERCE_E2E_BASE_URL=http://127.0.0.1:7102 npm run test:e2e:commerce -- --grep @smoke
101
165
  ```
102
166
 
103
- Browser commands consume existing SSR and REST artifacts; they never rebuild them. Install Chromium once when needed with `npx playwright install chromium`.
167
+ ### Cabloy Start
104
168
 
105
- ## Edition-sensitive note
169
+ The Start suite exercises Web at `/` and Admin at `/admin` through Vona's SSR dispatcher. Prepare current Start artifacts before a managed local run:
106
170
 
107
- Cabloy Start keeps the same high-level pattern while using different frontend flavors such as `cabloyStartAdmin` and `cabloyStartWeb`, plus its own SSR site baselines and project assets in the licensed private repository.
171
+ ```bash
172
+ npm run build:zova
173
+ npm run deps:vona
174
+ npm run test:e2e:start:clean
175
+ ```
108
176
 
109
- When documenting or automating flavor-specific commands, always confirm the active repo first.
177
+ ```bash
178
+ # Exact acceptance scenario
179
+ npm run test:e2e:start -- --grep ATP-START-FLOW-01
180
+
181
+ # Category or surface selection
182
+ npm run test:e2e:start:clean -- --grep @smoke
183
+ npm run test:e2e:start:clean -- --grep @admin
184
+ ```
185
+
186
+ For an externally managed Start target, set `START_E2E_BASE_URL` and use matching aggregate, surface, or forwarded-tag commands. The target owner is responsible for data, cache, and artifact freshness:
187
+
188
+ ```bash
189
+ START_E2E_BASE_URL=http://127.0.0.1:7102 npm run test:e2e:start
190
+ START_E2E_BASE_URL=http://127.0.0.1:7102 npm run test:e2e:start:admin
191
+ START_E2E_BASE_URL=http://127.0.0.1:7102 npm run test:e2e:start -- --grep @web
192
+ ```
193
+
194
+ Browser commands consume existing SSR and REST artifacts; they never rebuild them. Install Chromium once when needed with `npx playwright install chromium`.
110
195
 
111
196
  ## Read together with
112
197
 
@@ -12,7 +12,7 @@ const e2eSuites = {
12
12
  basic: {
13
13
  externalBaseUrlEnv: 'BASIC_E2E_BASE_URL',
14
14
  configFile: resolve(E2E_CONFIG_DIR, 'playwright.basic.config.ts'),
15
- testDir: resolve(E2E_SPECS_DIR, 'a-basic'),
15
+ testDir: resolve(E2E_SPECS_DIR, 'cabloy-basic'),
16
16
  readinessPath: '/',
17
17
  },
18
18
  commerce: {
@@ -8,31 +8,69 @@ const child = spawn('npm', ['run', 'dev:one'], {
8
8
  stdio: 'inherit',
9
9
  });
10
10
 
11
+ const gracefulShutdownTimeout = 7000;
12
+
11
13
  let stopping = false;
14
+ let forced = false;
15
+ let shutdownTimer: NodeJS.Timeout | undefined;
12
16
 
13
- function stop() {
14
- if (stopping) return;
15
- stopping = true;
16
- if (process.platform === 'win32') {
17
- child.kill('SIGINT');
18
- } else if (child.pid) {
19
- try {
20
- process.kill(-child.pid, 'SIGINT');
21
- } catch (error: any) {
22
- if (error.code !== 'ESRCH') throw error;
17
+ function finish(code: number) {
18
+ if (shutdownTimer) {
19
+ clearTimeout(shutdownTimer);
20
+ shutdownTimer = undefined;
21
+ }
22
+ process.exit(code);
23
+ }
24
+
25
+ function signalChild(signal: NodeJS.Signals) {
26
+ if (!child.pid) return;
27
+ try {
28
+ if (process.platform === 'win32') {
29
+ child.kill(signal);
30
+ } else {
31
+ process.kill(-child.pid, signal);
32
+ }
33
+ } catch (error: any) {
34
+ if (error.code !== 'ESRCH') {
35
+ // eslint-disable-next-line
36
+ console.error(error);
23
37
  }
24
38
  }
25
39
  }
26
40
 
41
+ function forceStop() {
42
+ if (forced) return;
43
+ forced = true;
44
+ // eslint-disable-next-line
45
+ console.error(
46
+ `E2E Vona process group did not stop within ${gracefulShutdownTimeout}ms; forcing termination: ${child.pid}`,
47
+ );
48
+ signalChild('SIGKILL');
49
+ finish(1);
50
+ }
51
+
52
+ function stop() {
53
+ if (stopping) {
54
+ forceStop();
55
+ return;
56
+ }
57
+ stopping = true;
58
+ // Vona handles SIGINT, not SIGTERM. Keep this deadline below Playwright's 10-second timeout.
59
+ signalChild('SIGINT');
60
+ shutdownTimer = setTimeout(forceStop, gracefulShutdownTimeout);
61
+ shutdownTimer.unref();
62
+ }
63
+
27
64
  process.on('SIGINT', stop);
28
65
  process.on('SIGTERM', stop);
29
66
 
30
67
  child.on('error', error => {
31
68
  // eslint-disable-next-line
32
69
  console.error(error);
33
- process.exitCode = 1;
70
+ finish(1);
34
71
  });
35
72
 
36
- child.on('exit', code => {
37
- process.exitCode = code ?? 1;
73
+ child.on('exit', (code, signal) => {
74
+ // Playwright waits for this wrapper to exit, not only for Vona's workers to stop.
75
+ finish(code ?? (signal ? 1 : 0));
38
76
  });
@@ -29,7 +29,7 @@ test(
29
29
  expect(documentResponse?.ok()).toBeTruthy();
30
30
  await expect(page).toHaveURL(/\/commerce(?:\/|$)/);
31
31
  await expect(page.locator('html')).toHaveAttribute('data-zova-hydrated', 'commerce');
32
- await expect(page.getByText('Web: en-us')).toBeVisible();
32
+ await expect(page.getByRole('heading', { name: 'Commerce catalogue' })).toBeVisible();
33
33
  await expect(page.getByText('Dashboard')).toHaveCount(0);
34
34
  await expect(page.locator('body')).toBeVisible();
35
35
  await expect(page).not.toHaveTitle(/error/i);
@@ -37,6 +37,130 @@ test(
37
37
  },
38
38
  );
39
39
 
40
+ test(
41
+ 'Commerce catalogue: public sellable inventory renders after hydration',
42
+ { tag: ['@web', '@flow'] },
43
+ async ({ page }) => {
44
+ const pageErrors = collectPageErrors(page);
45
+ const response = await page.goto('/commerce', { waitUntil: 'load' });
46
+ expect(response?.ok()).toBeTruthy();
47
+ await expect(page.locator('html')).toHaveAttribute('data-zova-hydrated', 'commerce');
48
+ await expect(page.getByRole('heading', { name: 'Commerce catalogue' })).toBeVisible();
49
+ await expect(page.getByRole('link', { name: 'Wireless Headphones' })).toBeVisible();
50
+ await expect(page.getByText('24 available')).toBeVisible();
51
+ await page.getByRole('link', { name: 'Wireless Headphones' }).click();
52
+ await expect(page).toHaveURL(/\/commerce\/product\/\d+(?:\/|$)/);
53
+ await expect(page.getByRole('heading', { name: 'Wireless Headphones' })).toBeVisible();
54
+ await expect(page.getByText('HPH-BLK')).toBeVisible();
55
+ expect(pageErrors).toEqual([]);
56
+ },
57
+ );
58
+
59
+ test(
60
+ 'Commerce catalogue: localized Product navigation preserves locale',
61
+ { tag: ['@web', '@flow'] },
62
+ async ({ page, request }) => {
63
+ const localizedPath = '/commerce/zh-cn';
64
+ const response = await request.get(localizedPath);
65
+ expect(response.ok()).toBeTruthy();
66
+ const html = await response.text();
67
+ expect(html.toLowerCase()).not.toContain('data-zova-hydrated');
68
+ expect(html).toContain('商品目录');
69
+ expect(html).toContain('当前价格和库存以结算时确认为准。');
70
+
71
+ const pageErrors = collectPageErrors(page);
72
+ const documentResponse = await page.goto(localizedPath, { waitUntil: 'load' });
73
+ expect(documentResponse?.ok()).toBeTruthy();
74
+ await expect(page).toHaveURL(/\/commerce\/zh-cn(?:\/|$)/);
75
+ await expect(page.locator('html')).toHaveAttribute('data-zova-hydrated', 'commerce');
76
+ await expect(page.getByRole('heading', { name: '商品目录' })).toBeVisible();
77
+ await expect(page.getByText('当前价格和库存以结算时确认为准。')).toBeVisible();
78
+ await expect(page.getByText('库存 24 件')).toBeVisible();
79
+
80
+ const productLink = page.getByRole('link', { name: 'Wireless Headphones' });
81
+ await expect(productLink).toHaveAttribute('href', /\/commerce\/zh-cn\/product\/\d+$/);
82
+ const productPath = await productLink.getAttribute('href');
83
+ const productResponse = await request.get(productPath!);
84
+ expect(productResponse.ok()).toBeTruthy();
85
+ expect((await productResponse.text()).toLowerCase()).not.toContain('data-zova-hydrated');
86
+ await productLink.click();
87
+ await expect(page).toHaveURL(/\/commerce\/zh-cn\/product\/\d+(?:\/|$)/);
88
+ await expect(page.getByRole('heading', { name: 'Wireless Headphones' })).toBeVisible();
89
+ await expect(page.getByText('HPH-BLK')).toBeVisible();
90
+ await expect(page.getByText('库存 24 件')).toBeVisible();
91
+ await expect(page.getByRole('link', { name: '购物车' })).toHaveAttribute(
92
+ 'href',
93
+ '/commerce/zh-cn/cart',
94
+ );
95
+ expect(pageErrors).toEqual([]);
96
+ },
97
+ );
98
+
99
+ test(
100
+ 'Commerce Product: Cart badge keeps SSR initial render neutral',
101
+ { tag: ['@web', '@cart'] },
102
+ async ({ page, request }) => {
103
+ const productPath = '/commerce/product/1';
104
+ const productResponse = await request.get(productPath);
105
+ expect(productResponse.ok()).toBeTruthy();
106
+ const productHtml = await productResponse.text();
107
+ expect(productHtml.toLowerCase()).not.toContain('data-zova-hydrated');
108
+ expect(productHtml).toContain('>Cart<!----></a>');
109
+
110
+ const pageErrors = collectPageErrors(page);
111
+ const documentResponse = await page.goto(productPath, { waitUntil: 'load' });
112
+ expect(documentResponse?.ok()).toBeTruthy();
113
+ await expect(page.locator('html')).toHaveAttribute('data-zova-hydrated', 'commerce');
114
+ await expect(page).toHaveURL(productPath);
115
+ await expect(page.getByRole('heading', { name: 'Wireless Headphones' })).toBeVisible();
116
+
117
+ const cartLink = page.locator('a[href="/commerce/cart"]');
118
+ await expect(cartLink).toHaveCount(1);
119
+ await expect(cartLink.locator('.badge')).toHaveCount(0);
120
+ expect(pageErrors).toEqual([]);
121
+ },
122
+ );
123
+
124
+ test(
125
+ 'Commerce Address: cookie-disabled SSR renders a neutral protected entry',
126
+ { tag: ['@web', '@cart'] },
127
+ async ({ page, request }) => {
128
+ const path = '/commerce/address';
129
+ const routePath = '/address';
130
+ const response = await request.get(path, { maxRedirects: 0 });
131
+ expect(response.status()).toBe(200);
132
+ expect(response.headers().location).toBeUndefined();
133
+ expect((await response.text()).toLowerCase()).not.toContain('data-zova-hydrated');
134
+
135
+ const pageErrors = collectPageErrors(page);
136
+ const documentResponse = await page.goto(path, { waitUntil: 'load' });
137
+ expect(documentResponse?.ok()).toBeTruthy();
138
+ await expect(page).toHaveURL(/\/commerce\/login\?(?:.*&)?returnTo=/);
139
+ const loginUrl = new URL(page.url());
140
+ expect(loginUrl.searchParams.getAll('returnTo')).toEqual([routePath]);
141
+ await expect(page.getByRole('heading', { name: 'Login' })).toBeVisible();
142
+ await expect(page.getByRole('heading', { name: 'Addresses' })).toHaveCount(0);
143
+ expect(pageErrors).toEqual([]);
144
+ },
145
+ );
146
+
147
+ test(
148
+ 'Commerce Cart: anonymous browser is redirected to login',
149
+ { tag: ['@web', '@cart'] },
150
+ async ({ page, request }) => {
151
+ const path = '/commerce/cart';
152
+ const response = await request.get(path);
153
+ expect(response.ok()).toBeTruthy();
154
+ expect((await response.text()).toLowerCase()).not.toContain('data-zova-hydrated');
155
+
156
+ const pageErrors = collectPageErrors(page);
157
+ const documentResponse = await page.goto(path, { waitUntil: 'load' });
158
+ expect(documentResponse?.ok()).toBeTruthy();
159
+ await expect(page).toHaveURL(/\/commerce\/login\?(?:.*&)?returnTo=/);
160
+ expect(pageErrors).toEqual([]);
161
+ },
162
+ );
163
+
40
164
  test(
41
165
  'ATP-SSR-02: Commerce Admin is an independent SSR site',
42
166
  { tag: ['@admin', '@smoke'] },
@@ -98,6 +98,14 @@ function assertVisualOrder(geometry: IFieldGeometry[]) {
98
98
  }
99
99
  }
100
100
 
101
+ async function getDocumentHorizontalOverflow(page: Page) {
102
+ return page.evaluate(() => {
103
+ return (
104
+ Math.max(document.documentElement.scrollWidth, document.body.scrollWidth) - window.innerWidth
105
+ );
106
+ });
107
+ }
108
+
101
109
  test(
102
110
  'ATP-BASIC-SSR-01: anonymous Web HTML hydrates through the default site',
103
111
  { tag: ['@web', '@smoke'] },
@@ -217,6 +225,8 @@ test(
217
225
  }
218
226
 
219
227
  await page.setViewportSize({ width: 700, height: 900 });
228
+ const drawer = page.locator('.drawer').first();
229
+ await expect(drawer).not.toHaveClass(/\bdrawer-open\b/);
220
230
  await expect
221
231
  .poll(
222
232
  async () =>
@@ -238,15 +248,10 @@ test(
238
248
  const createdAtEndBox = await createdAtEnd.boundingBox();
239
249
  expect(createdAtEndBox).not.toBeNull();
240
250
  expect(createdAtEndBox!.x + createdAtEndBox!.width).toBeLessThanOrEqual(viewport.width + 1);
241
- await expect
242
- .poll(() =>
243
- page.evaluate(
244
- () => document.documentElement.scrollWidth - document.documentElement.clientWidth,
245
- ),
246
- )
247
- .toBeLessThanOrEqual(1);
251
+ await expect.poll(() => getDocumentHorizontalOverflow(page)).toBeLessThanOrEqual(1);
248
252
 
249
253
  await page.setViewportSize({ width: 1440, height: 900 });
254
+ await expect(drawer).toHaveClass(/\bdrawer-open\b/);
250
255
  await name.fill('Flow E2E');
251
256
  await level.selectOption('2');
252
257
  await createdAtStart.fill('2026-01-10');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cabloy",
3
- "version": "5.1.111",
3
+ "version": "5.1.113",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A Node.js fullstack framework",
6
6
  "keywords": [
@@ -35,6 +35,7 @@
35
35
  "dev:zova:commerce:admin": "cd zova && npm run dev:ssr:cabloyCommerceAdmin",
36
36
  "build": "npm run build:zova && pnpm --dir vona run build",
37
37
  "build:docker": "npm run build:zova && pnpm --dir vona run build:docker",
38
+ "build:zova:all": "npm run build:zova && npm run build:zova:commerce",
38
39
  "build:zova": "pnpm --dir zova run build:ssr:cabloyBasicBatch",
39
40
  "build:zova:admin": "pnpm --dir zova run build:ssr:cabloyBasicAdmin && pnpm --dir zova run build:rest:cabloyBasicAdmin",
40
41
  "build:zova:web": "pnpm --dir zova run build:ssr:cabloyBasicWeb && pnpm --dir zova run build:rest:cabloyBasicWeb",
package/scripts/init.ts CHANGED
@@ -260,18 +260,12 @@ function initZova(): void {
260
260
  exec('npm run zova :tools:deps');
261
261
  }
262
262
 
263
- // --- Step E: buildSsrCabloyBasicStartBatch ---
263
+ // --- Step E: buildSsrZovaAll ---
264
264
 
265
- function buildSsrCabloyBasicStartBatch(): void {
266
- if (existsSync(resolve(ROOT_DIR, '__CABLOY_BASIC__'))) {
267
- // eslint-disable-next-line
268
- console.log('[init] Building zova SSR cabloyBasicBatch...');
269
- exec('pnpm run build:ssr:cabloyBasicBatch', ZOVA_DIR);
270
- } else if (existsSync(resolve(ROOT_DIR, '__CABLOY_START__'))) {
271
- // eslint-disable-next-line
272
- console.log('[init] Building zova SSR cabloyStartBatch...');
273
- exec('pnpm run build:ssr:cabloyStartBatch', ZOVA_DIR);
274
- }
265
+ function buildSsrZovaAll(): void {
266
+ // eslint-disable-next-line
267
+ console.log('[init] Building all zova SSR flavors...');
268
+ exec('npm run build:zova:all');
275
269
  }
276
270
 
277
271
  // --- Step F: cleanupWorkspaceYaml ---
@@ -314,7 +308,7 @@ generateEnvProdLocal();
314
308
  generateEnvProdDockerLocal();
315
309
  cleanupWorkspaceYaml();
316
310
  initZova();
317
- buildSsrCabloyBasicStartBatch();
311
+ buildSsrZovaAll();
318
312
  initVona();
319
313
  initCabloyDocs();
320
314
  writeVersionMarker();
@@ -51,15 +51,17 @@ const OVERWRITE_DIRS: string[] = [
51
51
  const OVERWRITE_DIRS_CABLOY_BASIC: string[] = [
52
52
  'vona/src/suite/cabloy-basic',
53
53
  'vona/src/suite/a-training',
54
+ 'vona/src/suite/a-commerce',
54
55
  'zova/src/suite/cabloy-basic',
55
56
  'zova/src/suite/a-training',
57
+ 'zova/src/suite/a-commerce',
56
58
  'zova/src/suite/a-devui',
57
59
  ];
58
60
 
59
61
  const FRAMEWORK_E2E_DIRS_CABLOY_BASIC: string[] = [
60
62
  'e2e/config',
61
63
  'e2e/scripts',
62
- 'e2e/specs/a-basic',
64
+ 'e2e/specs/cabloy-basic',
63
65
  'e2e/specs/a-commerce',
64
66
  ];
65
67
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-cli",
3
- "version": "1.1.130",
3
+ "version": "1.1.131",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "vona cli",
6
6
  "keywords": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-cli-set-api",
3
- "version": "1.1.128",
3
+ "version": "1.1.129",
4
4
  "gitHead": "a79189b882c17af5911573896a781bbb0046d37d",
5
5
  "description": "vona cli-set-api",
6
6
  "keywords": [
@@ -77,15 +77,12 @@ export class CliBinTest extends BeanCliBase {
77
77
  patterns.join(','),
78
78
  ]);
79
79
  // args = args.concat(['--experimental-transform-types', getImportEsm(), testFile, projectPath, (!!argv.coverage).toString(), patterns.join(',')]);
80
- // ignore error special in windows
81
- await catchError(() => {
82
- return this.helper.spawnExe({
83
- cmd: 'node',
84
- args,
85
- options: {
86
- cwd: projectPath,
87
- },
88
- });
80
+ await this.helper.spawnExe({
81
+ cmd: 'node',
82
+ args,
83
+ options: {
84
+ cwd: projectPath,
85
+ },
89
86
  });
90
87
  }
91
88