cabloy 5.1.50 → 5.1.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/.claude/skills/cabloy-backend-scaffold/SKILL.md +207 -0
  2. package/.claude/skills/cabloy-backend-scaffold/evals/evals.json +29 -0
  3. package/.claude/skills/cabloy-backend-scaffold/references/backend-thread-map.md +52 -0
  4. package/.claude/skills/cabloy-backend-scaffold/references/follow-up-checklist.md +39 -0
  5. package/.claude/skills/cabloy-contract-loop/SKILL.md +201 -0
  6. package/.claude/skills/cabloy-contract-loop/evals/evals.json +29 -0
  7. package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +47 -0
  8. package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +32 -0
  9. package/.claude/skills/cabloy-frontend-scaffold/SKILL.md +230 -0
  10. package/.claude/skills/cabloy-frontend-scaffold/evals/evals.json +35 -0
  11. package/.claude/skills/cabloy-frontend-scaffold/references/follow-up-checklist.md +41 -0
  12. package/.claude/skills/cabloy-frontend-scaffold/references/frontend-thread-map.md +54 -0
  13. package/.claude/skills/cabloy-workflow/SKILL.md +288 -0
  14. package/.claude/skills/cabloy-workflow/evals/evals.json +35 -0
  15. package/.claude/skills/cabloy-workflow/references/cli-strategy.md +39 -0
  16. package/.claude/skills/cabloy-workflow/references/edition-detection.md +29 -0
  17. package/.github/workflows/docs-pages.yml +54 -0
  18. package/.gitignore +1 -0
  19. package/CHANGELOG.md +29 -0
  20. package/CLAUDE.md +59 -0
  21. package/README.md +137 -0
  22. package/cabloy-docs/.vitepress/config.mjs +222 -0
  23. package/cabloy-docs/.vitepress/public/CNAME +1 -0
  24. package/cabloy-docs/.vitepress/theme/custom.css +64 -0
  25. package/cabloy-docs/.vitepress/theme/edition-badges.md +5 -0
  26. package/cabloy-docs/.vitepress/theme/index.js +5 -0
  27. package/cabloy-docs/ai/class-placement-rule.md +138 -0
  28. package/cabloy-docs/ai/cli-for-agents.md +56 -0
  29. package/cabloy-docs/ai/cli-to-skill-map.md +165 -0
  30. package/cabloy-docs/ai/docs-skills-rules-mapping.md +167 -0
  31. package/cabloy-docs/ai/edition-detection.md +30 -0
  32. package/cabloy-docs/ai/future-skill-roadmap.md +135 -0
  33. package/cabloy-docs/ai/global-bean-lookup.md +157 -0
  34. package/cabloy-docs/ai/introduction.md +62 -0
  35. package/cabloy-docs/ai/playbook-backend-module.md +111 -0
  36. package/cabloy-docs/ai/playbook-contract-regeneration.md +100 -0
  37. package/cabloy-docs/ai/playbook-frontend-page.md +99 -0
  38. package/cabloy-docs/ai/playbook-metadata-refresh.md +67 -0
  39. package/cabloy-docs/ai/repo-guidance.md +58 -0
  40. package/cabloy-docs/ai/rules-and-config.md +29 -0
  41. package/cabloy-docs/ai/skills.md +35 -0
  42. package/cabloy-docs/ai/verification.md +30 -0
  43. package/cabloy-docs/backend/aop-overview.md +128 -0
  44. package/cabloy-docs/backend/auth-guide.md +151 -0
  45. package/cabloy-docs/backend/backend-essentials.md +128 -0
  46. package/cabloy-docs/backend/broadcast-guide.md +138 -0
  47. package/cabloy-docs/backend/cache-guide.md +70 -0
  48. package/cabloy-docs/backend/captcha-guide.md +162 -0
  49. package/cabloy-docs/backend/cli.md +173 -0
  50. package/cabloy-docs/backend/config-guide.md +249 -0
  51. package/cabloy-docs/backend/controller-aop-guide.md +270 -0
  52. package/cabloy-docs/backend/controller-guide.md +347 -0
  53. package/cabloy-docs/backend/crud-workflow.md +118 -0
  54. package/cabloy-docs/backend/dto-guide.md +161 -0
  55. package/cabloy-docs/backend/dto-infer-generation.md +153 -0
  56. package/cabloy-docs/backend/dynamic-datasource-guide.md +70 -0
  57. package/cabloy-docs/backend/election-guide.md +141 -0
  58. package/cabloy-docs/backend/entity-guide.md +150 -0
  59. package/cabloy-docs/backend/error-guide.md +108 -0
  60. package/cabloy-docs/backend/event-guide.md +183 -0
  61. package/cabloy-docs/backend/external-aop-guide.md +149 -0
  62. package/cabloy-docs/backend/field-indexes.md +79 -0
  63. package/cabloy-docs/backend/foundation.md +281 -0
  64. package/cabloy-docs/backend/i18n-guide.md +211 -0
  65. package/cabloy-docs/backend/internal-aop-guide.md +181 -0
  66. package/cabloy-docs/backend/introduction.md +95 -0
  67. package/cabloy-docs/backend/jwt-guide.md +276 -0
  68. package/cabloy-docs/backend/logger-guide.md +223 -0
  69. package/cabloy-docs/backend/mail-guide.md +189 -0
  70. package/cabloy-docs/backend/menu-guide.md +80 -0
  71. package/cabloy-docs/backend/migration-and-changes.md +192 -0
  72. package/cabloy-docs/backend/model-guide.md +274 -0
  73. package/cabloy-docs/backend/multi-database-datasource.md +171 -0
  74. package/cabloy-docs/backend/multi-instance-and-instance-resolution.md +196 -0
  75. package/cabloy-docs/backend/openapi-guide.md +118 -0
  76. package/cabloy-docs/backend/orm-aggregate-group-guide.md +210 -0
  77. package/cabloy-docs/backend/orm-configuration-guide.md +165 -0
  78. package/cabloy-docs/backend/orm-guide.md +109 -0
  79. package/cabloy-docs/backend/orm-mutation-guide.md +195 -0
  80. package/cabloy-docs/backend/orm-select-guide.md +243 -0
  81. package/cabloy-docs/backend/queue-guide.md +271 -0
  82. package/cabloy-docs/backend/quickstart.md +141 -0
  83. package/cabloy-docs/backend/redis-guide.md +70 -0
  84. package/cabloy-docs/backend/redlock-guide.md +60 -0
  85. package/cabloy-docs/backend/relations-guide.md +250 -0
  86. package/cabloy-docs/backend/runtime-and-flavors.md +304 -0
  87. package/cabloy-docs/backend/schedule-guide.md +81 -0
  88. package/cabloy-docs/backend/scripts.md +116 -0
  89. package/cabloy-docs/backend/serialization-guide.md +192 -0
  90. package/cabloy-docs/backend/service-guide.md +166 -0
  91. package/cabloy-docs/backend/sharding-guide.md +49 -0
  92. package/cabloy-docs/backend/startup-guide.md +326 -0
  93. package/cabloy-docs/backend/transaction-guide.md +82 -0
  94. package/cabloy-docs/backend/unit-testing.md +209 -0
  95. package/cabloy-docs/backend/upload-guide.md +160 -0
  96. package/cabloy-docs/backend/user-access-guide.md +157 -0
  97. package/cabloy-docs/backend/validation-guide.md +80 -0
  98. package/cabloy-docs/backend/worker-guide.md +59 -0
  99. package/cabloy-docs/editions/cabloy-basic.md +25 -0
  100. package/cabloy-docs/editions/cabloy-start.md +24 -0
  101. package/cabloy-docs/editions/detection.md +31 -0
  102. package/cabloy-docs/editions/overview.md +44 -0
  103. package/cabloy-docs/frontend/api-guide.md +93 -0
  104. package/cabloy-docs/frontend/api-schema-guide.md +43 -0
  105. package/cabloy-docs/frontend/app-startup-guide.md +185 -0
  106. package/cabloy-docs/frontend/cli.md +78 -0
  107. package/cabloy-docs/frontend/component-guide.md +105 -0
  108. package/cabloy-docs/frontend/component-props-guide.md +97 -0
  109. package/cabloy-docs/frontend/component-v-model-guide.md +110 -0
  110. package/cabloy-docs/frontend/css-in-js-guide.md +151 -0
  111. package/cabloy-docs/frontend/design-principles.md +55 -0
  112. package/cabloy-docs/frontend/environment-config-guide.md +250 -0
  113. package/cabloy-docs/frontend/foundation.md +57 -0
  114. package/cabloy-docs/frontend/generic-component-guide.md +35 -0
  115. package/cabloy-docs/frontend/icon-engine-guide.md +88 -0
  116. package/cabloy-docs/frontend/introduction.md +32 -0
  117. package/cabloy-docs/frontend/ioc-and-beans.md +211 -0
  118. package/cabloy-docs/frontend/mock-guide.md +109 -0
  119. package/cabloy-docs/frontend/model-architecture.md +87 -0
  120. package/cabloy-docs/frontend/model-state-guide.md +70 -0
  121. package/cabloy-docs/frontend/module-scope.md +168 -0
  122. package/cabloy-docs/frontend/modules-and-suites.md +179 -0
  123. package/cabloy-docs/frontend/navigation-guards-guide.md +68 -0
  124. package/cabloy-docs/frontend/openapi-sdk-guide.md +102 -0
  125. package/cabloy-docs/frontend/page-guide.md +223 -0
  126. package/cabloy-docs/frontend/page-params-guide.md +87 -0
  127. package/cabloy-docs/frontend/page-query-guide.md +96 -0
  128. package/cabloy-docs/frontend/page-route-guide.md +147 -0
  129. package/cabloy-docs/frontend/quickstart.md +201 -0
  130. package/cabloy-docs/frontend/route-alias-guide.md +61 -0
  131. package/cabloy-docs/frontend/scripts.md +86 -0
  132. package/cabloy-docs/frontend/sdk-guide.md +45 -0
  133. package/cabloy-docs/frontend/server-data.md +74 -0
  134. package/cabloy-docs/frontend/ssr-client-only.md +40 -0
  135. package/cabloy-docs/frontend/ssr-env.md +51 -0
  136. package/cabloy-docs/frontend/ssr-init-data.md +46 -0
  137. package/cabloy-docs/frontend/ssr-overview.md +48 -0
  138. package/cabloy-docs/frontend/ssr-seo-meta.md +52 -0
  139. package/cabloy-docs/frontend/system-startup-guide.md +186 -0
  140. package/cabloy-docs/frontend/theme-guide.md +154 -0
  141. package/cabloy-docs/frontend/zod-guide.md +161 -0
  142. package/cabloy-docs/fullstack/edition-collaboration-differences.md +61 -0
  143. package/cabloy-docs/fullstack/frontend-metadata-to-backend.md +64 -0
  144. package/cabloy-docs/fullstack/introduction.md +69 -0
  145. package/cabloy-docs/fullstack/openapi-to-sdk.md +116 -0
  146. package/cabloy-docs/fullstack/quickstart.md +86 -0
  147. package/cabloy-docs/fullstack/vona-zova-integration.md +86 -0
  148. package/cabloy-docs/index.md +73 -0
  149. package/cabloy-docs/package.json +16 -0
  150. package/cabloy-docs/pnpm-lock.yaml +1607 -0
  151. package/cabloy-docs/reference/backend-directory-structure.md +88 -0
  152. package/cabloy-docs/reference/cli-reference.md +49 -0
  153. package/cabloy-docs/reference/glossary.md +38 -0
  154. package/cabloy-docs/reference/package-map.md +105 -0
  155. package/cabloy-docs/reference/repo-scripts.md +36 -0
  156. package/package.json +4 -1
  157. package/scripts/init.ts +12 -0
  158. package/scripts/upgrade.ts +31 -3
  159. package/vona/README.md +3 -3
  160. package/vona/README.zh-CN.md +4 -4
  161. package/vona/packages-vona/vona/package.json +1 -1
  162. package/vona/src/suite-vendor/a-cabloy/modules/a-datasharding/package.json +1 -1
  163. package/vona/src/suite-vendor/a-cabloy/modules/a-datasharding/src/bean/summerCache.datasourceWrite.ts +2 -2
  164. package/vona/src/suite-vendor/a-cabloy/package.json +1 -1
  165. package/vona/src/suite-vendor/a-captcha/modules/a-captcha/package.json +1 -1
  166. package/vona/src/suite-vendor/a-captcha/modules/a-captcha/src/bean/cacheRedis.captcha.ts +2 -2
  167. package/vona/src/suite-vendor/a-captcha/package.json +1 -1
  168. package/vona/src/suite-vendor/a-vona/modules/a-bean/cli/bean/metadata/generate.ts +5 -6
  169. package/vona/src/suite-vendor/a-vona/modules/a-bean/package.json +1 -1
  170. package/vona/src/suite-vendor/a-vona/modules/a-cache/cli/cacheMem/boilerplate/{{sceneName}}.{{beanName}}.ts_ +2 -2
  171. package/vona/src/suite-vendor/a-vona/modules/a-cache/cli/cacheRedis/boilerplate/{{sceneName}}.{{beanName}}.ts_ +2 -2
  172. package/vona/src/suite-vendor/a-vona/modules/a-cache/package.json +1 -1
  173. package/vona/src/suite-vendor/a-vona/modules/a-cache/src/.metadata/index.ts +13 -2
  174. package/vona/src/suite-vendor/a-vona/modules/a-cache/src/bean/bean.cache.ts +6 -7
  175. package/vona/src/suite-vendor/a-vona/modules/a-cache/src/{bean/bean.cacheMemBase.ts → service/cacheMemBase_.ts} +3 -3
  176. package/vona/src/suite-vendor/a-vona/modules/a-cache/src/{bean/bean.cacheRedisBase.ts → service/cacheRedisBase_.ts} +3 -3
  177. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/package.json +1 -1
  178. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/bean/cacheRedis.emailConfirm.ts +2 -2
  179. package/vona/src/suite-vendor/a-vona/modules/a-mailconfirm/src/bean/cacheRedis.passwordReset.ts +2 -2
  180. package/vona/src/suite-vendor/a-vona/modules/a-openapi/package.json +1 -1
  181. package/vona/src/suite-vendor/a-vona/modules/a-openapi/src/bean/summerCache.json.ts +2 -2
  182. package/vona/src/suite-vendor/a-vona/modules/a-orm/cli/databaseDialect/boilerplate/{{sceneName}}.{{beanName}}.ts_ +2 -2
  183. package/vona/src/suite-vendor/a-vona/modules/a-orm/package.json +1 -1
  184. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/.metadata/index.ts +4 -3
  185. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/bean/bean.database.ts +3 -3
  186. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/bean/bean.model.ts +1 -1
  187. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/bean/schedule.softDeletionPrune.ts +1 -1
  188. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/common/utils.ts +1 -1
  189. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/index.ts +1 -1
  190. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_cache.ts +1 -1
  191. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_meta.ts +1 -1
  192. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.modelBase.ts +0 -5
  193. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoAggregate.ts +1 -1
  194. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoCreate.ts +1 -1
  195. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoGet.ts +1 -1
  196. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoGroup.ts +1 -1
  197. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoMutate.ts +1 -1
  198. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoSelectAndCount.ts +1 -1
  199. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/dto/dtoUpdate.ts +1 -1
  200. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/index.ts +1 -0
  201. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/modelCacheBase.ts +3 -3
  202. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/relations.ts +1 -1
  203. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/relationsDynamic.ts +1 -1
  204. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/relationsMutate.ts +1 -1
  205. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/lib/relationsStatic.ts +1 -1
  206. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/cacheEntity_.ts +1 -1
  207. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/cacheQuery_.ts +1 -1
  208. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/database.ts +2 -2
  209. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean/bean.databaseDialectBase.ts → service/databaseDialectBase_.ts} +38 -41
  210. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/db_.ts +2 -2
  211. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/service/relations_.ts +3 -3
  212. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/database.ts +0 -5
  213. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/dto/dtoGet.ts +1 -1
  214. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/dto/dtoMutate.ts +1 -1
  215. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/dto/dtoSelectAndCount.ts +1 -1
  216. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/model.ts +1 -1
  217. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/modelAggr.ts +1 -1
  218. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/modelCount.ts +1 -1
  219. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/modelGeneral.ts +1 -1
  220. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/modelGroup.ts +1 -1
  221. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/modelIncrement.ts +1 -1
  222. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relations.ts +1 -1
  223. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsColumns.ts +1 -1
  224. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsDef.ts +1 -1
  225. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsDefDynamic.ts +1 -1
  226. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsDefMutate.ts +1 -1
  227. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsMutate.ts +1 -1
  228. package/vona/src/suite-vendor/a-vona/modules/a-orm/src/types/relationsTables.ts +1 -1
  229. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/package.json +1 -1
  230. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/bean/databaseDialect.betterSqlite3.ts +2 -2
  231. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/bean/databaseDialect.mysql.ts +2 -2
  232. package/vona/src/suite-vendor/a-vona/modules/a-ormdialect/src/bean/databaseDialect.pg.ts +2 -2
  233. package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
  234. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +109 -40
  235. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/summerCache.permission.ts +2 -2
  236. package/vona/src/suite-vendor/a-vona/modules/a-startup/package.json +1 -1
  237. package/vona/src/suite-vendor/a-vona/modules/a-startup/src/bean/cacheRedis.startupDebounce.ts +2 -2
  238. package/vona/src/suite-vendor/a-vona/modules/a-summer/cli/boilerplate/{{sceneName}}.{{beanName}}.ts_ +2 -2
  239. package/vona/src/suite-vendor/a-vona/modules/a-summer/package.json +1 -1
  240. package/vona/src/suite-vendor/a-vona/modules/a-summer/src/.metadata/index.ts +1 -1
  241. package/vona/src/suite-vendor/a-vona/modules/a-summer/src/bean/bean.summer.ts +3 -3
  242. package/vona/src/suite-vendor/a-vona/modules/a-summer/src/service/localMem_.ts +3 -3
  243. package/vona/src/suite-vendor/a-vona/modules/a-summer/src/service/localRedis_.ts +3 -3
  244. package/vona/src/suite-vendor/a-vona/modules/a-summer/src/{bean/bean.summerCacheBase.ts → service/summerCacheBase_.ts} +3 -3
  245. package/vona/src/suite-vendor/a-vona/modules/a-swagger/package.json +1 -1
  246. package/vona/src/suite-vendor/a-vona/modules/a-swagger/src/bean/summerCache.rapidoc.ts +2 -2
  247. package/vona/src/suite-vendor/a-vona/modules/a-swagger/src/bean/summerCache.swagger.ts +2 -2
  248. package/vona/src/suite-vendor/a-vona/modules/a-user/package.json +1 -1
  249. package/vona/src/suite-vendor/a-vona/modules/a-user/src/bean/cacheRedis.authToken.ts +2 -2
  250. package/vona/src/suite-vendor/a-vona/modules/a-worker/package.json +1 -1
  251. package/vona/src/suite-vendor/a-vona/modules/a-worker/src/bean/cacheRedis.workerAlive.ts +2 -2
  252. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  253. package/zova/README.md +4 -4
  254. package/zova/README.zh-CN.md +4 -4
  255. /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_crud.ts +0 -0
  256. /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_crud_inner.ts +0 -0
  257. /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_crud_table.ts +0 -0
  258. /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_knex.ts +0 -0
  259. /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_utils.ts +0 -0
  260. /package/vona/src/suite-vendor/a-vona/modules/a-orm/src/{bean → lib}/bean.model/bean.model_view.ts +0 -0
