cabloy 5.1.110 → 5.1.112

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 (370) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/skills/cabloy-backend-scaffold/SKILL.md +29 -1
  3. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +12 -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 +45 -0
  8. package/.gitignore +1 -0
  9. package/CHANGELOG.md +23 -0
  10. package/CLAUDE.md +4 -1
  11. package/README.md +8 -8
  12. package/cabloy-docs/backend/crud-workflow.md +10 -0
  13. package/cabloy-docs/backend/foundation.md +29 -4
  14. package/cabloy-docs/backend/introduction.md +1 -1
  15. package/cabloy-docs/backend/model-guide.md +9 -11
  16. package/cabloy-docs/backend/multi-instance-and-instance-resolution.md +18 -0
  17. package/cabloy-docs/backend/service-guide.md +1 -1
  18. package/cabloy-docs/frontend/a-router-guide.md +1 -1
  19. package/cabloy-docs/frontend/introduction.md +1 -1
  20. package/cabloy-docs/frontend/navigation-guards-guide.md +20 -11
  21. package/cabloy-docs/frontend/route-alias-guide.md +24 -0
  22. package/cabloy-docs/frontend/scripts.md +71 -24
  23. package/cabloy-docs/frontend/ssr-init-data.md +25 -0
  24. package/cabloy-docs/frontend/ssr-review-checklist.md +17 -7
  25. package/cabloy-docs/frontend/use-state-data-best-practices.md +4 -0
  26. package/cabloy-docs/frontend/zova-router-under-the-hood.md +4 -1
  27. package/cabloy-docs/fullstack/comparison-with-other-frameworks.md +19 -13
  28. package/cabloy-docs/fullstack/introduction.md +10 -10
  29. package/cabloy-docs/fullstack/quickstart.md +23 -1
  30. package/cabloy-docs/index.md +14 -14
  31. package/cabloy-docs/reference/package-map.md +11 -7
  32. package/cabloy-docs/reference/repo-scripts.md +108 -23
  33. package/e2e/scripts/e2e.ts +1 -1
  34. package/e2e/specs/a-commerce/commerce.spec.ts +124 -1
  35. package/package.json +2 -1
  36. package/scripts/init.ts +6 -12
  37. package/scripts/upgrade.ts +3 -1
  38. package/vona/packages-vona/vona/package.json +1 -1
  39. package/vona/pnpm-lock.yaml +70 -55
  40. package/vona/src/backend/config/config/config.ts +11 -0
  41. package/vona/src/suite/a-commerce/modules/commerce-catalog/package.json +4 -2
  42. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +732 -2
  43. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/locales.ts +18 -0
  44. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/meta.index.ts +14 -0
  45. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/meta.version.ts +52 -0
  46. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/ssrMenu.category.ts +30 -0
  47. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/ssrMenu.product.ts +30 -0
  48. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/bean/ssrMenu.sku.ts +30 -0
  49. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +19 -0
  50. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +19 -0
  51. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/controller/category.ts +65 -0
  52. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/controller/product.ts +86 -0
  53. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/controller/sku.ts +65 -0
  54. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categoryCreate.tsx +28 -0
  55. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categorySelectReq.tsx +25 -0
  56. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categorySelectRes.tsx +11 -0
  57. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categorySelectResItem.tsx +39 -0
  58. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categoryUpdate.tsx +28 -0
  59. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/categoryView.tsx +25 -0
  60. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productCreate.tsx +28 -0
  61. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublic.tsx +38 -0
  62. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublicSelectReq.tsx +23 -0
  63. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublicSelectRes.tsx +11 -0
  64. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productPublicSku.tsx +25 -0
  65. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productSelectReq.tsx +25 -0
  66. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productSelectRes.tsx +11 -0
  67. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productSelectResItem.tsx +39 -0
  68. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productUpdate.tsx +28 -0
  69. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/productView.tsx +25 -0
  70. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuCreate.tsx +28 -0
  71. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectReq.tsx +25 -0
  72. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectRes.tsx +11 -0
  73. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectResItem.tsx +39 -0
  74. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuUpdate.tsx +28 -0
  75. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuView.tsx +25 -0
  76. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/category.tsx +53 -0
  77. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/product.tsx +48 -0
  78. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/sku.tsx +66 -0
  79. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/index.ts +1 -0
  80. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/category.ts +15 -0
  81. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/product.ts +46 -0
  82. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/model/sku.ts +18 -0
  83. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/category.ts +47 -0
  84. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/product.ts +162 -0
  85. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/sku.ts +76 -0
  86. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/catalog.test.ts +358 -0
  87. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/category.test.ts +91 -0
  88. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/product.test.ts +154 -0
  89. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/sku.test.ts +190 -0
  90. package/vona/src/suite/a-commerce/modules/commerce-member/package.json +2 -1
  91. package/vona/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +342 -5
  92. package/vona/src/suite/a-commerce/modules/commerce-member/src/.metadata/locales.ts +18 -0
  93. package/vona/src/suite/a-commerce/modules/commerce-member/src/bean/meta.index.ts +12 -0
  94. package/vona/src/suite/a-commerce/modules/commerce-member/src/bean/meta.version.ts +31 -0
  95. package/vona/src/suite/a-commerce/modules/commerce-member/src/config/locale/en-us.ts +12 -0
  96. package/vona/src/suite/a-commerce/modules/commerce-member/src/config/locale/zh-cn.ts +12 -0
  97. package/vona/src/suite/a-commerce/modules/commerce-member/src/controller/address.ts +59 -0
  98. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressCreate.tsx +39 -0
  99. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectReq.tsx +30 -0
  100. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectRes.tsx +11 -0
  101. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressSelectResItem.tsx +53 -0
  102. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressUpdate.tsx +39 -0
  103. package/vona/src/suite/a-commerce/modules/commerce-member/src/dto/addressView.tsx +39 -0
  104. package/vona/src/suite/a-commerce/modules/commerce-member/src/entity/address.tsx +76 -0
  105. package/vona/src/suite/a-commerce/modules/commerce-member/src/index.ts +1 -0
  106. package/vona/src/suite/a-commerce/modules/commerce-member/src/model/address.ts +10 -0
  107. package/vona/src/suite/a-commerce/modules/commerce-member/src/service/address.ts +84 -0
  108. package/vona/src/suite/a-commerce/modules/commerce-member/test/addressOwnership.test.ts +203 -0
  109. package/vona/src/suite/a-commerce/modules/commerce-seed/package.json +52 -0
  110. package/vona/src/suite/a-commerce/modules/commerce-seed/src/.metadata/index.ts +55 -0
  111. package/vona/src/suite/a-commerce/modules/commerce-seed/src/.metadata/this.ts +2 -0
  112. package/vona/src/suite/a-commerce/modules/commerce-seed/src/bean/meta.version.ts +80 -0
  113. package/vona/src/suite/a-commerce/modules/commerce-seed/src/index.ts +1 -0
  114. package/vona/src/suite/a-commerce/modules/commerce-seed/tsconfig.build.json +11 -0
  115. package/vona/src/suite/a-commerce/modules/commerce-seed/tsconfig.json +7 -0
  116. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/package.json +4 -2
  117. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/index.ts +192 -2
  118. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/locales.ts +18 -0
  119. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/meta.version.ts +32 -0
  120. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/ssrMenu.home.ts +3 -1
  121. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/ssrMenuGroup.catalog.ts +21 -0
  122. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/bean/ssrMenuGroup.inventory.ts +21 -0
  123. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/en-us.ts +5 -0
  124. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/zh-cn.ts +5 -0
  125. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/controller/operator.ts +21 -0
  126. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/dto/operatorContext.ts +21 -0
  127. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/index.ts +1 -0
  128. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/service/operator.ts +18 -0
  129. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/meta.version.test.ts +44 -0
  130. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/operatorAccess.test.ts +55 -0
  131. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/test/ssrMenu.test.ts +77 -0
  132. package/vona/src/suite/a-commerce/modules/commerce-trade/package.json +2 -1
  133. package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +773 -2
  134. package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/locales.ts +18 -0
  135. package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/meta.index.ts +23 -0
  136. package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/meta.version.ts +79 -0
  137. package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/ssrMenu.stockAudit.ts +30 -0
  138. package/vona/src/suite/a-commerce/modules/commerce-trade/src/bean/ssrMenu.stockBalance.ts +30 -0
  139. package/vona/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +25 -0
  140. package/vona/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +25 -0
  141. package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/cart.ts +48 -0
  142. package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/stockAudit.ts +38 -0
  143. package/vona/src/suite/a-commerce/modules/commerce-trade/src/controller/stockBalance.ts +49 -0
  144. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartAddItem.tsx +19 -0
  145. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartItem.tsx +34 -0
  146. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartUpdateItem.tsx +15 -0
  147. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/cartView.tsx +18 -0
  148. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAdjust.tsx +32 -0
  149. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditCreate.tsx +28 -0
  150. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectReq.tsx +28 -0
  151. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectRes.tsx +11 -0
  152. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectResItem.tsx +33 -0
  153. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditUpdate.tsx +28 -0
  154. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditView.tsx +25 -0
  155. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceCreate.tsx +28 -0
  156. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectReq.tsx +28 -0
  157. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectRes.tsx +11 -0
  158. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectResItem.tsx +33 -0
  159. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceUpdate.tsx +28 -0
  160. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceView.tsx +25 -0
  161. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/cart.tsx +24 -0
  162. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/cartItem.tsx +30 -0
  163. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockAudit.tsx +86 -0
  164. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockBalance.tsx +53 -0
  165. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockReservation.tsx +63 -0
  166. package/vona/src/suite/a-commerce/modules/commerce-trade/src/index.ts +1 -0
  167. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/cart.ts +17 -0
  168. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/cartItem.ts +10 -0
  169. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/stockAudit.ts +10 -0
  170. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/stockBalance.ts +15 -0
  171. package/vona/src/suite/a-commerce/modules/commerce-trade/src/model/stockReservation.ts +10 -0
  172. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/cart.ts +152 -0
  173. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockAudit.ts +20 -0
  174. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockBalance.ts +305 -0
  175. package/vona/src/suite/a-commerce/modules/commerce-trade/test/cartOwnership.test.ts +174 -0
  176. package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockAudit.test.ts +37 -0
  177. package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockBalance.test.ts +186 -0
  178. package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockReservation.test.ts +262 -0
  179. package/vona/src/suite/a-commerce/package.json +1 -0
  180. package/vona/src/suite/a-commerce/tsconfig.json +3 -0
  181. package/vona/src/suite/a-home/modules/home-user/src/.metadata/index.ts +7 -1
  182. package/vona/src/suite/a-home/modules/home-user/test/role.test.ts +14 -23
  183. package/vona/src/suite/a-training/modules/training-record/src/.metadata/index.ts +10 -8
  184. package/vona/src/suite/a-training/modules/training-recordsubject/src/.metadata/index.ts +2 -0
  185. package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +3 -1
  186. package/vona/src/suite/a-training/modules/training-student/src/dto/studentSelectResItem.tsx +1 -1
  187. package/vona/src/suite-vendor/a-auth/modules/a-auth/package.json +1 -1
  188. package/vona/src/suite-vendor/a-auth/modules/a-auth/src/.metadata/index.ts +7 -3
  189. package/vona/src/suite-vendor/a-auth/modules/auth-simple/package.json +1 -1
  190. package/vona/src/suite-vendor/a-auth/modules/auth-simple/src/.metadata/index.ts +2 -0
  191. package/vona/src/suite-vendor/a-auth/package.json +1 -1
  192. package/vona/src/suite-vendor/a-cabloy/modules/a-datasharding/package.json +1 -1
  193. package/vona/src/suite-vendor/a-cabloy/modules/a-datasharding/src/.metadata/index.ts +1 -1
  194. package/vona/src/suite-vendor/a-cabloy/modules/a-datasource/package.json +1 -1
  195. package/vona/src/suite-vendor/a-cabloy/modules/a-datasource/src/.metadata/index.ts +3 -1
  196. package/vona/src/suite-vendor/a-cabloy/modules/a-socket/package.json +1 -1
  197. package/vona/src/suite-vendor/a-cabloy/modules/a-socket/src/.metadata/index.ts +1 -1
  198. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
  199. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/.metadata/index.ts +47 -47
  200. package/vona/src/suite-vendor/a-cabloy/modules/a-ssrhmr/package.json +1 -1
  201. package/vona/src/suite-vendor/a-cabloy/modules/a-ssrhmr/src/.metadata/index.ts +1 -1
  202. package/vona/src/suite-vendor/a-cabloy/modules/a-status/package.json +1 -1
  203. package/vona/src/suite-vendor/a-cabloy/modules/a-status/src/.metadata/index.ts +2 -0
  204. package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
  205. package/vona/src/suite-vendor/a-captcha/modules/a-captcha/package.json +1 -1
  206. package/vona/src/suite-vendor/a-captcha/modules/a-captcha/src/.metadata/index.ts +1 -1
  207. package/vona/src/suite-vendor/a-captcha/package.json +1 -1
  208. package/vona/src/suite-vendor/a-file/modules/a-file/package.json +1 -1
  209. package/vona/src/suite-vendor/a-file/modules/a-file/src/.metadata/index.ts +42 -38
  210. package/vona/src/suite-vendor/a-file/package.json +2 -2
  211. package/vona/src/suite-vendor/a-image/modules/a-image/package.json +1 -1
  212. package/vona/src/suite-vendor/a-image/modules/a-image/src/.metadata/index.ts +42 -38
  213. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/package.json +1 -1
  214. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/src/.metadata/index.ts +42 -27
  215. package/vona/src/suite-vendor/a-image/package.json +1 -1
  216. package/vona/src/suite-vendor/a-paypal/modules/a-paypal/package.json +1 -1
  217. package/vona/src/suite-vendor/a-paypal/modules/a-paypal/src/.metadata/index.ts +3 -1
  218. package/vona/src/suite-vendor/a-paypal/package.json +1 -1
  219. package/vona/src/suite-vendor/a-vona/modules/a-beanmutate/package.json +1 -1
  220. package/vona/src/suite-vendor/a-vona/modules/a-beanmutate/src/.metadata/index.ts +1 -1
  221. package/vona/src/suite-vendor/a-vona/modules/a-body/package.json +1 -1
  222. package/vona/src/suite-vendor/a-vona/modules/a-body/src/.metadata/index.ts +2 -2
  223. package/vona/src/suite-vendor/a-vona/modules/a-cache/package.json +1 -1
  224. package/vona/src/suite-vendor/a-vona/modules/a-cache/src/.metadata/index.ts +1 -1
  225. package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
  226. package/vona/src/suite-vendor/a-vona/modules/a-core/src/.metadata/index.ts +1 -1
  227. package/vona/src/suite-vendor/a-vona/modules/a-error/package.json +1 -1
  228. package/vona/src/suite-vendor/a-vona/modules/a-error/src/.metadata/index.ts +1 -1
  229. package/vona/src/suite-vendor/a-vona/modules/a-event/package.json +1 -1
  230. package/vona/src/suite-vendor/a-vona/modules/a-event/src/.metadata/index.ts +1 -1
  231. package/vona/src/suite-vendor/a-vona/modules/a-executor/package.json +1 -1
  232. package/vona/src/suite-vendor/a-vona/modules/a-executor/src/.metadata/index.ts +1 -1
  233. package/vona/src/suite-vendor/a-vona/modules/a-hmr/package.json +1 -1
  234. package/vona/src/suite-vendor/a-vona/modules/a-hmr/src/.metadata/index.ts +1 -1
  235. package/vona/src/suite-vendor/a-vona/modules/a-instance/package.json +1 -1
  236. package/vona/src/suite-vendor/a-vona/modules/a-instance/src/.metadata/index.ts +3 -1
  237. package/vona/src/suite-vendor/a-vona/modules/a-jwt/package.json +1 -1
  238. package/vona/src/suite-vendor/a-vona/modules/a-jwt/src/.metadata/index.ts +1 -1
  239. package/vona/src/suite-vendor/a-vona/modules/a-logger/package.json +1 -1
  240. package/vona/src/suite-vendor/a-vona/modules/a-logger/src/.metadata/index.ts +1 -1
  241. package/vona/src/suite-vendor/a-vona/modules/a-mail/package.json +1 -1
  242. package/vona/src/suite-vendor/a-vona/modules/a-mail/src/.metadata/index.ts +3 -1
  243. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/package.json +1 -1
  244. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/.metadata/index.ts +1 -1
  245. package/vona/src/suite-vendor/a-vona/modules/a-onion/package.json +1 -1
  246. package/vona/src/suite-vendor/a-vona/modules/a-onion/src/.metadata/index.ts +1 -1
  247. package/vona/src/suite-vendor/a-vona/modules/a-openapi/package.json +1 -1
  248. package/vona/src/suite-vendor/a-vona/modules/a-openapi/src/.metadata/index.ts +1 -1
  249. package/vona/src/suite-vendor/a-vona/modules/a-orm/cli/model/metadata/generate.ts +5 -11
  250. package/vona/src/suite-vendor/a-vona/modules/a-orm/package.json +1 -1
  251. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/bean.model/bean.model_cache.ts +52 -0
  252. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoGet.ts +4 -10
  253. package/vona/src/suite-vendor/a-vona/modules/a-redis/package.json +1 -1
  254. package/vona/src/suite-vendor/a-vona/modules/a-redis/src/.metadata/index.ts +1 -1
  255. package/vona/src/suite-vendor/a-vona/modules/a-security/package.json +1 -1
  256. package/vona/src/suite-vendor/a-vona/modules/a-security/src/.metadata/index.ts +1 -1
  257. package/vona/src/suite-vendor/a-vona/modules/a-serialization/package.json +1 -1
  258. package/vona/src/suite-vendor/a-vona/modules/a-serialization/src/.metadata/index.ts +1 -1
  259. package/vona/src/suite-vendor/a-vona/modules/a-summer/package.json +1 -1
  260. package/vona/src/suite-vendor/a-vona/modules/a-summer/src/.metadata/index.ts +1 -1
  261. package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
  262. package/vona/src/suite-vendor/a-vona/modules/a-user/src/.metadata/index.ts +4 -5
  263. package/vona/src/suite-vendor/a-vona/modules/a-validation/package.json +1 -1
  264. package/vona/src/suite-vendor/a-vona/modules/a-validation/src/.metadata/index.ts +1 -1
  265. package/vona/src/suite-vendor/a-vona/modules/a-version/package.json +1 -1
  266. package/vona/src/suite-vendor/a-vona/modules/a-version/src/.metadata/index.ts +6 -0
  267. package/vona/src/suite-vendor/a-vona/modules/a-web/package.json +1 -1
  268. package/vona/src/suite-vendor/a-vona/modules/a-web/src/.metadata/index.ts +1 -1
  269. package/vona/src/suite-vendor/a-vona/modules/a-worker/package.json +1 -1
  270. package/vona/src/suite-vendor/a-vona/modules/a-worker/src/.metadata/index.ts +1 -1
  271. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  272. package/zova/packages-cli/cli/package.json +2 -2
  273. package/zova/packages-cli/cli-set-front/package.json +1 -1
  274. package/zova/packages-cli/cli-set-front/src/lib/bean/toolsMetadata/generateScope.ts +1 -1
  275. package/zova/packages-zova/zova/package.json +2 -2
  276. package/zova/pnpm-lock.yaml +14 -14
  277. package/zova/src/front/config/config/config.cabloyCommerce.ts +5 -1
  278. package/zova/src/front/config/config/config.cabloyCommerceAdmin.ts +2 -1
  279. package/zova/src/suite/a-commerce/modules/commerce-catalog/cli/openapi.config.ts +9 -0
  280. package/zova/src/suite/a-commerce/modules/commerce-catalog/package.json +2 -1
  281. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +202 -3
  282. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/locales.ts +7 -0
  283. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/page/catalogue.ts +23 -0
  284. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/page/product.ts +19 -0
  285. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/commerceCatalogProduct.ts +52 -0
  286. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/baseURL.ts +5 -0
  287. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/index.ts +3 -0
  288. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/schemas.ts +412 -0
  289. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/types.ts +7159 -0
  290. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/apiSchema/commerceCatalogProduct.ts +20 -0
  291. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/en-us.ts +8 -0
  292. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/config/locale/zh-cn.ts +8 -0
  293. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/index.ts +1 -0
  294. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/model/catalogue.ts +38 -0
  295. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/page/catalogue/controller.tsx +71 -0
  296. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/page/product/controller.tsx +108 -0
  297. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/routes.ts +19 -0
  298. package/zova/src/suite/a-commerce/modules/commerce-member/cli/openapi.config.ts +9 -0
  299. package/zova/src/suite/a-commerce/modules/commerce-member/package.json +2 -1
  300. package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +182 -3
  301. package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/locales.ts +7 -0
  302. package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/page/address.ts +19 -0
  303. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/commerceMemberAddress.ts +111 -0
  304. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/baseURL.ts +5 -0
  305. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/index.ts +3 -0
  306. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/schemas.ts +432 -0
  307. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/types.ts +7445 -0
  308. package/zova/src/suite/a-commerce/modules/commerce-member/src/apiSchema/commerceMemberAddress.ts +35 -0
  309. package/zova/src/suite/a-commerce/modules/commerce-member/src/config/locale/en-us.ts +17 -0
  310. package/zova/src/suite/a-commerce/modules/commerce-member/src/config/locale/zh-cn.ts +17 -0
  311. package/zova/src/suite/a-commerce/modules/commerce-member/src/index.ts +1 -0
  312. package/zova/src/suite/a-commerce/modules/commerce-member/src/model/address.ts +38 -0
  313. package/zova/src/suite/a-commerce/modules/commerce-member/src/page/address/controller.tsx +194 -0
  314. package/zova/src/suite/a-commerce/modules/commerce-member/src/routes.ts +12 -0
  315. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/cli/openapi.config.ts +9 -0
  316. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/package.json +2 -1
  317. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/index.ts +175 -3
  318. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/locales.ts +7 -0
  319. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/page/dashboard.ts +9 -0
  320. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/commerceSiteadminOperator.ts +25 -0
  321. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/baseURL.ts +5 -0
  322. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/index.ts +3 -0
  323. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/schemas.ts +304 -0
  324. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/types.ts +5710 -0
  325. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/apiSchema/commerceSiteadminOperator.ts +13 -0
  326. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/en-us.ts +5 -0
  327. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/config/locale/zh-cn.ts +5 -0
  328. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/index.ts +1 -0
  329. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/model/operator.ts +17 -0
  330. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/page/dashboard/controller.tsx +34 -0
  331. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/routes.ts +5 -0
  332. package/zova/src/suite/a-commerce/modules/commerce-trade/cli/openapi.config.ts +15 -0
  333. package/zova/src/suite/a-commerce/modules/commerce-trade/package.json +2 -1
  334. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +182 -3
  335. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/locales.ts +7 -0
  336. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/page/cart.ts +19 -0
  337. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/commerceTradeCart.ts +99 -0
  338. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/baseURL.ts +5 -0
  339. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/index.ts +3 -0
  340. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/schemas.ts +446 -0
  341. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/types.ts +7651 -0
  342. package/zova/src/suite/a-commerce/modules/commerce-trade/src/apiSchema/commerceTradeCart.ts +35 -0
  343. package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/en-us.ts +8 -0
  344. package/zova/src/suite/a-commerce/modules/commerce-trade/src/config/locale/zh-cn.ts +8 -0
  345. package/zova/src/suite/a-commerce/modules/commerce-trade/src/index.ts +1 -0
  346. package/zova/src/suite/a-commerce/modules/commerce-trade/src/model/cart.ts +77 -0
  347. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/cart/controller.tsx +108 -0
  348. package/zova/src/suite/a-commerce/modules/commerce-trade/src/routes.ts +12 -0
  349. package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/index.ts +5 -5
  350. package/zova/src/suite/a-demo/modules/demo-todo/src/.metadata/index.ts +2 -2
  351. package/zova/src/suite/a-home/modules/home-base/src/service/routerGuards.ts +18 -10
  352. package/zova/src/suite/a-home/modules/home-indexweb/src/.metadata/index.ts +2 -2
  353. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  354. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/index.ts +4 -4
  355. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +1 -0
  356. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  357. package/zova/src/suite-vendor/a-zova/modules/a-bean/cli/controller/metadata/generateMetaPage.ts +3 -1
  358. package/zova/src/suite-vendor/a-zova/modules/a-bean/package.json +1 -1
  359. package/zova/src/suite-vendor/a-zova/modules/a-fetch/package.json +2 -2
  360. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +1 -1
  361. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/model/sdk.ts +3 -1
  362. package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
  363. package/zova/src/suite-vendor/a-zova/modules/a-router/src/bean/sys.router.ts +35 -8
  364. package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkeySys.ts +28 -12
  365. package/zova/src/suite-vendor/a-zova/modules/a-router/src/service/routerGuards.ts +6 -8
  366. package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/router.ts +14 -2
  367. package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/utils.ts +4 -1
  368. package/zova/src/suite-vendor/a-zova/package.json +5 -5
  369. package/CLAUDE.local.md +0 -4
  370. /package/e2e/specs/{a-basic → cabloy-basic}/basic.spec.ts +0 -0
