@yss123/cage-cli 0.2.0 → 0.3.1

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 (629) hide show
  1. package/README.md +47 -3
  2. package/bin/cage.js +5 -0
  3. package/bin/create-cage-app.js +5 -0
  4. package/dist/analyze.d.ts +16 -0
  5. package/dist/analyze.js +18 -2
  6. package/dist/analyze.js.map +1 -1
  7. package/dist/approval-tree.d.ts +88 -0
  8. package/dist/approval-tree.js +18 -0
  9. package/dist/approval-tree.js.map +1 -0
  10. package/dist/baseline.d.ts +8 -0
  11. package/dist/baseline.js +13 -0
  12. package/dist/baseline.js.map +1 -1
  13. package/dist/bootstrap.d.ts +20 -0
  14. package/dist/bootstrap.js +75 -0
  15. package/dist/bootstrap.js.map +1 -0
  16. package/dist/budget.d.ts +7 -0
  17. package/dist/budget.js +49 -5
  18. package/dist/budget.js.map +1 -1
  19. package/dist/capabilities.d.ts +38 -0
  20. package/dist/capabilities.js +148 -0
  21. package/dist/capabilities.js.map +1 -0
  22. package/dist/config.d.ts +31 -2
  23. package/dist/config.js +22 -0
  24. package/dist/config.js.map +1 -1
  25. package/dist/context.d.ts +14 -0
  26. package/dist/context.js +35 -2
  27. package/dist/context.js.map +1 -1
  28. package/dist/create-prompt.d.ts +7 -0
  29. package/dist/create-prompt.js +12 -0
  30. package/dist/create-prompt.js.map +1 -1
  31. package/dist/create.d.ts +21 -1
  32. package/dist/create.js +23 -1
  33. package/dist/create.js.map +1 -1
  34. package/dist/derive.d.ts +23 -0
  35. package/dist/derive.js +40 -0
  36. package/dist/derive.js.map +1 -1
  37. package/dist/dev.d.ts +6 -0
  38. package/dist/dev.js +11 -0
  39. package/dist/dev.js.map +1 -1
  40. package/dist/doctor.d.ts +98 -0
  41. package/dist/doctor.js +93 -0
  42. package/dist/doctor.js.map +1 -0
  43. package/dist/env.d.ts +6 -0
  44. package/dist/env.js +11 -0
  45. package/dist/env.js.map +1 -1
  46. package/dist/findings.d.ts +27 -0
  47. package/dist/findings.js +20 -0
  48. package/dist/findings.js.map +1 -1
  49. package/dist/gen/contracts.d.ts +28 -0
  50. package/dist/gen/contracts.js +52 -12
  51. package/dist/gen/contracts.js.map +1 -1
  52. package/dist/gen/index.d.ts +26 -0
  53. package/dist/gen/index.js +69 -1
  54. package/dist/gen/index.js.map +1 -1
  55. package/dist/gen/zod-code.d.ts +42 -0
  56. package/dist/gen/zod-code.js +178 -16
  57. package/dist/gen/zod-code.js.map +1 -1
  58. package/dist/graph-approvals.d.ts +70 -0
  59. package/dist/graph-approvals.js +93 -0
  60. package/dist/graph-approvals.js.map +1 -0
  61. package/dist/graph-business.d.ts +135 -0
  62. package/dist/graph-business.js +404 -0
  63. package/dist/graph-business.js.map +1 -0
  64. package/dist/graph-command.d.ts +17 -0
  65. package/dist/graph-command.js +21 -0
  66. package/dist/graph-command.js.map +1 -1
  67. package/dist/graph-model.d.ts +44 -0
  68. package/dist/graph-model.js +36 -3
  69. package/dist/graph-model.js.map +1 -1
  70. package/dist/graph-presentation.d.ts +16 -0
  71. package/dist/graph-presentation.js +10 -1
  72. package/dist/graph-presentation.js.map +1 -1
  73. package/dist/graph-query.d.ts +95 -0
  74. package/dist/graph-query.js +62 -0
  75. package/dist/graph-query.js.map +1 -1
  76. package/dist/graph-relations.d.ts +20 -0
  77. package/dist/graph-relations.js +42 -10
  78. package/dist/graph-relations.js.map +1 -1
  79. package/dist/graph-search.d.ts +35 -0
  80. package/dist/graph-search.js +36 -0
  81. package/dist/graph-search.js.map +1 -1
  82. package/dist/graph-snapshot.d.ts +26 -0
  83. package/dist/graph-snapshot.js +30 -1
  84. package/dist/graph-snapshot.js.map +1 -1
  85. package/dist/graph.d.ts +13 -2
  86. package/dist/graph.js +61 -4
  87. package/dist/graph.js.map +1 -1
  88. package/dist/impact.d.ts +50 -0
  89. package/dist/impact.js +62 -2
  90. package/dist/impact.js.map +1 -1
  91. package/dist/index.d.ts +10 -0
  92. package/dist/index.js +10 -0
  93. package/dist/index.js.map +1 -1
  94. package/dist/init.d.ts +12 -0
  95. package/dist/init.js +15 -0
  96. package/dist/init.js.map +1 -1
  97. package/dist/load.d.ts +10 -0
  98. package/dist/load.js +15 -0
  99. package/dist/load.js.map +1 -1
  100. package/dist/main.d.ts +6 -0
  101. package/dist/main.js +93 -5
  102. package/dist/main.js.map +1 -1
  103. package/dist/migrate.d.ts +12 -0
  104. package/dist/migrate.js +17 -0
  105. package/dist/migrate.js.map +1 -1
  106. package/dist/ontology.d.ts +67 -2
  107. package/dist/ontology.js +94 -4
  108. package/dist/ontology.js.map +1 -1
  109. package/dist/process-rules.d.ts +21 -0
  110. package/dist/process-rules.js +100 -0
  111. package/dist/process-rules.js.map +1 -0
  112. package/dist/process.d.ts +32 -0
  113. package/dist/process.js +32 -0
  114. package/dist/process.js.map +1 -1
  115. package/dist/project-structure.d.ts +5 -0
  116. package/dist/project-structure.js +10 -0
  117. package/dist/project-structure.js.map +1 -1
  118. package/dist/registration.d.ts +16 -0
  119. package/dist/registration.js +56 -0
  120. package/dist/registration.js.map +1 -0
  121. package/dist/rules.d.ts +52 -0
  122. package/dist/rules.js +58 -0
  123. package/dist/rules.js.map +1 -1
  124. package/dist/runtime-diagnostics.d.ts +27 -0
  125. package/dist/runtime-diagnostics.js +60 -0
  126. package/dist/runtime-diagnostics.js.map +1 -0
  127. package/dist/snapshots.d.ts +40 -0
  128. package/dist/snapshots.js +62 -0
  129. package/dist/snapshots.js.map +1 -0
  130. package/dist/static-check.d.ts +33 -0
  131. package/dist/static-check.js +37 -1
  132. package/dist/static-check.js.map +1 -1
  133. package/dist/sync.d.ts +11 -0
  134. package/dist/sync.js +66 -9
  135. package/dist/sync.js.map +1 -1
  136. package/dist/upgrade.d.ts +16 -0
  137. package/dist/upgrade.js +21 -0
  138. package/dist/upgrade.js.map +1 -1
  139. package/dist/verify.d.ts +14 -0
  140. package/dist/verify.js +19 -0
  141. package/dist/verify.js.map +1 -1
  142. package/dist/version.js +5 -0
  143. package/dist/version.js.map +1 -1
  144. package/graph-ui/app.js +321 -27
  145. package/graph-ui/approval-flow.js +185 -0
  146. package/graph-ui/approval-parallel.js +110 -0
  147. package/graph-ui/approval-tree.js +17 -0
  148. package/graph-ui/business.css +1011 -0
  149. package/graph-ui/business.js +566 -0
  150. package/graph-ui/flowchart-interaction.js +177 -0
  151. package/graph-ui/flowchart.js +1059 -0
  152. package/graph-ui/graph-approvals.js +92 -0
  153. package/graph-ui/graph-business.js +403 -0
  154. package/graph-ui/graph-model.js +36 -3
  155. package/graph-ui/graph-relations.js +42 -10
  156. package/graph-ui/graph-search.js +36 -0
  157. package/graph-ui/index.html +26 -12
  158. package/graph-ui/model.js +28 -0
  159. package/graph-ui/relations.js +4 -0
  160. package/graph-ui/structure.js +44 -0
  161. package/graph-ui/style.css +12 -0
  162. package/package.json +6 -4
  163. package/templates/app/.dockerignore +2 -0
  164. package/templates/app/.env.example +10 -0
  165. package/templates/app/AGENTS.md +50 -10
  166. package/templates/app/README.md +9 -5
  167. package/templates/app/_gitignore +1 -0
  168. package/templates/app/apps/api/package.json +2 -2
  169. package/templates/app/apps/api/src/main.ts +5 -1
  170. package/templates/app/apps/api/src/worker.ts +3 -0
  171. package/templates/app/apps/web/index.html +1 -0
  172. package/templates/app/apps/web/package.json +7 -3
  173. package/templates/app/apps/web/src/app/app.tsx +122 -12
  174. package/templates/app/apps/web/src/app/styles/global.css +88 -8
  175. package/templates/app/apps/web/src/app/use-session.ts +43 -0
  176. package/templates/app/apps/web/src/app/workspace-layout.tsx +58 -19
  177. package/templates/app/apps/web/src/main.tsx +5 -0
  178. package/templates/app/apps/web/src/modules/approval/components/task-operation-dialog.tsx +61 -0
  179. package/templates/app/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +13 -5
  180. package/templates/app/apps/web/src/modules/approval/index.ts +4 -0
  181. package/templates/app/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +89 -38
  182. package/templates/app/apps/web/src/modules/approval/pages/approval-tasks.css +18 -0
  183. package/templates/app/apps/web/src/modules/auth/index.ts +4 -0
  184. package/templates/app/apps/web/src/modules/auth/pages/login-page.tsx +12 -0
  185. package/templates/app/apps/web/src/modules/inventory/index.ts +4 -0
  186. package/templates/app/apps/web/src/modules/inventory/pages/inventory-page.tsx +29 -1
  187. package/templates/app/apps/web/src/modules/purchase/components/approval-history.tsx +67 -0
  188. package/templates/app/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -0
  189. package/templates/app/apps/web/src/modules/purchase/components/order-reviewers.tsx +38 -0
  190. package/templates/app/apps/web/src/modules/purchase/components/purchase-assistant-context.tsx +17 -0
  191. package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.css +6 -0
  192. package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.tsx +32 -3
  193. package/templates/app/apps/web/src/modules/purchase/index.ts +5 -0
  194. package/templates/app/apps/web/src/modules/purchase/lib/presentation.ts +20 -0
  195. package/templates/app/apps/web/src/modules/purchase/pages/purchase-intelligence.css +17 -0
  196. package/templates/app/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +156 -0
  197. package/templates/app/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +54 -22
  198. package/templates/app/apps/web/src/modules/workspace/index.ts +5 -0
  199. package/templates/app/apps/web/src/modules/workspace/pages/home-page.tsx +44 -0
  200. package/templates/app/apps/web/src/shared/hooks/use-command.ts +13 -0
  201. package/templates/app/apps/web/src/shared/lib/error-message.ts +15 -1
  202. package/templates/app/apps/web/src/shared/lib/navigation.ts +21 -0
  203. package/templates/app/apps/web/src/shared/ui/approval-member-picker.css +10 -0
  204. package/templates/app/apps/web/src/shared/ui/approval-member-picker.tsx +51 -0
  205. package/templates/app/apps/web/src/shared/ui/assistant-markdown.tsx +19 -0
  206. package/templates/app/apps/web/src/shared/ui/assistant-panel.css +134 -0
  207. package/templates/app/apps/web/src/shared/ui/assistant-panel.tsx +200 -0
  208. package/templates/app/apps/web/src/shared/ui/assistant-scope.tsx +72 -0
  209. package/templates/app/apps/web/src/shared/ui/attachment-upload.css +28 -0
  210. package/templates/app/apps/web/src/shared/ui/attachment-upload.tsx +163 -0
  211. package/templates/app/apps/web/src/shared/ui/notice.tsx +7 -0
  212. package/templates/app/apps/web/src/shared/ui/page-heading.tsx +7 -0
  213. package/templates/app/apps/web/src/shared/ui/page-state.css +47 -0
  214. package/templates/app/apps/web/src/shared/ui/page-state.tsx +76 -0
  215. package/templates/app/apps/web/src/shared/ui/require-capability.tsx +34 -0
  216. package/templates/app/apps/web/vite.config.ts +5 -0
  217. package/templates/app/cage.config.json +23 -0
  218. package/templates/app/db/migrations/0002_draft.sql +12 -0
  219. package/templates/app/db/migrations/0003_draft.sql +8 -0
  220. package/templates/app/db/migrations/0004_draft.sql +27 -0
  221. package/templates/app/deploy/nginx.conf +52 -0
  222. package/templates/app/docs/ai/README.md +28 -2
  223. package/templates/app/docs/ai/approvals.md +260 -0
  224. package/templates/app/docs/ai/architecture.md +26 -0
  225. package/templates/app/docs/ai/commenting.md +203 -0
  226. package/templates/app/docs/ai/diagnostics.md +80 -0
  227. package/templates/app/docs/ai/files.md +93 -0
  228. package/templates/app/docs/ai/intelligence.md +348 -0
  229. package/templates/app/docs/ai/ontology-context.md +59 -4
  230. package/templates/app/docs/ai/primitives.md +34 -1
  231. package/templates/app/docs/ai/project-structure.md +8 -3
  232. package/templates/app/docs/ai/purchase-example.md +35 -7
  233. package/templates/app/docs/ai/recipes.md +10 -2
  234. package/templates/app/docs/ai/routing.md +86 -0
  235. package/templates/app/docs/ai/troubleshooting.md +5 -0
  236. package/templates/app/docs/ai/workflow.md +24 -11
  237. package/templates/app/docs/errors/CAGE-AI-001.md +61 -0
  238. package/templates/app/docs/errors/CAGE-APPR-001.md +13 -9
  239. package/templates/app/docs/errors/CAGE-APPR-002.md +2 -2
  240. package/templates/app/docs/errors/CAGE-APPR-003.md +1 -1
  241. package/templates/app/docs/errors/CAGE-APPR-004.md +4 -4
  242. package/templates/app/docs/errors/CAGE-APPR-005.md +4 -4
  243. package/templates/app/docs/errors/CAGE-APPR-006.md +29 -8
  244. package/templates/app/docs/errors/CAGE-APPR-007.md +9 -7
  245. package/templates/app/docs/errors/CAGE-APPR-010.md +5 -5
  246. package/templates/app/docs/errors/CAGE-AUDIT-001.md +53 -0
  247. package/templates/app/docs/errors/CAGE-AUTH-001.md +1 -1
  248. package/templates/app/docs/errors/CAGE-BIZ-001.md +51 -0
  249. package/templates/app/docs/errors/CAGE-BIZ-002.md +49 -0
  250. package/templates/app/docs/errors/CAGE-BUDGET-001.md +1 -1
  251. package/templates/app/docs/errors/CAGE-BUDGET-002.md +1 -1
  252. package/templates/app/docs/errors/CAGE-BUDGET-003.md +1 -1
  253. package/templates/app/docs/errors/CAGE-CMD-002.md +1 -1
  254. package/templates/app/docs/errors/CAGE-CMD-003.md +1 -1
  255. package/templates/app/docs/errors/CAGE-CONN-001.md +3 -3
  256. package/templates/app/docs/errors/CAGE-CONN-002.md +1 -1
  257. package/templates/app/docs/errors/CAGE-CONN-003.md +1 -1
  258. package/templates/app/docs/errors/CAGE-CONN-004.md +1 -1
  259. package/templates/app/docs/errors/CAGE-CONN-005.md +1 -1
  260. package/templates/app/docs/errors/CAGE-CONN-006.md +1 -1
  261. package/templates/app/docs/errors/CAGE-CONN-007.md +6 -6
  262. package/templates/app/docs/errors/CAGE-CONN-008.md +5 -5
  263. package/templates/app/docs/errors/CAGE-CONN-009.md +6 -6
  264. package/templates/app/docs/errors/CAGE-CONN-010.md +6 -6
  265. package/templates/app/docs/errors/CAGE-CONN-011.md +1 -1
  266. package/templates/app/docs/errors/CAGE-CONN-012.md +1 -1
  267. package/templates/app/docs/errors/CAGE-CONN-013.md +49 -0
  268. package/templates/app/docs/errors/CAGE-CONN-014.md +48 -0
  269. package/templates/app/docs/errors/CAGE-CONN-015.md +49 -0
  270. package/templates/app/docs/errors/CAGE-CREATE-001.md +10 -9
  271. package/templates/app/docs/errors/CAGE-DECL-001.md +2 -2
  272. package/templates/app/docs/errors/CAGE-DECL-002.md +7 -6
  273. package/templates/app/docs/errors/CAGE-DECL-003.md +1 -1
  274. package/templates/app/docs/errors/CAGE-DECL-004.md +1 -1
  275. package/templates/app/docs/errors/CAGE-DEP-001.md +2 -2
  276. package/templates/app/docs/errors/CAGE-DEP-002.md +1 -1
  277. package/templates/app/docs/errors/CAGE-DEP-003.md +2 -2
  278. package/templates/app/docs/errors/CAGE-DEP-004.md +1 -1
  279. package/templates/app/docs/errors/CAGE-DEP-005.md +1 -1
  280. package/templates/app/docs/errors/CAGE-DIAG-001.md +53 -0
  281. package/templates/app/docs/errors/CAGE-DLQ-001.md +2 -2
  282. package/templates/app/docs/errors/CAGE-ENV-001.md +4 -4
  283. package/templates/app/docs/errors/CAGE-ENV-002.md +51 -0
  284. package/templates/app/docs/errors/CAGE-ENV-003.md +48 -0
  285. package/templates/app/docs/errors/CAGE-EVENT-001.md +1 -1
  286. package/templates/app/docs/errors/CAGE-EVENT-002.md +7 -7
  287. package/templates/app/docs/errors/CAGE-FIELD-001.md +2 -2
  288. package/templates/app/docs/errors/CAGE-FIELD-002.md +1 -1
  289. package/templates/app/docs/errors/CAGE-FIELD-003.md +1 -1
  290. package/templates/app/docs/errors/CAGE-FIELD-004.md +1 -1
  291. package/templates/app/docs/errors/CAGE-FILE-001.md +56 -0
  292. package/templates/app/docs/errors/CAGE-GEN-001.md +2 -2
  293. package/templates/app/docs/errors/CAGE-GEN-002.md +1 -1
  294. package/templates/app/docs/errors/CAGE-GEN-003.md +53 -0
  295. package/templates/app/docs/errors/CAGE-GRANT-001.md +3 -3
  296. package/templates/app/docs/errors/CAGE-GRANT-002.md +2 -2
  297. package/templates/app/docs/errors/CAGE-GRANT-003.md +7 -6
  298. package/templates/app/docs/errors/CAGE-IMPACT-001.md +2 -2
  299. package/templates/app/docs/errors/CAGE-IMPACT-002.md +52 -0
  300. package/templates/app/docs/errors/CAGE-INIT-001.md +1 -1
  301. package/templates/app/docs/errors/CAGE-INIT-002.md +1 -1
  302. package/templates/app/docs/errors/CAGE-INIT-003.md +2 -2
  303. package/templates/app/docs/errors/CAGE-INIT-004.md +1 -1
  304. package/templates/app/docs/errors/CAGE-INIT-005.md +52 -0
  305. package/templates/app/docs/errors/CAGE-JOB-001.md +1 -1
  306. package/templates/app/docs/errors/CAGE-JOB-002.md +1 -1
  307. package/templates/app/docs/errors/CAGE-JOB-003.md +1 -1
  308. package/templates/app/docs/errors/CAGE-LINT-001.md +1 -1
  309. package/templates/app/docs/errors/CAGE-MIG-001.md +1 -1
  310. package/templates/app/docs/errors/CAGE-MIG-002.md +1 -1
  311. package/templates/app/docs/errors/CAGE-MIG-005.md +1 -1
  312. package/templates/app/docs/errors/CAGE-NAME-001.md +1 -1
  313. package/templates/app/docs/errors/CAGE-NAME-002.md +1 -1
  314. package/templates/app/docs/errors/CAGE-NAME-003.md +3 -3
  315. package/templates/app/docs/errors/CAGE-NAME-004.md +1 -1
  316. package/templates/app/docs/errors/CAGE-NAME-005.md +1 -1
  317. package/templates/app/docs/errors/CAGE-NAME-006.md +1 -1
  318. package/templates/app/docs/errors/CAGE-ORG-001.md +7 -6
  319. package/templates/app/docs/errors/CAGE-PAIR-002.md +6 -5
  320. package/templates/app/docs/errors/CAGE-QUERY-001.md +1 -1
  321. package/templates/app/docs/errors/CAGE-QUERY-002.md +2 -2
  322. package/templates/app/docs/errors/CAGE-QUERY-003.md +7 -6
  323. package/templates/app/docs/errors/CAGE-REACT-001.md +3 -3
  324. package/templates/app/docs/errors/CAGE-REACT-002.md +1 -1
  325. package/templates/app/docs/errors/CAGE-REACT-003.md +50 -0
  326. package/templates/app/docs/errors/CAGE-READS-001.md +9 -6
  327. package/templates/app/docs/errors/CAGE-REG-001.md +13 -12
  328. package/templates/app/docs/errors/CAGE-REG-002.md +2 -1
  329. package/templates/app/docs/errors/CAGE-REG-003.md +1 -1
  330. package/templates/app/docs/errors/CAGE-REL-001.md +14 -14
  331. package/templates/app/docs/errors/CAGE-ROUTE-001.md +7 -6
  332. package/templates/app/docs/errors/CAGE-SCOPE-001.md +1 -1
  333. package/templates/app/docs/errors/CAGE-SCOPE-002.md +2 -2
  334. package/templates/app/docs/errors/CAGE-SECRET-001.md +2 -2
  335. package/templates/app/docs/errors/CAGE-SECRET-002.md +1 -1
  336. package/templates/app/docs/errors/CAGE-SENS-001.md +5 -5
  337. package/templates/app/docs/errors/CAGE-SQL-001.md +1 -1
  338. package/templates/app/docs/errors/CAGE-SQL-002.md +1 -1
  339. package/templates/app/docs/errors/CAGE-STATE-001.md +3 -3
  340. package/templates/app/docs/errors/CAGE-STATE-002.md +1 -1
  341. package/templates/app/docs/errors/CAGE-STATE-003.md +1 -1
  342. package/templates/app/docs/errors/CAGE-STATE-004.md +1 -1
  343. package/templates/app/docs/errors/CAGE-STATE-005.md +3 -2
  344. package/templates/app/docs/errors/CAGE-STATE-010.md +5 -5
  345. package/templates/app/docs/errors/CAGE-STATE-011.md +5 -5
  346. package/templates/app/docs/errors/CAGE-STRUCT-001.md +1 -1
  347. package/templates/app/docs/errors/CAGE-STRUCT-002.md +1 -1
  348. package/templates/app/docs/errors/CAGE-SYNC-001.md +3 -2
  349. package/templates/app/docs/errors/CAGE-TEST-001.md +1 -1
  350. package/templates/app/docs/errors/CAGE-TEST-002.md +50 -0
  351. package/templates/app/docs/errors/CAGE-TEST-003.md +52 -0
  352. package/templates/app/docs/errors/CAGE-UNSAFE-001.md +3 -2
  353. package/templates/app/docs/errors/CAGE-UPGRADE-001.md +2 -2
  354. package/templates/app/docs/errors/CAGE-WORKER-001.md +48 -0
  355. package/templates/app/docs/errors/CAGE-WORKER-002.md +50 -0
  356. package/templates/app/docs/errors/CAGE-WORKER-003.md +48 -0
  357. package/templates/app/docs/errors/README.md +52 -2
  358. package/templates/app/package.json +3 -3
  359. package/templates/app/packages/contracts/package.json +1 -1
  360. package/templates/app/packages/contracts/src/aggregates/approval-member/index.ts +70 -0
  361. package/templates/app/packages/contracts/src/aggregates/dept/index.ts +10 -10
  362. package/templates/app/packages/contracts/src/aggregates/inventory/index.ts +5 -5
  363. package/templates/app/packages/contracts/src/aggregates/inventory-lock/index.ts +4 -4
  364. package/templates/app/packages/contracts/src/aggregates/purchase-order/index.ts +34 -12
  365. package/templates/app/packages/contracts/src/aggregates/role/index.ts +15 -15
  366. package/templates/app/packages/contracts/src/aggregates/user/index.ts +16 -16
  367. package/templates/app/packages/contracts/src/index.ts +16 -1
  368. package/templates/app/packages/contracts/src/queries/index.ts +2 -2
  369. package/templates/app/packages/domain/package.json +5 -4
  370. package/templates/app/packages/domain/src/index.ts +4 -0
  371. package/templates/app/packages/domain/src/integrations/erp.ts +15 -0
  372. package/templates/app/packages/domain/src/integrations/intelligence.ts +20 -0
  373. package/templates/app/packages/domain/src/modules/inventory/index.ts +1 -0
  374. package/templates/app/packages/domain/src/modules/inventory/inventory.ts +12 -0
  375. package/templates/app/packages/domain/src/modules/purchase/approval-members.ts +54 -0
  376. package/templates/app/packages/domain/src/modules/purchase/approvals.ts +38 -6
  377. package/templates/app/packages/domain/src/modules/purchase/index.ts +2 -0
  378. package/templates/app/packages/domain/src/modules/purchase/intelligence.test.ts +224 -0
  379. package/templates/app/packages/domain/src/modules/purchase/jobs.ts +5 -0
  380. package/templates/app/packages/domain/src/modules/purchase/purchase-order.test.ts +9 -0
  381. package/templates/app/packages/domain/src/modules/purchase/purchase-order.ts +125 -4
  382. package/templates/app/packages/domain/src/modules/purchase/queries.ts +5 -0
  383. package/templates/app/packages/domain/src/workflows/purchase-inventory.ts +6 -0
  384. package/templates/app/packages/domain/src/workflows/purchase-process.ts +42 -0
  385. package/templates/blank/.dockerignore +2 -0
  386. package/templates/blank/.env.example +10 -0
  387. package/templates/blank/AGENTS.md +50 -10
  388. package/templates/blank/README.md +4 -1
  389. package/templates/blank/_gitignore +1 -0
  390. package/templates/blank/apps/api/package.json +1 -1
  391. package/templates/blank/apps/api/src/main.ts +4 -1
  392. package/templates/blank/apps/api/src/worker.ts +2 -0
  393. package/templates/blank/apps/web/index.html +1 -0
  394. package/templates/blank/apps/web/package.json +7 -3
  395. package/templates/blank/apps/web/src/app/app.tsx +80 -18
  396. package/templates/blank/apps/web/src/app/styles/global.css +90 -0
  397. package/templates/blank/apps/web/src/app/use-session.ts +43 -0
  398. package/templates/blank/apps/web/src/app/workspace-layout.tsx +30 -5
  399. package/templates/blank/apps/web/src/main.tsx +5 -0
  400. package/templates/blank/apps/web/src/modules/auth/index.ts +4 -0
  401. package/templates/blank/apps/web/src/modules/auth/pages/login-page.tsx +18 -1
  402. package/templates/blank/apps/web/src/modules/directory/index.ts +7 -0
  403. package/templates/blank/apps/web/src/modules/directory/pages/user-detail-page.tsx +78 -0
  404. package/templates/blank/apps/web/src/modules/directory/pages/users-page.tsx +93 -0
  405. package/templates/blank/apps/web/src/modules/workspace/index.ts +4 -0
  406. package/templates/blank/apps/web/src/modules/workspace/pages/home-page.tsx +17 -0
  407. package/templates/blank/apps/web/src/shared/lib/error-message.ts +11 -0
  408. package/templates/blank/apps/web/src/shared/lib/navigation.ts +21 -0
  409. package/templates/blank/apps/web/src/shared/ui/brand.tsx +10 -2
  410. package/templates/blank/apps/web/src/shared/ui/page-state.css +47 -0
  411. package/templates/blank/apps/web/src/shared/ui/page-state.tsx +76 -0
  412. package/templates/blank/apps/web/src/shared/ui/require-capability.tsx +34 -0
  413. package/templates/blank/apps/web/vite.config.ts +5 -0
  414. package/templates/blank/deploy/nginx.conf +52 -0
  415. package/templates/blank/docs/ai/README.md +28 -2
  416. package/templates/blank/docs/ai/approvals.md +260 -0
  417. package/templates/blank/docs/ai/architecture.md +26 -0
  418. package/templates/blank/docs/ai/commenting.md +203 -0
  419. package/templates/blank/docs/ai/diagnostics.md +80 -0
  420. package/templates/blank/docs/ai/files.md +93 -0
  421. package/templates/blank/docs/ai/intelligence.md +348 -0
  422. package/templates/blank/docs/ai/ontology-context.md +59 -4
  423. package/templates/blank/docs/ai/primitives.md +34 -1
  424. package/templates/blank/docs/ai/project-structure.md +8 -3
  425. package/templates/blank/docs/ai/purchase-example.md +35 -7
  426. package/templates/blank/docs/ai/recipes.md +10 -2
  427. package/templates/blank/docs/ai/routing.md +86 -0
  428. package/templates/blank/docs/ai/troubleshooting.md +5 -0
  429. package/templates/blank/docs/ai/workflow.md +24 -11
  430. package/templates/blank/docs/errors/CAGE-AI-001.md +61 -0
  431. package/templates/blank/docs/errors/CAGE-APPR-001.md +13 -9
  432. package/templates/blank/docs/errors/CAGE-APPR-002.md +2 -2
  433. package/templates/blank/docs/errors/CAGE-APPR-003.md +1 -1
  434. package/templates/blank/docs/errors/CAGE-APPR-004.md +4 -4
  435. package/templates/blank/docs/errors/CAGE-APPR-005.md +4 -4
  436. package/templates/blank/docs/errors/CAGE-APPR-006.md +29 -8
  437. package/templates/blank/docs/errors/CAGE-APPR-007.md +9 -7
  438. package/templates/blank/docs/errors/CAGE-APPR-010.md +5 -5
  439. package/templates/blank/docs/errors/CAGE-AUDIT-001.md +53 -0
  440. package/templates/blank/docs/errors/CAGE-AUTH-001.md +1 -1
  441. package/templates/blank/docs/errors/CAGE-BIZ-001.md +51 -0
  442. package/templates/blank/docs/errors/CAGE-BIZ-002.md +49 -0
  443. package/templates/blank/docs/errors/CAGE-BUDGET-001.md +1 -1
  444. package/templates/blank/docs/errors/CAGE-BUDGET-002.md +1 -1
  445. package/templates/blank/docs/errors/CAGE-BUDGET-003.md +1 -1
  446. package/templates/blank/docs/errors/CAGE-CMD-002.md +1 -1
  447. package/templates/blank/docs/errors/CAGE-CMD-003.md +1 -1
  448. package/templates/blank/docs/errors/CAGE-CONN-001.md +3 -3
  449. package/templates/blank/docs/errors/CAGE-CONN-002.md +1 -1
  450. package/templates/blank/docs/errors/CAGE-CONN-003.md +1 -1
  451. package/templates/blank/docs/errors/CAGE-CONN-004.md +1 -1
  452. package/templates/blank/docs/errors/CAGE-CONN-005.md +1 -1
  453. package/templates/blank/docs/errors/CAGE-CONN-006.md +1 -1
  454. package/templates/blank/docs/errors/CAGE-CONN-007.md +6 -6
  455. package/templates/blank/docs/errors/CAGE-CONN-008.md +5 -5
  456. package/templates/blank/docs/errors/CAGE-CONN-009.md +6 -6
  457. package/templates/blank/docs/errors/CAGE-CONN-010.md +6 -6
  458. package/templates/blank/docs/errors/CAGE-CONN-011.md +1 -1
  459. package/templates/blank/docs/errors/CAGE-CONN-012.md +1 -1
  460. package/templates/blank/docs/errors/CAGE-CONN-013.md +49 -0
  461. package/templates/blank/docs/errors/CAGE-CONN-014.md +48 -0
  462. package/templates/blank/docs/errors/CAGE-CONN-015.md +49 -0
  463. package/templates/blank/docs/errors/CAGE-CREATE-001.md +10 -9
  464. package/templates/blank/docs/errors/CAGE-DECL-001.md +2 -2
  465. package/templates/blank/docs/errors/CAGE-DECL-002.md +7 -6
  466. package/templates/blank/docs/errors/CAGE-DECL-003.md +1 -1
  467. package/templates/blank/docs/errors/CAGE-DECL-004.md +1 -1
  468. package/templates/blank/docs/errors/CAGE-DEP-001.md +2 -2
  469. package/templates/blank/docs/errors/CAGE-DEP-002.md +1 -1
  470. package/templates/blank/docs/errors/CAGE-DEP-003.md +2 -2
  471. package/templates/blank/docs/errors/CAGE-DEP-004.md +1 -1
  472. package/templates/blank/docs/errors/CAGE-DEP-005.md +1 -1
  473. package/templates/blank/docs/errors/CAGE-DIAG-001.md +53 -0
  474. package/templates/blank/docs/errors/CAGE-DLQ-001.md +2 -2
  475. package/templates/blank/docs/errors/CAGE-ENV-001.md +4 -4
  476. package/templates/blank/docs/errors/CAGE-ENV-002.md +51 -0
  477. package/templates/blank/docs/errors/CAGE-ENV-003.md +48 -0
  478. package/templates/blank/docs/errors/CAGE-EVENT-001.md +1 -1
  479. package/templates/blank/docs/errors/CAGE-EVENT-002.md +7 -7
  480. package/templates/blank/docs/errors/CAGE-FIELD-001.md +2 -2
  481. package/templates/blank/docs/errors/CAGE-FIELD-002.md +1 -1
  482. package/templates/blank/docs/errors/CAGE-FIELD-003.md +1 -1
  483. package/templates/blank/docs/errors/CAGE-FIELD-004.md +1 -1
  484. package/templates/blank/docs/errors/CAGE-FILE-001.md +56 -0
  485. package/templates/blank/docs/errors/CAGE-GEN-001.md +2 -2
  486. package/templates/blank/docs/errors/CAGE-GEN-002.md +1 -1
  487. package/templates/blank/docs/errors/CAGE-GEN-003.md +53 -0
  488. package/templates/blank/docs/errors/CAGE-GRANT-001.md +3 -3
  489. package/templates/blank/docs/errors/CAGE-GRANT-002.md +2 -2
  490. package/templates/blank/docs/errors/CAGE-GRANT-003.md +7 -6
  491. package/templates/blank/docs/errors/CAGE-IMPACT-001.md +2 -2
  492. package/templates/blank/docs/errors/CAGE-IMPACT-002.md +52 -0
  493. package/templates/blank/docs/errors/CAGE-INIT-001.md +1 -1
  494. package/templates/blank/docs/errors/CAGE-INIT-002.md +1 -1
  495. package/templates/blank/docs/errors/CAGE-INIT-003.md +2 -2
  496. package/templates/blank/docs/errors/CAGE-INIT-004.md +1 -1
  497. package/templates/blank/docs/errors/CAGE-INIT-005.md +52 -0
  498. package/templates/blank/docs/errors/CAGE-JOB-001.md +1 -1
  499. package/templates/blank/docs/errors/CAGE-JOB-002.md +1 -1
  500. package/templates/blank/docs/errors/CAGE-JOB-003.md +1 -1
  501. package/templates/blank/docs/errors/CAGE-LINT-001.md +1 -1
  502. package/templates/blank/docs/errors/CAGE-MIG-001.md +1 -1
  503. package/templates/blank/docs/errors/CAGE-MIG-002.md +1 -1
  504. package/templates/blank/docs/errors/CAGE-MIG-005.md +1 -1
  505. package/templates/blank/docs/errors/CAGE-NAME-001.md +1 -1
  506. package/templates/blank/docs/errors/CAGE-NAME-002.md +1 -1
  507. package/templates/blank/docs/errors/CAGE-NAME-003.md +3 -3
  508. package/templates/blank/docs/errors/CAGE-NAME-004.md +1 -1
  509. package/templates/blank/docs/errors/CAGE-NAME-005.md +1 -1
  510. package/templates/blank/docs/errors/CAGE-NAME-006.md +1 -1
  511. package/templates/blank/docs/errors/CAGE-ORG-001.md +7 -6
  512. package/templates/blank/docs/errors/CAGE-PAIR-002.md +6 -5
  513. package/templates/blank/docs/errors/CAGE-QUERY-001.md +1 -1
  514. package/templates/blank/docs/errors/CAGE-QUERY-002.md +2 -2
  515. package/templates/blank/docs/errors/CAGE-QUERY-003.md +7 -6
  516. package/templates/blank/docs/errors/CAGE-REACT-001.md +3 -3
  517. package/templates/blank/docs/errors/CAGE-REACT-002.md +1 -1
  518. package/templates/blank/docs/errors/CAGE-REACT-003.md +50 -0
  519. package/templates/blank/docs/errors/CAGE-READS-001.md +9 -6
  520. package/templates/blank/docs/errors/CAGE-REG-001.md +13 -12
  521. package/templates/blank/docs/errors/CAGE-REG-002.md +2 -1
  522. package/templates/blank/docs/errors/CAGE-REG-003.md +1 -1
  523. package/templates/blank/docs/errors/CAGE-REL-001.md +14 -14
  524. package/templates/blank/docs/errors/CAGE-ROUTE-001.md +7 -6
  525. package/templates/blank/docs/errors/CAGE-SCOPE-001.md +1 -1
  526. package/templates/blank/docs/errors/CAGE-SCOPE-002.md +2 -2
  527. package/templates/blank/docs/errors/CAGE-SECRET-001.md +2 -2
  528. package/templates/blank/docs/errors/CAGE-SECRET-002.md +1 -1
  529. package/templates/blank/docs/errors/CAGE-SENS-001.md +5 -5
  530. package/templates/blank/docs/errors/CAGE-SQL-001.md +1 -1
  531. package/templates/blank/docs/errors/CAGE-SQL-002.md +1 -1
  532. package/templates/blank/docs/errors/CAGE-STATE-001.md +3 -3
  533. package/templates/blank/docs/errors/CAGE-STATE-002.md +1 -1
  534. package/templates/blank/docs/errors/CAGE-STATE-003.md +1 -1
  535. package/templates/blank/docs/errors/CAGE-STATE-004.md +1 -1
  536. package/templates/blank/docs/errors/CAGE-STATE-005.md +3 -2
  537. package/templates/blank/docs/errors/CAGE-STATE-010.md +5 -5
  538. package/templates/blank/docs/errors/CAGE-STATE-011.md +5 -5
  539. package/templates/blank/docs/errors/CAGE-STRUCT-001.md +1 -1
  540. package/templates/blank/docs/errors/CAGE-STRUCT-002.md +1 -1
  541. package/templates/blank/docs/errors/CAGE-SYNC-001.md +3 -2
  542. package/templates/blank/docs/errors/CAGE-TEST-001.md +1 -1
  543. package/templates/blank/docs/errors/CAGE-TEST-002.md +50 -0
  544. package/templates/blank/docs/errors/CAGE-TEST-003.md +52 -0
  545. package/templates/blank/docs/errors/CAGE-UNSAFE-001.md +3 -2
  546. package/templates/blank/docs/errors/CAGE-UPGRADE-001.md +2 -2
  547. package/templates/blank/docs/errors/CAGE-WORKER-001.md +48 -0
  548. package/templates/blank/docs/errors/CAGE-WORKER-002.md +50 -0
  549. package/templates/blank/docs/errors/CAGE-WORKER-003.md +48 -0
  550. package/templates/blank/docs/errors/README.md +52 -2
  551. package/templates/blank/docs/examples/purchase-admin/apps/api/src/main.ts +5 -1
  552. package/templates/blank/docs/examples/purchase-admin/apps/api/src/worker.ts +3 -0
  553. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/app.tsx +122 -12
  554. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/styles/global.css +88 -8
  555. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/use-session.ts +43 -0
  556. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/workspace-layout.tsx +58 -19
  557. package/templates/blank/docs/examples/purchase-admin/apps/web/src/main.tsx +5 -0
  558. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/components/task-operation-dialog.tsx +61 -0
  559. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +13 -5
  560. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/index.ts +4 -0
  561. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +89 -38
  562. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/pages/approval-tasks.css +18 -0
  563. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/index.ts +4 -0
  564. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/pages/login-page.tsx +12 -0
  565. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/index.ts +4 -0
  566. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/pages/inventory-page.tsx +29 -1
  567. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/approval-history.tsx +67 -0
  568. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -0
  569. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/order-reviewers.tsx +38 -0
  570. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-assistant-context.tsx +17 -0
  571. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-order-form.css +6 -0
  572. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/purchase-order-form.tsx +32 -3
  573. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/index.ts +5 -0
  574. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/lib/presentation.ts +20 -0
  575. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-intelligence.css +17 -0
  576. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +156 -0
  577. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +54 -22
  578. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/workspace/index.ts +5 -0
  579. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/workspace/pages/home-page.tsx +44 -0
  580. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/hooks/use-command.ts +13 -0
  581. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/error-message.ts +15 -1
  582. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/navigation.ts +21 -0
  583. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/approval-member-picker.css +10 -0
  584. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/approval-member-picker.tsx +51 -0
  585. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-markdown.tsx +19 -0
  586. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-panel.css +134 -0
  587. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-panel.tsx +200 -0
  588. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-scope.tsx +72 -0
  589. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/attachment-upload.css +28 -0
  590. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/attachment-upload.tsx +163 -0
  591. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/notice.tsx +7 -0
  592. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-heading.tsx +7 -0
  593. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-state.css +47 -0
  594. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-state.tsx +76 -0
  595. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/require-capability.tsx +34 -0
  596. package/templates/blank/docs/examples/purchase-admin/cage.config.json +23 -0
  597. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/approval-member/index.ts +70 -0
  598. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/dept/index.ts +10 -10
  599. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory/index.ts +5 -5
  600. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory-lock/index.ts +4 -4
  601. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/purchase-order/index.ts +34 -12
  602. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/role/index.ts +15 -15
  603. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/user/index.ts +16 -16
  604. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/index.ts +16 -1
  605. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/queries/index.ts +2 -2
  606. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/index.ts +4 -0
  607. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/erp.ts +15 -0
  608. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/intelligence.ts +20 -0
  609. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/index.ts +1 -0
  610. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/inventory.ts +12 -0
  611. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approval-members.ts +54 -0
  612. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approvals.ts +38 -6
  613. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/index.ts +2 -0
  614. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/intelligence.test.ts +224 -0
  615. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/jobs.ts +5 -0
  616. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.test.ts +9 -0
  617. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.ts +125 -4
  618. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/queries.ts +5 -0
  619. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-inventory.ts +6 -0
  620. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-process.ts +42 -0
  621. package/templates/blank/package.json +3 -3
  622. package/templates/blank/packages/contracts/package.json +1 -1
  623. package/templates/blank/packages/contracts/src/aggregates/dept/index.ts +10 -10
  624. package/templates/blank/packages/contracts/src/aggregates/role/index.ts +15 -15
  625. package/templates/blank/packages/contracts/src/aggregates/user/index.ts +16 -16
  626. package/templates/blank/packages/contracts/src/index.ts +1 -1
  627. package/templates/blank/packages/contracts/src/queries/index.ts +1 -1
  628. package/templates/blank/packages/domain/package.json +5 -4
  629. package/templates/blank/packages/domain/src/index.ts +2 -1
