cabloy 5.1.136 → 5.1.138

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 (617) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/skills/cabloy-backend-scaffold/SKILL.md +13 -0
  3. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +11 -0
  4. package/.claude/skills/cabloy-contract-loop/SKILL.md +17 -0
  5. package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +35 -0
  6. package/.claude/skills/cabloy-frontend-scaffold/evals/evals.json +1 -1
  7. package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +4 -0
  8. package/.claude/skills/cabloy-zova-source-reading/SKILL.md +21 -0
  9. package/.claude/skills/cabloy-zova-source-reading/references/core-reading-paths.md +26 -0
  10. package/CHANGELOG.md +31 -0
  11. package/CLAUDE.md +5 -1
  12. package/cabloy-docs/.vitepress/config.mjs +1 -0
  13. package/cabloy-docs/.vitepress/theme/custom.css +124 -0
  14. package/cabloy-docs/backend/auth-guide.md +8 -0
  15. package/cabloy-docs/backend/config-guide.md +2 -0
  16. package/cabloy-docs/backend/controller-aop-guide.md +8 -0
  17. package/cabloy-docs/backend/controller-guide.md +33 -0
  18. package/cabloy-docs/backend/event-guide.md +3 -3
  19. package/cabloy-docs/backend/mail-guide.md +1 -1
  20. package/cabloy-docs/backend/markdown-guide.md +1 -1
  21. package/cabloy-docs/backend/runtime-and-flavors.md +29 -0
  22. package/cabloy-docs/backend/user-access-guide.md +2 -2
  23. package/cabloy-docs/blogs/ai-react-nextjs-enterprise-architecture-cabloy/cover-en-v1.png +0 -0
  24. package/cabloy-docs/blogs/ai-react-nextjs-enterprise-architecture-cabloy/index.md +177 -0
  25. package/cabloy-docs/blogs/cabloy-fullstack-resource-addressing/cover-en-v1.png +0 -0
  26. package/cabloy-docs/blogs/cabloy-fullstack-resource-addressing/index.md +430 -0
  27. package/cabloy-docs/blogs/index.md +69 -0
  28. package/cabloy-docs/blogs/nextjs-integrated-fullstack-cabloy-contract-loop/cover-en-v1.png +0 -0
  29. package/cabloy-docs/blogs/nextjs-integrated-fullstack-cabloy-contract-loop/index.md +195 -0
  30. package/cabloy-docs/blogs/vue-object-oriented-zova-beginner-mental-model/cover-en-v1.png +0 -0
  31. package/cabloy-docs/blogs/vue-object-oriented-zova-beginner-mental-model/index.md +483 -0
  32. package/cabloy-docs/frontend/a-openapi-under-the-hood.md +13 -0
  33. package/cabloy-docs/frontend/api-schema-guide.md +79 -0
  34. package/cabloy-docs/frontend/environment-config-guide.md +2 -0
  35. package/cabloy-docs/frontend/form-guide.md +37 -0
  36. package/cabloy-docs/frontend/markdown-guide.md +3 -0
  37. package/cabloy-docs/frontend/model-resource-owner-pattern.md +26 -1
  38. package/cabloy-docs/frontend/module-scope.md +24 -0
  39. package/cabloy-docs/frontend/modules-and-suites.md +23 -1
  40. package/cabloy-docs/frontend/navigation-guards-guide.md +2 -0
  41. package/cabloy-docs/frontend/page-params-guide.md +2 -0
  42. package/cabloy-docs/frontend/page-route-guide.md +10 -3
  43. package/cabloy-docs/frontend/route-alias-guide.md +12 -6
  44. package/cabloy-docs/frontend/ssr-env.md +15 -6
  45. package/cabloy-docs/frontend/ssr-overview.md +10 -0
  46. package/cabloy-docs/frontend/ssr-review-checklist.md +1 -0
  47. package/cabloy-docs/frontend/zova-form-under-the-hood.md +6 -0
  48. package/cabloy-docs/frontend/zova-router-under-the-hood.md +4 -5
  49. package/cabloy-docs/fullstack/a-pay-payment-suite.md +1 -1
  50. package/cabloy-docs/fullstack/deploy-cloudflare-docker.md +14 -8
  51. package/e2e/specs/a-commerce/commerce.spec.ts +17 -2
  52. package/e2e/specs/cabloy-basic/account.spec.ts +519 -0
  53. package/e2e/specs/cabloy-basic/basic.spec.ts +15 -3
  54. package/package.json +1 -1
  55. package/vona/env/.env +2 -0
  56. package/vona/packages-cli/cli/package.json +1 -1
  57. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/boilerplate/src/controller/{{resourceName}}.ts_ +14 -11
  58. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/snippets/3-en-us.ts +11 -1
  59. package/vona/packages-cli/cli-set-api/cli/templates/tools/crudStart/snippets/4-zh-cn.ts +11 -1
  60. package/vona/packages-cli/cli-set-api/package.json +1 -1
  61. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.tools.metadata.ts +1 -0
  62. package/vona/packages-cli/cli-set-api/src/lib/bean/toolsMetadata/generateOnions.ts +4 -3
  63. package/vona/packages-vona/vona/package.json +1 -1
  64. package/vona/pnpm-lock.yaml +237 -66
  65. package/vona/pnpm-workspace.yaml +1 -1
  66. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +33 -37
  67. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuSelectResItem.tsx +3 -0
  68. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/dto/skuView.tsx +3 -0
  69. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/entity/sku.tsx +17 -2
  70. package/vona/src/suite/a-commerce/modules/commerce-catalog/src/service/sku.ts +12 -2
  71. package/vona/src/suite/a-commerce/modules/commerce-catalog/test/skuPresentation.test.ts +52 -4
  72. package/vona/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +34 -36
  73. package/vona/src/suite/a-commerce/modules/commerce-payment/src/.metadata/index.ts +29 -33
  74. package/vona/src/suite/a-commerce/modules/commerce-promotion/src/.metadata/index.ts +34 -37
  75. package/vona/src/suite/a-commerce/modules/commerce-seed/src/.metadata/index.ts +8 -9
  76. package/vona/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/index.ts +33 -35
  77. package/vona/src/suite/a-commerce/modules/commerce-siteweb/src/.metadata/index.ts +11 -11
  78. package/vona/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +45 -42
  79. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditSelectResItem.tsx +4 -0
  80. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockAuditView.tsx +6 -1
  81. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceSelectResItem.tsx +4 -0
  82. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockBalanceView.tsx +6 -1
  83. package/vona/src/suite/a-commerce/modules/commerce-trade/src/dto/stockSkuRef.tsx +16 -0
  84. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockAudit.tsx +17 -2
  85. package/vona/src/suite/a-commerce/modules/commerce-trade/src/entity/stockBalance.tsx +17 -2
  86. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockAudit.ts +31 -2
  87. package/vona/src/suite/a-commerce/modules/commerce-trade/src/service/stockBalance.ts +31 -2
  88. package/vona/src/suite/a-commerce/modules/commerce-trade/test/stockPresentation.test.ts +116 -4
  89. package/vona/src/suite/a-demo/modules/demo-basic/src/.metadata/index.ts +11 -11
  90. package/vona/src/suite/a-home/modules/home-base/src/.metadata/index.ts +0 -3
  91. package/vona/src/suite/a-home/modules/home-index/src/.metadata/index.ts +12 -13
  92. package/vona/src/suite/a-home/modules/home-user/package.json +9 -1
  93. package/vona/src/suite/a-home/modules/home-user/src/.metadata/index.ts +333 -78
  94. package/vona/src/suite/a-home/modules/home-user/src/bean/cacheRedis.activation.ts +21 -0
  95. package/vona/src/suite/a-home/modules/home-user/src/bean/cacheRedis.activationCurrent.ts +15 -0
  96. package/vona/src/{suite-vendor/a-vona/modules/a-mailconfirm → suite/a-home/modules/home-user}/src/bean/cacheRedis.passwordReset.ts +6 -2
  97. package/vona/src/suite/a-home/modules/home-user/src/bean/cacheRedis.passwordResetCurrent.ts +15 -0
  98. package/vona/src/suite/a-home/modules/home-user/src/bean/cacheRedis.passwordResetRecipient.ts +13 -0
  99. package/vona/src/suite/a-home/modules/home-user/src/bean/cacheRedis.passwordSet.ts +22 -0
  100. package/vona/src/suite/a-home/modules/home-user/src/bean/cacheRedis.passwordSetCurrent.ts +15 -0
  101. package/vona/src/suite/a-home/modules/home-user/src/bean/imageScene.homeUserAvatar.ts +18 -0
  102. package/vona/src/suite/a-home/modules/home-user/src/bean/meta.redlock.ts +18 -0
  103. package/vona/src/suite/a-home/modules/home-user/src/bean/meta.version.ts +0 -1
  104. package/vona/src/suite/a-home/modules/home-user/src/bean/zodRefine.passwordConfirm.ts +8 -4
  105. package/vona/src/suite/a-home/modules/home-user/src/config/config.ts +10 -1
  106. package/vona/src/suite/a-home/modules/home-user/src/config/locale/en-us.ts +35 -3
  107. package/vona/src/suite/a-home/modules/home-user/src/config/locale/zh-cn.ts +35 -3
  108. package/vona/src/suite/a-home/modules/home-user/src/controller/account.ts +147 -0
  109. package/vona/src/suite/a-home/modules/home-user/src/controller/passport.ts +27 -7
  110. package/vona/src/suite/a-home/modules/home-user/src/dto/accountActivation.ts +12 -0
  111. package/vona/src/suite/a-home/modules/home-user/src/dto/accountCurrent.ts +31 -0
  112. package/vona/src/suite/a-home/modules/home-user/src/dto/accountPasswordChange.ts +41 -0
  113. package/vona/src/suite/a-home/modules/home-user/src/dto/accountPasswordReset.ts +35 -0
  114. package/vona/src/suite/a-home/modules/home-user/src/dto/accountPasswordResetRequest.ts +20 -0
  115. package/vona/src/suite/a-home/modules/home-user/src/dto/accountPasswordResetRequestResult.ts +13 -0
  116. package/vona/src/suite/a-home/modules/home-user/src/dto/accountPasswordSet.ts +35 -0
  117. package/vona/src/suite/a-home/modules/home-user/src/dto/accountPasswordSetIssue.ts +15 -0
  118. package/vona/src/suite/a-home/modules/home-user/src/dto/accountProfileUpdate.ts +53 -0
  119. package/vona/src/suite/a-home/modules/home-user/src/dto/accountRelogin.ts +12 -0
  120. package/vona/src/suite/a-home/modules/home-user/src/dto/passport.ts +2 -2
  121. package/vona/src/suite/a-home/modules/home-user/src/dto/passportUser.ts +43 -0
  122. package/vona/src/suite/a-home/modules/home-user/src/dto/register.ts +40 -5
  123. package/vona/src/suite/a-home/modules/home-user/src/service/account.ts +693 -0
  124. package/vona/src/suite/a-home/modules/home-user/test/account.test.ts +249 -0
  125. package/vona/src/suite/a-home/modules/home-user/test/accountActivation.test.ts +344 -0
  126. package/vona/src/suite/a-home/modules/home-user/test/accountOpenapi.test.ts +158 -0
  127. package/vona/src/suite/a-home/modules/home-user/test/accountPasswordReset.test.ts +724 -0
  128. package/vona/src/suite/a-home/modules/home-user/test/accountPasswordSet.test.ts +799 -0
  129. package/vona/src/suite/a-training/modules/training-record/src/.metadata/index.ts +73 -65
  130. package/vona/src/suite/a-training/modules/training-recordsubject/src/.metadata/index.ts +26 -17
  131. package/vona/src/suite/a-training/modules/training-student/src/.metadata/index.ts +47 -39
  132. package/vona/src/suite/cabloy-basic/modules/basic-metrics/src/.metadata/index.ts +22 -23
  133. package/vona/src/suite/cabloy-basic/modules/basic-siteadmin/src/.metadata/index.ts +15 -15
  134. package/vona/src/suite/cabloy-basic/modules/basic-siteweb/src/.metadata/index.ts +11 -11
  135. package/vona/src/suite-vendor/a-auth/modules/a-auth/package.json +1 -1
  136. package/vona/src/suite-vendor/a-auth/modules/a-auth/src/.metadata/index.ts +55 -41
  137. package/vona/src/suite-vendor/a-auth/modules/auth-oauth/package.json +1 -1
  138. package/vona/src/suite-vendor/a-auth/modules/auth-oauth/src/.metadata/index.ts +8 -8
  139. package/vona/src/suite-vendor/a-auth/modules/auth-simple/package.json +4 -2
  140. package/vona/src/suite-vendor/a-auth/modules/auth-simple/src/.metadata/index.ts +51 -27
  141. package/vona/src/suite-vendor/a-auth/modules/auth-simple/src/bean/meta.redlock.ts +11 -0
  142. package/vona/src/suite-vendor/a-auth/modules/auth-simple/src/service/authSimple.ts +53 -2
  143. package/vona/src/suite-vendor/a-auth/modules/auth-simple/test/authSimple.test.ts +56 -0
  144. package/vona/src/suite-vendor/a-auth/package.json +2 -2
  145. package/vona/src/suite-vendor/a-cabloy/modules/a-cabloy/package.json +1 -1
  146. package/vona/src/suite-vendor/a-cabloy/modules/a-cabloy/src/.metadata/index.ts +4 -4
  147. package/vona/src/suite-vendor/a-cabloy/modules/a-datasharding/package.json +1 -1
  148. package/vona/src/suite-vendor/a-cabloy/modules/a-datasharding/src/.metadata/index.ts +23 -24
  149. package/vona/src/suite-vendor/a-cabloy/modules/a-datasource/package.json +1 -1
  150. package/vona/src/suite-vendor/a-cabloy/modules/a-datasource/src/.metadata/index.ts +31 -22
  151. package/vona/src/suite-vendor/{a-vona/modules/a-mailconfirm → a-cabloy/modules/a-rbac}/package.json +13 -5
  152. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/.metadata/index.ts +147 -0
  153. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/.metadata/this.ts +2 -0
  154. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/bean/bean.rbacCatalog.ts +95 -0
  155. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/bean/bean.rbacScope.ts +218 -0
  156. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/bean/event.policyInvalidated.ts +17 -0
  157. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/bean/event.resolvePolicy.ts +13 -0
  158. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/bean/guard.rbac.ts +102 -0
  159. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/bean/index.ts +5 -0
  160. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/config/config.ts +10 -0
  161. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/index.ts +3 -0
  162. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/lib/index.ts +1 -0
  163. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/lib/rbac.ts +46 -0
  164. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/types/index.ts +2 -0
  165. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/types/rbac.ts +46 -0
  166. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/src/types/scope.ts +27 -0
  167. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/test/rbacCatalogGuard.test.ts +445 -0
  168. package/vona/src/suite-vendor/a-cabloy/modules/a-rbac/test/rbacScopeCurrent.test.ts +172 -0
  169. package/vona/src/suite-vendor/a-cabloy/modules/a-socket/package.json +1 -1
  170. package/vona/src/suite-vendor/a-cabloy/modules/a-socket/src/.metadata/index.ts +27 -31
  171. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/package.json +1 -1
  172. package/vona/src/suite-vendor/a-cabloy/modules/a-ssr/src/.metadata/index.ts +37 -45
  173. package/vona/src/suite-vendor/a-cabloy/modules/a-ssrhmr/package.json +1 -1
  174. package/vona/src/suite-vendor/a-cabloy/modules/a-ssrhmr/src/.metadata/index.ts +12 -12
  175. package/vona/src/suite-vendor/a-cabloy/modules/a-status/package.json +1 -1
  176. package/vona/src/suite-vendor/a-cabloy/modules/a-status/src/.metadata/index.ts +27 -19
  177. package/vona/src/suite-vendor/a-cabloy/package.json +2 -1
  178. package/vona/src/suite-vendor/a-cabloy/tsconfig.json +3 -0
  179. package/vona/src/suite-vendor/a-captcha/modules/a-captcha/package.json +1 -1
  180. package/vona/src/suite-vendor/a-captcha/modules/a-captcha/src/.metadata/index.ts +27 -29
  181. package/vona/src/suite-vendor/a-captcha/modules/captcha-simple/package.json +1 -1
  182. package/vona/src/suite-vendor/a-captcha/modules/captcha-simple/src/.metadata/index.ts +16 -17
  183. package/vona/src/suite-vendor/a-captcha/package.json +1 -1
  184. package/vona/src/suite-vendor/a-file/modules/a-file/package.json +1 -1
  185. package/vona/src/suite-vendor/a-file/modules/a-file/src/.metadata/index.ts +56 -38
  186. package/vona/src/suite-vendor/a-file/modules/file-cloudflare/package.json +1 -1
  187. package/vona/src/suite-vendor/a-file/modules/file-cloudflare/src/.metadata/index.ts +12 -13
  188. package/vona/src/suite-vendor/a-file/modules/file-native/package.json +1 -1
  189. package/vona/src/suite-vendor/a-file/modules/file-native/src/.metadata/index.ts +11 -12
  190. package/vona/src/suite-vendor/a-file/package.json +4 -4
  191. package/vona/src/suite-vendor/a-image/modules/a-image/package.json +1 -1
  192. package/vona/src/suite-vendor/a-image/modules/a-image/src/.metadata/index.ts +56 -38
  193. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/package.json +1 -1
  194. package/vona/src/suite-vendor/a-image/modules/image-cloudflare/src/.metadata/index.ts +12 -13
  195. package/vona/src/suite-vendor/a-image/modules/image-native/package.json +1 -1
  196. package/vona/src/suite-vendor/a-image/modules/image-native/src/.metadata/index.ts +11 -12
  197. package/vona/src/suite-vendor/a-image/package.json +1 -1
  198. package/vona/src/suite-vendor/a-pay/modules/a-pay/package.json +1 -1
  199. package/vona/src/suite-vendor/a-pay/modules/a-pay/src/.metadata/index.ts +0 -8
  200. package/vona/src/suite-vendor/a-pay/modules/pay-mock/package.json +1 -1
  201. package/vona/src/suite-vendor/a-pay/modules/pay-mock/src/.metadata/index.ts +21 -22
  202. package/vona/src/suite-vendor/a-pay/modules/pay-paypal/package.json +1 -1
  203. package/vona/src/suite-vendor/a-pay/modules/pay-paypal/src/.metadata/index.ts +8 -8
  204. package/vona/src/suite-vendor/a-pay/modules/pay-stripe/package.json +1 -1
  205. package/vona/src/suite-vendor/a-pay/modules/pay-stripe/src/.metadata/index.ts +8 -8
  206. package/vona/src/suite-vendor/a-pay/package.json +5 -5
  207. package/vona/src/suite-vendor/a-paypal/modules/a-paypal/package.json +1 -1
  208. package/vona/src/suite-vendor/a-paypal/modules/a-paypal/src/.metadata/index.ts +46 -40
  209. package/vona/src/suite-vendor/a-paypal/package.json +1 -1
  210. package/vona/src/suite-vendor/a-vona/modules/a-aspect/cli/guard/boilerplate/{{sceneName}}.{{beanName}}.ts_ +6 -8
  211. package/vona/src/suite-vendor/a-vona/modules/a-aspect/package.json +1 -1
  212. package/vona/src/suite-vendor/a-vona/modules/a-aspect/src/.metadata/index.ts +8 -16
  213. package/vona/src/suite-vendor/a-vona/modules/a-aspect/src/lib/utils/guardBase.ts +22 -0
  214. package/vona/src/suite-vendor/a-vona/modules/a-aspect/src/lib/utils/index.ts +1 -0
  215. package/vona/src/suite-vendor/a-vona/modules/a-aspect/src/types/guard.ts +4 -1
  216. package/vona/src/suite-vendor/a-vona/modules/a-aspectutils/package.json +1 -1
  217. package/vona/src/suite-vendor/a-vona/modules/a-aspectutils/src/.metadata/index.ts +8 -10
  218. package/vona/src/suite-vendor/a-vona/modules/a-bean/package.json +1 -1
  219. package/vona/src/suite-vendor/a-vona/modules/a-bean/src/.metadata/index.ts +4 -4
  220. package/vona/src/suite-vendor/a-vona/modules/a-beanmutate/package.json +1 -1
  221. package/vona/src/suite-vendor/a-vona/modules/a-beanmutate/src/.metadata/index.ts +17 -19
  222. package/vona/src/suite-vendor/a-vona/modules/a-body/package.json +1 -1
  223. package/vona/src/suite-vendor/a-vona/modules/a-body/src/.metadata/index.ts +12 -12
  224. package/vona/src/suite-vendor/a-vona/modules/a-body/src/bean/interceptor.bodyReq.ts +1 -1
  225. package/vona/src/suite-vendor/a-vona/modules/a-body/src/types/bodyParser.ts +1 -1
  226. package/vona/src/suite-vendor/a-vona/modules/a-broadcast/package.json +1 -1
  227. package/vona/src/suite-vendor/a-vona/modules/a-broadcast/src/.metadata/index.ts +8 -9
  228. package/vona/src/suite-vendor/a-vona/modules/a-cache/package.json +1 -1
  229. package/vona/src/suite-vendor/a-vona/modules/a-cache/src/.metadata/index.ts +14 -14
  230. package/vona/src/suite-vendor/a-vona/modules/a-caching/package.json +1 -1
  231. package/vona/src/suite-vendor/a-vona/modules/a-caching/src/.metadata/index.ts +8 -8
  232. package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
  233. package/vona/src/suite-vendor/a-vona/modules/a-core/src/.metadata/index.ts +20 -22
  234. package/vona/src/suite-vendor/a-vona/modules/a-election/package.json +1 -1
  235. package/vona/src/suite-vendor/a-vona/modules/a-election/src/.metadata/index.ts +15 -16
  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 +19 -21
  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 +16 -18
  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 +12 -13
  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 +24 -28
  244. package/vona/src/suite-vendor/a-vona/modules/a-hmrbase/package.json +1 -1
  245. package/vona/src/suite-vendor/a-vona/modules/a-hmrbase/src/.metadata/index.ts +4 -4
  246. package/vona/src/suite-vendor/a-vona/modules/a-index/package.json +1 -1
  247. package/vona/src/suite-vendor/a-vona/modules/a-index/src/.metadata/index.ts +11 -13
  248. package/vona/src/suite-vendor/a-vona/modules/a-instance/package.json +1 -1
  249. package/vona/src/suite-vendor/a-vona/modules/a-instance/src/.metadata/index.ts +42 -35
  250. package/vona/src/suite-vendor/a-vona/modules/a-jwt/package.json +1 -1
  251. package/vona/src/suite-vendor/a-vona/modules/a-jwt/src/.metadata/index.ts +15 -17
  252. package/vona/src/suite-vendor/a-vona/modules/a-locale/package.json +1 -1
  253. package/vona/src/suite-vendor/a-vona/modules/a-locale/src/.metadata/index.ts +3 -3
  254. package/vona/src/suite-vendor/a-vona/modules/a-locale/src/main.ts +4 -1
  255. package/vona/src/suite-vendor/a-vona/modules/a-logger/package.json +1 -1
  256. package/vona/src/suite-vendor/a-vona/modules/a-logger/src/.metadata/index.ts +20 -20
  257. package/vona/src/suite-vendor/a-vona/modules/a-mail/package.json +3 -3
  258. package/vona/src/suite-vendor/a-vona/modules/a-mail/src/.metadata/index.ts +38 -30
  259. package/vona/src/suite-vendor/a-vona/modules/a-mail/src/types/config.ts +1 -0
  260. package/vona/src/suite-vendor/a-vona/modules/a-menu/package.json +1 -1
  261. package/vona/src/suite-vendor/a-vona/modules/a-menu/src/.metadata/index.ts +8 -8
  262. package/vona/src/suite-vendor/a-vona/modules/a-meta/package.json +1 -1
  263. package/vona/src/suite-vendor/a-vona/modules/a-meta/src/.metadata/index.ts +4 -4
  264. package/vona/src/suite-vendor/a-vona/modules/a-metrics/package.json +1 -1
  265. package/vona/src/suite-vendor/a-vona/modules/a-metrics/src/.metadata/index.ts +15 -18
  266. package/vona/src/suite-vendor/a-vona/modules/a-onion/package.json +1 -1
  267. package/vona/src/suite-vendor/a-vona/modules/a-onion/src/.metadata/index.ts +11 -11
  268. package/vona/src/suite-vendor/a-vona/modules/a-openapi/package.json +1 -1
  269. package/vona/src/suite-vendor/a-vona/modules/a-openapi/src/.metadata/index.ts +15 -16
  270. package/vona/src/suite-vendor/a-vona/modules/a-openapi/src/types/decorator.ts +2 -1
  271. package/vona/src/suite-vendor/a-vona/modules/a-openapi/src/types/permissions.ts +24 -1
  272. package/vona/src/suite-vendor/a-vona/modules/a-openapischema/package.json +1 -1
  273. package/vona/src/suite-vendor/a-vona/modules/a-openapischema/src/.metadata/index.ts +17 -17
  274. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/package.json +1 -1
  275. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/src/.metadata/index.ts +3 -3
  276. package/vona/src/suite-vendor/a-vona/modules/a-orm/package.json +1 -1
  277. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/.metadata/index.ts +34 -39
  278. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/bean.model/bean.model_view.ts +10 -6
  279. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/columns_.ts +1 -2
  280. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/databaseDialectBase_.ts +37 -1
  281. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/transactionFiber_.ts +8 -2
  282. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/transaction_.ts +5 -8
  283. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/columns.ts +1 -0
  284. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/package.json +1 -1
  285. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/.metadata/index.ts +8 -8
  286. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/bean/databaseDialect.mysql.ts +28 -0
  287. package/vona/src/suite-vendor/a-vona/modules/a-ormutils/package.json +1 -1
  288. package/vona/src/suite-vendor/a-vona/modules/a-ormutils/src/.metadata/index.ts +4 -4
  289. package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +4 -1
  290. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/.metadata/index.ts +35 -22
  291. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +61 -8
  292. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/event.retrievePermissionAction.ts +2 -2
  293. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/summerCache.permissionActionByUser.ts +24 -0
  294. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/dto/permissions.tsx +18 -1
  295. package/vona/src/suite-vendor/a-vona/modules/a-permission/test/permission.test.ts +340 -0
  296. package/vona/src/suite-vendor/a-vona/modules/a-play/package.json +1 -1
  297. package/vona/src/suite-vendor/a-vona/modules/a-play/src/.metadata/index.ts +13 -13
  298. package/vona/src/suite-vendor/a-vona/modules/a-printtip/package.json +1 -1
  299. package/vona/src/suite-vendor/a-vona/modules/a-printtip/src/.metadata/index.ts +11 -12
  300. package/vona/src/suite-vendor/a-vona/modules/a-queue/package.json +1 -1
  301. package/vona/src/suite-vendor/a-vona/modules/a-queue/src/.metadata/index.ts +15 -17
  302. package/vona/src/suite-vendor/a-vona/modules/a-ratelimit/package.json +1 -1
  303. package/vona/src/suite-vendor/a-vona/modules/a-ratelimit/src/.metadata/index.ts +0 -1
  304. package/vona/src/suite-vendor/a-vona/modules/a-redis/package.json +1 -1
  305. package/vona/src/suite-vendor/a-vona/modules/a-redis/src/.metadata/index.ts +12 -13
  306. package/vona/src/suite-vendor/a-vona/modules/a-redlock/package.json +1 -1
  307. package/vona/src/suite-vendor/a-vona/modules/a-redlock/src/.metadata/index.ts +7 -8
  308. package/vona/src/suite-vendor/a-vona/modules/a-retryable/package.json +1 -1
  309. package/vona/src/suite-vendor/a-vona/modules/a-retryable/src/.metadata/index.ts +8 -8
  310. package/vona/src/suite-vendor/a-vona/modules/a-runtime/package.json +1 -1
  311. package/vona/src/suite-vendor/a-vona/modules/a-runtime/src/.metadata/index.ts +12 -13
  312. package/vona/src/suite-vendor/a-vona/modules/a-schedule/package.json +1 -1
  313. package/vona/src/suite-vendor/a-vona/modules/a-schedule/src/.metadata/index.ts +23 -26
  314. package/vona/src/suite-vendor/a-vona/modules/a-security/package.json +1 -1
  315. package/vona/src/suite-vendor/a-vona/modules/a-security/src/.metadata/index.ts +12 -12
  316. package/vona/src/suite-vendor/a-vona/modules/a-security/src/bean/bean.security.ts +78 -0
  317. package/vona/src/suite-vendor/a-vona/modules/a-security/src/bean/middlewareSystem.cors.ts +4 -2
  318. package/vona/src/suite-vendor/a-vona/modules/a-security/src/index.ts +1 -0
  319. package/vona/src/suite-vendor/a-vona/modules/a-security/src/types/index.ts +7 -0
  320. package/vona/src/suite-vendor/a-vona/modules/a-security/test/origin.test.ts +178 -0
  321. package/vona/src/suite-vendor/a-vona/modules/a-serialization/package.json +1 -1
  322. package/vona/src/suite-vendor/a-vona/modules/a-serialization/src/.metadata/index.ts +16 -16
  323. package/vona/src/suite-vendor/a-vona/modules/a-startup/package.json +1 -1
  324. package/vona/src/suite-vendor/a-vona/modules/a-startup/src/.metadata/index.ts +19 -22
  325. package/vona/src/suite-vendor/a-vona/modules/a-static/package.json +1 -1
  326. package/vona/src/suite-vendor/a-vona/modules/a-static/src/.metadata/index.ts +13 -14
  327. package/vona/src/suite-vendor/a-vona/modules/a-summer/package.json +1 -1
  328. package/vona/src/suite-vendor/a-vona/modules/a-summer/src/.metadata/index.ts +10 -10
  329. package/vona/src/suite-vendor/a-vona/modules/a-swagger/package.json +1 -1
  330. package/vona/src/suite-vendor/a-vona/modules/a-swagger/src/.metadata/index.ts +16 -17
  331. package/vona/src/suite-vendor/a-vona/modules/a-telemetry/package.json +1 -1
  332. package/vona/src/suite-vendor/a-vona/modules/a-telemetry/src/.metadata/index.ts +15 -16
  333. package/vona/src/suite-vendor/a-vona/modules/a-upload/package.json +1 -1
  334. package/vona/src/suite-vendor/a-vona/modules/a-upload/src/.metadata/index.ts +8 -8
  335. package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
  336. package/vona/src/suite-vendor/a-vona/modules/a-user/src/.metadata/index.ts +26 -35
  337. package/vona/src/suite-vendor/a-vona/modules/a-user/src/bean/guard.passport.ts +4 -2
  338. package/vona/src/suite-vendor/a-vona/modules/a-user/src/bean/guard.roleName.ts +5 -23
  339. package/vona/src/suite-vendor/a-vona/modules/a-user/src/lib/passport.ts +17 -2
  340. package/vona/src/suite-vendor/a-vona/modules/a-validation/package.json +1 -1
  341. package/vona/src/suite-vendor/a-vona/modules/a-validation/src/.metadata/index.ts +7 -7
  342. package/vona/src/suite-vendor/a-vona/modules/a-version/package.json +1 -1
  343. package/vona/src/suite-vendor/a-vona/modules/a-version/src/.metadata/index.ts +62 -37
  344. package/vona/src/suite-vendor/a-vona/modules/a-vona/package.json +1 -2
  345. package/vona/src/suite-vendor/a-vona/modules/a-vona/src/.metadata/index.ts +4 -4
  346. package/vona/src/suite-vendor/a-vona/modules/a-web/package.json +1 -1
  347. package/vona/src/suite-vendor/a-vona/modules/a-web/src/.metadata/index.ts +27 -30
  348. package/vona/src/suite-vendor/a-vona/modules/a-web/src/lib/decorator/arguments.ts +5 -0
  349. package/vona/src/suite-vendor/a-vona/modules/a-web/src/lib/decorator/pipesArgument.ts +3 -1
  350. package/vona/src/suite-vendor/a-vona/modules/a-web/src/lib/middleware/extractValue.ts +5 -0
  351. package/vona/src/suite-vendor/a-vona/modules/a-web/src/types/controller.ts +3 -0
  352. package/vona/src/suite-vendor/a-vona/modules/a-worker/package.json +1 -1
  353. package/vona/src/suite-vendor/a-vona/modules/a-worker/src/.metadata/index.ts +15 -15
  354. package/vona/src/suite-vendor/a-vona/modules/a-zod/package.json +1 -1
  355. package/vona/src/suite-vendor/a-vona/modules/a-zod/src/.metadata/index.ts +4 -4
  356. package/vona/src/suite-vendor/a-vona/package.json +2 -3
  357. package/vona/src/suite-vendor/a-vona/tsconfig.json +0 -3
  358. package/zova/env/.env.admin +1 -0
  359. package/zova/env/.env.ssr.web +0 -1
  360. package/zova/env/.env.web +1 -0
  361. package/zova/package.original.json +1 -1
  362. package/zova/packages-cli/cli/package.json +2 -2
  363. package/zova/packages-cli/cli-set-front/package.json +1 -1
  364. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.openapi.generate.ts +15 -4
  365. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.tools.metadata.ts +1 -0
  366. package/zova/packages-utils/zova-jsx/package.json +2 -2
  367. package/zova/packages-zova/zova/package.json +3 -3
  368. package/zova/packages-zova/zova-core/package.json +1 -1
  369. package/zova/packages-zova/zova-core/src/core/component/locale.ts +10 -3
  370. package/zova/packages-zova/zova-core/src/core/sys/util.ts +6 -0
  371. package/zova/pnpm-lock.yaml +94 -25
  372. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/.metadata/index.ts +21 -21
  373. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/schemas.ts +92 -46
  374. package/zova/src/suite/a-commerce/modules/commerce-catalog/src/api/openapi/types.ts +834 -499
  375. package/zova/src/suite/a-commerce/modules/commerce-member/src/.metadata/index.ts +22 -22
  376. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/schemas.ts +104 -50
  377. package/zova/src/suite/a-commerce/modules/commerce-member/src/api/openapi/types.ts +1202 -667
  378. package/zova/src/suite/a-commerce/modules/commerce-payment/src/.metadata/index.ts +5 -5
  379. package/zova/src/suite/a-commerce/modules/commerce-promotion/src/.metadata/index.ts +18 -18
  380. package/zova/src/suite/a-commerce/modules/commerce-promotion/src/api/openapi/schemas.ts +136 -62
  381. package/zova/src/suite/a-commerce/modules/commerce-promotion/src/api/openapi/types.ts +1564 -874
  382. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/.metadata/index.ts +24 -24
  383. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/schemas.ts +413 -59
  384. package/zova/src/suite/a-commerce/modules/commerce-siteadmin/src/api/openapi/types.ts +6290 -1946
  385. package/zova/src/suite/a-commerce/modules/commerce-siteweb/src/.metadata/index.ts +5 -5
  386. package/zova/src/suite/a-commerce/modules/commerce-trade/src/.metadata/index.ts +29 -29
  387. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/schemas.ts +112 -58
  388. package/zova/src/suite/a-commerce/modules/commerce-trade/src/api/openapi/types.ts +980 -721
  389. package/zova/src/suite/a-commerce/modules/commerce-trade/src/bean/tableCell.actionRefund.tsx +1 -1
  390. package/zova/src/suite/a-commerce/modules/commerce-trade/src/bean/tableCell.actionShip.tsx +1 -1
  391. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/payment/controller.tsx +1 -3
  392. package/zova/src/suite/a-demo/modules/demo-basic/src/.metadata/index.ts +23 -23
  393. package/zova/src/suite/a-demo/modules/demo-todo/src/.metadata/index.ts +17 -17
  394. package/zova/src/suite/a-devui/modules/devui-adapter/src/.metadata/index.ts +10 -10
  395. package/zova/src/suite/a-home/modules/home-api/cli/openapi.config.ts +1 -0
  396. package/zova/src/suite/a-home/modules/home-api/mock/passport.fake.ts +1 -1
  397. package/zova/src/suite/a-home/modules/home-api/src/.metadata/index.ts +61 -31
  398. package/zova/src/suite/a-home/modules/home-api/src/api/homeUserAccount.ts +171 -0
  399. package/zova/src/suite/a-home/modules/home-api/src/api/openapi/schemas.ts +96 -50
  400. package/zova/src/suite/a-home/modules/home-api/src/api/openapi/types.ts +857 -504
  401. package/zova/src/suite/a-home/modules/home-api/src/apiSchema/homeUserAccount.ts +62 -0
  402. package/zova/src/suite/a-home/modules/home-base/assets/img/avatar_user.png +0 -0
  403. package/zova/src/suite/a-home/modules/home-base/src/.metadata/index.ts +16 -16
  404. package/zova/src/suite/a-home/modules/home-base/src/config/config.ts +5 -0
  405. package/zova/src/suite/a-home/modules/home-base/src/service/routerGuards.ts +1 -8
  406. package/zova/src/suite/a-home/modules/home-icon/src/.metadata/index.ts +5 -5
  407. package/zova/src/suite/a-home/modules/home-indexadmin/src/.metadata/index.ts +11 -11
  408. package/zova/src/suite/a-home/modules/home-indexweb/src/.metadata/index.ts +9 -9
  409. package/zova/src/suite/a-home/modules/home-layoutadmin/src/.metadata/index.ts +19 -19
  410. package/zova/src/suite/a-home/modules/home-layoutadmin/src/component/layoutAdmin/render.user.tsx +19 -2
  411. package/zova/src/suite/a-home/modules/home-layoutadmin/src/config/locale/en-us.ts +1 -0
  412. package/zova/src/suite/a-home/modules/home-layoutadmin/src/config/locale/zh-cn.ts +1 -0
  413. package/zova/src/suite/a-home/modules/home-layoutempty/src/.metadata/index.ts +7 -7
  414. package/zova/src/suite/a-home/modules/home-layoutweb/src/.metadata/component/layoutWeb.ts +1 -0
  415. package/zova/src/suite/a-home/modules/home-layoutweb/src/.metadata/index.ts +23 -15
  416. package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.header.tsx +1 -0
  417. package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.tsx +4 -0
  418. package/zova/src/suite/a-home/modules/home-layoutweb/src/component/layoutWeb/render.user.tsx +68 -0
  419. package/zova/src/suite/a-home/modules/home-layoutweb/src/config/locale/en-us.ts +11 -8
  420. package/zova/src/suite/a-home/modules/home-layoutweb/src/config/locale/zh-cn.ts +11 -8
  421. package/zova/src/suite/a-home/modules/home-login/src/.metadata/index.ts +38 -18
  422. package/zova/src/suite/a-home/modules/home-login/src/.metadata/page/passwordResetRequest.ts +9 -0
  423. package/zova/src/suite/a-home/modules/home-login/src/.metadata/page/register.ts +5 -0
  424. package/zova/src/suite/a-home/modules/home-login/src/config/locale/en-us.ts +14 -0
  425. package/zova/src/suite/a-home/modules/home-login/src/config/locale/zh-cn.ts +12 -0
  426. package/zova/src/suite/a-home/modules/home-login/src/page/login/controller.tsx +10 -0
  427. package/zova/src/suite/a-home/modules/home-login/src/page/login/render.tsx +14 -0
  428. package/zova/src/suite/a-home/modules/home-login/src/page/passwordResetRequest/controller.tsx +130 -0
  429. package/zova/src/suite/a-home/modules/home-login/src/page/register/controller.tsx +124 -0
  430. package/zova/src/suite/a-home/modules/home-login/src/routes.ts +20 -0
  431. package/zova/src/suite/a-home/modules/home-passport/src/.metadata/index.ts +8 -8
  432. package/zova/src/suite/a-home/modules/home-passport/src/lib/permissionActionMatcher.ts +37 -0
  433. package/zova/src/suite/a-home/modules/home-passport/src/model/passport.ts +32 -12
  434. package/zova/src/suite/a-home/modules/home-passport/test/lib/permissionActionMatcher.test.ts +80 -0
  435. package/zova/src/suite/a-home/modules/home-theme/src/.metadata/index.ts +13 -13
  436. package/zova/src/suite/a-home/modules/home-user/package.json +60 -0
  437. package/zova/src/suite/a-home/modules/home-user/src/.metadata/index.ts +168 -0
  438. package/zova/src/suite/a-home/modules/home-user/src/.metadata/locales.ts +7 -0
  439. package/zova/src/suite/a-home/modules/home-user/src/.metadata/page/account.ts +5 -0
  440. package/zova/src/suite/a-home/modules/home-user/src/.metadata/page/activation.ts +16 -0
  441. package/zova/src/suite/a-home/modules/home-user/src/.metadata/page/passwordReset.ts +16 -0
  442. package/zova/src/suite/a-home/modules/home-user/src/.metadata/page/passwordSet.ts +16 -0
  443. package/zova/src/suite/a-home/modules/home-user/src/.metadata/this.ts +2 -0
  444. package/zova/src/suite/a-home/modules/home-user/src/config/locale/en-us.ts +52 -0
  445. package/zova/src/suite/a-home/modules/home-user/src/config/locale/zh-cn.ts +49 -0
  446. package/zova/src/suite/a-home/modules/home-user/src/index.ts +2 -0
  447. package/zova/src/suite/a-home/modules/home-user/src/model/account.ts +126 -0
  448. package/zova/src/suite/a-home/modules/home-user/src/page/account/controller.tsx +357 -0
  449. package/zova/src/suite/a-home/modules/home-user/src/page/activation/controller.tsx +83 -0
  450. package/zova/src/suite/a-home/modules/home-user/src/page/passwordReset/controller.tsx +138 -0
  451. package/zova/src/suite/a-home/modules/home-user/src/page/passwordSet/controller.tsx +138 -0
  452. package/zova/src/suite/a-home/modules/home-user/src/routes.ts +44 -0
  453. package/zova/src/suite/a-home/modules/home-user/tsconfig.build.json +13 -0
  454. package/zova/src/suite/a-home/modules/home-user/tsconfig.json +5 -0
  455. package/zova/src/suite/a-home/package.json +2 -1
  456. package/zova/src/suite/a-training/modules/training-student/src/.metadata/index.ts +25 -25
  457. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/schemas.ts +136 -62
  458. package/zova/src/suite/a-training/modules/training-student/src/api/openapi/types.ts +1601 -884
  459. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionDeleteForce.tsx +1 -1
  460. package/zova/src/suite/cabloy-basic/modules/basic-adapter/src/.metadata/index.ts +4 -4
  461. package/zova/src/suite/cabloy-basic/modules/basic-app/src/.metadata/index.ts +12 -12
  462. package/zova/src/suite/cabloy-basic/modules/basic-captcha/src/.metadata/index.ts +8 -8
  463. package/zova/src/suite/cabloy-basic/modules/basic-commands/src/.metadata/index.ts +9 -9
  464. package/zova/src/suite/cabloy-basic/modules/basic-commandssync/src/.metadata/index.ts +9 -9
  465. package/zova/src/suite/cabloy-basic/modules/basic-currency/src/.metadata/index.ts +13 -13
  466. package/zova/src/suite/cabloy-basic/modules/basic-date/src/.metadata/index.ts +13 -13
  467. package/zova/src/suite/cabloy-basic/modules/basic-details/src/.metadata/index.ts +21 -21
  468. package/zova/src/suite/cabloy-basic/modules/basic-file/src/.metadata/index.ts +26 -26
  469. package/zova/src/suite/cabloy-basic/modules/basic-file/src/api/openapi/schemas.ts +417 -59
  470. package/zova/src/suite/cabloy-basic/modules/basic-file/src/api/openapi/types.ts +6316 -1926
  471. package/zova/src/suite/cabloy-basic/modules/basic-form/src/.metadata/index.ts +12 -12
  472. package/zova/src/suite/cabloy-basic/modules/basic-image/src/.metadata/component/imageUploader.ts +31 -0
  473. package/zova/src/suite/cabloy-basic/modules/basic-image/src/.metadata/index.ts +39 -26
  474. package/zova/src/suite/cabloy-basic/modules/basic-image/src/api/openapi/schemas.ts +417 -59
  475. package/zova/src/suite/cabloy-basic/modules/basic-image/src/api/openapi/types.ts +6316 -1926
  476. package/zova/src/suite/cabloy-basic/modules/basic-image/src/component/formFieldImage/controller.tsx +194 -514
  477. package/zova/src/suite/cabloy-basic/modules/basic-image/src/component/imageUploader/controller.tsx +386 -0
  478. package/zova/src/suite/cabloy-basic/modules/basic-image/src/config/locale/en-us.ts +1 -0
  479. package/zova/src/suite/cabloy-basic/modules/basic-image/src/config/locale/zh-cn.ts +1 -0
  480. package/zova/src/suite/cabloy-basic/modules/basic-image/src/lib/imageTransform.tsx +296 -0
  481. package/zova/src/suite/cabloy-basic/modules/basic-image/src/lib/index.ts +1 -0
  482. package/zova/src/suite/cabloy-basic/modules/basic-input/src/.metadata/index.ts +9 -9
  483. package/zova/src/suite/cabloy-basic/modules/basic-metrics/src/.metadata/index.ts +19 -19
  484. package/zova/src/suite/cabloy-basic/modules/basic-page/src/.metadata/index.ts +8 -8
  485. package/zova/src/suite/cabloy-basic/modules/basic-pageentry/src/.metadata/index.ts +8 -8
  486. package/zova/src/suite/cabloy-basic/modules/basic-pageentry/src/component/blockToolbarRow/controller.tsx +9 -2
  487. package/zova/src/suite/cabloy-basic/modules/basic-resource/src/.metadata/index.ts +13 -13
  488. package/zova/src/suite/cabloy-basic/modules/basic-select/src/.metadata/index.ts +13 -13
  489. package/zova/src/suite/cabloy-basic/modules/basic-select/src/bean/tableCell.select.tsx +2 -3
  490. package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +2 -3
  491. package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/select/controller.tsx +7 -7
  492. package/zova/src/suite/cabloy-basic/modules/basic-select/src/lib/utils.ts +5 -0
  493. package/zova/src/suite/cabloy-basic/modules/basic-select/test/lib/utils.test.ts +28 -0
  494. package/zova/src/suite/cabloy-basic/modules/basic-table/src/.metadata/index.ts +16 -16
  495. package/zova/src/suite/cabloy-basic/modules/basic-table/src/bean/tableCell.actionOperationsRow.tsx +3 -1
  496. package/zova/src/suite/cabloy-basic/modules/basic-text/src/.metadata/index.ts +13 -13
  497. package/zova/src/suite-vendor/a-cabloy/modules/a-rbac/package.json +52 -0
  498. package/zova/src/suite-vendor/a-cabloy/modules/a-rbac/src/.metadata/index.ts +26 -0
  499. package/zova/src/suite-vendor/a-cabloy/modules/a-rbac/src/.metadata/this.ts +2 -0
  500. package/zova/src/suite-vendor/a-cabloy/modules/a-rbac/src/index.ts +1 -0
  501. package/zova/src/suite-vendor/a-cabloy/modules/a-rbac/tsconfig.build.json +13 -0
  502. package/zova/src/suite-vendor/a-cabloy/modules/a-rbac/tsconfig.json +5 -0
  503. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  504. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/.metadata/index.ts +15 -15
  505. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/lib/deleteRequest.ts +12 -0
  506. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +12 -6
  507. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/test/lib/deleteRequest.test.ts +37 -0
  508. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/test/model/resource.types.ts +24 -0
  509. package/zova/src/suite-vendor/a-cabloy/package.json +3 -2
  510. package/zova/src/suite-vendor/a-pay/modules/a-pay/cli/openapi.config.ts +1 -1
  511. package/zova/src/suite-vendor/a-pay/modules/a-pay/package.json +1 -1
  512. package/zova/src/suite-vendor/a-pay/modules/a-pay/src/.metadata/index.ts +43 -43
  513. package/zova/src/suite-vendor/a-pay/modules/a-pay/src/api/openapi/schemas.ts +120 -58
  514. package/zova/src/suite-vendor/a-pay/modules/a-pay/src/api/openapi/types.ts +1408 -938
  515. package/zova/src/suite-vendor/a-pay/modules/a-pay/src/api/payPaymentSession.ts +74 -0
  516. package/zova/src/suite-vendor/a-pay/modules/a-pay/src/apiSchema/payPaymentSession.ts +25 -0
  517. package/zova/src/suite-vendor/a-pay/modules/a-pay/src/model/paymentSession.ts +3 -3
  518. package/zova/src/suite-vendor/a-pay/modules/pay-mock/cli/openapi.config.ts +1 -1
  519. package/zova/src/suite-vendor/a-pay/modules/pay-mock/package.json +1 -1
  520. package/zova/src/suite-vendor/a-pay/modules/pay-mock/src/.metadata/index.ts +34 -34
  521. package/zova/src/suite-vendor/a-pay/modules/pay-mock/src/api/openapi/schemas.ts +140 -66
  522. package/zova/src/suite-vendor/a-pay/modules/pay-mock/src/api/openapi/types.ts +1621 -891
  523. package/zova/src/suite-vendor/a-pay/modules/pay-mock/src/api/payMockMockPayment.ts +34 -0
  524. package/zova/src/suite-vendor/a-pay/modules/pay-mock/src/apiSchema/payMockMockPayment.ts +13 -0
  525. package/zova/src/suite-vendor/a-pay/modules/pay-mock/src/model/payMockPayment.ts +3 -3
  526. package/zova/src/suite-vendor/a-pay/modules/pay-paypal/package.json +1 -1
  527. package/zova/src/suite-vendor/a-pay/modules/pay-paypal/src/.metadata/index.ts +4 -4
  528. package/zova/src/suite-vendor/a-pay/modules/pay-stripe/package.json +1 -1
  529. package/zova/src/suite-vendor/a-pay/modules/pay-stripe/src/.metadata/index.ts +4 -4
  530. package/zova/src/suite-vendor/a-pay/package.json +5 -5
  531. package/zova/src/suite-vendor/a-zova/modules/a-api/package.json +1 -1
  532. package/zova/src/suite-vendor/a-zova/modules/a-api/src/.metadata/index.ts +7 -7
  533. package/zova/src/suite-vendor/a-zova/modules/a-app/package.json +1 -1
  534. package/zova/src/suite-vendor/a-zova/modules/a-app/src/.metadata/index.ts +8 -8
  535. package/zova/src/suite-vendor/a-zova/modules/a-bean/package.json +1 -1
  536. package/zova/src/suite-vendor/a-zova/modules/a-bean/src/.metadata/index.ts +15 -15
  537. package/zova/src/suite-vendor/a-zova/modules/a-behavior/package.json +1 -1
  538. package/zova/src/suite-vendor/a-zova/modules/a-behavior/src/.metadata/index.ts +25 -25
  539. package/zova/src/suite-vendor/a-zova/modules/a-behaviors/package.json +1 -1
  540. package/zova/src/suite-vendor/a-zova/modules/a-behaviors/src/.metadata/index.ts +9 -9
  541. package/zova/src/suite-vendor/a-zova/modules/a-boundary/package.json +1 -1
  542. package/zova/src/suite-vendor/a-zova/modules/a-boundary/src/.metadata/index.ts +5 -5
  543. package/zova/src/suite-vendor/a-zova/modules/a-command/package.json +1 -1
  544. package/zova/src/suite-vendor/a-zova/modules/a-command/src/.metadata/index.ts +5 -5
  545. package/zova/src/suite-vendor/a-zova/modules/a-fetch/package.json +1 -1
  546. package/zova/src/suite-vendor/a-zova/modules/a-fetch/src/.metadata/index.ts +14 -14
  547. package/zova/src/suite-vendor/a-zova/modules/a-form/package.json +1 -1
  548. package/zova/src/suite-vendor/a-zova/modules/a-form/src/.metadata/index.ts +12 -12
  549. package/zova/src/suite-vendor/a-zova/modules/a-icon/package.json +1 -1
  550. package/zova/src/suite-vendor/a-zova/modules/a-icon/src/.metadata/index.ts +18 -18
  551. package/zova/src/suite-vendor/a-zova/modules/a-interceptor/package.json +1 -1
  552. package/zova/src/suite-vendor/a-zova/modules/a-interceptor/src/.metadata/index.ts +8 -8
  553. package/zova/src/suite-vendor/a-zova/modules/a-logger/package.json +1 -1
  554. package/zova/src/suite-vendor/a-zova/modules/a-logger/src/.metadata/index.ts +9 -9
  555. package/zova/src/suite-vendor/a-zova/modules/a-meta/package.json +1 -1
  556. package/zova/src/suite-vendor/a-zova/modules/a-meta/src/.metadata/index.ts +5 -5
  557. package/zova/src/suite-vendor/a-zova/modules/a-model/package.json +1 -1
  558. package/zova/src/suite-vendor/a-zova/modules/a-model/src/.metadata/index.ts +12 -12
  559. package/zova/src/suite-vendor/a-zova/modules/a-openapi/package.json +3 -2
  560. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/.metadata/index.ts +13 -13
  561. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/monkey.ts +16 -27
  562. package/zova/src/suite-vendor/a-zova/modules/a-openapi/src/types/permissions.ts +18 -1
  563. package/zova/src/suite-vendor/a-zova/modules/a-router/package.json +1 -1
  564. package/zova/src/suite-vendor/a-zova/modules/a-router/src/.metadata/index.ts +27 -27
  565. package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkey.ts +9 -6
  566. package/zova/src/suite-vendor/a-zova/modules/a-router/src/monkeySys.ts +15 -5
  567. package/zova/src/suite-vendor/a-zova/modules/a-router/src/types/router.ts +2 -2
  568. package/zova/src/suite-vendor/a-zova/modules/a-routerstack/package.json +1 -1
  569. package/zova/src/suite-vendor/a-zova/modules/a-routerstack/src/.metadata/index.ts +13 -13
  570. package/zova/src/suite-vendor/a-zova/modules/a-routertabs/package.json +1 -1
  571. package/zova/src/suite-vendor/a-zova/modules/a-routertabs/src/.metadata/index.ts +13 -13
  572. package/zova/src/suite-vendor/a-zova/modules/a-ssr/package.json +1 -1
  573. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/.metadata/index.ts +9 -9
  574. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/ssr.ts +15 -4
  575. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/ssrNavigation.ts +40 -0
  576. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/lib/ssrProfile.ts +6 -1
  577. package/zova/src/suite-vendor/a-zova/modules/a-ssr/src/monkey.ts +20 -6
  578. package/zova/src/suite-vendor/a-zova/modules/a-ssr/test/lib/ssrNavigation.test.ts +69 -0
  579. package/zova/src/suite-vendor/a-zova/modules/a-ssr/test/lib/ssrProfile.test.ts +25 -6
  580. package/zova/src/suite-vendor/a-zova/modules/a-ssrhmr/package.json +1 -1
  581. package/zova/src/suite-vendor/a-zova/modules/a-ssrhmr/src/.metadata/index.ts +4 -4
  582. package/zova/src/suite-vendor/a-zova/modules/a-ssrserver/package.json +1 -1
  583. package/zova/src/suite-vendor/a-zova/modules/a-ssrserver/src/.metadata/index.ts +10 -10
  584. package/zova/src/suite-vendor/a-zova/modules/a-ssrserver/src/service/ssrHandler.ts +1 -2
  585. package/zova/src/suite-vendor/a-zova/modules/a-style/package.json +1 -1
  586. package/zova/src/suite-vendor/a-zova/modules/a-style/src/.metadata/index.ts +9 -9
  587. package/zova/src/suite-vendor/a-zova/modules/a-style/src/bean/bean.theme.ts +2 -2
  588. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
  589. package/zova/src/suite-vendor/a-zova/modules/a-table/src/.metadata/index.ts +12 -12
  590. package/zova/src/suite-vendor/a-zova/modules/a-zod/package.json +1 -1
  591. package/zova/src/suite-vendor/a-zova/modules/a-zod/src/.metadata/index.ts +9 -9
  592. package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +2 -2
  593. package/zova/src/suite-vendor/a-zova/modules/a-zova/src/.metadata/index.ts +5 -5
  594. package/zova/src/suite-vendor/a-zova/package.json +26 -26
  595. package/vona/src/suite/a-home/modules/home-user/src/bean/eventListener.emailConfirmCallback.ts +0 -32
  596. package/vona/src/suite/a-home/modules/home-user/src/bean/eventListener.passwordResetCallback.ts +0 -30
  597. package/vona/src/suite/a-home/modules/home-user/src/bean/eventListener.register.ts +0 -27
  598. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/.metadata/index.ts +0 -207
  599. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/.metadata/locales.ts +0 -18
  600. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/.metadata/this.ts +0 -2
  601. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/bean/bean.mailConfirm.ts +0 -63
  602. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/bean/cacheRedis.emailConfirm.ts +0 -17
  603. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/bean/event.emailConfirmCallback.ts +0 -13
  604. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/bean/event.passwordResetCallback.ts +0 -13
  605. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/config/locale/en-us.ts +0 -13
  606. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/config/locale/mail/en-us.ts +0 -29
  607. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/config/locale/mail/zh-cn.ts +0 -29
  608. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/config/locale/zh-cn.ts +0 -13
  609. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/controller/mail.ts +0 -34
  610. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/index.ts +0 -2
  611. package/zova/src/suite-vendor/a-pay/modules/a-pay/src/api/paymentSession.ts +0 -74
  612. package/zova/src/suite-vendor/a-pay/modules/a-pay/src/apiSchema/paymentSession.ts +0 -25
  613. package/zova/src/suite-vendor/a-pay/modules/pay-mock/src/api/payMockPayment.ts +0 -34
  614. package/zova/src/suite-vendor/a-pay/modules/pay-mock/src/apiSchema/payMockPayment.ts +0 -13
  615. /package/vona/patches/{zova-core@5.1.84.patch → zova-core@5.1.85.patch} +0 -0
  616. /package/vona/src/suite-vendor/{a-vona/modules/a-mailconfirm → a-cabloy/modules/a-rbac}/tsconfig.build.json +0 -0
  617. /package/vona/src/suite-vendor/{a-vona/modules/a-mailconfirm → a-cabloy/modules/a-rbac}/tsconfig.json +0 -0