@@ -0,0 +1,195 @@
1
+ # ORM Mutation Guide
2
+
3
+ This guide explains how ORM mutation operations work in Vona within the Cabloy monorepo.
4
+
5
+ ## Why mutation operations matter
6
+
7
+ Mutation is where data shape, persistence behavior, soft deletion, relation-aware writes, and business rules intersect.
8
+
9
+ Vona ORM provides a structured mutation surface rather than forcing every change through raw SQL or hand-written branching.
10
+
11
+ ## Basic mutation operations
12
+
13
+ Representative operations include:
14
+
15
+ - `insert`
16
+ - `insertBulk`
17
+ - `update`
18
+ - `updateBulk`
19
+ - `delete`
20
+ - `deleteBulk`
21
+
22
+ Representative examples:
23
+
24
+ ```typescript
25
+ await this.scope.model.post.insert({ title: 'Post001' });
26
+ await this.scope.model.post.update({ id: 1, title: 'Post001-Update' });
27
+ await this.scope.model.post.delete({ id: 1 });
28
+ ```
29
+
30
+ These operations are the clearest fit when the caller already knows the exact write intent.
31
+
32
+ ## Conditional update and delete paths
33
+
34
+ Write operations do not have to target one row only by primary key.
35
+
36
+ Representative patterns:
37
+
38
+ ```typescript
39
+ await this.scope.model.post.update(
40
+ {
41
+ title: 'Post001-Update',
42
+ },
43
+ {
44
+ where: {
45
+ title: { _startsWith_: 'Post001' },
46
+ },
47
+ },
48
+ );
49
+ ```
50
+
51
+ ```typescript
52
+ await this.scope.model.post.delete({
53
+ title: {
54
+ _startsWith_: 'Post',
55
+ },
56
+ });
57
+ ```
58
+
59
+ That matters because the mutation layer still participates in the same structured query language used by select operations.
60
+
61
+ ## Bulk mutation operations
62
+
63
+ Representative bulk patterns:
64
+
65
+ ```typescript
66
+ await this.scope.model.post.insertBulk([{ title: 'Post001' }, { title: 'Post002' }]);
67
+ ```
68
+
69
+ ```typescript
70
+ await this.scope.model.post.updateBulk([
71
+ { id: 1, title: 'Post001-Update' },
72
+ { id: 2, title: 'Post002-Update' },
73
+ ]);
74
+ ```
75
+
76
+ ```typescript
77
+ await this.scope.model.post.deleteBulk([1, 2]);
78
+ ```
79
+
80
+ Bulk methods are useful when the business flow already has a set of independent records to process in one operation family.
81
+
82
+ ## `mutate` and `mutateBulk`
83
+
84
+ One of the most interesting Vona ideas is the `mutate` model.
85
+
86
+ Instead of forcing callers to choose insert/update/delete up front, Vona can infer the mutation kind from data characteristics.
87
+
88
+ Representative logic:
89
+
90
+ - no `id` → insert
91
+ - `id` present → update
92
+ - `id` present and `deleted: true` → delete
93
+
94
+ Representative pattern:
95
+
96
+ ```typescript
97
+ const post = await this.scope.model.post.mutate({
98
+ title: 'Post001',
99
+ });
100
+
101
+ await this.scope.model.post.mutate({
102
+ id: post.id,
103
+ title: 'Post001-Update',
104
+ });
105
+
106
+ await this.scope.model.post.mutate({
107
+ id: post.id,
108
+ deleted: true,
109
+ });
110
+ ```
111
+
112
+ `mutateBulk` applies the same inference to a list of rows:
113
+
114
+ ```typescript
115
+ await this.scope.model.post.mutateBulk([
116
+ { title: 'Post003' },
117
+ { id: 1, title: 'Post001-Update' },
118
+ { id: 2, deleted: true },
119
+ ]);
120
+ ```
121
+
122
+ This is important because many CRUD-oriented business flows naturally arrive as mixed create/update/delete batches.
123
+
124
+ ## Explicit operations vs `mutate`
125
+
126
+ A practical rule is:
127
+
128
+ - use explicit `insert` / `update` / `delete` when write intent should stay obvious at the call site
129
+ - use `mutate` when the business payload itself should drive the write behavior
130
+ - use `mutateBulk` when one payload contains mixed create/update/delete rows
131
+
132
+ That keeps write APIs expressive without overcomplicating caller logic.
133
+
134
+ ## Relation-aware writes and nested CRUD
135
+
136
+ Mutation is also where relations become operational, not only descriptive.
137
+
138
+ For `hasOne`, `hasMany`, and `belongsToMany` scenarios, nested writes can be expressed by combining the write payload with `include` or `with` relation definitions.
139
+
140
+ A representative `hasMany` pattern is:
141
+
142
+ ```typescript
143
+ await this.scope.model.order.update(
144
+ {
145
+ id: orderCreate.id,
146
+ orderNo: 'Order001-Update',
147
+ products: [
148
+ { name: 'Peach' },
149
+ { id: orderCreate.products?.[0].id, name: 'Apple-Update' },
150
+ { id: orderCreate.products?.[1].id, deleted: true },
151
+ ],
152
+ },
153
+ {
154
+ include: {
155
+ products: true,
156
+ },
157
+ },
158
+ );
159
+ ```
160
+
161
+ This is one of the strongest reasons mutation guidance must be read together with relation guidance.
162
+
163
+ ## Relationship to soft deletion
164
+
165
+ Deletion behavior is not always hard deletion. In Vona, mutation semantics may also interact with soft-delete behavior, model defaults, and cleanup policies.
166
+
167
+ Read this guide together with:
168
+
169
+ - [ORM Configuration Guide](/backend/orm-configuration-guide)
170
+ - [Relations Guide](/backend/relations-guide)
171
+ - [Transaction Guide](/backend/transaction-guide)
172
+
173
+ ## Relationship to magic methods
174
+
175
+ Legacy ORM docs also highlighted model-level convenience methods such as `getByName`, `updateById`, or custom helper methods that wrap ordinary mutation/select behavior.
176
+
177
+ The important rule is:
178
+
179
+ - magic-style methods are convenience entry points
180
+ - the underlying write semantics still come from the standard ORM mutation surface
181
+ - custom model methods take precedence when business-specific behavior is needed
182
+
183
+ That means mutation should stay conceptually grounded in the standard model methods even when convenience wrappers are present.
184
+
185
+ ## Implementation checks for ORM mutation changes
186
+
187
+ When writing mutation logic, ask:
188
+
189
+ 1. is this best expressed as explicit insert/update/delete?
190
+ 2. or is `mutate` a cleaner fit for the business flow?
191
+ 3. does the deletion behavior depend on Vona soft-delete semantics?
192
+ 4. does the write path also update related records through `include` or `with`?
193
+ 5. should the mutation contract be reflected in DTO or controller definitions too?
194
+
195
+ That helps keep write-path logic aligned with the ORM’s intended abstractions.
@@ -0,0 +1,243 @@
1
+ # ORM Select Guide
2
+
3
+ This guide explains how ORM select operations work in Vona within the Cabloy monorepo.
4
+
5
+ ## Why select operations matter
6
+
7
+ Select operations are where model definitions, relationships, filters, ordering, pagination, and caching behavior begin to interact.
8
+
9
+ Vona does not treat queries as untyped string fragments. It provides a richer model-aware query surface.
10
+
11
+ ## Basic select operations
12
+
13
+ Representative patterns:
14
+
15
+ ```typescript
16
+ await this.scope.model.post.select();
17
+ await this.scope.model.post.count();
18
+ await this.scope.model.post.selectAndCount();
19
+ await this.scope.model.post.get({ id });
20
+ await this.scope.model.post.mget(ids);
21
+ ```
22
+
23
+ These operations show the basic query vocabulary that services can build on.
24
+
25
+ ## Rich select parameters
26
+
27
+ `select` can combine:
28
+
29
+ - `distinct`
30
+ - `columns`
31
+ - `where`
32
+ - `joins`
33
+ - `orders`
34
+ - `offset`
35
+ - `limit`
36
+ - `include`
37
+ - `with`
38
+
39
+ Representative pattern:
40
+
41
+ ```typescript
42
+ await this.scope.model.post.select(
43
+ {
44
+ columns: ['id', 'title', 'userId'],
45
+ where: {
46
+ 'id': { _gt_: 1 },
47
+ 'testVonaUser.id': 1,
48
+ },
49
+ joins: [['innerJoin', 'testVonaUser', ['userId', 'testVonaUser.id']]],
50
+ offset: 0,
51
+ limit: 20,
52
+ orders: [['createdAt', 'desc']],
53
+ },
54
+ {
55
+ disableDeleted: false,
56
+ },
57
+ 'test-vona:user',
58
+ );
59
+ ```
60
+
61
+ This matters because Vona ORM encourages structured query building rather than ad hoc query scattering.
62
+
63
+ ## Query options
64
+
65
+ Representative option areas include:
66
+
67
+ - `disableDeleted`
68
+ - `disableCreateTime`
69
+ - `disableUpdateTime`
70
+ - `disableCacheQuery`
71
+ - `disableCacheEntity`
72
+ - `deleted`
73
+
74
+ This is important because select behavior may depend on caching and soft-deletion policy, not only on columns and filters.
75
+
76
+ ## `joins`, `include`, and `with`
77
+
78
+ A useful distinction is:
79
+
80
+ - `joins` shapes table-level join behavior
81
+ - `include` loads declared static relations
82
+ - `with` loads dynamic relations declared at the usage site
83
+
84
+ That means joins are not floating SQL trivia. They are part of a model-aware query system that can move between table-level control and relation-level convenience.
85
+
86
+ ## Type-guided joins
87
+
88
+ A key insight is that joinable tables often come from relationships already declared on the model.
89
+
90
+ In broader systems, not every useful join is declared on the current model. In those cases, the `_modelJoins` parameter can provide additional model hints so the join surface remains typed and discoverable.
91
+
92
+ ## `where` operators
93
+
94
+ The operator model is broad and includes examples like:
95
+
96
+ - `_eq_`
97
+ - `_notEq_`
98
+ - `_gt_`
99
+ - `_gte_`
100
+ - `_lt_`
101
+ - `_lte_`
102
+ - `_in_`
103
+ - `_notIn_`
104
+ - `_is_`
105
+ - `_isNot_`
106
+ - `_between_`
107
+ - `_notBetween_`
108
+ - `_startsWith_`
109
+ - `_endsWith_`
110
+ - `_includes_`
111
+ - case-insensitive variants
112
+ - `_ref_`
113
+ - `_skip_`
114
+
115
+ That operator vocabulary is part of the Cabloy data language and should be reused consistently.
116
+
117
+ A practical operator-family reading is:
118
+
119
+ - comparison: `_eq_`, `_notEq_`, `_gt_`, `_gte_`, `_lt_`, `_lte_`
120
+ - membership/range: `_in_`, `_notIn_`, `_between_`, `_notBetween_`
121
+ - null checks: `_is_`, `_isNot_`
122
+ - string matching: `_startsWith_`, `_endsWith_`, `_includes_`, and case-insensitive variants
123
+ - composition/subquery: `_and_`, `_or_`, `_not_`, `_exists_`, `_notExists_`
124
+ - identifier or composition helpers: `_ref_`, `_skip_`
125
+
126
+ ### `_skip_`
127
+
128
+ `_skip_` is especially useful when building query objects compositionally.
129
+
130
+ Representative pattern:
131
+
132
+ ```typescript
133
+ const where = {
134
+ title: { _includes_: 'ai' },
135
+ stars: { _gt_: 20 },
136
+ };
137
+
138
+ await this.scope.model.post.select({
139
+ where: {
140
+ ...where,
141
+ stars: '_skip_' as const,
142
+ },
143
+ });
144
+ ```
145
+
146
+ This lets a query builder remove one condition cleanly without rebuilding the whole `where` object by hand.
147
+
148
+ ## Joint operators and subqueries
149
+
150
+ The query language also supports joint operators such as:
151
+
152
+ - `_and_`
153
+ - `_or_`
154
+ - `_not_`
155
+ - `_exists_`
156
+ - `_notExists_`
157
+
158
+ These operators matter because many real queries are not flat field comparisons.
159
+
160
+ Representative `_exists_` pattern:
161
+
162
+ ```typescript
163
+ await this.scope.model.post.select({
164
+ where: {
165
+ _exists_: function (builder: Knex.QueryBuilder) {
166
+ builder
167
+ .select('*')
168
+ .from('testVonaPostContent')
169
+ .where('postId', this.scope.model.post.ref('testVonaPost.id'));
170
+ } as any,
171
+ },
172
+ });
173
+ ```
174
+
175
+ ## `raw` and `ref`
176
+
177
+ The structured query language is the default, but Vona still exposes escape hatches when they are truly needed.
178
+
179
+ Representative `raw` pattern:
180
+
181
+ ```typescript
182
+ await this.scope.model.post.select({
183
+ where: this.scope.model.post.raw('?? > ?', ['stars', 20]) as any,
184
+ });
185
+ ```
186
+
187
+ Representative `ref` pattern:
188
+
189
+ ```typescript
190
+ await this.scope.model.post.select({
191
+ where: {
192
+ title: {
193
+ _eq_: this.scope.model.post.ref('testVonaPost.title') as any,
194
+ },
195
+ },
196
+ });
197
+ ```
198
+
199
+ A practical rule is:
200
+
201
+ - start with structured operators first
202
+ - use `ref` when comparisons need identifier semantics
203
+ - use `raw` only when the structured surface is not sufficient
204
+
205
+ ## `selectAndCount` and pagination-shaped results
206
+
207
+ `selectAndCount` is especially useful when one backend query should return both rows and pagination metadata together.
208
+
209
+ A practical result shape includes:
210
+
211
+ - `list`
212
+ - `total`
213
+ - `pageCount`
214
+ - `pageSize`
215
+ - `pageNo`
216
+
217
+ This matters because page-query contracts often need more than a plain row array. They need a stable list-plus-metadata response shape that can map directly into DTOs and controller response contracts.
218
+
219
+ ## Relationship to aggregate/group and DTOs
220
+
221
+ Read this guide together with:
222
+
223
+ - [Relations Guide](/backend/relations-guide)
224
+ - [ORM Aggregate and Group Guide](/backend/orm-aggregate-group-guide)
225
+ - [DTO Infer and Generation](/backend/dto-infer-generation)
226
+
227
+ A practical split is:
228
+
229
+ - use this guide for row-oriented query structure
230
+ - use the aggregate/group guide when the result shape is summary-oriented
231
+ - use DTO guidance when query shape must become an explicit API contract
232
+
233
+ ## Implementation checks for ORM select changes
234
+
235
+ When writing or editing select logic:
236
+
237
+ 1. start from model relationships and typed query structure
238
+ 2. choose deliberately among `joins`, `include`, and `with`
239
+ 3. prefer the ORM query surface before dropping to raw SQL
240
+ 4. remember that soft-delete, cache, and datasource behavior may affect query semantics
241
+ 5. think about whether the query shape should also drive DTO or OpenAPI-facing output
242
+
243
+ That keeps query logic aligned with Vona’s intended abstractions.
@@ -0,0 +1,271 @@
1
+ # Queue Guide
2
+
3
+ This guide explains how queues work in Vona within the Cabloy monorepo.
4
+
5
+ ## Why queues matter
6
+
7
+ Vona provides a queue component based on BullMQ so business logic can be executed asynchronously and reliably through framework-native job handling.
8
+
9
+ This is one of the main bridges between synchronous application code and distributed background execution.
10
+
11
+ ## Create a queue
12
+
13
+ Example: create a queue named `add` in module `demo-student`.
14
+
15
+ ```bash
16
+ npm run vona :create:bean queue add -- --module=demo-student
17
+ ```
18
+
19
+ ## Queue definition
20
+
21
+ Representative shape:
22
+
23
+ ```typescript
24
+ @Queue()
25
+ export class QueueAdd
26
+ extends BeanQueueBase<TypeQueueAddJobData, TypeQueueAddJobResult>
27
+ implements IQueueExecute<TypeQueueAddJobData, TypeQueueAddJobResult>
28
+ {
29
+ async execute(
30
+ data: TypeQueueAddJobData,
31
+ _options?: IQueuePushOptions,
32
+ ): Promise<TypeQueueAddJobResult> {
33
+ return data.a + data.b;
34
+ }
35
+ }
36
+ ```
37
+
38
+ The important point is that queue jobs are strongly typed at both input and output boundaries.
39
+
40
+ ## Push jobs
41
+
42
+ Two main modes are supported:
43
+
44
+ - `push` for fire-and-forget jobs
45
+ - `pushAsync` for jobs where the caller awaits a result
46
+
47
+ Representative patterns:
48
+
49
+ ```typescript
50
+ this.scope.queue.add.push({ a: 1, b: 2 });
51
+ ```
52
+
53
+ ```typescript
54
+ const result = await this.scope.queue.add.pushAsync({ a: 1, b: 2 });
55
+ ```
56
+
57
+ This is important because it gives queue usage a clear business-level interface.
58
+
59
+ ## Push options and propagated context
60
+
61
+ `push` and `pushAsync` both support queue-push options.
62
+
63
+ Representative option areas include:
64
+
65
+ - `queueNameSub`
66
+ - `jobName`
67
+ - `jobOptions`
68
+ - `dbInfo`
69
+ - `locale`
70
+ - `instanceName`
71
+ - `extraData`
72
+
73
+ This matters because a queue push can propagate more than business payload alone. It can also carry runtime context that affects how the worker executes the job.
74
+
75
+ A practical push-context reading is:
76
+
77
+ | Field | Typical purpose |
78
+ | --------------- | --------------------------------------------------- |
79
+ | `data` | business payload |
80
+ | `queueNameSub` | refine queue routing |
81
+ | `jobName` | identify the job kind |
82
+ | `jobOptions` | pass BullMQ job options |
83
+ | `dbInfo` | control datasource/runtime database context |
84
+ | `locale` / `tz` | preserve request-oriented locale/timezone context |
85
+ | `instanceName` | preserve instance-aware execution context |
86
+ | `extraData` | pass selected request metadata or auxiliary context |
87
+
88
+ ## Datasource-level isolation and deadlock avoidance
89
+
90
+ One of the most important distributed queue details is datasource-level isolation.
91
+
92
+ A common risk looks like this:
93
+
94
+ 1. a request opens a database transaction
95
+ 2. the request pushes a queue job and awaits its result
96
+ 3. the worker handling the job also needs a database connection
97
+ 4. both sides could wait on the same constrained datasource pool
98
+
99
+ Vona avoids this by using datasource levels so queue work can run with an isolated datasource context.
100
+
101
+ A useful practical rule is:
102
+
103
+ - ordinary request code uses the current datasource level
104
+ - queued job execution is pushed to `current.level + 1`
105
+
106
+ Representative pattern:
107
+
108
+ ```typescript
109
+ await this.scope.queue.add.pushAsync(data);
110
+ ```
111
+
112
+ This behaves like passing:
113
+
114
+ ```typescript
115
+ await this.scope.queue.add.pushAsync(data, {
116
+ dbInfo: {
117
+ level: this.bean.database.current.level + 1,
118
+ },
119
+ });
120
+ ```
121
+
122
+ So queue behavior is not only “run later.” It also participates in connection-pool isolation and distributed consistency design.
123
+
124
+ A practical refinement is:
125
+
126
+ - queue push helpers prepare and carry runtime context explicitly before execution
127
+ - that is why queue jobs can preserve datasource, locale, and instance-aware behavior without forcing the business payload itself to hold every context field
128
+
129
+ For the surrounding datasource architecture, also see [Multi-Database and Datasource Guide](/backend/multi-database-datasource) and [Dynamic Datasource Guide](/backend/dynamic-datasource-guide).
130
+
131
+ ## Extra data and header passthrough
132
+
133
+ Queue pushes can also include `extraData`.
134
+
135
+ Representative pattern:
136
+
137
+ ```typescript
138
+ this.scope.queue.add.push(data, {
139
+ extraData: {
140
+ request: {
141
+ headers: {
142
+ 'x-custom': 'xxxx',
143
+ },
144
+ },
145
+ },
146
+ });
147
+ ```
148
+
149
+ The job can then read the propagated header value from request context:
150
+
151
+ ```typescript
152
+ @Queue()
153
+ class QueueAdd {
154
+ async execute(data, _options) {
155
+ console.log(this.ctx.headers['x-custom']);
156
+ }
157
+ }
158
+ ```
159
+
160
+ Vona also provides a header passthrough convention: headers prefixed with `x-vona-data-` are appended automatically to extra data and passed through to the job context.
161
+
162
+ This is useful when background work needs selected request metadata without manually copying every field into the main business payload.
163
+
164
+ ## Queue options
165
+
166
+ The queue system supports options around:
167
+
168
+ - concurrency
169
+ - transaction behavior
170
+ - Bull queue/worker/job options
171
+ - redlock-backed serial execution behavior
172
+
173
+ Representative decorator pattern:
174
+
175
+ ```typescript
176
+ @Queue({
177
+ concurrency: false,
178
+ transaction: false,
179
+ options: {
180
+ queue: {},
181
+ worker: {},
182
+ job: {},
183
+ redlock: {},
184
+ },
185
+ })
186
+ class QueueAdd {}
187
+ ```
188
+
189
+ That means queue behavior is not only asynchronous. It also participates in concurrency, isolation, and consistency policy.
190
+
191
+ ## Configure queues in app config
192
+
193
+ Queue options can also be overridden in app config.
194
+
195
+ Representative pattern:
196
+
197
+ ```typescript
198
+ config.onions = {
199
+ queue: {
200
+ 'demo-student:add': {
201
+ concurrency: false,
202
+ transaction: false,
203
+ options: {
204
+ queue: {},
205
+ worker: {},
206
+ job: {},
207
+ redlock: {},
208
+ },
209
+ },
210
+ },
211
+ };
212
+ ```
213
+
214
+ ## Enable/disable and environment scoping
215
+
216
+ Queues can also be enabled or limited by environment metadata such as flavor or mode.
217
+
218
+ Representative pattern:
219
+
220
+ ```typescript
221
+ @Queue({
222
+ meta: {
223
+ flavor: 'normal',
224
+ mode: 'dev',
225
+ },
226
+ })
227
+ class QueueAdd {}
228
+ ```
229
+
230
+ This is especially important in Cabloy because runtime environment and flavor are first-class concepts.
231
+
232
+ ## Relationship to startup, election, and broadcast
233
+
234
+ Read this guide together with:
235
+
236
+ - [Backend Startup Guide](/backend/startup-guide)
237
+ - [Election Guide](/backend/election-guide)
238
+ - [Broadcast Guide](/backend/broadcast-guide)
239
+ - [Worker Guide](/backend/worker-guide)
240
+ - [Schedule Guide](/backend/schedule-guide)
241
+ - [Redlock Guide](/backend/redlock-guide)
242
+
243
+ A practical split is:
244
+
245
+ - startup initializes queue workers and other runtime capabilities
246
+ - election decides which worker should own singleton-like responsibilities
247
+ - queue handles asynchronous point-to-point work
248
+ - broadcast sends the same message to multiple workers
249
+ - redlock helps serialize queue behavior when concurrent execution must be restricted
250
+
251
+ ## Inspection
252
+
253
+ The queue system can expose the effective queue list for inspection, which is useful for debugging and operational visibility.
254
+
255
+ Representative pattern:
256
+
257
+ ```typescript
258
+ this.bean.onion.queue.inspect();
259
+ ```
260
+
261
+ ## Implementation checks for background-job changes
262
+
263
+ When asked to move work into the background, ask:
264
+
265
+ 1. is this a queue job instead of an inline request-path operation?
266
+ 2. should the caller use `push` or `pushAsync`?
267
+ 3. does the queue need transactional, serialized, or datasource-isolated behavior?
268
+ 4. does the job need request metadata through `extraData` or header passthrough?
269
+ 5. should enable/disable rules depend on flavor or mode?
270
+
271
+ That keeps background work aligned with Vona’s distributed execution model.