@@ -2,6 +2,11 @@
2
2
  import { daysAgo, job } from '@yss123/cage-kernel';
3
3
  import { PurchaseOrder, cancel } from './purchase-order.js';
4
4
 
5
+ /**
6
+ * 每日 02:00 候选周期清理创建超过三十天且仍为 draft 的单据,时间解释沿用 worker 调度器环境。
7
+ * reads/calls 是实际运行白名单;查询默认批次上限为 1000,逐条取消各自经过独立命令事务。
8
+ * 已成功取消的单据不会再次匹配 draft;中途失败保留已提交进度,不能把本轮任务视为整体回滚。
9
+ */
5
10
  export const expireStaleOrders = job('expireStaleOrders', {
6
11
  cron: '0 2 * * *',
7
12
  reads: [PurchaseOrder],
@@ -10,6 +10,10 @@ import * as domain from '../../index.js';
10
10
  let env: TestEnv;
11
11
  let buyer: TestUser;
12
12
  let manager: TestUser;
13
+ /**
14
+ * 夹具通过真实命令建立部门负责人和库存,不绕过领域规则直接造业务行。
15
+ * 申请人和经理能力分开,经理额度限定为 50000,确保后续断言真的经过职责分离与额度分支。
16
+ */
13
17
  beforeAll(async () => {
14
18
  env = await createTestEnv({
15
19
  domain,
@@ -27,6 +31,7 @@ beforeAll(async () => {
27
31
  });
28
32
  afterAll(() => env?.close());
29
33
 
34
+ /** 创建并提交一张 1200 元、两件 A-01 的采购单;只推进领域状态,不在此助手中消费 outbox。 */
30
35
  async function submitted() {
31
36
  const ctx = await buyer.ctx();
32
37
  const order = await env.kernel.execute(
@@ -37,6 +42,7 @@ async function submitted() {
37
42
  return env.kernel.execute('PurchaseOrder.submit', { id: order.id }, ctx);
38
43
  }
39
44
 
45
+ /** 同时验证同步提交边界、异步释放与审计条数,避免把命令成功返回当作后台已完成。 */
40
46
  it('审批成功同事务建锁;取消后 worker 释放锁,且每步都有审计', async () => {
41
47
  const order = await submitted();
42
48
  const process = env.kernel.processCtx({
@@ -62,6 +68,7 @@ it('审批成功同事务建锁;取消后 worker 释放锁,且每步都有
62
68
  ).toHaveLength(1);
63
69
  });
64
70
 
71
+ /** process 只是调用来源,onBehalfOf 仍保留实际操作者;流程身份不得消除创建人分离约束。 */
65
72
  it('提单人不能借流程身份审批自己的采购单', async () => {
66
73
  const order = await submitted();
67
74
  const process = env.kernel.processCtx({
@@ -75,6 +82,7 @@ it('提单人不能借流程身份审批自己的采购单', async () => {
75
82
  );
76
83
  });
77
84
 
85
+ /** 通过控制事件消费顺序模拟 ERP 响应迟到,覆盖取消和收货两条终态路径及后续锁释放。 */
78
86
  it.each(['cancelled', 'received'] as const)(
79
87
  '采购单进入 %s 后,延迟的 ERP 回写保留终态且不会阻塞解锁',
80
88
  async (status) => {
@@ -118,6 +126,7 @@ it.each(['cancelled', 'received'] as const)(
118
126
  },
119
127
  );
120
128
 
129
+ /** 低额度反例检查硬约束阻止批准,且同事务反应没有留下半成功的占用记录。 */
121
130
  it('审批额度不够时保留待审批状态,不创建库存锁', async () => {
122
131
  const order = await submitted();
123
132
  const lowLimit = await env.user({
@@ -1,12 +1,17 @@
1
- // 采购单声明集中列出状态、范围、不变量、命令和事件。
2
- // handler 只读声明的依赖;数据库写入、版本检查、审计由内核完成。
1
+ /**
2
+ * 采购单声明集中列出申请材料、专业复核名单、状态、范围、命令和事件,由 API、worker 和生成器统一消费。
3
+ * 草稿可编辑专业复核名单,提交重新核对协作名录;handler 仅读取声明依赖,数据库写入、版本与审计由内核完成。
4
+ * 审批结论仍以 process 命令执行职责分离、额度和库存检查;选入名录或路由不授予权限。
5
+ */
3
6
  import {
4
7
  aggregate,
8
+ bool,
5
9
  ceiling,
6
10
  command,
7
11
  emit,
8
12
  event,
9
13
  fail,
14
+ files,
10
15
  id,
11
16
  int,
12
17
  list,
@@ -16,22 +21,47 @@ import {
16
21
  sod,
17
22
  states,
18
23
  text,
24
+ type ReadRepo,
19
25
  } from '@yss123/cage-kernel';
20
26
  import { z } from 'zod';
21
27
  import { Inventory } from '../inventory/index.js';
28
+ import { ApprovalMember } from './approval-members.js';
22
29
 
30
+ /**
31
+ * 采购单生命周期:草稿提交后等待审批,通过后等待外部收货;退回修改重新进入草稿。
32
+ * received/rejected/cancelled 是流程终点,终点标记供图谱检查;记录迟到 ERP 回执仍由专门命令显式允许。
33
+ */
23
34
  export const POStatus = states('draft', 'pending_approval', 'approved', 'received', 'rejected', 'cancelled', {
24
35
  terminal: ['received', 'rejected', 'cancelled'],
25
36
  });
26
37
 
38
+ /**
39
+ * 采购主对象保存申请材料、流程状态和外部回执;不在此聚合直接维护库存占用记录。
40
+ * 所有写入都要求正金额和非空明细;部门字段提供范围依据,实际可见部门由当前角色授权决定。
41
+ * 金额和附件在数据库提交前由字段原语校验,用户不能通过修改前端界面绕过约束。
42
+ */
27
43
  export const PurchaseOrder = aggregate('PurchaseOrder', {
28
44
  fields: {
45
+ /** 归属部门;创建输入省略时使用操作者部门,也是审批选人与部门子树范围的依据。 */
29
46
  deptId: ref('Dept'),
47
+ /** 创建人由内核设置,用于本人范围与审批职责分离,客户端不提供该身份。 */
30
48
  createdBy: ref('User'),
49
+ /** 可缺省的供应商电话;普通读侧按 phone 策略掩码,明文读取需要单独授权和审计。 */
31
50
  supplierPhone: text(32).sensitive('phone').optional(),
51
+ /** 采购总额,以十进制金额字符串传输,最多两位小数;范例按元解释,不存整数分。 */
32
52
  amount: money(),
53
+ /** 可为空的用途说明;创建可先存草稿,AI 预审会判断是否足以支撑审批。 */
54
+ reason: text(2000).optional(),
55
+ /** 是否增加专业会签;旧记录 null/缺省按 false,不改变已经启动的审批实例。 */
56
+ needsSpecialistReview: bool().optional(),
57
+ /** 提交快照的专业复核用户 UUID;旧记录可为空,启用复核时必须为 1–5 个不同且非创建人的有效名录用户。 */
58
+ reviewerIds: list(id()).optional(),
59
+ /** 申请明细快照:sku 为物料编码,qty 为整数件数;输入额外要求每行数量为正。 */
33
60
  items: list({ sku: text(64), qty: int() }),
61
+ /** ERP 成功响应后回填的外部单号,尚未同步时为空;不作为采购单生命周期状态。 */
34
62
  erpNo: text(64).optional(),
63
+ /** 最多十个私有文件 ID;每个上限 2 GiB,命令提交时才把 ready 上传与本单事务绑定。 */
64
+ attachments: files({ maxCount: 10, maxBytes: 2 * 1024 ** 3, accept: ['application/pdf', 'image/jpeg', 'image/png', 'text/plain'] }),
35
65
  },
36
66
  states: POStatus,
37
67
  scope: scope.deptSubtree('deptId'),
@@ -41,16 +71,42 @@ export const PurchaseOrder = aggregate('PurchaseOrder', {
41
71
  },
42
72
  });
43
73
 
74
+ /** 提交快照供审批启动:orderId 关联主对象,金额和部门供声明过的路由条件使用。 */
44
75
  export const OrderSubmitted = event('OrderSubmitted', { orderId: id(), amount: money(), deptId: id() });
76
+ /** 审批通过时固定需要占用/推送的物料明细,同一份事件驱动同事务建锁和异步 ERP 推送。 */
45
77
  export const OrderApproved = event('OrderApproved', {
46
78
  orderId: id(),
47
79
  items: list({ sku: text(64), qty: int() }),
48
80
  });
81
+ /** 取消记录原状态,使释放反应只处理此前已经批准、实际持锁的采购单。 */
49
82
  export const OrderCancelled = event('OrderCancelled', { orderId: id(), previousStatus: text() });
83
+ /** 外部收货确认后发出,后台据此释放采购占用;不携带可直接写库的库存指令。 */
50
84
  export const OrderReceived = event('OrderReceived', { orderId: id() });
51
85
 
86
+ /** 命令输入比持久化 int 原语更具体:至少一行且每行数量为正,避免零数量申请进入审批。 */
52
87
  const itemsInput = z.array(z.object({ sku: z.string(), qty: z.number().int().positive() })).min(1);
53
88
 
89
+ /**
90
+ * 在设置和提交时核对专业复核名单,防止界面被绕过、名录退役或重复账号减少会签人数。
91
+ * disabled/范围/批准能力仍由审批运行时处理;此处只按当前命令声明的名录读依赖判断业务成员 active。
92
+ * 关闭专业复核必须传空名单;旧记录 null 等价 false/[]。最多五人使逐人查询有明确上限。
93
+ */
94
+ async function validateReviewers(needsReview: boolean | null | undefined, ids: string[] | null | undefined, creator: string, members: ReadRepo<typeof ApprovalMember>) {
95
+ const selected = ids ?? [];
96
+ if (!needsReview) return selected.length ? fail('REVIEWERS_NOT_REQUIRED', '未启用专业复核时请清空复核人员') : undefined;
97
+ if (selected.length < 1 || selected.length > 5) return fail('REVIEWERS_REQUIRED', '专业复核需选择 1–5 位协作人');
98
+ if (new Set(selected).size !== selected.length) return fail('DUPLICATE_REVIEWERS', '同一人不能重复承担专业会签');
99
+ if (selected.includes(creator)) return fail('REVIEWER_IS_APPLICANT', '提单人不能担任本单专业复核人');
100
+ for (const userId of selected) {
101
+ if (!await members.findOne({ userId, status: 'active' })) return fail('REVIEWER_UNAVAILABLE', '所选专业复核人不在有效协作名录中');
102
+ }
103
+ }
104
+
105
+ /**
106
+ * 保存草稿;金额格式、字段长度和不变量由内核随后统一校验,handler 无额外副作用。
107
+ * deptId 可指定但仍须满足创建范围;attachments 为已完成上传 ID,省略时初始化为空集合。
108
+ * 此处不提交审批、不调用 ERP,便于用户先完成材料整理。
109
+ */
54
110
  export const create = command(PurchaseOrder, {
55
111
  from: 'new',
56
112
  to: 'draft',
@@ -58,18 +114,76 @@ export const create = command(PurchaseOrder, {
58
114
  amount: z.string(),
59
115
  items: itemsInput,
60
116
  supplierPhone: z.string().optional(),
117
+ reason: z.string().max(2000).optional(),
118
+ needsSpecialistReview: z.boolean().optional(),
119
+ reviewerIds: z.array(z.string().uuid()).max(5).optional(),
61
120
  deptId: z.string().uuid().optional(),
121
+ attachments: z.array(z.string().uuid()).max(10).optional(),
62
122
  }),
63
- handler: (o) => o,
123
+ // 草稿允许先保存未选完的复核需求;提交才要求完整名单,新记录统一 false/[],旧记录兼容 null。
124
+ handler: (o) => ({ ...o, needsSpecialistReview: o.needsSpecialistReview ?? false, reviewerIds: o.reviewerIds ?? [] }),
125
+ });
126
+
127
+ /**
128
+ * 在 draft 中调整本单专业复核需求和名单;需要 PurchaseOrder.setReviewers,不能直接修改待审批快照。
129
+ * 输入保存前核对 1–5 位不同且非提单人的 active 名录成员;关闭时用 false/[],失败整次回滚。
130
+ * 提交还会重新查询名录,以拒绝保存后退役的成员;名录不授予对单据的读取、批准能力或额度。
131
+ */
132
+ export const setReviewers = command(PurchaseOrder, {
133
+ name: 'setReviewers', description: '设置采购单专业复核需求和人员', from: 'draft', to: null,
134
+ input: z.object({ id: z.string().uuid(), needsSpecialistReview: z.boolean(), reviewerIds: z.array(z.string().uuid()).max(5) }),
135
+ reads: { members: ApprovalMember },
136
+ handler: async (draft, input, { members }) => {
137
+ const invalid = await validateReviewers(input.needsSpecialistReview, input.reviewerIds, draft.createdBy, members);
138
+ return invalid ?? { needsSpecialistReview: input.needsSpecialistReview, reviewerIds: input.reviewerIds };
139
+ },
140
+ });
141
+
142
+ // 退回后的说明只在草稿状态修改,保留提交时的版本校验和原始审计。
143
+ /** 只更新用途并保留 draft 状态;trim 后至少一个字符,修改结果与版本递增、审计一起提交。 */
144
+ export const explainPurpose = command(PurchaseOrder, {
145
+ from: 'draft', to: null,
146
+ description: '补充采购用途与必要性,保存后可以重新提交审核',
147
+ input: z.object({ id: z.string().uuid(), reason: z.string().trim().min(1).max(2000) }),
148
+ handler: (_draft, input) => ({ reason: input.reason }),
149
+ });
150
+
151
+ /** 审批流程将材料不足的单据退回草稿;process 专用,浏览器不能绕过待办直接调用。 */
152
+ export const returnForChanges = command(PurchaseOrder, {
153
+ from: 'pending_approval', to: 'draft', invokedBy: 'process',
154
+ description: '审核材料不足时退回修改,重提后重新进行 AI 和人工审核',
155
+ handler: (draft) => draft,
64
156
  });
65
157
 
158
+ // 附件变更与其他业务写入一样受状态、版本、范围和审计约束;审批后不能替换原始材料。
159
+ /** 替换完整附件 ID 集合,空数组表示移除全部;上传归属检查、绑定和解绑由同一命令事务落实。 */
160
+ export const setAttachments = command(PurchaseOrder, {
161
+ from: 'draft', to: null,
162
+ input: z.object({ id: z.string().uuid(), attachments: z.array(z.string().uuid()).max(10) }),
163
+ handler: (_draft, input) => ({ attachments: input.attachments }),
164
+ });
165
+
166
+ /**
167
+ * 提交前重查专业复核名单,避免草稿保存后退役的成员进入新流程;缺省旧字段按无需复核处理。
168
+ * 成功只改变状态并记录 OrderSubmitted,实例由 worker 消费后创建;HTTP 成功不表示审批完成。
169
+ */
66
170
  export const submit = command(PurchaseOrder, {
67
171
  from: 'draft',
68
172
  to: 'pending_approval',
69
173
  emits: [OrderSubmitted],
70
- handler: (o) => (o.items.length === 0 ? fail('NO_ITEMS') : o),
174
+ reads: { members: ApprovalMember },
175
+ handler: async (o, _input, { members }) => {
176
+ if (o.items.length === 0) return fail('NO_ITEMS');
177
+ return await validateReviewers(o.needsSpecialistReview, o.reviewerIds, o.createdBy, members) ?? o;
178
+ },
71
179
  });
72
180
 
181
+ /**
182
+ * 审批终结命令必须同时满足创建人与审批人分离、当前角色额度,以及声明的库存只读检查。
183
+ * stock 是 reads 绑定的受范围约束仓储;找不到 SKU 或登记数量不足时返回 STOCK_SHORT 并回滚。
184
+ * 该检查不扣减 available;真正占用由 OrderApproved 的同事务反应创建 InventoryLock。
185
+ * 范例展示资源配对,不实现多订单累计扣减、仓库出入库或价格核算。
186
+ */
73
187
  export const approve = command(PurchaseOrder, {
74
188
  from: 'pending_approval',
75
189
  to: 'approved',
@@ -87,6 +201,7 @@ export const approve = command(PurchaseOrder, {
87
201
  },
88
202
  });
89
203
 
204
+ /** 人工审批拒绝后进入终态;此时尚未批准建锁,因此不需要发出库存释放事件。 */
90
205
  export const reject = command(PurchaseOrder, {
91
206
  from: 'pending_approval',
92
207
  to: 'rejected',
@@ -94,6 +209,10 @@ export const reject = command(PurchaseOrder, {
94
209
  handler: (o) => o,
95
210
  });
96
211
 
212
+ /**
213
+ * 草稿、待审批和已批准单据均可取消;显式事件映射使用提交前快照保留 previousStatus。
214
+ * 待审批取消会关闭对应审批,已批准取消会异步释放锁;两者都由订阅声明处理。
215
+ */
97
216
  export const cancel = command(PurchaseOrder, {
98
217
  from: ['draft', 'pending_approval', 'approved'],
99
218
  to: 'cancelled',
@@ -102,6 +221,7 @@ export const cancel = command(PurchaseOrder, {
102
221
  });
103
222
 
104
223
  // 仅连接器能回写 ERP 单号和收货结论,浏览器无法直接调用这两个命令。
224
+ /** 接受可能迟到的 ERP 回执,只补单号并递增版本;to:null 明确保留 approved/received/cancelled 原状态。 */
105
225
  export const recordErpNo = command(PurchaseOrder, {
106
226
  // ERP 推送可能早于取消发出、晚于取消返回;收货回调也可能先于推送应答到达。
107
227
  // 这里只记录外部回执,保留当前生命周期,保证 outbox 后续的解锁事件能够继续投递。
@@ -112,6 +232,7 @@ export const recordErpNo = command(PurchaseOrder, {
112
232
  handler: (_o, input) => ({ erpNo: input.erpNo }),
113
233
  });
114
234
 
235
+ /** 只允许已批准单据确认收货;验签后的 external 调用触发事件,库存释放需等待 worker 消费。 */
115
236
  export const markReceived = command(PurchaseOrder, {
116
237
  from: 'approved',
117
238
  to: 'received',
@@ -3,6 +3,11 @@ import { query } from '@yss123/cage-kernel';
3
3
  import { z } from 'zod';
4
4
  import { PurchaseOrder } from './purchase-order.js';
5
5
 
6
+ /**
7
+ * 按指定状态统计当前调用者可见采购单的部门分布,结果为 dept_id 与整数 n。
8
+ * reads 声明触发 PurchaseOrder.read 检查;safe.purchase_order 继续执行租户和数据范围过滤。
9
+ * :status 由内核绑定为参数,结果不代表跨权限的全公司统计;本声明没有业务写入副作用。
10
+ */
6
11
  export const poByStatus = query('poByStatus', {
7
12
  reads: [PurchaseOrder],
8
13
  input: z.object({ status: z.string() }),
@@ -4,6 +4,10 @@ import { reaction } from '@yss123/cage-kernel';
4
4
  import { OrderApproved, OrderCancelled, OrderReceived } from '../modules/purchase/index.js';
5
5
  import { acquireLock, releaseLock } from '../modules/inventory/index.js';
6
6
 
7
+ /**
8
+ * 审批与建锁共用一笔数据库事务,任一命令失败则二者回滚;不会出现批准成功但没有锁的中间提交。
9
+ * acquires 仅供图规则配对,实际写入来自 acquireLock,映射只传当前批准事件的固定快照。
10
+ */
7
11
  export const lockOnApprove = reaction(OrderApproved, {
8
12
  command: acquireLock,
9
13
  tx: 'same',
@@ -11,12 +15,14 @@ export const lockOnApprove = reaction(OrderApproved, {
11
15
  map: (e) => ({ id: e.orderId, orderId: e.orderId, items: e.items }),
12
16
  });
13
17
 
18
+ /** 草稿/待审批取消从未建锁,返回 null 跳过;已批准取消进入 outbox,等待 worker 按单据顺序释放。 */
14
19
  export const releaseOnCancel = reaction(OrderCancelled, {
15
20
  command: releaseLock,
16
21
  releases: 'inventory.lock',
17
22
  map: (e) => (e.previousStatus === 'approved' ? { id: e.orderId } : null),
18
23
  });
19
24
 
25
+ /** 收货事件保证来自已批准单据,因此按订单 ID 释放;默认异步失败由 worker 重试/死信处理。 */
20
26
  export const releaseOnReceive = reaction(OrderReceived, {
21
27
  command: releaseLock,
22
28
  releases: 'inventory.lock',
@@ -0,0 +1,42 @@
1
+ // 阅读规格引用真实命令与审批;人工收货通知与自动锁库存分别表达。
2
+ import { businessProcess } from '@yss123/cage-kernel';
3
+ import { PurchaseOrder, create, submit, approve, reject, cancel, markReceived, poApproval, returnForChanges, explainPurpose } from '../modules/purchase/index.js';
4
+ import { InventoryLock, acquireLock, releaseLock } from '../modules/inventory/index.js';
5
+
6
+ /**
7
+ * 面向人和 agent 的流程阅读规格,引用真实命令、审批和资源对象,供本体图展示及一致性检查。
8
+ * stages/transitions 说明人工、自动和等待关系,本声明本身不调度命令,也不新增权限或运行时副作用。
9
+ * 自动动作的真实事务和异步边界分别以 approval、reaction、connector 声明为准。
10
+ */
11
+ export const purchaseLifecycle = businessProcess('purchase-lifecycle', {
12
+ title: '采购全流程', description: '从填写申请、提交审批到确认收货,查看库存占用与释放。',
13
+ area: { id: 'purchase', title: '采购管理', description: '采购申请、审批、收货与库存协作。' },
14
+ subject: PurchaseOrder, entry: 'create',
15
+ stages: {
16
+ create: { title: '填写采购申请', description: '录入采购金额和明细,保存采购草稿。', actor: '申请人', action: create },
17
+ submit: { title: '提交申请', description: '检查明细并提交采购审批。', actor: '申请人', action: submit },
18
+ approval: { title: '采购审批', description: 'AI 先核查材料;通过后部门经理审批,金额超过五万元时增加财务审批。疑难材料由本步骤转人工。', actor: 'AI、部门经理、财务', kind: 'decision', action: poApproval },
19
+ returned: { title: '退回修改', description: '材料不足退回草稿,保留本轮审核理由。', actor: '审批流程', action: returnForChanges },
20
+ revise: { title: '补充采购用途', description: '依据建议补充用途,再次提交后从 AI 预审开始。', actor: '申请人', action: explainPurpose },
21
+ approved: { title: '批准并锁定库存', description: '审批结论通过权限、额度和库存校验后,同事务锁定所需库存。', actor: '审批流程与系统', action: approve,
22
+ related: [{ object: InventoryLock, label: '同事务锁库存', via: acquireLock }] },
23
+ received: { title: '确认收货', description: '接收外部收货通知并更新采购单,异步释放库存锁。', actor: '外部系统与系统', kind: 'end', action: markReceived,
24
+ related: [{ object: InventoryLock, label: '收货后释放占用', via: releaseLock }] },
25
+ rejected: { title: '审批驳回', description: '驳回结论通过领域命令落到采购单,本范例此轮采购结束。', actor: '审批流程', kind: 'end', action: reject },
26
+ cancelled: { title: '取消采购', description: '申请人取消采购;若已批准则按实际映射释放库存占用。', actor: '申请人', kind: 'end', action: cancel,
27
+ related: [{ object: InventoryLock, label: '按原状态释放占用', via: releaseLock }] },
28
+ },
29
+ transitions: [
30
+ { from: 'create', to: 'submit', mode: 'manual', label: '填写完成后提交' },
31
+ { from: 'submit', to: 'approval', mode: 'automatic', label: '提交成功后启动审批' },
32
+ { from: 'approval', to: 'approved', mode: 'automatic', label: '审批通过' },
33
+ { from: 'approval', to: 'rejected', mode: 'automatic', label: '审批驳回' },
34
+ { from: 'approval', to: 'returned', mode: 'automatic', label: '材料不足' },
35
+ { from: 'returned', to: 'revise', mode: 'manual', label: '补充材料' },
36
+ { from: 'revise', to: 'submit', mode: 'manual', label: '重新提交' },
37
+ { from: 'approved', to: 'received', mode: 'wait', label: '等待外部收货通知' },
38
+ { from: 'create', to: 'cancelled', mode: 'manual', label: '取消草稿', branch: true },
39
+ { from: 'submit', to: 'cancelled', mode: 'manual', label: '取消审批中的采购', branch: true },
40
+ { from: 'approved', to: 'cancelled', mode: 'manual', label: '取消已批准采购', branch: true },
41
+ ],
42
+ });
@@ -11,9 +11,9 @@
11
11
  "build:app": "pnpm --filter @app/domain build && pnpm --filter @app/api build && pnpm --filter @app/web build"
12
12
  },
13
13
  "devDependencies": {
14
- "@yss123/cage-cli": "0.2.0",
15
- "@yss123/cage-testkit": "0.2.0",
16
- "@yss123/cage-lint": "0.2.0",
14
+ "@yss123/cage-cli": "0.3.1",
15
+ "@yss123/cage-testkit": "0.3.1",
16
+ "@yss123/cage-lint": "0.3.1",
17
17
  "@types/node": "^24.3.0",
18
18
  "typescript": "~5.9.3",
19
19
  "vitest": "^4.1.12",
@@ -10,7 +10,7 @@
10
10
  "typecheck": "tsc -p tsconfig.json --noEmit"
11
11
  },
12
12
  "dependencies": {
13
- "@yss123/cage-client": "0.2.0",
13
+ "@yss123/cage-client": "0.3.1",
14
14
  "zod": "^4.1.5"
15
15
  }
16
16
  }
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable */
3
3
 
4
4
  import { z } from 'zod';
5
- import { client, useCageList, useCageQuery, type TransferTask } from '@yss123/cage-client';
5
+ import { client, useCageList, useCageQuery, type TransferTask, type RequestOptions } from '@yss123/cage-client';
6
6
 
7
7
  /** 部门:读侧快照(敏感字段是按权限掩码后的值) */
8
8
  export const DeptSchema = z.object({
@@ -23,9 +23,9 @@ export const DeptStates = ['active', 'archived'] as const;
23
23
 
24
24
  /** 命令输入:和后端命令的输入校验完全一致 */
25
25
  export const DeptInputs = {
26
- archive: z.object({ id: z.string().uuid() }),
27
- create: z.object({ name: z.string().min(1).max(100), code: z.string().max(64).optional(), parentId: z.string().uuid().nullable().optional(), leaderId: z.string().uuid().nullable().optional() }),
28
- update: z.object({ id: z.string().uuid(), name: z.string().min(1).max(100).optional(), code: z.string().max(64).nullable().optional(), leaderId: z.string().uuid().nullable().optional() }),
26
+ archive: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")) }),
27
+ create: z.object({ name: z.string().min(1).max(100), code: z.string().max(64).optional(), parentId: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")).nullable().optional(), leaderId: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")).nullable().optional() }),
28
+ update: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")), name: z.string().min(1).max(100).optional(), code: z.string().max(64).nullable().optional(), leaderId: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")).nullable().optional() }),
29
29
  };
30
30
 
31
31
  /** Dept.archive 可能返回的错误码 */
@@ -55,15 +55,15 @@ export interface DeptListParams {
55
55
  /** 调用方法:每个命令一个;client 自动生成并附带幂等键和 CSRF 令牌 */
56
56
  export const dept = {
57
57
  /** 停用部门(没有在职用户和下级部门时) */
58
- archive: (id: string, expectedVersion?: number) => client.post<Dept, DeptArchiveError>(`/api/dept/${encodeURIComponent(id)}/archive`, { expectedVersion }),
58
+ archive: (id: string, expectedVersion?: number, options: RequestOptions = {}) => client.post<Dept, DeptArchiveError>(`/api/dept/${encodeURIComponent(id)}/archive`, { expectedVersion }, options),
59
59
  /** 新建部门 */
60
- create: (input: z.input<typeof DeptInputs.create>) => client.post<Dept, DeptCreateError>('/api/dept/create', input),
60
+ create: (input: z.input<typeof DeptInputs.create>, options: RequestOptions = {}) => client.post<Dept, DeptCreateError>('/api/dept/create', input, options),
61
61
  /** 修改部门名称、编码、负责人 */
62
- update: (id: string, input: Omit<z.input<typeof DeptInputs.update>, 'id'>, expectedVersion?: number) => client.post<Dept, DeptUpdateError>(`/api/dept/${encodeURIComponent(id)}/update`, { ...input, expectedVersion }),
62
+ update: (id: string, input: Omit<z.input<typeof DeptInputs.update>, 'id'>, expectedVersion?: number, options: RequestOptions = {}) => client.post<Dept, DeptUpdateError>(`/api/dept/${encodeURIComponent(id)}/update`, { ...input, expectedVersion }, options),
63
63
  /** 异步导出 CSV:返回任务,使用 client.transfer(id) 查状态,完成后下载。需要 Dept.export 能力。 */
64
- export: (params: DeptListParams = {}, options: { idempotencyKey?: string } = {}) => client.post<TransferTask, 'CONFLICT'>('/api/dept/export', params, options),
65
- get: (id: string) => client.get<Dept>(`/api/dept/${encodeURIComponent(id)}`),
66
- list: (params: DeptListParams = {}) => client.get<{ items: Dept[]; total: number; page: number; pageSize: number }>('/api/dept', params as Record<string, unknown>),
64
+ export: (params: DeptListParams = {}, options: RequestOptions = {}) => client.post<TransferTask, 'CONFLICT'>('/api/dept/export', params, options),
65
+ get: (id: string, options: RequestOptions = {}) => client.get<Dept>(`/api/dept/${encodeURIComponent(id)}`, undefined, options),
66
+ list: (params: DeptListParams = {}, options: RequestOptions = {}) => client.get<{ items: Dept[]; total: number; page: number; pageSize: number }>('/api/dept', params as Record<string, unknown>, options),
67
67
  };
68
68
 
69
69
  /** 详情查询 hook:响应也用 schema 校验;范围外返回 NOT_FOUND */
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable */
3
3
 
4
4
  import { z } from 'zod';
5
- import { client, useCageList, useCageQuery, type TransferTask } from '@yss123/cage-client';
5
+ import { client, useCageList, useCageQuery, type TransferTask, type RequestOptions } from '@yss123/cage-client';
6
6
 
7
7
  /** 角色:读侧快照(敏感字段是按权限掩码后的值) */
8
8
  export const RoleSchema = z.object({
@@ -22,12 +22,12 @@ export const RoleStates = ['active', 'archived'] as const;
22
22
 
23
23
  /** 命令输入:和后端命令的输入校验完全一致 */
24
24
  export const RoleInputs = {
25
- archive: z.object({ id: z.string().uuid() }),
25
+ archive: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")) }),
26
26
  create: z.object({ code: z.string().min(1).max(64).regex(new RegExp("^[a-z][a-z0-9_]*$")), name: z.string().min(1).max(100) }),
27
- grantCapability: z.object({ id: z.string().uuid(), capability: z.string().min(1).max(200), params: z.record(z.string(), z.unknown()).optional() }),
28
- rename: z.object({ id: z.string().uuid(), name: z.string().min(1).max(100) }),
29
- revokeCapability: z.object({ id: z.string().uuid(), capability: z.string().min(1).max(200) }),
30
- setScope: z.object({ id: z.string().uuid(), aggregate: z.string().min(1).max(100), combinator: z.enum(["all", "self", "dept", "deptSubtree", "deptSet"]).nullable(), deptIds: z.array(z.string().uuid()).optional() }),
27
+ grantCapability: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")), capability: z.string().min(1).max(200), params: z.record(z.string(), z.unknown()).optional() }),
28
+ rename: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")), name: z.string().min(1).max(100) }),
29
+ revokeCapability: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")), capability: z.string().min(1).max(200) }),
30
+ setScope: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")), aggregate: z.string().min(1).max(100), combinator: z.enum(["all", "self", "dept", "deptSubtree", "deptSet"]).nullable(), deptIds: z.array(z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"))).optional() }),
31
31
  };
32
32
 
33
33
  /** Role.archive 可能返回的错误码 */
@@ -60,21 +60,21 @@ export interface RoleListParams {
60
60
  /** 调用方法:每个命令一个;client 自动生成并附带幂等键和 CSRF 令牌 */
61
61
  export const role = {
62
62
  /** 停用角色 */
63
- archive: (id: string, expectedVersion?: number) => client.post<Role, RoleArchiveError>(`/api/role/${encodeURIComponent(id)}/archive`, { expectedVersion }),
63
+ archive: (id: string, expectedVersion?: number, options: RequestOptions = {}) => client.post<Role, RoleArchiveError>(`/api/role/${encodeURIComponent(id)}/archive`, { expectedVersion }, options),
64
64
  /** 新建角色(默认没有任何能力) */
65
- create: (input: z.input<typeof RoleInputs.create>) => client.post<Role, RoleCreateError>('/api/role/create', input),
65
+ create: (input: z.input<typeof RoleInputs.create>, options: RequestOptions = {}) => client.post<Role, RoleCreateError>('/api/role/create', input, options),
66
66
  /** 给角色授予能力点(不能授出自己没有的能力点) */
67
- grantCapability: (id: string, input: Omit<z.input<typeof RoleInputs.grantCapability>, 'id'>, expectedVersion?: number) => client.post<Role, RoleGrantCapabilityError>(`/api/role/${encodeURIComponent(id)}/grant-capability`, { ...input, expectedVersion }),
67
+ grantCapability: (id: string, input: Omit<z.input<typeof RoleInputs.grantCapability>, 'id'>, expectedVersion?: number, options: RequestOptions = {}) => client.post<Role, RoleGrantCapabilityError>(`/api/role/${encodeURIComponent(id)}/grant-capability`, { ...input, expectedVersion }, options),
68
68
  /** 修改角色名称 */
69
- rename: (id: string, input: Omit<z.input<typeof RoleInputs.rename>, 'id'>, expectedVersion?: number) => client.post<Role, RoleRenameError>(`/api/role/${encodeURIComponent(id)}/rename`, { ...input, expectedVersion }),
69
+ rename: (id: string, input: Omit<z.input<typeof RoleInputs.rename>, 'id'>, expectedVersion?: number, options: RequestOptions = {}) => client.post<Role, RoleRenameError>(`/api/role/${encodeURIComponent(id)}/rename`, { ...input, expectedVersion }, options),
70
70
  /** 收回角色的能力点 */
71
- revokeCapability: (id: string, input: Omit<z.input<typeof RoleInputs.revokeCapability>, 'id'>, expectedVersion?: number) => client.post<Role, RoleRevokeCapabilityError>(`/api/role/${encodeURIComponent(id)}/revoke-capability`, { ...input, expectedVersion }),
71
+ revokeCapability: (id: string, input: Omit<z.input<typeof RoleInputs.revokeCapability>, 'id'>, expectedVersion?: number, options: RequestOptions = {}) => client.post<Role, RoleRevokeCapabilityError>(`/api/role/${encodeURIComponent(id)}/revoke-capability`, { ...input, expectedVersion }, options),
72
72
  /** 设置角色在某个聚合上的数据范围(不能授出比自己更宽的范围) */
73
- setScope: (id: string, input: Omit<z.input<typeof RoleInputs.setScope>, 'id'>, expectedVersion?: number) => client.post<Role, RoleSetScopeError>(`/api/role/${encodeURIComponent(id)}/set-scope`, { ...input, expectedVersion }),
73
+ setScope: (id: string, input: Omit<z.input<typeof RoleInputs.setScope>, 'id'>, expectedVersion?: number, options: RequestOptions = {}) => client.post<Role, RoleSetScopeError>(`/api/role/${encodeURIComponent(id)}/set-scope`, { ...input, expectedVersion }, options),
74
74
  /** 异步导出 CSV:返回任务,使用 client.transfer(id) 查状态,完成后下载。需要 Role.export 能力。 */
75
- export: (params: RoleListParams = {}, options: { idempotencyKey?: string } = {}) => client.post<TransferTask, 'CONFLICT'>('/api/role/export', params, options),
76
- get: (id: string) => client.get<Role>(`/api/role/${encodeURIComponent(id)}`),
77
- list: (params: RoleListParams = {}) => client.get<{ items: Role[]; total: number; page: number; pageSize: number }>('/api/role', params as Record<string, unknown>),
75
+ export: (params: RoleListParams = {}, options: RequestOptions = {}) => client.post<TransferTask, 'CONFLICT'>('/api/role/export', params, options),
76
+ get: (id: string, options: RequestOptions = {}) => client.get<Role>(`/api/role/${encodeURIComponent(id)}`, undefined, options),
77
+ list: (params: RoleListParams = {}, options: RequestOptions = {}) => client.get<{ items: Role[]; total: number; page: number; pageSize: number }>('/api/role', params as Record<string, unknown>, options),
78
78
  };
79
79
 
80
80
  /** 详情查询 hook:响应也用 schema 校验;范围外返回 NOT_FOUND */
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable */
3
3
 
4
4
  import { z } from 'zod';
5
- import { client, useCageList, useCageQuery, type TransferTask } from '@yss123/cage-client';
5
+ import { client, useCageList, useCageQuery, type TransferTask, type RequestOptions } from '@yss123/cage-client';
6
6
 
7
7
  /** 用户:读侧快照(敏感字段是按权限掩码后的值) */
8
8
  export const UserSchema = z.object({
@@ -25,12 +25,12 @@ export const UserStates = ['active', 'disabled'] as const;
25
25
 
26
26
  /** 命令输入:和后端命令的输入校验完全一致 */
27
27
  export const UserInputs = {
28
- assignRoles: z.object({ id: z.string().uuid(), roleIds: z.array(z.string().uuid()).max(50) }),
29
- create: z.object({ username: z.string().min(2).max(64).regex(new RegExp("^[A-Za-z0-9_.@-]+$")), name: z.string().min(1).max(100), deptId: z.string().uuid(), phone: z.string().max(32).nullable().optional(), email: z.string().email().max(200).nullable().optional(), ssoSubject: z.string().max(200).nullable().optional() }),
30
- disable: z.object({ id: z.string().uuid() }),
31
- enable: z.object({ id: z.string().uuid() }),
32
- setPassword: z.object({ id: z.string().uuid(), password: z.string().min(8).max(200) }),
33
- update: z.object({ id: z.string().uuid(), name: z.string().min(1).max(100).optional(), deptId: z.string().uuid().optional(), phone: z.string().max(32).nullable().optional(), email: z.string().email().max(200).nullable().optional() }),
28
+ assignRoles: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")), roleIds: z.array(z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"))).max(50) }),
29
+ create: z.object({ username: z.string().min(2).max(64).regex(new RegExp("^[A-Za-z0-9_.@-]+$")), name: z.string().min(1).max(100), deptId: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")), phone: z.string().max(32).nullable().optional(), email: z.string().email().max(200).nullable().optional(), ssoSubject: z.string().max(200).nullable().optional() }),
30
+ disable: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")) }),
31
+ enable: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")) }),
32
+ setPassword: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")), password: z.string().min(8).max(200) }),
33
+ update: z.object({ id: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")), name: z.string().min(1).max(100).optional(), deptId: z.string().uuid().regex(new RegExp("^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$")).optional(), phone: z.string().max(32).nullable().optional(), email: z.string().email().max(200).nullable().optional() }),
34
34
  };
35
35
 
36
36
  /** User.assignRoles 可能返回的错误码 */
@@ -64,21 +64,21 @@ export interface UserListParams {
64
64
  /** 调用方法:每个命令一个;client 自动生成并附带幂等键和 CSRF 令牌 */
65
65
  export const user = {
66
66
  /** 设置用户的角色(不能分配包含自己没有的能力的角色) */
67
- assignRoles: (id: string, input: Omit<z.input<typeof UserInputs.assignRoles>, 'id'>, expectedVersion?: number) => client.post<User, UserAssignRolesError>(`/api/user/${encodeURIComponent(id)}/assign-roles`, { ...input, expectedVersion }),
67
+ assignRoles: (id: string, input: Omit<z.input<typeof UserInputs.assignRoles>, 'id'>, expectedVersion?: number, options: RequestOptions = {}) => client.post<User, UserAssignRolesError>(`/api/user/${encodeURIComponent(id)}/assign-roles`, { ...input, expectedVersion }, options),
68
68
  /** 新建用户(默认没有任何角色) */
69
- create: (input: z.input<typeof UserInputs.create>) => client.post<User, UserCreateError>('/api/user/create', input),
69
+ create: (input: z.input<typeof UserInputs.create>, options: RequestOptions = {}) => client.post<User, UserCreateError>('/api/user/create', input, options),
70
70
  /** 停用用户 */
71
- disable: (id: string, expectedVersion?: number) => client.post<User, UserDisableError>(`/api/user/${encodeURIComponent(id)}/disable`, { expectedVersion }),
71
+ disable: (id: string, expectedVersion?: number, options: RequestOptions = {}) => client.post<User, UserDisableError>(`/api/user/${encodeURIComponent(id)}/disable`, { expectedVersion }, options),
72
72
  /** 启用用户 */
73
- enable: (id: string, expectedVersion?: number) => client.post<User, UserEnableError>(`/api/user/${encodeURIComponent(id)}/enable`, { expectedVersion }),
73
+ enable: (id: string, expectedVersion?: number, options: RequestOptions = {}) => client.post<User, UserEnableError>(`/api/user/${encodeURIComponent(id)}/enable`, { expectedVersion }, options),
74
74
  /** 重置密码 */
75
- setPassword: (id: string, input: Omit<z.input<typeof UserInputs.setPassword>, 'id'>, expectedVersion?: number) => client.post<User, UserSetPasswordError>(`/api/user/${encodeURIComponent(id)}/set-password`, { ...input, expectedVersion }),
75
+ setPassword: (id: string, input: Omit<z.input<typeof UserInputs.setPassword>, 'id'>, expectedVersion?: number, options: RequestOptions = {}) => client.post<User, UserSetPasswordError>(`/api/user/${encodeURIComponent(id)}/set-password`, { ...input, expectedVersion }, options),
76
76
  /** 修改用户信息 */
77
- update: (id: string, input: Omit<z.input<typeof UserInputs.update>, 'id'>, expectedVersion?: number) => client.post<User, UserUpdateError>(`/api/user/${encodeURIComponent(id)}/update`, { ...input, expectedVersion }),
77
+ update: (id: string, input: Omit<z.input<typeof UserInputs.update>, 'id'>, expectedVersion?: number, options: RequestOptions = {}) => client.post<User, UserUpdateError>(`/api/user/${encodeURIComponent(id)}/update`, { ...input, expectedVersion }, options),
78
78
  /** 异步导出 CSV:返回任务,使用 client.transfer(id) 查状态,完成后下载。需要 User.export 能力。 */
79
- export: (params: UserListParams = {}, options: { idempotencyKey?: string } = {}) => client.post<TransferTask, 'CONFLICT'>('/api/user/export', params, options),
80
- get: (id: string) => client.get<User>(`/api/user/${encodeURIComponent(id)}`),
81
- list: (params: UserListParams = {}) => client.get<{ items: User[]; total: number; page: number; pageSize: number }>('/api/user', params as Record<string, unknown>),
79
+ export: (params: UserListParams = {}, options: RequestOptions = {}) => client.post<TransferTask, 'CONFLICT'>('/api/user/export', params, options),
80
+ get: (id: string, options: RequestOptions = {}) => client.get<User>(`/api/user/${encodeURIComponent(id)}`, undefined, options),
81
+ list: (params: UserListParams = {}, options: RequestOptions = {}) => client.get<{ items: User[]; total: number; page: number; pageSize: number }>('/api/user', params as Record<string, unknown>, options),
82
82
  };
83
83
 
84
84
  /** 详情查询 hook:响应也用 schema 校验;范围外返回 NOT_FOUND */
@@ -9,7 +9,7 @@ import { can as baseCan, useCan as baseUseCan } from '@yss123/cage-client';
9
9
  import { DeptInputs } from './aggregates/dept';
10
10
  import { RoleInputs } from './aggregates/role';
11
11
  import { UserInputs } from './aggregates/user';
12
- export { client, configureClient, loadMe, currentUser, CageQueryError, useTransfer, type CageResult, type CommonError, type TransferTask, type ImportReport } from '@yss123/cage-client';
12
+ export { client, configureClient, loadMe, currentUser, CageQueryError, CageCommandError, useTransfer, useFileUpload, FileUploadError, type FileUploadTask, type FileUploadSnapshot, type UploadSession, type FileInfo, type RequestOptions, type CageResult, type CommonError, type TransferTask, type ImportReport } from '@yss123/cage-client';
13
13
 
14
14
  /** 能力目录(由代码派生):写错能力点名会编译失败 */
15
15
  export const capabilities = [
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable */
3
3
 
4
4
  import { z } from 'zod';
5
- import { client, useCageQuery } from '@yss123/cage-client';
5
+ import { client, useCageQuery, type RequestOptions } from '@yss123/cage-client';
6
6
 
7
7
  /** 查询输入 */
8
8
  export const QueryInputs = {
@@ -14,10 +14,11 @@
14
14
  "typecheck": "tsc -p tsconfig.json --noEmit"
15
15
  },
16
16
  "dependencies": {
17
- "@yss123/cage-kernel": "0.2.0",
18
- "@yss123/cage-admin": "0.2.0",
19
- "@yss123/cage-approval": "0.2.0",
20
- "@yss123/cage-connectors": "0.2.0",
17
+ "@yss123/cage-kernel": "0.3.1",
18
+ "@yss123/cage-admin": "0.3.1",
19
+ "@yss123/cage-approval": "0.3.1",
20
+ "@yss123/cage-connectors": "0.3.1",
21
+ "@yss123/cage-ai": "0.3.1",
21
22
  "zod": "^4.1.5"
22
23
  }
23
24
  }
@@ -1,4 +1,5 @@
1
1
  // CLI、API 与 worker 共用这个领域入口。空白项目只注册组织基础模型,
2
- // 不注册采购示例;新增业务写在同目录的 .ts 文件,再从这里统一导出。
2
+ // 不注册采购示例;新增业务写在 modules/<业务>,跨模块流程和外部集成分别放 workflows、integrations,再统一导出。
3
3
  // 完整采购代码保存在 docs/examples/purchase-admin,仅作离线参考。
4
+ // 未导出的声明不参与注册、生成或事件消费;本入口只组合声明,不做数据库初始化与网络访问。
4
5
  export * from '@yss123/cage-admin/domain';