@@ -0,0 +1,483 @@
1
+ ---
2
+ title: 'Stop Turning Vue3 into a Tangle: From Scattered State to Object Collaboration with Zova'
3
+ titleZh: 不必把 Vue 写成“麻花”:从状态碎片到对象协作,重新理解 Zova 的前端心智模型
4
+ subtitle: 'Vue 3 remains the reactive foundation. Zova addresses a different question: how state, behavior, dependencies, and lifecycle gain clear ownership as an application grows.'
5
+ summary: Starting from the familiar experience of excessive composable destructuring, unclear state ownership, and multiple overlapping state mechanisms in Vue projects, this beginner-friendly article introduces how Cabloy/Zova combines Vue 3 reactivity, TSX, and Angular-style dependency injection into one collaborative model built around Controllers, Beans, and Models.
6
+ tags:
7
+ - Vue 3
8
+ - Zova
9
+ - Cabloy
10
+ - Object-Oriented Programming
11
+ - Dependency Injection
12
+ - State Management
13
+ - Frontend Architecture
14
+ slug: vue-object-oriented-zova-beginner-mental-model
15
+ cover: ./cover-en-v1.png
16
+ date: 2026-08-02
17
+ ---
18
+
19
+ # Stop Turning Vue3 into a Tangle: From Scattered State to Object Collaboration with Zova
20
+
21
+ > Vue 3 remains the reactive foundation. Zova addresses a different question: how state, behavior, dependencies, and lifecycle gain clear ownership as an application grows.
22
+
23
+ Vue 3 has been remarkably successful. It is lightweight, flexible, and built on an elegant reactive system. React and Angular continue to evolve as well, which naturally leads many developers to ask: what will help Vue remain compelling in the future?
24
+
25
+ One promising direction is not simply another round of debate about which state-management library to choose. It is a more fundamental question:
26
+
27
+ > As a real application becomes more complex, how should we organize state, behavior, and the relationships between them?
28
+
29
+ Across many Vue 3 projects, I keep seeing a familiar pattern:
30
+
31
+ ```ts
32
+ const { list, loading, fetchList, createItem, removeItem } = useTodo();
33
+ ```
34
+
35
+ At first, this is wonderfully concise. But as a page and its business logic grow, friction starts to appear:
36
+
37
+ - One component consumes several composables, and the destructured variables keep accumulating.
38
+ - You have to scan up and down the file to remember where `list`, `loading`, `submit`, or `reset` came from.
39
+ - Names begin to collide, so prefixes spread everywhere: `userList`, `orderList`, `todoList`.
40
+ - To avoid losing reactivity through destructuring, you need to remember rules around `toRefs`, `storeToRefs`, `computed`, and related helpers.
41
+ - Pinia, `provide/inject`, composables, and component-local `ref` or `reactive` each solve part of the problem—but the developer must assemble the overall architecture.
42
+
43
+ This is not an argument against destructuring, nor is it an argument that Vue 3's Composition API is flawed. On the contrary: it is very powerful.
44
+
45
+ The real problem is this: **as business complexity rises, code can drift from collaboration between objects toward assembly from individual variables.**
46
+
47
+ Once variables are scattered, ownership of state, boundaries of behavior, lifecycle, and dependencies can become scattered too.
48
+
49
+ That is the problem Cabloy/Zova aims to address.
50
+
51
+ ---
52
+
53
+ ## Vue reactivity is excellent—but application code should not become a pile of variables
54
+
55
+ First, an important clarification:
56
+
57
+ > Vue is not a framework that must be written in an object-oriented style, and the Vue 3 Composition API is not an incorrect architectural approach.
58
+
59
+ Vue 3 gives us an excellent reactive foundation. You can organize code with functions or with objects. You can use `ref` and `reactive` directly, or encapsulate them in composables, stores, or other abstractions.
60
+
61
+ The question is not whether functional or object-oriented programming is inherently more advanced. The question is:
62
+
63
+ > Does your business state and business behavior have clear, stable, and understandable ownership?
64
+
65
+ A typical todo page may need:
66
+
67
+ - a list query, loading state, and error state;
68
+ - create, update, and delete actions;
69
+ - query caching and a refresh policy after mutations;
70
+ - page input state;
71
+ - page-rendering logic;
72
+ - perhaps permissions, route parameters, and state shared across pages.
73
+
74
+ If all of these are continually destructured from separate composables, the page can eventually look like this:
75
+
76
+ ```ts
77
+ const { todos, loading, refresh } = useTodos();
78
+ const { createTodo, creating } = useCreateTodo();
79
+ const { removeTodo, removing } = useRemoveTodo();
80
+ const { keyword, resetKeyword } = useSearch();
81
+ const { currentUser } = useAuth();
82
+ ```
83
+
84
+ Every line is reasonable in isolation. Together, though, the structure of the page becomes much less obvious.
85
+
86
+ - Who owns the todo list?
87
+ - Who refreshes the list after a successful create?
88
+ - Is `loading` for the query, or for the create operation?
89
+ - Which state should survive across pages, and which belongs only to this page?
90
+ - When another page needs the todo list, should you duplicate logic, extract a shared composable, or create a store?
91
+
92
+ These are not syntax problems. They are **architectural questions about state and behavior**.
93
+
94
+ ---
95
+
96
+ ## A different perspective: put state and behavior back into objects
97
+
98
+ Zova does not try to replace Vue 3's reactive capabilities.
99
+
100
+ It does something else:
101
+
102
+ > On top of Vue 3 reactivity, Zova introduces Controllers, Beans, Models, and dependency injection so that state, behavior, lifecycle, and dependencies can again be organized as collaborating objects.
103
+
104
+ Its three central characteristics can be summarized as:
105
+
106
+ > **Vue 3 reactivity + TSX rendering + Angular-style dependency injection**
107
+
108
+ This is not a matter of transplanting Angular or React into Vue. It combines what each approach does well:
109
+
110
+ | Capability | Zova's approach |
111
+ | ------------------------------------------------ | -------------------------- |
112
+ | Reactive foundation | Vue 3 |
113
+ | Rendering expression | TSX |
114
+ | Object organization and dependency collaboration | IoC / dependency injection |
115
+ | Page logic | Controller |
116
+ | Reusable business state | Model |
117
+ | Extracted business capabilities | Service / Bean |
118
+
119
+ Instead of first asking, “Which composable should contain this logic?”, a developer can ask a more natural question:
120
+
121
+ > Who should own this state and behavior?
122
+
123
+ ---
124
+
125
+ ## A page is an object with a responsibility
126
+
127
+ Suppose we are building the simplest possible counter page.
128
+
129
+ In Zova, it can look like this:
130
+
131
+ ```tsx
132
+ @Controller()
133
+ export class ControllerPageCounter extends BeanControllerPageBase {
134
+ count = 0;
135
+
136
+ get countText() {
137
+ return `Current count: ${this.count}`;
138
+ }
139
+
140
+ increment() {
141
+ this.count++;
142
+ }
143
+
144
+ protected render() {
145
+ return (
146
+ <div>
147
+ <div>{this.countText}</div>
148
+ <button onClick={() => this.increment()}>Increment</button>
149
+ </div>
150
+ );
151
+ }
152
+ }
153
+ ```
154
+
155
+ The important part of this code is not simply that it uses a class. It expresses the business meaning directly:
156
+
157
+ - `count` is state owned by this page.
158
+ - `increment()` is behavior provided by this page.
159
+ - `countText` is display data derived from that state.
160
+ - `render()` describes how the page is presented.
161
+ - Everything is organized around one object.
162
+
163
+ You do not first create `ref(0)`, return a group of values, and destructure them at the call site:
164
+
165
+ ```ts
166
+ const { count, increment } = useCounter();
167
+ ```
168
+
169
+ You use the object's state and behavior directly:
170
+
171
+ ```ts
172
+ this.count;
173
+ this.increment();
174
+ ```
175
+
176
+ This is a small but significant difference: **state no longer floats in a function return value; it clearly belongs to an object.**
177
+
178
+ Of course, `count` is not reactive because class fields are inherently reactive.
179
+
180
+ The actual mechanism is that Zova creates the Controller as a container-managed Bean and connects it to Vue's reactivity underneath. When `this.count++` runs, rendering that depends on it updates just as it would with ordinary Vue reactive code.
181
+
182
+ In other words:
183
+
184
+ > Object-oriented design organizes the code; Vue 3 makes the state inside those objects reactive.
185
+
186
+ ---
187
+
188
+ ## Do not destructure everything: keep dependencies visible in the code
189
+
190
+ The real challenge of many complex pages is not the UI. It is the collaboration between multiple business capabilities.
191
+
192
+ For example, a todo page needs a todo data model. In a conventional Vue project, that might be:
193
+
194
+ - a composable;
195
+ - a Pinia store;
196
+ - a group of API functions plus several `ref`s;
197
+ - or a mixture of all of the above.
198
+
199
+ In Zova, it can be expressed explicitly as a Model:
200
+
201
+ ```ts
202
+ @Model()
203
+ export class ModelTodo extends BeanModelBase {
204
+ findAll() {
205
+ return this.$useStateData({
206
+ queryKey: ['list'],
207
+ queryFn: async () => {
208
+ return await this.scope.api.todo.findAll();
209
+ },
210
+ });
211
+ }
212
+
213
+ create() {
214
+ return this.$useMutationData({
215
+ mutationKey: ['create'],
216
+ mutationFn: async body => {
217
+ return await this.scope.api.todo.create(body);
218
+ },
219
+ onSuccess: () => {
220
+ this.$invalidateQueries({ queryKey: ['list'] });
221
+ },
222
+ });
223
+ }
224
+ }
225
+ ```
226
+
227
+ `ModelTodo` is not merely an API utility class.
228
+
229
+ It owns a coherent set of responsibilities:
230
+
231
+ - todo queries;
232
+ - query-cache identity;
233
+ - create operations;
234
+ - state during creation;
235
+ - list invalidation and refresh policy after a successful create.
236
+
237
+ The page Controller can then inject it:
238
+
239
+ ```tsx
240
+ @Controller()
241
+ export class ControllerPageTodo extends BeanControllerPageBase {
242
+ @Use()
243
+ $$modelTodo: ModelTodo;
244
+
245
+ get queryTodos() {
246
+ return this.$$modelTodo.findAll();
247
+ }
248
+
249
+ async addTodo() {
250
+ await this.$$modelTodo.create().mutateAsync({
251
+ title: 'Learn Zova',
252
+ });
253
+ }
254
+
255
+ protected render() {
256
+ const todos = this.queryTodos.data ?? [];
257
+
258
+ return (
259
+ <div>
260
+ <button onClick={() => this.addTodo()}>Create todo</button>
261
+
262
+ <ul>
263
+ {todos.map(item => (
264
+ <li key={item.id}>{item.title}</li>
265
+ ))}
266
+ </ul>
267
+ </div>
268
+ );
269
+ }
270
+ }
271
+ ```
272
+
273
+ There is an important reading experience in these lines:
274
+
275
+ ```ts
276
+ this.$$modelTodo.findAll();
277
+ this.$$modelTodo.create();
278
+ ```
279
+
280
+ You can see immediately that:
281
+
282
+ - these capabilities come from `ModelTodo`;
283
+ - the page depends on the todo model;
284
+ - query and write logic are not scattered throughout the page;
285
+ - there is a specific object to inspect when you need to understand caching, requests, or invalidation.
286
+
287
+ That is the value of dependency injection. It is not merely a way to write fewer imports. It makes dependencies between objects explicit, stable, and traceable.
288
+
289
+ ---
290
+
291
+ ## Pinia, provide/inject, and composables: not three kinds of “state management,” but fragments of one question
292
+
293
+ Common ways to organize state in the Vue ecosystem include:
294
+
295
+ - component-local `ref` / `reactive`;
296
+ - composables;
297
+ - Pinia;
298
+ - `provide/inject`;
299
+ - data-fetching and caching libraries.
300
+
301
+ They are all valuable, and each fits particular situations.
302
+
303
+ For beginners, though, they can create a recurring question:
304
+
305
+ > When should I use a composable? When should I use Pinia? When should I use `provide/inject`? When should the state remain in the component?
306
+
307
+ Zova offers a different starting point: do not begin with a tool name. Begin with **state ownership and lifecycle**.
308
+
309
+ | Question | A more suitable owner |
310
+ | ---------------------------------------------------------------------- | --------------------- |
311
+ | Short-lived input, toggle, or interaction state on the current page | Page Controller |
312
+ | State and behavior of a reusable UI unit | Component Controller |
313
+ | Business data, queries, caches, or persisted state reused across pages | Model |
314
+ | Reusable business or foundational capability | Service Bean |
315
+ | A collaboration object local to a component tree | `ctx`-scoped Bean |
316
+ | An object that belongs to an application or SSR request | `app`-scoped Bean |
317
+ | System-wide, long-lived object | `sys`-scoped Bean |
318
+
319
+ Concepts that may otherwise be spread across several tools can gradually become one mental model:
320
+
321
+ > **Do not first decide which library should hold state. First decide which object owns it, how long it should live, and who depends on it.**
322
+
323
+ That shifts the architectural discussion from technology selection back toward business modeling.
324
+
325
+ ---
326
+
327
+ ## “Object-oriented” does not mean writing Java-style frontend code
328
+
329
+ When developers see `class`, `@Controller()`, `@Model()`, and `@Use()`, a common concern is:
330
+
331
+ > Will this become over-engineering?
332
+ > Will it turn into layers of traditional Java-style wrappers?
333
+
334
+ The answer depends on how the system is used.
335
+
336
+ Zova does not require you to split everything into many classes from the beginning. A small page can be just one Controller:
337
+
338
+ ```tsx
339
+ @Controller()
340
+ export class ControllerPageProfile extends BeanControllerPageBase {
341
+ nickname = '';
342
+
343
+ save() {
344
+ // Save the nickname.
345
+ }
346
+
347
+ protected render() {
348
+ return (
349
+ <input
350
+ value={this.nickname}
351
+ onInput={event => {
352
+ this.nickname = event.target.value;
353
+ }}
354
+ />
355
+ );
356
+ }
357
+ }
358
+ ```
359
+
360
+ Only when responsibilities genuinely grow do you split them gradually:
361
+
362
+ 1. **The page becomes complex**: extract a Render Bean.
363
+ 2. **Styling becomes complex**: extract a Style Bean.
364
+ 3. **Business behavior becomes reusable**: extract a Service Bean.
365
+ 4. **Data needs caching, reuse, persistence, or SSR coordination**: extract a Model.
366
+
367
+ This is not object orientation for its own sake. It lets code grow with the business.
368
+
369
+ A good architecture should not require developers to design a perfect class diagram on day one. It should let them start simply and provide a clear evolution path when complexity actually arrives.
370
+
371
+ ---
372
+
373
+ ## TSX brings rendering and behavior closer together
374
+
375
+ Zova uses TSX as its main rendering expression.
376
+
377
+ That does not mean Vue templates are bad. Templates are friendly for simple pages and have a mature ecosystem.
378
+
379
+ But as business UI becomes more complex, TSX has a practical advantage: **rendering logic and TypeScript logic are expressed in the same language.**
380
+
381
+ Conditions, loops, local variables, event handling, and component composition can all live naturally in the same code:
382
+
383
+ ```tsx
384
+ protected render() {
385
+ const query = this.$$modelTodo.findAll();
386
+
387
+ if (query.isPending) {
388
+ return <div>Loading…</div>;
389
+ }
390
+
391
+ if (query.isError) {
392
+ return <div>Loading failed. Please try again later.</div>;
393
+ }
394
+
395
+ return (
396
+ <ul>
397
+ {query.data?.map(todo => (
398
+ <li key={todo.id}>
399
+ <span>{todo.title}</span>
400
+ <button onClick={() => this.removeTodo(todo.id)}>
401
+ Delete
402
+ </button>
403
+ </li>
404
+ ))}
405
+ </ul>
406
+ );
407
+ }
408
+ ```
409
+
410
+ Here:
411
+
412
+ - it is clear which Model provides the data;
413
+ - it is clear which behavior the click invokes;
414
+ - it is clear how the page branches on state;
415
+ - it is clear how TypeScript types flow through the code.
416
+
417
+ For developers accustomed to complex business logic and rich component composition, this continuity of logic, state, and rendering within one object can provide a strong sense of control.
418
+
419
+ ---
420
+
421
+ ## Zova does not reject Vue; it adds a more complete application language on top of it
422
+
423
+ On the surface, Zova may look like Vue 3 plus classes, decorators, an IoC container, and Models.
424
+
425
+ A more accurate description is that it offers a more unified language for frontend application architecture:
426
+
427
+ - **Controllers** express interactive responsibilities of pages and components.
428
+ - **Beans** express composable, injectable capabilities.
429
+ - **Models** express data state with lifecycle, caching, and invalidation policy.
430
+ - **IoC** expresses object creation, scope, and dependencies.
431
+ - **Vue 3 reactivity** keeps state changes and UI updates naturally connected.
432
+ - **TSX** lets rendering and logic collaborate in one language.
433
+
434
+ So Zova is not saying:
435
+
436
+ > “Vue 3's Composition API is not good enough.”
437
+
438
+ It is closer to saying:
439
+
440
+ > “When a project grows from a component into a business application, we need more than composable functions. We need clear object boundaries, dependencies, and state ownership.”
441
+
442
+ ---
443
+
444
+ ## Closing: from “how do we manage state?” to “who owns this state?”
445
+
446
+ Frontend development has spent years discussing state management.
447
+
448
+ But sometimes we start with the wrong question.
449
+
450
+ We often ask:
451
+
452
+ - Should we use Pinia or composables?
453
+ - Where should global state live?
454
+ - How do we avoid prop drilling?
455
+ - How do we cache data fetching automatically?
456
+
457
+ Those questions matter. But behind them sits one more fundamental set of questions:
458
+
459
+ > Who owns this state?
460
+ > Who is allowed to change it?
461
+ > Who depends on it?
462
+ > How long should it live?
463
+ > When it changes, who is responsible for preserving consistency?
464
+
465
+ When those questions have clear answers, the choice of tools often becomes much easier.
466
+
467
+ That is the experience Cabloy/Zova aims to provide:
468
+
469
+ > Do not let business code become a collection of variables that have been destructured, moved around, and assembled.
470
+ > Put state back into objects, behavior back into responsibilities, and dependencies back into structure.
471
+
472
+ If you already know Vue 3, try writing one small Zova feature: one Controller, one Model, and a few TSX expressions. You may find that Vue 3 reactivity still feels familiar—but organizing a complex business feature no longer feels like untangling a knot.
473
+
474
+ ---
475
+
476
+ ## Further reading
477
+
478
+ - [Zova Frontend Foundation](https://docs.cabloy.com/frontend/foundation)
479
+ - [Reading Zova for Vue Developers](https://docs.cabloy.com/frontend/reading-zova-for-vue-developers)
480
+ - [Zova vs Vue 3 Comparison](https://docs.cabloy.com/frontend/zova-vs-vue3-comparison)
481
+ - [IoC and Beans](https://docs.cabloy.com/frontend/ioc-and-beans)
482
+ - [State Architecture for Vue Developers](https://docs.cabloy.com/frontend/state-architecture-for-vue-developers)
483
+ - [Model Architecture](https://docs.cabloy.com/frontend/model-architecture)
@@ -70,6 +70,19 @@ That means `$sdk` is not a static global object.
70
70
 
71
71
  It is a runtime-injected, locale-scoped model surface.
72
72
 
73
+ ### Locale switches and API-schema facade lifetime
74
+
75
+ A locale switch changes the active runtime, not merely a display string:
76
+
77
+ 1. the `a-openapi` monkey observes `app.meta.locale.current` and replaces the selected `ModelSdk`;
78
+ 2. `ModelSdk` is selector-backed by locale;
79
+ 3. `SysSdk` uses its locale when requesting OpenAPI schema data, including the configured locale header;
80
+ 4. each `createApiSchemas(...)` call creates a facade around the SDK query selected at that moment.
81
+
82
+ Consequently, a controller or model should not keep an `apiSchemas` facade, its `requestBody`, or a transformed schema object as a locale-independent long-lived value. Obtain the current facade through a getter or owning resource inside the reactive schema derivation. See [API Schema Guide](/frontend/api-schema-guide) for the public authoring pattern.
83
+
84
+ This is also a useful diagnostic boundary: if emitted OpenAPI metadata and generated consumers are correct but a mounted form keeps the previous language, inspect the consumer's schema-facade lifetime before regenerating the contract.
85
+
73
86
  ## `ModelSdk` responsibilities
74
87
 
75
88
  The selector-backed model lives in:
@@ -21,6 +21,81 @@ In the Cabloy/Zova model, schema metadata can support higher-level frontend beha
21
21
 
22
22
  This is one reason the server-data thread in Zova is more powerful than a plain request library.
23
23
 
24
+ ## The generated and runtime path
25
+
26
+ A schema-driven frontend normally follows this contract path:
27
+
28
+ ```text
29
+ backend entity / DTO / controller metadata
30
+ -> Swagger / OpenAPI
31
+ -> generated API bean + API-schema bean + static types
32
+ -> $api / $apiSchema / $sdk
33
+ -> ModelResource when the API belongs to a reusable resource
34
+ -> ZForm for schema-driven form runtime
35
+ -> page/controller for local orchestration
36
+ ```
37
+
38
+ Each layer has a different responsibility:
39
+
40
+ | Layer | Responsibility |
41
+ | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
42
+ | Backend entity or inferred field contract | Reusable field meaning, validation, titles, ordering, and shared renderer metadata |
43
+ | Backend DTO | Operation-specific request/response projection and composition |
44
+ | Generated `$api` | Execute a typed backend operation |
45
+ | Generated `$apiSchema` | Expose a named operation's schema-oriented facade |
46
+ | `$sdk` | Provide the lower-level schema/query runtime used by schema facades and dynamic consumers |
47
+ | `ModelResource` | Own reusable resource schema, query, mutation, cache, invalidation, and permission state |
48
+ | `ZForm` | Consume a resolved schema and own form binding, validation, submission, and field rendering |
49
+ | Page/controller | Coordinate local page lifecycle and page-specific actions without duplicating shared contract or cache state |
50
+
51
+ The generated API bean, API-schema bean, and static OpenAPI types are separate frontend surfaces for the same backend operation. Runtime schema metadata such as titles, renderer names, validation, and scene information is consumed through `$apiSchema`/`$sdk`; static request and response typing is consumed through the generated TypeScript types and `$api` methods.
52
+
53
+ ### Direct schema-driven form pattern
54
+
55
+ For a page-specific form whose request-body schema is already exposed by a generated API-schema bean, expose a getter that obtains the current facade, load its SDK query, and derive the schema reactively:
56
+
57
+ ```ts
58
+ get apiSchemasRegister() {
59
+ return this.$apiSchema.homeUserPassport.register({ authToken: false });
60
+ }
61
+
62
+ protected async __init__() {
63
+ await $QueryEnsureLoaded(() => this.apiSchemasRegister.sdk);
64
+ this.schemaRegister = this.$computed(() => {
65
+ return this.apiSchemasRegister.requestBody;
66
+ });
67
+ }
68
+ ```
69
+
70
+ ```tsx
71
+ <ZForm
72
+ data={this.user}
73
+ schema={this.schemaRegister}
74
+ onSubmitData={data => this.submitRegister(data)}
75
+ slotFooter={$form => {
76
+ return <button type="submit">Register</button>;
77
+ }}
78
+ ></ZForm>
79
+ ```
80
+
81
+ When `ZForm` receives a schema without a default body slot, it iterates the schema properties and resolves each field from the contract metadata. `slotFooter` is independent of body rendering, so page-specific submit actions can remain in the form without replacing automatic field rendering. Adding default children to the form changes the body path to explicit composition and should be reserved for manual or mixed forms.
82
+
83
+ ### Locale-aware schema lifetime
84
+
85
+ OpenAPI schema metadata can include localized titles, descriptions, validation messages, and renderer metadata. Obtain it through the current `$apiSchema`/`$sdk` runtime rather than retaining a one-time `apiSchemas` facade or `requestBody` snapshot across a locale change. A `$computed` only helps when its callback rereads a live getter or owning resource; wrapping a facade created before the locale change still reads that earlier schema.
86
+
87
+ Apply page-specific schema derivation in the same reactive callback:
88
+
89
+ ```ts
90
+ this.schemaPasswordSet = this.$computed(() => {
91
+ return omitSchemaProperty(this.apiSchemasPasswordSet.requestBody, 'token');
92
+ });
93
+ ```
94
+
95
+ This keeps both the source schema and the filtered view current. The same rule applies to `pick`, property ordering, or any other schema transformation. `staleTime: Infinity` is cache behavior within the selected runtime; it does not make a schema facade locale-neutral.
96
+
97
+ For a reusable resource, prefer the owning `ModelResource` to supply `formSchema`, `formData`, `formMeta`, and mutation policy. For a low-reuse page action with no shared query, cache, mutation, or invalidation state, the page controller may call the generated `$api` directly. A model should not wrap an API merely to add an extra indirection.
98
+
24
99
  ## How to think about `$apiSchema`
25
100
 
26
101
  Use `$apiSchema` when the frontend needs to inspect what the backend contract says, not just call the backend endpoint.
@@ -54,6 +129,10 @@ Use this page together with:
54
129
  - [Server Data](/frontend/server-data)
55
130
  - [OpenAPI SDK Guide](/frontend/openapi-sdk-guide)
56
131
  - [Backend OpenAPI to Frontend SDK](/fullstack/openapi-to-sdk)
132
+ - [Form Guide](/frontend/form-guide)
133
+ - [Generated Contract Consumption Specimen](/frontend/generated-contract-consumption-specimen)
134
+ - [Model Resource Owner Pattern](/frontend/model-resource-owner-pattern)
135
+ - [Contract Loop Playbook](/fullstack/contract-loop-playbook)
57
136
  - [SDK Guide](/frontend/sdk-guide)
58
137
  - [A-OpenAPI Under the Hood](/frontend/a-openapi-under-the-hood)
59
138
 
@@ -110,6 +110,8 @@ A concrete example in the current Cabloy Basic frontend setup is the default SSR
110
110
 
111
111
  The effective profile is request-local: the active flavor's `SSR_PROFILE` supplies its default, and `route.meta.ssrProfile` can override it after route resolution. `public` keeps cookie-derived identity and theme state out of the server render; `session` permits normal cookie-backed Passport recovery and theme resolution, while forcing a private, non-storable response. Profiles define request-cookie capability, not a locale source: existing `route.meta.locale` controls URL-locale participation.
112
112
 
113
+ The flavor fallback does not replace route authoring. Choose `ssrProfile` from the route's rendering contract: `session` is explicit when SSR needs cookie-backed state, protected admission, personalized first paint, or private data, while `public` remains valid for an explicit URL-locale or deliberately locale-neutral, cache-safe, hydration-equivalent public contract. The absence of `locale` params alone does not determine the profile. Choose anonymous admission separately with `requiresAuth: false`; a session route still does not gain authentication or authorization.
114
+
113
115
  That means flavor selection is not only a packaging choice. It establishes the default capability boundary, while individual routes remain able to select the profile their rendering contract requires.
114
116
 
115
117
  Before assuming how SSR theme state is handed off and finalized, combine:
@@ -312,6 +312,43 @@ Schema-driven rendering is a strong fit when:
312
312
  - frontend and backend should stay close to the same Student contract truth
313
313
  - you want to reduce duplicated Student field configuration
314
314
 
315
+ ### Keep an OpenAPI schema current across locale changes
316
+
317
+ When the form schema comes from `$apiSchema`, titles, descriptions, validation messages, and renderer metadata can change with the active locale. Derive the schema from a live getter inside `$computed`; do not retain an `apiSchemas` facade created before the locale changes:
318
+
319
+ ```ts
320
+ get apiSchemasStudentCreate() {
321
+ return this.$apiSchema.trainingStudent.create();
322
+ }
323
+
324
+ protected async __init__() {
325
+ await $QueryEnsureLoaded(() => this.apiSchemasStudentCreate.sdk);
326
+ this.studentFormSchema = this.$computed(() => {
327
+ return this.apiSchemasStudentCreate.requestBody;
328
+ });
329
+ }
330
+ ```
331
+
332
+ If the page removes or rearranges contract fields, perform that work inside the same computed callback so the derived schema changes with the source schema:
333
+
334
+ ```ts
335
+ this.studentFormSchema = this.$computed(() => {
336
+ return omitSchemaProperty(this.apiSchemasStudentCreate.requestBody, 'internalField');
337
+ });
338
+ ```
339
+
340
+ ### Preserve the automatic/custom rendering boundary
341
+
342
+ | Need | Recommended approach |
343
+ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
344
+ | The contract already defines the fields and render metadata | Pass the current schema to `ZForm` and leave the default body slot empty for automatic rendering. |
345
+ | Only page actions are custom | Use `slotHeader`, `slotFooter`, or another structural slot without replacing the automatic field body. |
346
+ | One field needs custom UI | Use `ZFormFieldPreset`, `ZFormField`, or a registered renderer while keeping the rest schema-driven. |
347
+ | A reusable renderer is frontend-owned but referenced by backend metadata | Treat it as reverse-chain work: build the relevant Zova flavor and run `npm run deps:vona`. |
348
+ | The page needs unusual local composition | Use manual or mixed form composition deliberately, and render every required field explicitly. |
349
+
350
+ A nonempty default body slot is an intentional boundary: it replaces automatic schema-property iteration. Custom field composition still consumes the schema that the form owner provides, so it must use the current locale's schema as well. Read [API Schema Guide](/frontend/api-schema-guide) for the schema ownership and locale-lifetime pattern, and [Tutorial 4: Custom Form/Table Renderers for Level](/fullstack/tutorial-4-custom-level-renderers) when the contract needs a reusable custom renderer.
351
+
315
352
  A practical expression example is a schema-driven field display that formats a numeric value through CEL:
316
353
 
317
354
  ```text
@@ -7,6 +7,9 @@ This guide explains how Markdown works across the Cabloy Basic frontend and back
7
7
 
8
8
  The Zova frontend provides the editor and the trusted-HTML display component. The Vona backend owns Markdown parsing, HTML rendering, and sanitization.
9
9
 
10
+ > [!NOTE]
11
+ > The module identity is edition-specific: Cabloy Basic uses `basic-markdown` and `zova-module-basic-markdown`; Cabloy Start uses `start-markdown` and `zova-module-start-markdown`. Substitute the matching renderer ID and import path in every example below.
12
+
10
13
  Use this page together with:
11
14
 
12
15
  - [Form Guide](/frontend/form-guide)