package/.cabloy-version CHANGED
@@ -1 +1 @@
1
- 5.1.110
1
+ 5.1.112
@@ -140,7 +140,35 @@ Check whether the feature needs:
140
140
  - `meta.version`
141
141
  - field indexes
142
142
  - relation definitions
143
- - datasource or cache considerations
143
+ - datasource or cache considerations, including cross-Model query-cache dependencies
144
+
145
+ For normal resource persistence, preserve Vona's default active-instance scope:
146
+
147
+ - in the current tenancy model, a tenant corresponds to an instance and ordinary model CRUD handles the current `iid`
148
+ - do not expose caller-controlled `iid` or tenant selection in ordinary resource DTOs or controller logic
149
+ - treat a record absent from an ordinary scoped model lookup as absent; do not use raw cross-instance probes merely to choose between `403` and not-found behavior
150
+ - use `disableInstance`, plain builders, or raw SQL only for an explicit global/system or otherwise authorized contract
151
+ - model a future multi-merchant requirement as a separate boundary within an instance, with its own ownership and authorization rules
152
+
153
+ For the canonical explanation, read [Multi-Instance and Instance Resolution](../../../cabloy-docs/backend/multi-instance-and-instance-resolution.md) and [Model Guide](../../../cabloy-docs/backend/model-guide.md).
154
+
155
+ ### Cross-module resource lookup
156
+
157
+ Choose the narrowest lookup form before evaluating module dependency intent:
158
+
159
+ - use `this.scope` for resources owned by the current `BeanBase` module
160
+ - use `this.$scope.<fixedModule>` when the target module is statically known and the typed shorthand is available
161
+ - use `app.scope('<module-name>')` in tests or standalone code with an application reference instead of BeanBase shorthands
162
+ - use `this.app.scope(moduleName)` or `app.scope(moduleName)` when the module name is genuinely selected at runtime; do not replace a fixed module target with a dynamic string lookup merely for style
163
+
164
+ Then distinguish runtime lookup from a true module dependency:
165
+
166
+ - lookup resolves a resource from a module already composed into the application; it does not by itself require a `vonaModule.dependencies` entry or create a circular dependency edge
167
+ - add `vonaModule.dependencies` only when the feature genuinely requires the target module's availability, dependency-first ordering, or minimum compatible version
168
+ - do not add a dependency declaration merely because code looks up another module's service, model, config, locale, or other resource
169
+ - scope lookup cannot make an absent module available; validate application/suite composition separately when the target must exist
170
+
171
+ For the canonical distinction, read [Backend Foundation](../../../cabloy-docs/backend/foundation.md#scope-lookup-vs-module-dependencies) and [Package Map](../../../cabloy-docs/reference/package-map.md).
144
172
 
145
173
  ### Verification
146
174
 
@@ -28,8 +28,20 @@ After generating or extending a backend thread, check which follow-up layers app
28
28
  - relations
29
29
  - datasource choice
30
30
  - cache behavior
31
+ - cross-Model query-cache dependencies: when a source mutation can change another Model's cached query members, totals, projections, includes, or visibility, declare exactly one directed `modelsClear` / `modelsClearedBy` edge
32
+ - keep the dependency graph acyclic and free of duplicate edges; do not declare both forms for the same edge because propagation is transitive and current runtime collection does not deduplicate targets
33
+ - when `modelsClearedByFn` is required, treat it as replacement behavior and explicitly own the target clear and any necessary downstream propagation
34
+ - prefer normal Model/service mutation paths so source invalidation, commit-time re-clear, and configured double-delete remain active
35
+ - add a warm-query → mutate-source → repeat-query regression test for each new dependency path; read [Vona Cross-Model Query-Cache Dependencies](../../../../.docs-internal/architecture/vona-cross-model-query-cache-dependencies.md) for the source-backed decision rules
31
36
  - transaction behavior
32
37
 
38
+ ## Module composition and dependency intent
39
+
40
+ - target module is already composed into the application when code uses cross-module scope lookup
41
+ - cross-module `this.$scope.<module>` or `app.scope(...)` lookup alone does not require `vonaModule.dependencies`
42
+ - `vonaModule.dependencies` is added only for a genuine target-module availability, dependency-first ordering, or minimum-version requirement
43
+ - do not create speculative dependency edges or circular declarations merely to document a lookup
44
+
33
45
  ## Verification follow-up
34
46
 
35
47
  - unit tests
@@ -136,6 +136,8 @@ Check whether the feature needs:
136
136
  - SSR init-data updates
137
137
  - OpenAPI SDK regeneration
138
138
  - schema-driven UI or `$apiSchema` review
139
+ - SSR hydration-equivalence review: classify state as SSR-required or intentionally deferred; keep server HTML and the hydration-time client render equivalent; defer private, cookie-unavailable, or browser-only query/load/render branches to an explicit post-hydration, admission, mounted, or interaction boundary
140
+ - distinguish `$useStateData(...)` query ownership from readiness waits: `disableSuspenseOnInit` only skips its init-time suspense kick and does not prevent query creation or fetches; choose `$QueryEnsureLoaded(...)` or freshness helpers only at the later boundary that needs them
139
141
  - reverse fullstack handoff when newly added frontend resources will later be consumed by backend metadata or backend tooling
140
142
 
141
143
  If the frontend change introduces resources such as a custom form-field renderer, table-cell renderer, or other generated metadata that backend `ZovaRender.field(...)` / `ZovaRender.cell(...)` will consume, do not treat the task as frontend-only cleanup.
@@ -166,6 +168,7 @@ Check whether the feature needs:
166
168
  - build
167
169
  - metadata regeneration verification
168
170
  - SSR or route-path verification
171
+ - hydration-time initial-render equivalence when SSR, private state, browser-only state, or async model state changes
169
172
  - edition-specific flavor, SSR site baseline, and project-asset verification
170
173
 
171
174
  ### SSR theme review reminder
@@ -13,6 +13,10 @@ After generating or extending a frontend thread, check which follow-up layers ap
13
13
 
14
14
  - API service or model alignment
15
15
  - SSR init-data needs
16
+ - classify render-driving state as SSR-required or intentionally deferred; server HTML and the hydration-time client render must remain equivalent
17
+ - for intentionally deferred private, cookie-unavailable, or browser-only state, keep the same neutral shell/placeholder through hydration and begin query/load/render work only at an explicit post-hydration, admission, mounted, or interaction boundary
18
+ - `disableSuspenseOnInit` skips only the init-time suspense kick; do not treat it as a no-fetch or hydration-deferral mechanism
19
+ - use `$QueryEnsureLoaded(...)` only where loaded data is explicitly required; choose freshness helpers when the boundary requires domain-valid data
16
20
  - OpenAPI SDK or schema-driven layer impact
17
21
  - backend contract reminder if frontend depends on generated backend contract output
18
22
  - if backend metadata will consume newly added frontend render resources, run the relevant Zova build first and then `npm run deps:vona`
@@ -152,7 +152,18 @@ Important rule:
152
152
 
153
153
  - do not start from hand-patching DTO placement or relation semantics until the generator path and specimen shape have been checked first
154
154
 
155
- ## Step 6: Keep fullstack boundaries explicit
155
+ ## Step 6: Preserve the instance boundary across the aggregate
156
+
157
+ Master-detail ownership is separate from Vona's tenant/instance boundary:
158
+
159
+ - in the current tenancy model, a tenant corresponds to an instance and normal parent/detail model operations retain the active instance scope
160
+ - relation and foreign-key checks must preserve that scope; aggregate ownership does not authorize bypassing it
161
+ - treat a missing parent or detail from the normal scoped aggregate flow as absent; do not add unscoped existence probes merely to distinguish a foreign-instance row
162
+ - if a future multi-merchant design is needed, model merchant ownership explicitly within the instance in addition to the aggregate relation
163
+
164
+ For the canonical tenancy explanation, read [Multi-Instance and Instance Resolution](../../../cabloy-docs/backend/multi-instance-and-instance-resolution.md) and [Model Guide](../../../cabloy-docs/backend/model-guide.md).
165
+
166
+ ## Step 7: Keep fullstack boundaries explicit
156
167
 
157
168
  This skill is primarily for backend detail aggregation.
158
169
 
@@ -166,7 +177,7 @@ Use this skill first when the core problem is still:
166
177
  - aggregate vs standalone detail mode
167
178
  - nested detail DTO naming or placement in a scaffolding context
168
179
 
169
- ## Step 7: Verification guidance
180
+ ## Step 8: Verification guidance
170
181
 
171
182
  Always finish with verification that matches the detail shape.
172
183
 
@@ -0,0 +1,45 @@
1
+ name: playwright-e2e
2
+ on:
3
+ push:
4
+ branches:
5
+ - main
6
+ jobs:
7
+ test:
8
+ runs-on: ubuntu-latest
9
+ env:
10
+ DATABASE_DEFAULT_CLIENT: sqlite3
11
+ PNPM_CONFIG_MINIMUM_RELEASE_AGE: 0
12
+ services:
13
+ redis:
14
+ image: redis:latest
15
+ ports:
16
+ - 6379:6379
17
+ steps:
18
+ - uses: actions/checkout@v6
19
+ - uses: actions/setup-node@v6
20
+ with:
21
+ node-version: 24
22
+ - uses: pnpm/action-setup@v5
23
+ with:
24
+ version: 11.5.2
25
+ - name: init
26
+ run: npm run init
27
+ - name: install Chromium
28
+ run: npx playwright install --with-deps chromium
29
+ - name: run Basic E2E baseline
30
+ run: npm run test:e2e:basic:clean
31
+ - name: build Commerce Zova artifacts
32
+ run: npm run build:zova:commerce
33
+ - name: synchronize Vona dependencies
34
+ run: npm run deps:vona
35
+ - name: run Commerce E2E baseline
36
+ run: npm run test:e2e:commerce:clean
37
+ - name: upload Playwright artifacts
38
+ if: failure()
39
+ uses: actions/upload-artifact@v4
40
+ with:
41
+ name: playwright-artifacts
42
+ path: |
43
+ playwright-report/
44
+ test-results/
45
+ if-no-files-found: ignore
package/.gitignore CHANGED
@@ -16,6 +16,7 @@ blob-report/
16
16
 
17
17
  **/.claude/settings.local.json
18
18
  **/.claude/worktrees
19
+ **/CLAUDE.local.md
19
20
 
20
21
  **/.idea
21
22
  **/.DS_Store
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.1.112
4
+
5
+ ### Features
6
+
7
+ - Add commerce member address ownership support.
8
+ - Add commerce cart capabilities.
9
+ - Add a commerce test seed module.
10
+ - Add rules and catalog capabilities.
11
+ - Add server-side rendered menu support.
12
+ - Add commerce site administration capabilities.
13
+
14
+ ### Improvements
15
+
16
+ - Update commerce DTOs, controllers, routing, product handling, stock balances, and upgrade flows.
17
+ - Add Playwright end-to-end test workflow coverage.
18
+ - Refine full-stack positioning documentation.
19
+
20
+ ## 5.1.111
21
+
22
+ ### Features
23
+
24
+ - Update the application functionality.
25
+
3
26
  ## 5.1.110
4
27
 
5
28
  ### Features
package/CLAUDE.md CHANGED
@@ -54,7 +54,8 @@ Before inventing a custom implementation path:
54
54
  - For Zova frontend analysis, do not default to generic Vue reinterpretation first. Read the code through Zova’s controller / bean / IoC architecture before mapping it to Vue concepts.
55
55
  - For Zova source-reading or Vue-vs-Zova explanation tasks, start from the frontend reading guides and source-reading map in `cabloy-docs/frontend/` before doing framework-neutral reinterpretation.
56
56
  - For frontend async state that affects rendering or interaction across consumers, prefer model-owned `$useStateData(...)` over controller-managed fetch/cache state.
57
- - Default to establishing such query state during render. Use `disableSuspenseOnInit: true` only for relatively stable query-backed state when you want to skip the init-time `query.suspense()` kick; if strict readiness is needed later, wait explicitly at the interaction boundary.
57
+ - Default to establishing such query state during render. Use `disableSuspenseOnInit: true` only for relatively stable query-backed state when you want to skip the init-time `query.suspense()` kick; it does not prevent query creation, fetches, or hydration-time rendering. If strict readiness is needed later, wait explicitly at the interaction boundary.
58
+ - In SSR, keep server HTML and the client's hydration-time initial render equivalent. When server rendering intentionally omits private, cookie-unavailable, or browser-only state, keep the same neutral shell or placeholder through hydration and defer its query/load/render branch to an explicit post-hydration, admission, mounted, or interaction boundary.
58
59
  - Keep repo-wide AI rules in `CLAUDE.md` short and durable; put branching Zova analysis workflows in `.claude/skills/`.
59
60
  - For SSR theme-sensitive frontend work, detect the active edition marker and UI library before making assumptions. Cabloy Basic currently means DaisyUI + Tailwind CSS assumptions; Cabloy Start currently means Vuetify assumptions.
60
61
  - In Web SSR without cookie-backed theme resolution, do not treat server reads of `$theme.dark`, `$theme.darkMode`, or `$token` as final browser truth. Keep theme-sensitive SSR branching hydration-tolerant or defer final theme-sensitive decisions to the client.
@@ -68,6 +69,8 @@ Before inventing a custom implementation path:
68
69
  - When backend code references `this.bean.xxx`, `ctx.bean.xxx`, or `app.bean.xxx`, use `IBeanRecordGlobal` and module `src/.metadata/index.ts` as the first static lookup surface; use `IBeanRecordGeneral` or `src/service` only when the target is not a global shorthand.
69
70
  - When adding a persisted field to an existing backend resource, ask the user whether `vonaModule.fileVersion` should be incremented before changing `meta.version.ts` or the module schema path. If yes, add a new migration version and bump `fileVersion`. If no, keep the current `fileVersion` and fold the schema change into the current version path. Do not assume the versioning strategy without confirmation.
70
71
  - In shared-database multitenancy, do not use `table.unique(...)` for business uniqueness. Keep ordinary indexes for lookup performance and enforce tenant-scoped uniqueness in the business layer.
72
+ - In Vona, a tenant corresponds to an instance. Ordinary resource-model CRUD is automatically scoped to the active instance; treat records absent from that scope as absent, and do not use raw cross-instance probes merely to choose between `403` and not-found behavior. Model future multi-merchant boundaries explicitly inside an instance.
73
+ - Model cross-Model query-cache dependencies as one directed, acyclic `modelsClear` / `modelsClearedBy` graph, and verify source mutations refresh warmed dependent queries; read `.docs-internal/architecture/vona-cross-model-query-cache-dependencies.md` before designing a nontrivial graph.
71
74
  - For `@Api.field(...)` and related schemaLike composition, framework guards now preserve previously attached OpenAPI metadata across schema rebuilds, but structure-shaping schemaLike is still order-sensitive. Treat `v.object(...)`, `v.array(...)`, `v.optional()`, `v.nullable()`, `v.default(...)`, and preprocess/transform wrappers as structure-shaping; keep the final structure-defining schemaLike last and verify emitted schema/OpenAPI output after such edits.
72
75
 
73
76
  ## Verification expectations
package/README.md CHANGED
@@ -8,9 +8,9 @@
8
8
 
9
9
  Cabloy is a Node.js fullstack framework for AI vibe coding.
10
10
 
11
- Use one fullstack framework instead of stitching together separate backend and frontend stacks.
11
+ **One fullstack system for AI vibe coding—bidirectional type sync, CLI-first workflows, docs, and skills.**
12
12
 
13
- With Vona, Zova, suite-based modules, and CLI-first workflows, Cabloy turns common scaffolding, metadata, refactors, and verification into explicit commands for faster, more accurate AI vibe coding.
13
+ 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 provide the aligned architecture behind that workflow.
14
14
 
15
15
  [Documentation](https://docs.cabloy.com) · [npm](https://www.npmjs.com/package/cabloy) · [Web Demo](https://cabloy.com) · [Admin Demo](https://cabloy.com/admin) · [GitHub](https://github.com/cabloy/cabloy)
16
16
 
@@ -102,12 +102,12 @@ npm run upgrade
102
102
 
103
103
  ## Highlights
104
104
 
105
- - **One framework system** — build backend and frontend in one fullstack architecture
106
- - **Vona + Zova** — use aligned backend and frontend frameworks for code sharing, workflow reuse, and cross-stack consistency
107
- - **Suite-based modular system** — organize capabilities as suites and modules so services, features, metadata, and tooling evolve in composable units
108
- - **Multiple delivery modes** — deliver SSR, SPA, Web, and Admin applications with shared conventions across the stack
109
- - **CLI-first workflows for AI vibe coding** — turn common scaffolding, metadata, refactors, and verification into explicit commands for faster, more accurate AI vibe coding
110
- - **Monorepo-native development** — keep framework source, docs, and tooling aligned in one monorepo workflow
105
+ - **One fullstack system** — build backend and frontend together instead of assembling separate stacks
106
+ - **Bidirectional type sync** — use the contract loop to keep backend contracts and frontend metadata aligned in both directions
107
+ - **CLI-first workflows** — use explicit commands for scaffolding, generation, refactors, and verification
108
+ - **Docs and skills** — give people and AI agents reusable, source-grounded guidance for the current repository
109
+ - **Vona + Zova** — use aligned backend and frontend layers for code sharing and cross-stack consistency
110
+ - **Modular delivery** — organize capabilities as suites and modules, then deliver SSR, SPA, Web, and Admin applications with shared conventions
111
111
 
112
112
  ## Technology Stack
113
113
 
@@ -95,6 +95,16 @@ Read this guide together with:
95
95
  - [Migration and Changes](/backend/migration-and-changes)
96
96
  - [Unit Testing](/backend/unit-testing)
97
97
 
98
+ ## Instance-scoped CRUD
99
+
100
+ Generated controller, service, and model flows retain Vona's default active-instance scope. In the current tenancy model, a tenant corresponds to an instance, so ordinary resource CRUD should not accept caller-controlled `iid` or tenant selection.
101
+
102
+ When a normal scoped view, update, or delete target is not found, preserve its absent/not-found semantics. Do not run an unscoped raw-table probe merely to discover whether another instance owns the same identifier and convert that result into `403`.
103
+
104
+ If a future requirement introduces multiple merchants inside one instance, model that as an explicit additional business boundary with its own ownership, authorization, relations, indexes, and tests. It does not replace the existing instance scope.
105
+
106
+ For the runtime tenancy boundary, see [Multi-Instance and Instance Resolution](/backend/multi-instance-and-instance-resolution). For model-level behavior and exceptional raw/builder usage, see [Model Guide](/backend/model-guide).
107
+
98
108
  ## Recommended workflow
99
109
 
100
110
  1. run the CRUD generator
@@ -232,14 +232,39 @@ Scope groups a module’s resources behind one structured facade, including area
232
232
  - locale
233
233
  - error
234
234
 
235
- The key distinction is:
235
+ Choose the narrowest lookup form that matches what is known at the call site:
236
236
 
237
- - `this.scope` means local module resources
238
- - `this.$scope.<module>` means cross-module resources
239
- - `app.scope(...)` means explicit app-level scope lookup outside the local class shorthand
237
+ | Situation | Preferred form | Example |
238
+ | -------------------------------------------------------------------------------------------------------- | ---------------------------- | ----------------------------------------- |
239
+ | Resource belongs to the current `BeanBase` module | `this.scope` | `this.scope.model.stockBalance` |
240
+ | Another module is fixed in source and `$scope` is available | `this.$scope.<fixedModule>` | `this.$scope.commerceCatalog.model.sku` |
241
+ | Code has an application reference rather than `BeanBase` shorthands, such as a test or standalone helper | `app.scope('<module-name>')` | `app.scope('commerce-catalog').model.sku` |
242
+ | A class uses the explicit application API or selects the module name at runtime | `this.app.scope(moduleName)` | `this.app.scope(moduleName)` |
243
+
244
+ Prefer `this.scope` for module-local business code and `this.$scope.<fixedModule>` for a statically known cross-module target. Use `app.scope(...)` or `this.app.scope(...)` when the shorthand is unavailable or the module name is genuinely dynamic. Do not replace a fixed typed shorthand with a string lookup merely for style, or mix equivalent fixed lookup forms in one access path.
240
245
 
241
246
  This is one of the reasons Vona backend code can stay concise without flattening everything into arbitrary imports.
242
247
 
248
+ ## Scope lookup vs module dependencies
249
+
250
+ All of the lookup forms above resolve a resource from a module that is already part of the active application composition. Fixed cross-module Bean code normally uses:
251
+
252
+ ```typescript
253
+ const modelSku = this.$scope.commerceCatalog.model.sku;
254
+ ```
255
+
256
+ A test or standalone helper with an application reference can use:
257
+
258
+ ```typescript
259
+ const modelSku = app.scope('commerce-catalog').model.sku;
260
+ ```
261
+
262
+ Using `this.$scope.<fixedModule>`, `app.scope(...)`, or `this.app.scope(...)` does not by itself require adding the target module to the caller's `vonaModule.dependencies`. Lookup does not create a module dependency edge, so lookup alone cannot create a circular dependency.
263
+
264
+ Scope lookup also does not compose, install, load, or order an absent module. The target must already be available through suite/application composition. Declare `vonaModule.dependencies` only when the caller has a genuine requirement for a target module's availability, dependency-first ordering, or minimum compatible version—not merely because it looks up that module's service, model, config, locale, or another resource.
265
+
266
+ For the package, suite, and module dependency distinction, see [Package Map](/reference/package-map).
267
+
243
268
  ## Suite / module / package boundaries
244
269
 
245
270
  Vona architecture is not only about classes and beans. It is also about structural boundaries.
@@ -2,7 +2,7 @@
2
2
 
3
3
  This page is the backend hub for Cabloy users, contributors, and AI vibe coding workflows that need the backend side of the framework.
4
4
 
5
- Vona is the backend half of Cabloy’s one-framework-system fullstack architecture.
5
+ Vona is the backend layer of Cabloy’s one fullstack system, supporting bidirectional type sync, CLI-first workflows, and source-grounded docs and skills.
6
6
 
7
7
  ## What Vona is responsible for
8
8
 
@@ -199,23 +199,21 @@ A practical implication is:
199
199
 
200
200
  ## Instance-aware model semantics
201
201
 
202
- One important current-runtime distinction is that ordinary model usage is instance-aware by default.
202
+ One important current-runtime distinction is that ordinary model usage is instance-aware by default. In Vona's current tenancy model, the active instance is the tenant boundary.
203
203
 
204
- A practical interpretation is:
204
+ For normal resource models, the model layer handles the active instance `iid` as part of ordinary persistence behavior:
205
205
 
206
- - normal model operations participate in the current instance context
207
- - instance-aware filtering is part of normal model behavior unless disabled
208
- - request-scoped code should usually preserve that behavior instead of bypassing it casually
206
+ - inserts receive the active instance identity
207
+ - selects, `getById`, counts, updates, and deletes receive the active instance predicate
208
+ - request-scoped code should preserve this behavior instead of accepting caller-controlled tenant or `iid` scope
209
209
 
210
- This is why `disableInstance` is a meaningful semantic choice rather than a minor ORM toggle.
210
+ This is why `disableInstance` is a meaningful semantic choice rather than a minor ORM toggle. Use it only for a genuinely global/system model or another explicitly authorized contract that must ignore the active instance boundary.
211
211
 
212
- Use it only when the model truly should ignore the active instance boundary.
212
+ A scoped miss is absent in the current tenant/instance. Do not use `disableInstance`, a plain builder, or raw SQL merely to probe another instance and choose between `403` and not-found behavior. A real authorization failure can still be `403`; the distinction is that an ordinary resource lookup should not disclose cross-instance existence.
213
213
 
214
- Another practical implication is:
214
+ Lower-level builders and raw SQL need extra care when replacing ordinary model behavior. Preserve the active instance predicate when the operation is meant to remain instance-scoped, and document the authorization and audit contract when it deliberately is not.
215
215
 
216
- - lower-level builder or raw-SQL flows may need extra care when you are reproducing behavior that the ordinary model path would have applied automatically
217
-
218
- For the broader instance/config story, also see [Config Guide](/backend/config-guide).
216
+ For the tenancy terminology and runtime boundary, see [Multi-Instance and Instance Resolution](/backend/multi-instance-and-instance-resolution). For generated resource flows, see [CRUD Workflow](/backend/crud-workflow). For the broader instance/config story, also see [Config Guide](/backend/config-guide).
219
217
 
220
218
  ## Datasource selection
221
219
 
@@ -191,6 +191,24 @@ That means:
191
191
 
192
192
  For the model-layer perspective, also see [Model Guide](/backend/model-guide).
193
193
 
194
+ ## Tenancy boundary: one Vona tenant per instance
195
+
196
+ In Vona's current tenancy model, a tenant corresponds to an instance. The resolved active instance is the data-isolation boundary for ordinary resource code.
197
+
198
+ For resources that inherit the normal entity base behavior:
199
+
200
+ - `iid` persists the instance discriminator when instances share a datasource
201
+ - normal model CRUD uses the active `ctx.instance.id` rather than a caller-supplied tenant or `iid`
202
+ - isolated instances can add a separate datasource boundary through `isolateClient`, but they still remain separate instances
203
+
204
+ This means a normal scoped lookup has one business result when it finds no row: that resource is absent in the current tenant/instance. Do not bypass model scope or issue an unscoped secondary lookup merely to reveal that another instance has the same identifier and change the result to `403`.
205
+
206
+ This rule does not eliminate genuine authorization failures. Return `403` when the current request is not authorized to perform an operation on a resource that is available in its authorized scope. The rule only prevents ordinary scoped misses from becoming cross-instance existence disclosures.
207
+
208
+ Do not use instance selection to represent a future merchant, store, organization, or similar business boundary. A multi-merchant design belongs inside one instance and needs explicit merchant ownership, authorization, relations, indexes, and tests in addition to the existing instance boundary.
209
+
210
+ For the operational model rules, see [Model Guide](/backend/model-guide). For generated resource behavior, see [CRUD Workflow](/backend/crud-workflow).
211
+
194
212
  ## Relationship to runtime and config docs
195
213
 
196
214
  Read this guide together with:
@@ -94,7 +94,7 @@ A useful distinction is:
94
94
  - `this.scope` means local module resources
95
95
  - `this.$scope.<module>` means cross-module resources
96
96
 
97
- That same access model also appears for model, entity, config, locale, and other scope resources.
97
+ That same access model also appears for model, entity, config, locale, and other scope resources. Cross-module scope lookup alone does not require a `vonaModule.dependencies` entry; see [Backend Foundation](/backend/foundation#scope-lookup-vs-module-dependencies) for the distinction between lookup and a true module dependency.
98
98
 
99
99
  ## Direct bean access
100
100
 
@@ -122,7 +122,7 @@ Its main jobs are:
122
122
  - merge config-route overrides
123
123
  - synthesize alias routes when needed
124
124
  - wrap routed pages with layout routes when `meta.layout` requires it
125
- - expose helpers such as `getPagePath(...)`, `resolveName(...)`, and `ensureRoute(...)`
125
+ - expose helpers such as `getPagePath(...)`, `getAliasPath(...)`, `resolveName(...)`, and `ensureRoute(...)`
126
126
 
127
127
  This is the file that most clearly shows how a module-local route record becomes operational router structure.
128
128
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  This page is the frontend hub for Cabloy users, contributors, and AI vibe coding workflows that need the frontend side of the framework.
4
4
 
5
- Zova is the frontend half of Cabloy’s one-framework-system fullstack architecture.
5
+ Zova is the frontend layer of Cabloy’s one fullstack system, supporting bidirectional type sync, CLI-first workflows, and source-grounded docs and skills.
6
6
 
7
7
  ## What Zova is responsible for
8
8
 
@@ -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
- !this.sys.config.ssr.cookieDisabledOnServer &&
27
- to.meta.requiresAuth !== false &&
28
- !this.$passport.isAuthenticated
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
- if (!this.$passport.isAuthenticated) {
38
- this.app.$gotoLogin(to.fullPath);
39
- return false;
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: