@yss123/cage-cli 0.1.0 → 0.3.0

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 (734) hide show
  1. package/README.md +69 -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 +20 -2
  6. package/dist/analyze.js.map +1 -1
  7. package/dist/baseline.d.ts +8 -0
  8. package/dist/baseline.js +13 -0
  9. package/dist/baseline.js.map +1 -1
  10. package/dist/bootstrap.d.ts +20 -0
  11. package/dist/bootstrap.js +75 -0
  12. package/dist/bootstrap.js.map +1 -0
  13. package/dist/budget.d.ts +7 -0
  14. package/dist/budget.js +49 -5
  15. package/dist/budget.js.map +1 -1
  16. package/dist/capabilities.d.ts +38 -0
  17. package/dist/capabilities.js +133 -0
  18. package/dist/capabilities.js.map +1 -0
  19. package/dist/config.d.ts +33 -4
  20. package/dist/config.js +22 -1
  21. package/dist/config.js.map +1 -1
  22. package/dist/context.d.ts +86 -0
  23. package/dist/context.js +235 -0
  24. package/dist/context.js.map +1 -0
  25. package/dist/create-prompt.d.ts +12 -0
  26. package/dist/create-prompt.js +62 -0
  27. package/dist/create-prompt.js.map +1 -0
  28. package/dist/create.d.ts +38 -1
  29. package/dist/create.js +52 -13
  30. package/dist/create.js.map +1 -1
  31. package/dist/derive.d.ts +23 -0
  32. package/dist/derive.js +40 -0
  33. package/dist/derive.js.map +1 -1
  34. package/dist/dev.d.ts +6 -0
  35. package/dist/dev.js +23 -51
  36. package/dist/dev.js.map +1 -1
  37. package/dist/doctor.d.ts +98 -0
  38. package/dist/doctor.js +93 -0
  39. package/dist/doctor.js.map +1 -0
  40. package/dist/env.d.ts +6 -0
  41. package/dist/env.js +11 -0
  42. package/dist/env.js.map +1 -1
  43. package/dist/findings.d.ts +27 -0
  44. package/dist/findings.js +20 -0
  45. package/dist/findings.js.map +1 -1
  46. package/dist/gen/contracts.d.ts +28 -0
  47. package/dist/gen/contracts.js +81 -20
  48. package/dist/gen/contracts.js.map +1 -1
  49. package/dist/gen/index.d.ts +26 -0
  50. package/dist/gen/index.js +112 -4
  51. package/dist/gen/index.js.map +1 -1
  52. package/dist/gen/zod-code.d.ts +43 -1
  53. package/dist/gen/zod-code.js +180 -16
  54. package/dist/gen/zod-code.js.map +1 -1
  55. package/dist/graph-approvals.d.ts +60 -0
  56. package/dist/graph-approvals.js +80 -0
  57. package/dist/graph-approvals.js.map +1 -0
  58. package/dist/graph-business.d.ts +135 -0
  59. package/dist/graph-business.js +404 -0
  60. package/dist/graph-business.js.map +1 -0
  61. package/dist/graph-command.d.ts +28 -0
  62. package/dist/graph-command.js +88 -0
  63. package/dist/graph-command.js.map +1 -0
  64. package/dist/graph-model.d.ts +65 -0
  65. package/dist/graph-model.js +134 -0
  66. package/dist/graph-model.js.map +1 -0
  67. package/dist/graph-presentation.d.ts +27 -0
  68. package/dist/graph-presentation.js +34 -0
  69. package/dist/graph-presentation.js.map +1 -0
  70. package/dist/graph-query.d.ts +266 -0
  71. package/dist/graph-query.js +304 -0
  72. package/dist/graph-query.js.map +1 -0
  73. package/dist/graph-relations.d.ts +34 -0
  74. package/dist/graph-relations.js +172 -0
  75. package/dist/graph-relations.js.map +1 -0
  76. package/dist/graph-search.d.ts +56 -0
  77. package/dist/graph-search.js +99 -0
  78. package/dist/graph-search.js.map +1 -0
  79. package/dist/graph-snapshot.d.ts +28 -4
  80. package/dist/graph-snapshot.js +32 -20
  81. package/dist/graph-snapshot.js.map +1 -1
  82. package/dist/graph.d.ts +13 -2
  83. package/dist/graph.js +78 -5
  84. package/dist/graph.js.map +1 -1
  85. package/dist/impact.d.ts +56 -0
  86. package/dist/impact.js +90 -18
  87. package/dist/impact.js.map +1 -1
  88. package/dist/index.d.ts +15 -1
  89. package/dist/index.js +15 -1
  90. package/dist/index.js.map +1 -1
  91. package/dist/init.d.ts +18 -0
  92. package/dist/init.js +146 -0
  93. package/dist/init.js.map +1 -0
  94. package/dist/load.d.ts +10 -0
  95. package/dist/load.js +15 -0
  96. package/dist/load.js.map +1 -1
  97. package/dist/main.d.ts +6 -0
  98. package/dist/main.js +170 -37
  99. package/dist/main.js.map +1 -1
  100. package/dist/migrate.d.ts +15 -6
  101. package/dist/migrate.js +31 -53
  102. package/dist/migrate.js.map +1 -1
  103. package/dist/ontology.d.ts +69 -2
  104. package/dist/ontology.js +101 -4
  105. package/dist/ontology.js.map +1 -1
  106. package/dist/process-rules.d.ts +21 -0
  107. package/dist/process-rules.js +100 -0
  108. package/dist/process-rules.js.map +1 -0
  109. package/dist/process.d.ts +32 -0
  110. package/dist/process.js +32 -0
  111. package/dist/process.js.map +1 -1
  112. package/dist/project-structure.d.ts +13 -0
  113. package/dist/project-structure.js +104 -0
  114. package/dist/project-structure.js.map +1 -0
  115. package/dist/registration.d.ts +16 -0
  116. package/dist/registration.js +56 -0
  117. package/dist/registration.js.map +1 -0
  118. package/dist/rules.d.ts +52 -0
  119. package/dist/rules.js +58 -0
  120. package/dist/rules.js.map +1 -1
  121. package/dist/runtime-diagnostics.d.ts +27 -0
  122. package/dist/runtime-diagnostics.js +60 -0
  123. package/dist/runtime-diagnostics.js.map +1 -0
  124. package/dist/snapshots.d.ts +40 -0
  125. package/dist/snapshots.js +62 -0
  126. package/dist/snapshots.js.map +1 -0
  127. package/dist/static-check.d.ts +33 -0
  128. package/dist/static-check.js +38 -5
  129. package/dist/static-check.js.map +1 -1
  130. package/dist/sync.d.ts +11 -0
  131. package/dist/sync.js +139 -10
  132. package/dist/sync.js.map +1 -1
  133. package/dist/upgrade.d.ts +16 -0
  134. package/dist/upgrade.js +21 -0
  135. package/dist/upgrade.js.map +1 -1
  136. package/dist/verify.d.ts +14 -0
  137. package/dist/verify.js +19 -0
  138. package/dist/verify.js.map +1 -1
  139. package/dist/version.js +5 -0
  140. package/dist/version.js.map +1 -1
  141. package/graph-ui/app.js +367 -35
  142. package/graph-ui/approval-flow.js +165 -0
  143. package/graph-ui/business.css +985 -0
  144. package/graph-ui/business.js +549 -0
  145. package/graph-ui/flowchart-interaction.js +177 -0
  146. package/graph-ui/flowchart.js +1059 -0
  147. package/graph-ui/graph-approvals.js +79 -0
  148. package/graph-ui/graph-business.js +403 -0
  149. package/graph-ui/graph-model.js +133 -0
  150. package/graph-ui/graph-relations.js +171 -0
  151. package/graph-ui/graph-search.js +98 -0
  152. package/graph-ui/index.html +26 -12
  153. package/graph-ui/model.js +47 -77
  154. package/graph-ui/relations.js +6 -125
  155. package/graph-ui/structure.js +48 -1
  156. package/graph-ui/style.css +33 -0
  157. package/package.json +10 -8
  158. package/templates/app/.dockerignore +2 -0
  159. package/templates/app/.env.example +68 -14
  160. package/templates/app/AGENTS.md +135 -12
  161. package/templates/app/Dockerfile +2 -0
  162. package/templates/app/README.md +49 -16
  163. package/templates/app/_gitignore +9 -0
  164. package/templates/app/apps/api/package.json +2 -2
  165. package/templates/app/apps/api/src/main.ts +5 -1
  166. package/templates/app/apps/api/src/worker.ts +3 -0
  167. package/templates/app/apps/web/index.html +1 -0
  168. package/templates/app/apps/web/package.json +7 -3
  169. package/templates/app/apps/web/src/app/app.tsx +128 -0
  170. package/templates/app/apps/web/src/{style.css → app/styles/global.css} +88 -8
  171. package/templates/app/apps/web/src/app/use-session.ts +43 -0
  172. package/templates/app/apps/web/src/app/workspace-layout.tsx +109 -0
  173. package/templates/app/apps/web/src/main.tsx +9 -543
  174. package/templates/app/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +31 -0
  175. package/templates/app/apps/web/src/modules/approval/index.ts +6 -0
  176. package/templates/app/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +73 -0
  177. package/templates/app/apps/web/src/modules/auth/index.ts +5 -0
  178. package/templates/app/apps/web/src/modules/auth/pages/login-page.tsx +71 -0
  179. package/templates/app/apps/web/src/modules/inventory/index.ts +5 -0
  180. package/templates/app/apps/web/src/modules/inventory/pages/inventory-page.tsx +102 -0
  181. package/templates/app/apps/web/src/modules/purchase/components/approval-history.tsx +32 -0
  182. package/templates/app/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -0
  183. package/templates/app/apps/web/src/modules/purchase/components/purchase-assistant-context.tsx +17 -0
  184. package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.css +6 -0
  185. package/templates/app/apps/web/src/modules/purchase/components/purchase-order-form.tsx +82 -0
  186. package/templates/app/apps/web/src/modules/purchase/index.ts +7 -0
  187. package/templates/app/apps/web/src/modules/purchase/lib/presentation.ts +20 -0
  188. package/templates/app/apps/web/src/modules/purchase/pages/purchase-intelligence.css +15 -0
  189. package/templates/app/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +154 -0
  190. package/templates/app/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +240 -0
  191. package/templates/app/apps/web/src/modules/workspace/index.ts +5 -0
  192. package/templates/app/apps/web/src/modules/workspace/pages/home-page.tsx +44 -0
  193. package/templates/app/apps/web/src/shared/hooks/use-command.ts +42 -0
  194. package/templates/app/apps/web/src/shared/lib/error-message.ts +24 -0
  195. package/templates/app/apps/web/src/shared/lib/navigation.ts +21 -0
  196. package/templates/app/apps/web/src/shared/ui/assistant-markdown.tsx +19 -0
  197. package/templates/app/apps/web/src/shared/ui/assistant-panel.css +134 -0
  198. package/templates/app/apps/web/src/shared/ui/assistant-panel.tsx +200 -0
  199. package/templates/app/apps/web/src/shared/ui/assistant-scope.tsx +72 -0
  200. package/templates/app/apps/web/src/shared/ui/attachment-upload.css +28 -0
  201. package/templates/app/apps/web/src/shared/ui/attachment-upload.tsx +163 -0
  202. package/templates/app/apps/web/src/shared/ui/notice.tsx +20 -0
  203. package/templates/app/apps/web/src/shared/ui/page-heading.tsx +35 -0
  204. package/templates/app/apps/web/src/shared/ui/page-state.css +47 -0
  205. package/templates/app/apps/web/src/shared/ui/page-state.tsx +76 -0
  206. package/templates/app/apps/web/src/shared/ui/require-capability.tsx +34 -0
  207. package/templates/app/apps/web/vite.config.ts +8 -0
  208. package/templates/app/cage.config.json +10 -1
  209. package/templates/app/db/migrations/0002_draft.sql +12 -0
  210. package/templates/app/db/migrations/0003_draft.sql +8 -0
  211. package/templates/app/deploy/nginx.conf +52 -0
  212. package/templates/app/docs/ai/README.md +98 -0
  213. package/templates/app/docs/ai/architecture.md +148 -0
  214. package/templates/app/docs/ai/commenting.md +203 -0
  215. package/templates/app/docs/ai/diagnostics.md +80 -0
  216. package/templates/app/docs/ai/files.md +93 -0
  217. package/templates/app/docs/ai/intelligence.md +348 -0
  218. package/templates/app/docs/ai/ontology-context.md +172 -0
  219. package/templates/app/docs/ai/primitives.md +282 -0
  220. package/templates/app/docs/ai/project-structure.md +128 -0
  221. package/templates/app/docs/ai/purchase-example.md +111 -0
  222. package/templates/app/docs/ai/recipes.md +89 -0
  223. package/templates/app/docs/ai/relations.md +160 -0
  224. package/templates/app/docs/ai/routing.md +86 -0
  225. package/templates/app/docs/ai/transfers.md +92 -0
  226. package/templates/app/docs/ai/troubleshooting.md +65 -0
  227. package/templates/app/docs/ai/workflow.md +152 -0
  228. package/templates/app/docs/errors/CAGE-AI-001.md +61 -0
  229. package/templates/app/docs/errors/CAGE-APPR-001.md +48 -0
  230. package/templates/app/docs/errors/CAGE-APPR-002.md +47 -0
  231. package/templates/app/docs/errors/CAGE-APPR-003.md +47 -0
  232. package/templates/app/docs/errors/CAGE-APPR-004.md +47 -0
  233. package/templates/app/docs/errors/CAGE-APPR-005.md +47 -0
  234. package/templates/app/docs/errors/CAGE-APPR-006.md +53 -0
  235. package/templates/app/docs/errors/CAGE-APPR-007.md +50 -0
  236. package/templates/app/docs/errors/CAGE-APPR-010.md +48 -0
  237. package/templates/app/docs/errors/CAGE-AUDIT-001.md +53 -0
  238. package/templates/app/docs/errors/CAGE-AUTH-001.md +47 -0
  239. package/templates/app/docs/errors/CAGE-BIZ-001.md +51 -0
  240. package/templates/app/docs/errors/CAGE-BIZ-002.md +49 -0
  241. package/templates/app/docs/errors/CAGE-BUDGET-001.md +47 -0
  242. package/templates/app/docs/errors/CAGE-BUDGET-002.md +47 -0
  243. package/templates/app/docs/errors/CAGE-BUDGET-003.md +47 -0
  244. package/templates/app/docs/errors/CAGE-CMD-002.md +47 -0
  245. package/templates/app/docs/errors/CAGE-CMD-003.md +47 -0
  246. package/templates/app/docs/errors/CAGE-CONN-001.md +47 -0
  247. package/templates/app/docs/errors/CAGE-CONN-002.md +47 -0
  248. package/templates/app/docs/errors/CAGE-CONN-003.md +47 -0
  249. package/templates/app/docs/errors/CAGE-CONN-004.md +47 -0
  250. package/templates/app/docs/errors/CAGE-CONN-005.md +47 -0
  251. package/templates/app/docs/errors/CAGE-CONN-006.md +47 -0
  252. package/templates/app/docs/errors/CAGE-CONN-007.md +47 -0
  253. package/templates/app/docs/errors/CAGE-CONN-008.md +47 -0
  254. package/templates/app/docs/errors/CAGE-CONN-009.md +47 -0
  255. package/templates/app/docs/errors/CAGE-CONN-010.md +47 -0
  256. package/templates/app/docs/errors/CAGE-CONN-011.md +47 -0
  257. package/templates/app/docs/errors/CAGE-CONN-012.md +47 -0
  258. package/templates/app/docs/errors/CAGE-CONN-013.md +49 -0
  259. package/templates/app/docs/errors/CAGE-CONN-014.md +48 -0
  260. package/templates/app/docs/errors/CAGE-CONN-015.md +49 -0
  261. package/templates/app/docs/errors/CAGE-CREATE-001.md +53 -0
  262. package/templates/app/docs/errors/CAGE-DECL-001.md +48 -0
  263. package/templates/app/docs/errors/CAGE-DECL-002.md +48 -0
  264. package/templates/app/docs/errors/CAGE-DECL-003.md +47 -0
  265. package/templates/app/docs/errors/CAGE-DECL-004.md +47 -0
  266. package/templates/app/docs/errors/CAGE-DEP-001.md +48 -0
  267. package/templates/app/docs/errors/CAGE-DEP-002.md +47 -0
  268. package/templates/app/docs/errors/CAGE-DEP-003.md +47 -0
  269. package/templates/app/docs/errors/CAGE-DEP-004.md +47 -0
  270. package/templates/app/docs/errors/CAGE-DEP-005.md +47 -0
  271. package/templates/app/docs/errors/CAGE-DIAG-001.md +53 -0
  272. package/templates/app/docs/errors/CAGE-DLQ-001.md +48 -0
  273. package/templates/app/docs/errors/CAGE-ENV-001.md +52 -0
  274. package/templates/app/docs/errors/CAGE-ENV-002.md +51 -0
  275. package/templates/app/docs/errors/CAGE-ENV-003.md +48 -0
  276. package/templates/app/docs/errors/CAGE-EVENT-001.md +47 -0
  277. package/templates/app/docs/errors/CAGE-EVENT-002.md +50 -0
  278. package/templates/app/docs/errors/CAGE-FIELD-001.md +47 -0
  279. package/templates/app/docs/errors/CAGE-FIELD-002.md +47 -0
  280. package/templates/app/docs/errors/CAGE-FIELD-003.md +47 -0
  281. package/templates/app/docs/errors/CAGE-FIELD-004.md +47 -0
  282. package/templates/app/docs/errors/CAGE-FILE-001.md +56 -0
  283. package/templates/app/docs/errors/CAGE-GEN-001.md +48 -0
  284. package/templates/app/docs/errors/CAGE-GEN-002.md +47 -0
  285. package/templates/app/docs/errors/CAGE-GEN-003.md +53 -0
  286. package/templates/app/docs/errors/CAGE-GRANT-001.md +49 -0
  287. package/templates/app/docs/errors/CAGE-GRANT-002.md +48 -0
  288. package/templates/app/docs/errors/CAGE-GRANT-003.md +48 -0
  289. package/templates/app/docs/errors/CAGE-IMPACT-001.md +48 -0
  290. package/templates/app/docs/errors/CAGE-IMPACT-002.md +52 -0
  291. package/templates/app/docs/errors/CAGE-INIT-001.md +47 -0
  292. package/templates/app/docs/errors/CAGE-INIT-002.md +49 -0
  293. package/templates/app/docs/errors/CAGE-INIT-003.md +48 -0
  294. package/templates/app/docs/errors/CAGE-INIT-004.md +48 -0
  295. package/templates/app/docs/errors/CAGE-INIT-005.md +52 -0
  296. package/templates/app/docs/errors/CAGE-JOB-001.md +47 -0
  297. package/templates/app/docs/errors/CAGE-JOB-002.md +47 -0
  298. package/templates/app/docs/errors/CAGE-JOB-003.md +47 -0
  299. package/templates/app/docs/errors/CAGE-LINT-001.md +47 -0
  300. package/templates/app/docs/errors/CAGE-MIG-001.md +47 -0
  301. package/templates/app/docs/errors/CAGE-MIG-002.md +47 -0
  302. package/templates/app/docs/errors/CAGE-MIG-003.md +5 -0
  303. package/templates/app/docs/errors/CAGE-MIG-004.md +5 -0
  304. package/templates/app/docs/errors/CAGE-MIG-005.md +47 -0
  305. package/templates/app/docs/errors/CAGE-NAME-001.md +47 -0
  306. package/templates/app/docs/errors/CAGE-NAME-002.md +47 -0
  307. package/templates/app/docs/errors/CAGE-NAME-003.md +47 -0
  308. package/templates/app/docs/errors/CAGE-NAME-004.md +47 -0
  309. package/templates/app/docs/errors/CAGE-NAME-005.md +47 -0
  310. package/templates/app/docs/errors/CAGE-NAME-006.md +47 -0
  311. package/templates/app/docs/errors/CAGE-ORG-001.md +50 -0
  312. package/templates/app/docs/errors/CAGE-PAIR-002.md +51 -0
  313. package/templates/app/docs/errors/CAGE-QUERY-001.md +47 -0
  314. package/templates/app/docs/errors/CAGE-QUERY-002.md +47 -0
  315. package/templates/app/docs/errors/CAGE-QUERY-003.md +50 -0
  316. package/templates/app/docs/errors/CAGE-REACT-001.md +47 -0
  317. package/templates/app/docs/errors/CAGE-REACT-002.md +47 -0
  318. package/templates/app/docs/errors/CAGE-REACT-003.md +50 -0
  319. package/templates/app/docs/errors/CAGE-READS-001.md +50 -0
  320. package/templates/app/docs/errors/CAGE-REG-001.md +54 -0
  321. package/templates/app/docs/errors/CAGE-REG-002.md +49 -0
  322. package/templates/app/docs/errors/CAGE-REG-003.md +47 -0
  323. package/templates/app/docs/errors/CAGE-REL-001.md +64 -0
  324. package/templates/app/docs/errors/CAGE-ROUTE-001.md +48 -0
  325. package/templates/app/docs/errors/CAGE-SCOPE-001.md +47 -0
  326. package/templates/app/docs/errors/CAGE-SCOPE-002.md +47 -0
  327. package/templates/app/docs/errors/CAGE-SECRET-001.md +48 -0
  328. package/templates/app/docs/errors/CAGE-SECRET-002.md +47 -0
  329. package/templates/app/docs/errors/CAGE-SENS-001.md +48 -0
  330. package/templates/app/docs/errors/CAGE-SQL-001.md +47 -0
  331. package/templates/app/docs/errors/CAGE-SQL-002.md +47 -0
  332. package/templates/app/docs/errors/CAGE-STATE-001.md +49 -0
  333. package/templates/app/docs/errors/CAGE-STATE-002.md +47 -0
  334. package/templates/app/docs/errors/CAGE-STATE-003.md +47 -0
  335. package/templates/app/docs/errors/CAGE-STATE-004.md +47 -0
  336. package/templates/app/docs/errors/CAGE-STATE-005.md +49 -0
  337. package/templates/app/docs/errors/CAGE-STATE-010.md +48 -0
  338. package/templates/app/docs/errors/CAGE-STATE-011.md +48 -0
  339. package/templates/app/docs/errors/CAGE-STRUCT-001.md +51 -0
  340. package/templates/app/docs/errors/CAGE-STRUCT-002.md +51 -0
  341. package/templates/app/docs/errors/CAGE-SYNC-001.md +49 -0
  342. package/templates/app/docs/errors/CAGE-TEST-001.md +47 -0
  343. package/templates/app/docs/errors/CAGE-TEST-002.md +50 -0
  344. package/templates/app/docs/errors/CAGE-TEST-003.md +52 -0
  345. package/templates/app/docs/errors/CAGE-UNSAFE-001.md +49 -0
  346. package/templates/app/docs/errors/CAGE-UPGRADE-001.md +48 -0
  347. package/templates/app/docs/errors/CAGE-WORKER-001.md +48 -0
  348. package/templates/app/docs/errors/CAGE-WORKER-002.md +50 -0
  349. package/templates/app/docs/errors/CAGE-WORKER-003.md +48 -0
  350. package/templates/app/docs/errors/README.md +357 -0
  351. package/templates/app/docs/errors/runtime.md +50 -0
  352. package/templates/app/package.json +4 -7
  353. package/templates/app/packages/contracts/package.json +1 -1
  354. package/templates/app/packages/contracts/src/{dept.ts → aggregates/dept/index.ts} +11 -11
  355. package/templates/app/packages/contracts/src/{inventory.ts → aggregates/inventory/index.ts} +6 -6
  356. package/templates/app/packages/contracts/src/{inventory-lock.ts → aggregates/inventory-lock/index.ts} +5 -5
  357. package/templates/app/packages/contracts/src/aggregates/purchase-order/index.ts +86 -0
  358. package/templates/app/packages/contracts/src/{role.ts → aggregates/role/index.ts} +16 -16
  359. package/templates/app/packages/contracts/src/aggregates/user/index.ts +89 -0
  360. package/templates/app/packages/contracts/src/index.ts +20 -14
  361. package/templates/app/packages/contracts/src/{queries.ts → queries/index.ts} +2 -2
  362. package/templates/app/packages/domain/package.json +5 -4
  363. package/templates/app/packages/domain/src/index.ts +8 -7
  364. package/templates/app/packages/domain/src/{erp.ts → integrations/erp.ts} +16 -1
  365. package/templates/app/packages/domain/src/integrations/intelligence.ts +20 -0
  366. package/templates/app/packages/domain/src/modules/inventory/index.ts +3 -0
  367. package/templates/app/packages/domain/src/{inventory.ts → modules/inventory/inventory.ts} +12 -0
  368. package/templates/app/packages/domain/src/modules/purchase/approvals.ts +39 -0
  369. package/templates/app/packages/domain/src/modules/purchase/index.ts +7 -0
  370. package/templates/app/packages/domain/src/modules/purchase/intelligence.test.ts +62 -0
  371. package/templates/app/packages/domain/src/{jobs.ts → modules/purchase/jobs.ts} +5 -0
  372. package/templates/app/packages/domain/src/{purchase-order.test.ts → modules/purchase/purchase-order.test.ts} +11 -2
  373. package/templates/app/packages/domain/src/modules/purchase/purchase-order.ts +192 -0
  374. package/templates/app/packages/domain/src/{queries.ts → modules/purchase/queries.ts} +5 -0
  375. package/templates/app/packages/domain/src/{reactions.ts → workflows/purchase-inventory.ts} +8 -2
  376. package/templates/app/packages/domain/src/workflows/purchase-process.ts +42 -0
  377. package/templates/blank/.dockerignore +12 -0
  378. package/templates/blank/.env.example +71 -0
  379. package/templates/blank/.github/workflows/cage.yml +44 -0
  380. package/templates/blank/AGENTS.md +136 -0
  381. package/templates/blank/Dockerfile +25 -0
  382. package/templates/blank/README.md +40 -0
  383. package/templates/blank/_gitignore +9 -0
  384. package/templates/blank/apps/api/package.json +15 -0
  385. package/templates/blank/apps/api/src/main.ts +14 -0
  386. package/templates/blank/apps/api/src/worker.ts +10 -0
  387. package/templates/blank/apps/api/tsconfig.json +5 -0
  388. package/templates/blank/apps/web/index.html +14 -0
  389. package/templates/blank/apps/web/package.json +26 -0
  390. package/templates/blank/apps/web/src/app/app.tsx +106 -0
  391. package/templates/blank/apps/web/src/app/styles/global.css +606 -0
  392. package/templates/blank/apps/web/src/app/use-session.ts +43 -0
  393. package/templates/blank/apps/web/src/app/workspace-layout.tsx +95 -0
  394. package/templates/blank/apps/web/src/main.tsx +18 -0
  395. package/templates/blank/apps/web/src/modules/auth/index.ts +5 -0
  396. package/templates/blank/apps/web/src/modules/auth/pages/login-page.tsx +104 -0
  397. package/templates/blank/apps/web/src/modules/directory/index.ts +7 -0
  398. package/templates/blank/apps/web/src/modules/directory/pages/user-detail-page.tsx +78 -0
  399. package/templates/blank/apps/web/src/modules/directory/pages/users-page.tsx +93 -0
  400. package/templates/blank/apps/web/src/modules/workspace/index.ts +5 -0
  401. package/templates/blank/apps/web/src/modules/workspace/pages/home-page.tsx +62 -0
  402. package/templates/blank/apps/web/src/shared/lib/error-message.ts +22 -0
  403. package/templates/blank/apps/web/src/shared/lib/navigation.ts +21 -0
  404. package/templates/blank/apps/web/src/shared/ui/brand.tsx +19 -0
  405. package/templates/blank/apps/web/src/shared/ui/page-state.css +47 -0
  406. package/templates/blank/apps/web/src/shared/ui/page-state.tsx +76 -0
  407. package/templates/blank/apps/web/src/shared/ui/require-capability.tsx +34 -0
  408. package/templates/blank/apps/web/tsconfig.json +11 -0
  409. package/templates/blank/apps/web/vite.config.ts +24 -0
  410. package/templates/blank/cage.config.json +14 -0
  411. package/templates/blank/db/migrations/0001_init.sql +63 -0
  412. package/templates/blank/deploy/nginx.conf +52 -0
  413. package/templates/blank/docs/ai/README.md +98 -0
  414. package/templates/blank/docs/ai/architecture.md +148 -0
  415. package/templates/blank/docs/ai/commenting.md +203 -0
  416. package/templates/blank/docs/ai/diagnostics.md +80 -0
  417. package/templates/blank/docs/ai/files.md +93 -0
  418. package/templates/blank/docs/ai/intelligence.md +348 -0
  419. package/templates/blank/docs/ai/ontology-context.md +172 -0
  420. package/templates/blank/docs/ai/primitives.md +282 -0
  421. package/templates/blank/docs/ai/project-structure.md +128 -0
  422. package/templates/blank/docs/ai/purchase-example.md +111 -0
  423. package/templates/blank/docs/ai/recipes.md +89 -0
  424. package/templates/blank/docs/ai/relations.md +160 -0
  425. package/templates/blank/docs/ai/routing.md +86 -0
  426. package/templates/blank/docs/ai/transfers.md +92 -0
  427. package/templates/blank/docs/ai/troubleshooting.md +65 -0
  428. package/templates/blank/docs/ai/workflow.md +152 -0
  429. package/templates/blank/docs/errors/CAGE-AI-001.md +61 -0
  430. package/templates/blank/docs/errors/CAGE-APPR-001.md +48 -0
  431. package/templates/blank/docs/errors/CAGE-APPR-002.md +47 -0
  432. package/templates/blank/docs/errors/CAGE-APPR-003.md +47 -0
  433. package/templates/blank/docs/errors/CAGE-APPR-004.md +47 -0
  434. package/templates/blank/docs/errors/CAGE-APPR-005.md +47 -0
  435. package/templates/blank/docs/errors/CAGE-APPR-006.md +53 -0
  436. package/templates/blank/docs/errors/CAGE-APPR-007.md +50 -0
  437. package/templates/blank/docs/errors/CAGE-APPR-010.md +48 -0
  438. package/templates/blank/docs/errors/CAGE-AUDIT-001.md +53 -0
  439. package/templates/blank/docs/errors/CAGE-AUTH-001.md +47 -0
  440. package/templates/blank/docs/errors/CAGE-BIZ-001.md +51 -0
  441. package/templates/blank/docs/errors/CAGE-BIZ-002.md +49 -0
  442. package/templates/blank/docs/errors/CAGE-BUDGET-001.md +47 -0
  443. package/templates/blank/docs/errors/CAGE-BUDGET-002.md +47 -0
  444. package/templates/blank/docs/errors/CAGE-BUDGET-003.md +47 -0
  445. package/templates/blank/docs/errors/CAGE-CMD-002.md +47 -0
  446. package/templates/blank/docs/errors/CAGE-CMD-003.md +47 -0
  447. package/templates/blank/docs/errors/CAGE-CONN-001.md +47 -0
  448. package/templates/blank/docs/errors/CAGE-CONN-002.md +47 -0
  449. package/templates/blank/docs/errors/CAGE-CONN-003.md +47 -0
  450. package/templates/blank/docs/errors/CAGE-CONN-004.md +47 -0
  451. package/templates/blank/docs/errors/CAGE-CONN-005.md +47 -0
  452. package/templates/blank/docs/errors/CAGE-CONN-006.md +47 -0
  453. package/templates/blank/docs/errors/CAGE-CONN-007.md +47 -0
  454. package/templates/blank/docs/errors/CAGE-CONN-008.md +47 -0
  455. package/templates/blank/docs/errors/CAGE-CONN-009.md +47 -0
  456. package/templates/blank/docs/errors/CAGE-CONN-010.md +47 -0
  457. package/templates/blank/docs/errors/CAGE-CONN-011.md +47 -0
  458. package/templates/blank/docs/errors/CAGE-CONN-012.md +47 -0
  459. package/templates/blank/docs/errors/CAGE-CONN-013.md +49 -0
  460. package/templates/blank/docs/errors/CAGE-CONN-014.md +48 -0
  461. package/templates/blank/docs/errors/CAGE-CONN-015.md +49 -0
  462. package/templates/blank/docs/errors/CAGE-CREATE-001.md +53 -0
  463. package/templates/blank/docs/errors/CAGE-DECL-001.md +48 -0
  464. package/templates/blank/docs/errors/CAGE-DECL-002.md +48 -0
  465. package/templates/blank/docs/errors/CAGE-DECL-003.md +47 -0
  466. package/templates/blank/docs/errors/CAGE-DECL-004.md +47 -0
  467. package/templates/blank/docs/errors/CAGE-DEP-001.md +48 -0
  468. package/templates/blank/docs/errors/CAGE-DEP-002.md +47 -0
  469. package/templates/blank/docs/errors/CAGE-DEP-003.md +47 -0
  470. package/templates/blank/docs/errors/CAGE-DEP-004.md +47 -0
  471. package/templates/blank/docs/errors/CAGE-DEP-005.md +47 -0
  472. package/templates/blank/docs/errors/CAGE-DIAG-001.md +53 -0
  473. package/templates/blank/docs/errors/CAGE-DLQ-001.md +48 -0
  474. package/templates/blank/docs/errors/CAGE-ENV-001.md +52 -0
  475. package/templates/blank/docs/errors/CAGE-ENV-002.md +51 -0
  476. package/templates/blank/docs/errors/CAGE-ENV-003.md +48 -0
  477. package/templates/blank/docs/errors/CAGE-EVENT-001.md +47 -0
  478. package/templates/blank/docs/errors/CAGE-EVENT-002.md +50 -0
  479. package/templates/blank/docs/errors/CAGE-FIELD-001.md +47 -0
  480. package/templates/blank/docs/errors/CAGE-FIELD-002.md +47 -0
  481. package/templates/blank/docs/errors/CAGE-FIELD-003.md +47 -0
  482. package/templates/blank/docs/errors/CAGE-FIELD-004.md +47 -0
  483. package/templates/blank/docs/errors/CAGE-FILE-001.md +56 -0
  484. package/templates/blank/docs/errors/CAGE-GEN-001.md +48 -0
  485. package/templates/blank/docs/errors/CAGE-GEN-002.md +47 -0
  486. package/templates/blank/docs/errors/CAGE-GEN-003.md +53 -0
  487. package/templates/blank/docs/errors/CAGE-GRANT-001.md +49 -0
  488. package/templates/blank/docs/errors/CAGE-GRANT-002.md +48 -0
  489. package/templates/blank/docs/errors/CAGE-GRANT-003.md +48 -0
  490. package/templates/blank/docs/errors/CAGE-IMPACT-001.md +48 -0
  491. package/templates/blank/docs/errors/CAGE-IMPACT-002.md +52 -0
  492. package/templates/blank/docs/errors/CAGE-INIT-001.md +47 -0
  493. package/templates/blank/docs/errors/CAGE-INIT-002.md +49 -0
  494. package/templates/blank/docs/errors/CAGE-INIT-003.md +48 -0
  495. package/templates/blank/docs/errors/CAGE-INIT-004.md +48 -0
  496. package/templates/blank/docs/errors/CAGE-INIT-005.md +52 -0
  497. package/templates/blank/docs/errors/CAGE-JOB-001.md +47 -0
  498. package/templates/blank/docs/errors/CAGE-JOB-002.md +47 -0
  499. package/templates/blank/docs/errors/CAGE-JOB-003.md +47 -0
  500. package/templates/blank/docs/errors/CAGE-LINT-001.md +47 -0
  501. package/templates/blank/docs/errors/CAGE-MIG-001.md +47 -0
  502. package/templates/blank/docs/errors/CAGE-MIG-002.md +47 -0
  503. package/templates/blank/docs/errors/CAGE-MIG-003.md +5 -0
  504. package/templates/blank/docs/errors/CAGE-MIG-004.md +5 -0
  505. package/templates/blank/docs/errors/CAGE-MIG-005.md +47 -0
  506. package/templates/blank/docs/errors/CAGE-NAME-001.md +47 -0
  507. package/templates/blank/docs/errors/CAGE-NAME-002.md +47 -0
  508. package/templates/blank/docs/errors/CAGE-NAME-003.md +47 -0
  509. package/templates/blank/docs/errors/CAGE-NAME-004.md +47 -0
  510. package/templates/blank/docs/errors/CAGE-NAME-005.md +47 -0
  511. package/templates/blank/docs/errors/CAGE-NAME-006.md +47 -0
  512. package/templates/blank/docs/errors/CAGE-ORG-001.md +50 -0
  513. package/templates/blank/docs/errors/CAGE-PAIR-002.md +51 -0
  514. package/templates/blank/docs/errors/CAGE-QUERY-001.md +47 -0
  515. package/templates/blank/docs/errors/CAGE-QUERY-002.md +47 -0
  516. package/templates/blank/docs/errors/CAGE-QUERY-003.md +50 -0
  517. package/templates/blank/docs/errors/CAGE-REACT-001.md +47 -0
  518. package/templates/blank/docs/errors/CAGE-REACT-002.md +47 -0
  519. package/templates/blank/docs/errors/CAGE-REACT-003.md +50 -0
  520. package/templates/blank/docs/errors/CAGE-READS-001.md +50 -0
  521. package/templates/blank/docs/errors/CAGE-REG-001.md +54 -0
  522. package/templates/blank/docs/errors/CAGE-REG-002.md +49 -0
  523. package/templates/blank/docs/errors/CAGE-REG-003.md +47 -0
  524. package/templates/blank/docs/errors/CAGE-REL-001.md +64 -0
  525. package/templates/blank/docs/errors/CAGE-ROUTE-001.md +48 -0
  526. package/templates/blank/docs/errors/CAGE-SCOPE-001.md +47 -0
  527. package/templates/blank/docs/errors/CAGE-SCOPE-002.md +47 -0
  528. package/templates/blank/docs/errors/CAGE-SECRET-001.md +48 -0
  529. package/templates/blank/docs/errors/CAGE-SECRET-002.md +47 -0
  530. package/templates/blank/docs/errors/CAGE-SENS-001.md +48 -0
  531. package/templates/blank/docs/errors/CAGE-SQL-001.md +47 -0
  532. package/templates/blank/docs/errors/CAGE-SQL-002.md +47 -0
  533. package/templates/blank/docs/errors/CAGE-STATE-001.md +49 -0
  534. package/templates/blank/docs/errors/CAGE-STATE-002.md +47 -0
  535. package/templates/blank/docs/errors/CAGE-STATE-003.md +47 -0
  536. package/templates/blank/docs/errors/CAGE-STATE-004.md +47 -0
  537. package/templates/blank/docs/errors/CAGE-STATE-005.md +49 -0
  538. package/templates/blank/docs/errors/CAGE-STATE-010.md +48 -0
  539. package/templates/blank/docs/errors/CAGE-STATE-011.md +48 -0
  540. package/templates/blank/docs/errors/CAGE-STRUCT-001.md +51 -0
  541. package/templates/blank/docs/errors/CAGE-STRUCT-002.md +51 -0
  542. package/templates/blank/docs/errors/CAGE-SYNC-001.md +49 -0
  543. package/templates/blank/docs/errors/CAGE-TEST-001.md +47 -0
  544. package/templates/blank/docs/errors/CAGE-TEST-002.md +50 -0
  545. package/templates/blank/docs/errors/CAGE-TEST-003.md +52 -0
  546. package/templates/blank/docs/errors/CAGE-UNSAFE-001.md +49 -0
  547. package/templates/blank/docs/errors/CAGE-UPGRADE-001.md +48 -0
  548. package/templates/blank/docs/errors/CAGE-WORKER-001.md +48 -0
  549. package/templates/blank/docs/errors/CAGE-WORKER-002.md +50 -0
  550. package/templates/blank/docs/errors/CAGE-WORKER-003.md +48 -0
  551. package/templates/blank/docs/errors/README.md +357 -0
  552. package/templates/blank/docs/errors/runtime.md +50 -0
  553. package/templates/blank/docs/examples/purchase-admin/README.md +5 -0
  554. package/templates/blank/docs/examples/purchase-admin/apps/api/src/main.ts +14 -0
  555. package/templates/blank/docs/examples/purchase-admin/apps/api/src/worker.ts +17 -0
  556. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/app.tsx +128 -0
  557. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/styles/global.css +743 -0
  558. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/use-session.ts +43 -0
  559. package/templates/blank/docs/examples/purchase-admin/apps/web/src/app/workspace-layout.tsx +109 -0
  560. package/templates/blank/docs/examples/purchase-admin/apps/web/src/main.tsx +18 -0
  561. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/hooks/use-approval-tasks.ts +31 -0
  562. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/index.ts +6 -0
  563. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/approval/pages/approval-tasks-page.tsx +73 -0
  564. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/index.ts +5 -0
  565. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/auth/pages/login-page.tsx +71 -0
  566. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/index.ts +5 -0
  567. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/inventory/pages/inventory-page.tsx +102 -0
  568. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/approval-history.tsx +32 -0
  569. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/components/order-attachments.tsx +29 -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 +82 -0
  573. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/index.ts +7 -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 +15 -0
  576. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-order-detail-page.tsx +154 -0
  577. package/templates/blank/docs/examples/purchase-admin/apps/web/src/modules/purchase/pages/purchase-orders-page.tsx +240 -0
  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 +42 -0
  581. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/lib/error-message.ts +24 -0
  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/assistant-markdown.tsx +19 -0
  584. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-panel.css +134 -0
  585. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-panel.tsx +200 -0
  586. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/assistant-scope.tsx +72 -0
  587. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/attachment-upload.css +28 -0
  588. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/attachment-upload.tsx +163 -0
  589. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/notice.tsx +20 -0
  590. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-heading.tsx +35 -0
  591. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-state.css +47 -0
  592. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/page-state.tsx +76 -0
  593. package/templates/blank/docs/examples/purchase-admin/apps/web/src/shared/ui/require-capability.tsx +34 -0
  594. package/templates/blank/docs/examples/purchase-admin/cage.config.json +123 -0
  595. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/dept/index.ts +74 -0
  596. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory/index.ts +57 -0
  597. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/inventory-lock/index.ts +52 -0
  598. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/purchase-order/index.ts +86 -0
  599. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/role/index.ts +85 -0
  600. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/aggregates/user/index.ts +89 -0
  601. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/index.ts +87 -0
  602. package/templates/blank/docs/examples/purchase-admin/packages/contracts/src/queries/index.ts +17 -0
  603. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/index.ts +10 -0
  604. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/erp.ts +51 -0
  605. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/integrations/intelligence.ts +20 -0
  606. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/index.ts +3 -0
  607. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/inventory/inventory.ts +55 -0
  608. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/approvals.ts +39 -0
  609. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/index.ts +7 -0
  610. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/intelligence.test.ts +62 -0
  611. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/jobs.ts +18 -0
  612. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.test.ts +146 -0
  613. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/purchase-order.ts +192 -0
  614. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/modules/purchase/queries.ts +15 -0
  615. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-inventory.ts +30 -0
  616. package/templates/blank/docs/examples/purchase-admin/packages/domain/src/workflows/purchase-process.ts +42 -0
  617. package/templates/blank/package.json +22 -0
  618. package/templates/blank/packages/contracts/package.json +16 -0
  619. package/templates/blank/packages/contracts/src/aggregates/dept/index.ts +74 -0
  620. package/templates/blank/packages/contracts/src/aggregates/role/index.ts +85 -0
  621. package/templates/blank/packages/contracts/src/aggregates/user/index.ts +89 -0
  622. package/templates/blank/packages/contracts/src/index.ts +55 -0
  623. package/templates/blank/packages/contracts/src/queries/index.ts +13 -0
  624. package/templates/blank/packages/contracts/tsconfig.json +5 -0
  625. package/templates/blank/packages/domain/package.json +24 -0
  626. package/templates/blank/packages/domain/src/index.ts +5 -0
  627. package/templates/blank/packages/domain/tsconfig.json +5 -0
  628. package/templates/blank/pnpm-workspace.yaml +10 -0
  629. package/templates/blank/renovate.json +5 -0
  630. package/templates/blank/tsconfig.base.json +8 -0
  631. package/dist/database.d.ts +0 -5
  632. package/dist/database.js +0 -70
  633. package/dist/database.js.map +0 -1
  634. package/managed/errors/CAGE-APPR-001.md +0 -32
  635. package/managed/errors/CAGE-APPR-002.md +0 -32
  636. package/managed/errors/CAGE-APPR-003.md +0 -32
  637. package/managed/errors/CAGE-APPR-004.md +0 -32
  638. package/managed/errors/CAGE-APPR-005.md +0 -32
  639. package/managed/errors/CAGE-APPR-006.md +0 -32
  640. package/managed/errors/CAGE-APPR-007.md +0 -32
  641. package/managed/errors/CAGE-APPR-010.md +0 -32
  642. package/managed/errors/CAGE-AUTH-001.md +0 -32
  643. package/managed/errors/CAGE-BUDGET-001.md +0 -32
  644. package/managed/errors/CAGE-BUDGET-002.md +0 -32
  645. package/managed/errors/CAGE-BUDGET-003.md +0 -32
  646. package/managed/errors/CAGE-CMD-002.md +0 -32
  647. package/managed/errors/CAGE-CMD-003.md +0 -34
  648. package/managed/errors/CAGE-CONN-001.md +0 -32
  649. package/managed/errors/CAGE-CONN-002.md +0 -32
  650. package/managed/errors/CAGE-CONN-003.md +0 -32
  651. package/managed/errors/CAGE-CONN-004.md +0 -32
  652. package/managed/errors/CAGE-CONN-005.md +0 -32
  653. package/managed/errors/CAGE-CONN-006.md +0 -32
  654. package/managed/errors/CAGE-CONN-007.md +0 -32
  655. package/managed/errors/CAGE-CONN-008.md +0 -32
  656. package/managed/errors/CAGE-CONN-009.md +0 -32
  657. package/managed/errors/CAGE-CONN-010.md +0 -32
  658. package/managed/errors/CAGE-CONN-011.md +0 -32
  659. package/managed/errors/CAGE-CONN-012.md +0 -32
  660. package/managed/errors/CAGE-CREATE-001.md +0 -32
  661. package/managed/errors/CAGE-DECL-001.md +0 -34
  662. package/managed/errors/CAGE-DECL-002.md +0 -34
  663. package/managed/errors/CAGE-DECL-003.md +0 -34
  664. package/managed/errors/CAGE-DECL-004.md +0 -34
  665. package/managed/errors/CAGE-DEP-001.md +0 -34
  666. package/managed/errors/CAGE-DEP-002.md +0 -34
  667. package/managed/errors/CAGE-DEP-003.md +0 -34
  668. package/managed/errors/CAGE-DEP-004.md +0 -34
  669. package/managed/errors/CAGE-DEP-005.md +0 -34
  670. package/managed/errors/CAGE-DLQ-001.md +0 -32
  671. package/managed/errors/CAGE-ENV-001.md +0 -32
  672. package/managed/errors/CAGE-EVENT-001.md +0 -32
  673. package/managed/errors/CAGE-EVENT-002.md +0 -32
  674. package/managed/errors/CAGE-FIELD-001.md +0 -32
  675. package/managed/errors/CAGE-FIELD-002.md +0 -32
  676. package/managed/errors/CAGE-FIELD-003.md +0 -32
  677. package/managed/errors/CAGE-FIELD-004.md +0 -32
  678. package/managed/errors/CAGE-GEN-001.md +0 -33
  679. package/managed/errors/CAGE-GEN-002.md +0 -33
  680. package/managed/errors/CAGE-GRANT-001.md +0 -32
  681. package/managed/errors/CAGE-GRANT-002.md +0 -32
  682. package/managed/errors/CAGE-GRANT-003.md +0 -32
  683. package/managed/errors/CAGE-IMPACT-001.md +0 -32
  684. package/managed/errors/CAGE-JOB-001.md +0 -32
  685. package/managed/errors/CAGE-JOB-002.md +0 -32
  686. package/managed/errors/CAGE-JOB-003.md +0 -32
  687. package/managed/errors/CAGE-LINT-001.md +0 -32
  688. package/managed/errors/CAGE-MIG-001.md +0 -32
  689. package/managed/errors/CAGE-MIG-002.md +0 -32
  690. package/managed/errors/CAGE-MIG-003.md +0 -32
  691. package/managed/errors/CAGE-MIG-004.md +0 -32
  692. package/managed/errors/CAGE-MIG-005.md +0 -32
  693. package/managed/errors/CAGE-NAME-001.md +0 -32
  694. package/managed/errors/CAGE-NAME-002.md +0 -32
  695. package/managed/errors/CAGE-NAME-003.md +0 -32
  696. package/managed/errors/CAGE-NAME-004.md +0 -32
  697. package/managed/errors/CAGE-NAME-005.md +0 -32
  698. package/managed/errors/CAGE-NAME-006.md +0 -32
  699. package/managed/errors/CAGE-ORG-001.md +0 -32
  700. package/managed/errors/CAGE-PAIR-002.md +0 -33
  701. package/managed/errors/CAGE-QUERY-001.md +0 -32
  702. package/managed/errors/CAGE-QUERY-002.md +0 -32
  703. package/managed/errors/CAGE-QUERY-003.md +0 -32
  704. package/managed/errors/CAGE-REACT-001.md +0 -32
  705. package/managed/errors/CAGE-REACT-002.md +0 -32
  706. package/managed/errors/CAGE-READS-001.md +0 -32
  707. package/managed/errors/CAGE-REG-001.md +0 -32
  708. package/managed/errors/CAGE-REG-002.md +0 -32
  709. package/managed/errors/CAGE-REG-003.md +0 -32
  710. package/managed/errors/CAGE-ROUTE-001.md +0 -32
  711. package/managed/errors/CAGE-SCOPE-001.md +0 -32
  712. package/managed/errors/CAGE-SCOPE-002.md +0 -32
  713. package/managed/errors/CAGE-SECRET-001.md +0 -32
  714. package/managed/errors/CAGE-SECRET-002.md +0 -32
  715. package/managed/errors/CAGE-SENS-001.md +0 -32
  716. package/managed/errors/CAGE-SQL-001.md +0 -32
  717. package/managed/errors/CAGE-SQL-002.md +0 -32
  718. package/managed/errors/CAGE-STATE-001.md +0 -32
  719. package/managed/errors/CAGE-STATE-002.md +0 -32
  720. package/managed/errors/CAGE-STATE-003.md +0 -32
  721. package/managed/errors/CAGE-STATE-004.md +0 -32
  722. package/managed/errors/CAGE-STATE-005.md +0 -32
  723. package/managed/errors/CAGE-STATE-010.md +0 -32
  724. package/managed/errors/CAGE-STATE-011.md +0 -32
  725. package/managed/errors/CAGE-SYNC-001.md +0 -35
  726. package/managed/errors/CAGE-TEST-001.md +0 -33
  727. package/managed/errors/CAGE-UNSAFE-001.md +0 -32
  728. package/managed/errors/CAGE-UPGRADE-001.md +0 -32
  729. package/managed/errors/README.md +0 -99
  730. package/templates/app/compose.yaml +0 -39
  731. package/templates/app/packages/contracts/src/purchase-order.ts +0 -72
  732. package/templates/app/packages/contracts/src/user.ts +0 -89
  733. package/templates/app/packages/domain/src/approvals.ts +0 -18
  734. package/templates/app/packages/domain/src/purchase-order.ts +0 -122
@@ -0,0 +1,171 @@
1
+ /**
2
+ * 将每种本体连线翻译为中文原因、用途、方向与证据,供 CLI 和浏览器详情复用。
3
+ * 解释基于投影端点及已抽取属性,分别标注显式声明、规则推导与文本匹配。
4
+ * 不求值 handler、映射或审批条件;存在连线只代表对应声明关系,不证明某次操作已发生。
5
+ */
6
+ import { kindLabels, nodeLabel } from './graph-model.js';
7
+ /**
8
+ * 按真实关系种类解释连线,补充声明来源和证据强度。
9
+ * @param edge 已投影且两端有效的边。
10
+ * @param model 展示图,提供端点和辅助声明。
11
+ * @param labels 中文名称覆盖。
12
+ * @returns 中文解释;只读元数据,不执行审批、映射、查询或业务命令。
13
+ */
14
+ export function explainEdge(edge, model, labels = {}) {
15
+ const from = model.nodes.find((n) => n.key === edge.from);
16
+ const to = model.nodes.find((n) => n.key === edge.to);
17
+ const a = nodeLabel(from, labels), b = nodeLabel(to, labels);
18
+ const field = to.id.slice(to.id.indexOf('.') + 1);
19
+ const resource = (id) => labels[`resource:${id}`] ?? id;
20
+ const result = (label, category, why, purpose, evidence, source = from) => ({
21
+ label,
22
+ category,
23
+ why,
24
+ purpose,
25
+ evidence,
26
+ source,
27
+ basis: edge.derived || (edge.kind === 'uses' && ['事件载荷', '出站映射'].includes(edge.as ?? ''))
28
+ ? 'inferred'
29
+ : edge.kind === 'uses' && edge.as === '查询'
30
+ ? 'text-match'
31
+ : 'declared',
32
+ direction: `“${a}” → “${b}”:${label}。`,
33
+ });
34
+ switch (edge.kind) {
35
+ case 'contains':
36
+ return result('包含业务阶段', '业务流程', `“${a}”声明了“${b}”阶段。`, '组织完整业务过程;阶段本身不执行命令。', [`${from.id}.stages → ${to.id}`]);
37
+ case 'implements':
38
+ return result('阶段实现', '实现依据', `“${a}”引用“${b}”作为实现。`, '从业务阶段追到实际声明;引用顺序不表示执行顺序。', [`${from.id}.action / details → ${to.id}`]);
39
+ case 'follows': {
40
+ const mode = { manual: '人工下一步', automatic: '自动触发', wait: '等待后继续' }[edge.mode ?? 'manual'];
41
+ return result(edge.label ?? mode, mode, `“${a}” → “${b}”:${edge.label}(${mode})。`, edge.mode === 'automatic' ? '检查实际触发链是否存在;映射条件、事务和权限仍以引用的实现为准。' : '这是业务规格中的后续步骤,不会自动调度目标操作。', [`${from.attrs.process}.transitions`, `mode: ${edge.mode}`]);
42
+ }
43
+ case 'relates':
44
+ return result(edge.label ?? '关联业务对象', '业务关联', `“${a}”关联“${b}”:${edge.label}。`, '展示这个环节涉及的业务对象;数据引用、读取和写入由对应实现决定。', [edge.via ?? `${from.id}.subject`]);
45
+ case 'field':
46
+ return result(to.attrs.virtual ? '声明关联字段' : '包含字段', '数据结构', `“${a}”的字段声明中包含“${b}”。`, to.attrs.virtual
47
+ ? '这是 fields 中的集合关系,不占主表列;点击它指向目标的连线,查看关系基数、存储和读写方式。'
48
+ : '说明业务对象由哪些数据组成;调整字段时,可以继续沿线查看受影响的查询、审批和事件。', [`${from.id}.fields.${field}`]);
49
+ case 'refs': {
50
+ if (edge.cardinality === 'one-to-many')
51
+ return result('一对多 1:N', '反向关联 · 只读', `“${a}”使用 hasMany 反查“${b}”,对应外键是 ${to.id}.${edge.mappedBy}。`, '按需分页列出属于当前对象的子对象,不新建列或中间表。改变归属要执行子对象的命令;读取同时受两侧权限和范围约束。', [`${from.id}: hasMany(${JSON.stringify(to.id)}, { mappedBy: ${JSON.stringify(edge.mappedBy)} })`]);
52
+ if (edge.cardinality === 'many-to-many')
53
+ return result('多对多 N:M', '集合关联 · 自动中间表', `“${a}”声明 manyToMany:一个所属对象可以关联多个“${b}”,同一个目标也可被多个所属对象关联。`, '框架生成中间表、同租户外键和组合唯一约束;所属对象的命令用 ID 数组替换关联,与主记录共同提交。解绑不删除目标,读取通过独立分页接口。', [`${from.id}: manyToMany(${JSON.stringify(to.id)})`, `自动中间表:${from.attrs.through}`]);
54
+ return result(edge.cardinality === 'one-to-one' ? '一对一 1:1' : '多对一 N:1', '数据关联', `“${a}”声明为引用“${b}”的字段,保存所关联对象的标识。`, edge.cardinality === 'one-to-one'
55
+ ? '租户内的唯一约束保证同一目标最多被这一字段引用一次;可选字段允许没有关联,并不要求双方一定存在。'
56
+ : `多个所属对象可以引用同一${kindLabels[to.kind]}。字段保存外键;具体查询仍受数据范围约束,这条线本身不执行查询。`, [`${from.id}: ref(${JSON.stringify(to.id)})${edge.cardinality === 'one-to-one' ? '.unique()' : ''}`]);
57
+ }
58
+ case 'ownership':
59
+ return result(`拥有${kindLabels[to.kind]}`, '标识归属 · 推导', `“${b}”的标识位于“${from.id}.”之下,投影据此将它归入“${a}”。`, '帮助整理同一业务对象的命令、状态和能力点。这是标识推导的归属,不是抽取器声明的依赖,也不会触发命令。', [`${to.id} → 所属聚合 ${from.id}`]);
60
+ case 'transition': {
61
+ const command = model.nodes.find((n) => n.kind === 'command' && n.id === edge.via);
62
+ const name = nodeLabel(command, labels);
63
+ const stays = edge.from === edge.to;
64
+ return result(stays ? '保持状态' : '迁移状态', '状态变化', `“${name}”声明${stays ? `在“${a}”状态执行后保持原状态` : `从“${a}”进入“${b}”`}。`, `用于检查业务生命周期是否完整。只有命令通过权限、约束并成功提交,${stays ? '操作才生效' : '状态才改变'}。`, [
65
+ `命令:${command.id}`,
66
+ `from: ${JSON.stringify(command.attrs.from)}`,
67
+ `to: ${JSON.stringify(command.attrs.to)}`,
68
+ ], command);
69
+ }
70
+ case 'reads':
71
+ case 'queries':
72
+ return result('读取数据', '读取依赖', `“${a}”在 reads 中声明读取“${b}”${edge.alias ? `,使用别名 ${edge.alias}` : ''}。`, '明确可读取的业务对象,并让影响分析找到依赖方;实际读取通过安全视图,受权限和数据范围约束。箭头指向数据来源,不表示先执行它。', [`${from.id}.reads${edge.alias ? `.${edge.alias}` : ''} → ${to.id}`]);
73
+ case 'emits':
74
+ return result('产生事件', '事件协作', `“${a}”的 emits 中声明了“${b}”事件。`, '命令成功执行时按声明生成事件,连接后续反应、审批或外部同步;事务失败时不能当作已经发生。', [`${from.id}.emits → ${to.id}`]);
75
+ case 'uses': {
76
+ const as = edge.as ?? '';
77
+ if (as === '可路由字段')
78
+ return result('允许审批读取', '审批可用字段', `“${a}”把“${b}”列入 routable,允许该字段作为审批流程变量。`, '明确审批可以拿到哪些业务数据。这里只表示允许使用;是否真的参与分支或审批选人,要查看审批路由的字段关系。', [`${from.id}.routable 包含 ${field}`]);
79
+ if (as === '路由条件') {
80
+ // fieldsUsed 同时包含 when 条件和 deptLeader 选人字段,不能一律解释成条件判断。
81
+ const nodes = from.attrs.nodes;
82
+ const conditions = nodes.filter((n) => n.kind === 'when' && n.cond.field === field);
83
+ const steps = nodes
84
+ .flatMap((n) => (n.kind !== 'when' ? [n] : n.steps))
85
+ .filter((s) => (s.approver ?? s.handoff)?.kind === 'deptLeader' && (s.approver ?? s.handoff)?.field === field);
86
+ const operators = {
87
+ gt: '大于',
88
+ gte: '大于等于',
89
+ lt: '小于',
90
+ lte: '小于等于',
91
+ eq: '等于',
92
+ ne: '不等于',
93
+ in: '属于',
94
+ };
95
+ const reasons = [
96
+ ...steps.map((s) => `“${s.title}”步骤根据“${b}”找到对应部门的负责人`),
97
+ ...conditions.map((n) => `当“${b}”${operators[n.cond.op]} ${JSON.stringify(n.cond.value)} 时,加入${n.steps.map((s) => `“${s.title}”`).join('、')}步骤`),
98
+ ];
99
+ return result(steps.length && conditions.length ? '选人和分支依据' : steps.length ? '确定审批人' : '判断审批分支', '审批路由依赖', `${reasons.join(';')}。`, '字段值会影响审批人或需要经过的审批步骤;修改字段含义时,应一起检查这些路由配置。', [
100
+ ...steps.map((s) => `${s.title}: approver.deptLeader(${JSON.stringify(field)})`),
101
+ ...conditions.map((n) => `when(${n.cond.op}(${JSON.stringify(field)}, ${JSON.stringify(n.cond.value)}))`),
102
+ ]);
103
+ }
104
+ if (as === '事件载荷')
105
+ return result('携带字段', '事件数据依赖', `“${a}”的默认事件载荷按同名字段从业务对象取“${b}”。`, '订阅方可以用事件中的这份数据处理后续业务;字段变更需要检查事件及订阅方的数据约定。箭头指向载荷的数据来源。', [`事件 ${from.id} 的同名字段 ${field} ← ${to.id}`]);
106
+ if (as === '查询')
107
+ return result('查询使用字段', '查询字段线索', `抽取器在“${a}”的 SQL 或查询构造函数文本中匹配到了“${b}”的字段名。`, '提供检查查询依赖的线索。这里基于字段名文本匹配,可能匹配到注释或同名内容;实际筛选、分组或计算用途请核对查询声明。', [`${from.id}: SQL / build 文本匹配 ${field}`]);
108
+ if (as === '出站映射')
109
+ return result('映射外发字段', '外部同步数据', `“${a}”的 fields 声明包含“${b}”对应的字段名;抽取器将它关联到发出事件的聚合中同名字段。`, '用于核对外发字段范围和字段变更的同步影响;具体取值及转换由事件载荷与 map 函数决定。', [`${from.id}.fields 包含 ${field}`, `同名聚合字段:${to.id}`]);
110
+ if (as.startsWith('约束 ')) {
111
+ const rule = as.slice(3);
112
+ const purpose = rule.startsWith('ceiling(')
113
+ ? `用于校验“${b}”是否超出调用人的审批额度。`
114
+ : rule.startsWith('sod.notSameAs(')
115
+ ? `用于校验调用人与“${b}”记录的人不同,避免同一人完成需要分离的职责。`
116
+ : `该约束读取“${b}”执行命令前的业务检查;字段变更时应一起复核约束。`;
117
+ return result('执行约束检查', '命令校验依赖', `“${a}”声明的约束 ${rule} 使用“${b}”。`, purpose, [
118
+ `${from.id}.constraints → ${rule}`,
119
+ `约束 fields 包含 ${field}`,
120
+ ]);
121
+ }
122
+ return result('使用字段', '字段依赖', `“${a}”声明使用“${b}”。`, '用于追踪字段变更的影响范围。', [
123
+ as || edge.kind,
124
+ ]);
125
+ }
126
+ case 'cancels':
127
+ return result('取消审批', '流程取消', `“${b}”在 cancelOn 中声明了“${a}”事件。`, '事件发生后取消该单据仍在进行的审批;不会启动新流程,也不替代释放资源等业务反应。', [`${to.id}.cancelOn 包含 ${from.id}`], to);
128
+ case 'triggers': {
129
+ const label = to.kind === 'approval' ? '启动审批' : to.kind === 'outbound' ? '触发外部同步' : '触发反应';
130
+ return result(label, '事件触发', `“${b}”订阅“${a}”作为${to.kind === 'approval' ? '启动' : '触发'}事件。`, to.kind === 'approval'
131
+ ? '事件发生后启动对应审批流程,生成流程中的审批任务。'
132
+ : to.kind === 'outbound'
133
+ ? '事件发生后由 worker 处理外部推送,失败按投递策略重试。'
134
+ : `事件发生后执行订阅的反应${to.attrs.tx === 'same' ? ',该反应与原命令处于同一事务' : ';执行方式由反应的事务声明决定'}。`, [`${to.id}.${to.kind === 'approval' ? 'start' : 'event'} → ${from.id}`], to);
135
+ }
136
+ case 'targets': {
137
+ if (to.kind === 'connector')
138
+ return result('调用外部系统', '连接器调用', `“${a}”声明通过“${b}”执行操作 ${labels[`operation:${from.attrs.operation}`] ?? from.attrs.operation}。`, '由连接器统一处理地址与字段白名单、密钥、限流和超时,让外部同步保持可管控。', [`${from.id}.connector → ${to.id}`, `operation: ${from.attrs.operation}`]);
139
+ if (from.kind === 'outbound')
140
+ return result('成功后回写', '同步成功回调', `“${a}”的 onSuccess 绑定“${b}”。`, '外部操作成功后调用该命令,将返回结果按映射写回业务;失败时不执行成功回写。', [`${from.id}.onSuccess → ${to.id}`]);
141
+ if (from.kind === 'inbound')
142
+ return result('回调转为命令', '外部回调', `“${a}”将接收的外部回调映射到“${b}”。`, '外部回调通过验签和数据校验后,使用业务命令处理,统一遵守状态和业务约束。', [`${from.id}.command → ${to.id}`]);
143
+ const resources = [
144
+ edge.acquires ? `获取“${resource(edge.acquires)}”` : '',
145
+ edge.releases ? `释放“${resource(edge.releases)}”` : '',
146
+ ].filter(Boolean);
147
+ const collection = from.attrs.collection;
148
+ const execution = [
149
+ from.attrs.tx === 'same' ? '同一事务,任意一项失败共同回滚' : '异步投递',
150
+ from.attrs.order !== null && from.attrs.order !== undefined ? `步骤顺序 ${from.attrs.order}` : '',
151
+ collection ? `最多 ${collection.maxItems} 项,按 ${collection.orderBy} 排序,串行调用` : '',
152
+ ].filter(Boolean);
153
+ return result('调用业务命令', '反应调用', `“${a}”把事件映射后交给“${b}”处理。`, `将后续业务操作交给受约束的命令执行。${execution.join(';')}。${resources.length ? `此声明还标记${resources.join('、')},用于检查资源获取与释放是否成对。` : ''}`, [`${from.id}.command → ${to.id}`, ...execution, ...resources]);
154
+ }
155
+ case 'binds': {
156
+ if (from.kind === 'route')
157
+ return result('定义审批步骤', '流程配置', `“${a}”与“${b}”使用同一流程标识 ${from.attrs.process}。`, '这份路由定义流程里的审批步骤、选人方式和条件分支,供代码内审批引擎使用。', [`process: ${from.attrs.process}`]);
158
+ const approved = from.attrs.onApproved === to.id;
159
+ const rejected = from.attrs.onRejected === to.id;
160
+ const returned = from.attrs.onReturned === to.id;
161
+ const outcome = approved && rejected ? '结束' : approved ? '通过' : returned ? '退回修改' : '驳回';
162
+ return result(`${outcome}后执行`, '审批结论回写', `“${a}”${outcome}时绑定执行“${b}”。`, '将审批结论交给业务命令推进单据状态,并统一执行权限和业务约束。', [
163
+ approved ? `${from.id}.onApproved → ${to.id}` : '',
164
+ rejected ? `${from.id}.onRejected → ${to.id}` : '',
165
+ returned ? `${from.id}.onReturned → ${to.id}` : '',
166
+ ].filter(Boolean));
167
+ }
168
+ case 'calls':
169
+ return result('允许调用命令', '任务调用范围', `“${a}”在 calls 中声明可以调用“${b}”。`, '明确任务能执行哪些业务写入,并支持影响分析。每次任务是否实际调用该命令,取决于 run 中的业务逻辑。', [`${from.id}.calls → ${to.id}`]);
170
+ }
171
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * 不依赖模型的本体名称检索,供 CLI、agent 上下文和浏览器筛选共用。
3
+ * 归一化标识与文案,按完整命中或英文词、相邻中文片段计算权重,并返回命中字段。
4
+ * 结果是稳定排序的候选;不进行语义推理,无法保证理解否定、业务同义词或任意自然语言要求。
5
+ */
6
+ // 轻量、可解释的名称检索;不调用模型,不把关键词匹配描述成“理解任意需求”。
7
+ // 中文用相邻双字作为线索,让“采购单取消”能匹配“取消采购单”,同时返回命中依据。
8
+ import { kindLabels, nodeLabel } from './graph-model.js';
9
+ /**
10
+ * 统一全半角、大小写与首尾空白后进行词法比较,不改变输出中的原始标识。
11
+ */
12
+ const normalize = (value) => value.normalize('NFKC').toLowerCase().trim();
13
+ /**
14
+ * 拆出英文标识词及连续中文的相邻双字片段,并稳定去重。
15
+ * @param query 已归一化查询。
16
+ * @returns 匹配词列表;单汉字单独保留,不执行分词模型。
17
+ */
18
+ function searchTerms(query) {
19
+ const terms = query.match(/[a-z0-9_$.:/-]+/g) ?? [];
20
+ for (const segment of query.match(/[\p{Script=Han}]+/gu) ?? []) {
21
+ const chars = [...segment];
22
+ if (chars.length === 1)
23
+ terms.push(segment);
24
+ else
25
+ for (let i = 0; i < chars.length - 1; i++)
26
+ terms.push(chars[i] + chars[i + 1]);
27
+ }
28
+ return [...new Set(terms)];
29
+ }
30
+ /**
31
+ * 对 key、ID、中文文案、原描述及所属对象分别评分,取最高单字段得分。
32
+ * @param node 待匹配节点。
33
+ * @param query 用户输入。
34
+ * @param labels 显示覆盖。
35
+ * @param descriptions 声明原始描述。
36
+ * @returns 有依据的候选或 undefined;所有命中字段仍保留,不把分数当业务证明。
37
+ */
38
+ function matchNode(node, query, labels, descriptions) {
39
+ const normalized = normalize(query);
40
+ if (!normalized)
41
+ return;
42
+ const terms = searchTerms(normalized);
43
+ const ownerId = ['field', 'state', 'command', 'capability', 'entry'].includes(node.kind)
44
+ ? node.id.split('.')[0]
45
+ : undefined;
46
+ const fields = [
47
+ ['key', node.key, 18],
48
+ ['id', node.id, 16],
49
+ ['label', nodeLabel(node, labels), 12],
50
+ ['description', descriptions[node.key] ?? String(node.attrs.description ?? ''), 10],
51
+ ['owner', ownerId ? (labels[`aggregate:${ownerId}`] ?? ownerId) : '', 2],
52
+ ];
53
+ const matches = [];
54
+ let score = 0;
55
+ for (const [field, value, weight] of fields) {
56
+ const text = normalize(value);
57
+ if (!text)
58
+ continue;
59
+ const exact = text === normalized;
60
+ const whole = text.includes(normalized);
61
+ const found = terms.filter((term) => text.includes(term));
62
+ if (!exact && !whole && found.length === 0)
63
+ continue;
64
+ const points = exact ? weight * 100 : whole ? weight * 30 : weight * found.length;
65
+ score = Math.max(score, points);
66
+ matches.push({ field, value, terms: exact || whole ? [query.trim()] : found });
67
+ }
68
+ if (!matches.length)
69
+ return;
70
+ return { key: node.key, id: node.id, kind: node.kind, label: nodeLabel(node, labels), score, matches };
71
+ }
72
+ /** 排序稳定,结果携带命中字段;多个候选不静默合成一个“正确需求”。 */
73
+ /**
74
+ * 按可选类型筛选并稳定排序名称候选。
75
+ * @param model 展示图。
76
+ * @param query 关键词。
77
+ * @param labels 中文覆盖。
78
+ * @param options 类型范围及原始描述。
79
+ * @returns 完整候选数组,调用方负责 limit 和截断提示。
80
+ */
81
+ export function searchGraphNodes(model, query, labels = {}, options = {}) {
82
+ return model.nodes
83
+ .filter((node) => !options.kind || node.kind === options.kind)
84
+ .map((node) => matchNode(node, query, labels, options.descriptions ?? {}))
85
+ .filter((hit) => !!hit)
86
+ .sort((a, b) => b.score - a.score || a.key.localeCompare(b.key));
87
+ }
88
+ /** 画布的筛选与搜索下拉共用同一匹配规则,保留按节点类型查找的用法。 */
89
+ /**
90
+ * 供画布筛选复用名称匹配,并额外允许按中文类型名称筛选。
91
+ * @param node 展示节点。
92
+ * @param query 筛选文字。
93
+ * @param labels 中文映射。
94
+ * @returns 是否命中;空查询可匹配类型名称,不修改图。
95
+ */
96
+ export function matchesNode(node, query, labels) {
97
+ return !!matchNode(node, query, labels, {}) || normalize(kindLabels[node.kind]).includes(normalize(query));
98
+ }
@@ -1,4 +1,6 @@
1
1
  <!doctype html>
2
+ <!-- 本地本体探索器的静态骨架,由 graph 服务提供并由 app.js 填充。
3
+ ID 是脚本绑定契约;本页不嵌入领域执行代码,业务地图与完整本体共用导航和检查结果。 -->
2
4
  <html lang="zh-CN">
3
5
  <head>
4
6
  <meta charset="UTF-8" />
@@ -10,6 +12,7 @@
10
12
  href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Crect width='40' height='40' rx='10' fill='%232d665a'/%3E%3Cpath d='M11 12h18v16H11zm0 8h18m-9-8v16' stroke='%23fff' fill='none' stroke-width='2'/%3E%3C/svg%3E"
11
13
  />
12
14
  <link rel="stylesheet" href="/style.css" />
15
+ <link rel="stylesheet" href="/business.css" />
13
16
  </head>
14
17
  <body>
15
18
  <div class="app-shell">
@@ -19,7 +22,7 @@
19
22
  ><strong>CAGE<span>ATLAS</span></strong></a
20
23
  >
21
24
  <div class="breadcrumb">
22
- <span>开发者工作台</span><b>/</b><span id="project-name">正在读取项目</span>
25
+ <span>业务探索工作台</span><b>/</b><span id="project-name">正在读取项目</span>
23
26
  </div>
24
27
  <span class="local-badge"><i></i>本地声明</span>
25
28
  <button
@@ -32,10 +35,13 @@
32
35
  </button>
33
36
  </header>
34
37
 
38
+ <!-- 对象/板块导航与类型筛选由当前视图重建,移动端展开状态由按钮的 aria-expanded 同步。 -->
35
39
  <aside class="sidebar" id="sidebar">
36
40
  <div class="section-label">项目工作区 <span>01</span></div>
37
41
  <div class="nav-active"><span class="nav-symbol">◇</span> 本体图谱 <span class="nav-dot"></span></div>
38
- <div class="sidebar-heading">业务对象 <span id="aggregate-total"></span></div>
42
+ <div class="sidebar-heading">
43
+ <span id="objects-heading-label">业务板块</span><span id="aggregate-total"></span>
44
+ </div>
39
45
  <div id="aggregate-list" class="aggregate-list"></div>
40
46
  <div class="sidebar-heading" id="types-heading">
41
47
  节点类型 <button id="reset-types" class="text-button">重置</button>
@@ -61,12 +67,12 @@
61
67
  >
62
68
  </aside>
63
69
 
64
- <main class="main">
70
+ <main class="main business-page" id="main">
65
71
  <section class="page-heading">
66
72
  <div>
67
73
  <div class="eyebrow">业务关系探索</div>
68
- <h1>本体图谱<span class="version-tag">v0.1</span></h1>
69
- <p>从声明出发,看见业务如何连接。</p>
74
+ <h1 id="page-title">业务地图</h1>
75
+ <p id="page-description">先理解业务,再沿流程找到实现。</p>
70
76
  </div>
71
77
  <div class="heading-actions">
72
78
  <button id="download" class="button secondary"><span>↓</span> 导出 JSON</button
@@ -77,15 +83,17 @@
77
83
  <section class="overview" aria-label="图谱统计">
78
84
  <div class="overview-item">
79
85
  <span class="metric-icon aggregate-icon">◇</span>
80
- <div><small>业务对象</small><strong id="metric-aggregates">—</strong></div>
86
+ <div>
87
+ <small id="metric-first-label">业务板块</small><strong id="metric-aggregates">—</strong>
88
+ </div>
81
89
  </div>
82
90
  <div class="overview-item">
83
91
  <span class="metric-icon node-icon">⠿</span>
84
- <div><small>声明节点</small><strong id="metric-nodes">—</strong></div>
92
+ <div><small id="metric-second-label">流程入口</small><strong id="metric-nodes">—</strong></div>
85
93
  </div>
86
94
  <div class="overview-item">
87
95
  <span class="metric-icon edge-icon">↗</span>
88
- <div><small>声明关系</small><strong id="metric-edges">—</strong></div>
96
+ <div><small id="metric-third-label">业务对象</small><strong id="metric-edges">—</strong></div>
89
97
  </div>
90
98
  <div class="overview-health">
91
99
  <span id="health-dot" class="health-dot"></span>
@@ -94,12 +102,13 @@
94
102
  </div>
95
103
  </section>
96
104
 
97
- <section class="explorer" aria-label="交互式本体图谱">
105
+ <!-- 三个视图共享工具条;business-view 承载流程,canvas 承载完整图和对象字段图。 -->
106
+ <section class="explorer business-mode" id="explorer" aria-label="交互式业务地图与本体图谱">
98
107
  <div class="graph-panel">
99
108
  <div class="graph-toolbar">
100
109
  <div class="tabs" role="group" aria-label="图谱视图">
101
- <button data-mode="structure" class="active" aria-pressed="true">对象与字段</button
102
- ><button data-mode="business" aria-pressed="false">业务流程</button
110
+ <button data-mode="business" class="active" aria-pressed="true">业务地图</button
111
+ ><button data-mode="structure" aria-pressed="false">对象与字段</button
103
112
  ><button data-mode="all" aria-pressed="false">完整本体</button>
104
113
  </div>
105
114
  <div class="search-wrap">
@@ -107,13 +116,14 @@
107
116
  ><input
108
117
  id="search"
109
118
  type="search"
110
- placeholder="搜索中文名称或代码标识"
119
+ placeholder="搜索业务、流程或代码标识"
111
120
  aria-label="搜索节点"
112
121
  autocomplete="off"
113
122
  /><kbd>/</kbd>
114
123
  <div id="search-results" class="search-results" hidden></div>
115
124
  </div>
116
125
  </div>
126
+ <div id="business-view" class="business-view" aria-label="业务板块与流程"></div>
117
127
  <div class="graph-subbar">
118
128
  <span
119
129
  ><i class="tiny-dot"></i><strong id="view-title">全部业务</strong
@@ -150,6 +160,7 @@
150
160
  <path d="M0 0L10 5L0 10z" fill="#357c6c" />
151
161
  </marker>
152
162
  </defs>
163
+ <!-- 脚本只变换 viewport 来实现平移和缩放,边先于节点绘制以保留节点命中面。 -->
153
164
  <g id="viewport">
154
165
  <g id="edges"></g>
155
166
  <g id="nodes"></g>
@@ -180,11 +191,13 @@
180
191
  </div>
181
192
  <aside id="inspector" class="inspector" aria-label="节点与关系详情" aria-live="polite"></aside>
182
193
  </section>
194
+ <div id="business-health" class="business-health" aria-live="polite"></div>
183
195
  <footer class="page-footer">
184
196
  <span id="domain-path">packages/domain/src/index.ts</span><span>只读探索 · 不连接业务数据库</span>
185
197
  </footer>
186
198
  </main>
187
199
  </div>
200
+ <!-- 规则发现保留在独立对话框,不因主画布能显示就隐藏声明错误。 -->
188
201
  <dialog id="findings-dialog">
189
202
  <div class="dialog-heading">
190
203
  <h2>声明检查</h2>
@@ -192,6 +205,7 @@
192
205
  </div>
193
206
  <div id="findings-list"></div>
194
207
  </dialog>
208
+ <!-- 模块入口在 DOM 骨架之后加载,固定资源由 CLI 构建脚本输出到 graph-ui。 -->
195
209
  <script type="module" src="/app.js"></script>
196
210
  </body>
197
211
  </html>
package/graph-ui/model.js CHANGED
@@ -1,86 +1,49 @@
1
+ import { kindLabels } from './graph-model.js';
2
+ export { nodeLabel, projectGraph, neighborhood, edgeLabels } from './graph-model.js';
3
+ export { matchesNode } from './graph-search.js';
4
+ /**
5
+ * 节点类型对应的中文标签、颜色、短字和布局列优先级;只影响图谱呈现。
6
+ */
1
7
  export const kinds = {
2
- aggregate: { label: '业务对象', color: '#197c72', short: '表', column: 0 },
3
- command: { label: '命令', color: '#547db2', short: '令', column: 1 },
4
- event: { label: '事件', color: '#c08c36', short: '事', column: 2 },
5
- reaction: { label: '反应', color: '#aa7288', short: '应', column: 3 },
6
- query: { label: '查询', color: '#648c5b', short: '查', column: 1 },
7
- approval: { label: '审批', color: '#9c739f', short: '审', column: 3 },
8
- route: { label: '审批路由', color: '#9c739f', short: '路', column: 3 },
9
- job: { label: '定时任务', color: '#7f82a0', short: '时', column: 0 },
10
- connector: { label: '连接器', color: '#b57452', short: '连', column: 4 },
11
- outbound: { label: '出站映射', color: '#b57452', short: '出', column: 3 },
12
- inbound: { label: '入站回调', color: '#b57452', short: '入', column: 4 },
13
- field: { label: '字段', color: '#67998f', short: '字', column: 1 },
14
- state: { label: '状态', color: '#898b69', short: '态', column: 2 },
15
- capability: { label: '能力点', color: '#81949f', short: '权', column: 1 },
16
- entry: { label: '新建入口', color: '#89938e', short: '+', column: 0 },
8
+ aggregate: { label: kindLabels.aggregate, color: '#197c72', short: '表', column: 0 },
9
+ command: { label: kindLabels.command, color: '#547db2', short: '令', column: 1 },
10
+ event: { label: kindLabels.event, color: '#c08c36', short: '事', column: 2 },
11
+ reaction: { label: kindLabels.reaction, color: '#aa7288', short: '应', column: 3 },
12
+ query: { label: kindLabels.query, color: '#648c5b', short: '查', column: 1 },
13
+ approval: { label: kindLabels.approval, color: '#9c739f', short: '审', column: 3 },
14
+ route: { label: kindLabels.route, color: '#9c739f', short: '路', column: 3 },
15
+ job: { label: kindLabels.job, color: '#7f82a0', short: '时', column: 0 },
16
+ connector: { label: kindLabels.connector, color: '#b57452', short: '连', column: 4 },
17
+ outbound: { label: kindLabels.outbound, color: '#b57452', short: '出', column: 3 },
18
+ inbound: { label: kindLabels.inbound, color: '#b57452', short: '入', column: 4 },
19
+ field: { label: kindLabels.field, color: '#67998f', short: '字', column: 1 },
20
+ state: { label: kindLabels.state, color: '#898b69', short: '态', column: 2 },
21
+ capability: { label: kindLabels.capability, color: '#81949f', short: '权', column: 1 },
22
+ entry: { label: kindLabels.entry, color: '#89938e', short: '+', column: 0 },
23
+ process: { label: kindLabels.process, color: '#397a56', short: '流', column: 0 },
24
+ stage: { label: kindLabels.stage, color: '#648c5b', short: '段', column: 1 },
17
25
  };
18
- export const edgeLabels = {
19
- transition: '状态迁移',
20
- reads: '读取',
21
- emits: '发出',
22
- uses: '使用字段',
23
- triggers: '触发',
24
- targets: '调用目标',
25
- queries: '查询',
26
- refs: '引用',
27
- calls: '调用',
28
- binds: '审批绑定',
29
- field: '声明字段',
30
- ownership: '归属(视图推导)',
31
- };
32
- /** 中文用于展示,英文仍作为复制、搜索和查源码的稳定标识。
33
- * 没有配置业务名称的未知节点保留原标识,不能猜测业务含义后悄悄改名。 */
34
- export function nodeLabel(node, labels = {}) {
35
- if (node.kind === 'entry')
36
- return '新建入口';
37
- return labels[node.key] || String(node.attrs.description || node.id);
38
- }
39
- export function matchesNode(node, query, labels) {
40
- return `${nodeLabel(node, labels)} ${node.id} ${kinds[node.kind].label}`
41
- .toLowerCase()
42
- .includes(query.toLowerCase());
43
- }
44
- export function projectGraph(graph) {
45
- const nodes = graph.nodes.map((n) => ({ ...n, key: `${n.kind}:${n.id}` }));
46
- const edges = [];
47
- // 节点身份包含 kind。能力点和命令可能同名,不能单用显示名作为 SVG 的主键。
48
- const find = (id) => nodes.find((n) => n.id === id && n.kind !== 'capability') ?? nodes.find((n) => n.id === id);
49
- for (const e of graph.edges) {
50
- let from = find(e.from);
51
- const to = find(e.to);
52
- // [new] 是迁移的起点,并不属于声明状态;在视图中显式标为虚拟入口。
53
- if (!from && e.kind === 'transition' && e.from.endsWith('.[new]')) {
54
- from = { key: `entry:${e.from}`, id: e.from, kind: 'entry', hash: '', attrs: {} };
55
- nodes.push(from);
56
- }
57
- if (from && to)
58
- edges.push({ ...e, from: from.key, to: to.key, key: `edge:${edges.length}`, derived: false });
59
- }
60
- for (const n of nodes) {
61
- if (!['command', 'state', 'capability', 'entry'].includes(n.kind))
62
- continue;
63
- const owner = nodes.find((a) => a.kind === 'aggregate' && n.id.startsWith(`${a.id}.`));
64
- if (owner)
65
- edges.push({ key: `owner:${n.key}`, kind: 'ownership', from: owner.key, to: n.key, derived: true });
66
- }
67
- return { nodes, edges };
68
- }
69
- export const isSystem = (n) => /^(User|Role|Dept)(\.|$)/.test(n.id);
70
- export function neighborhood(model, key) {
71
- const connected = new Set([key]);
72
- for (const e of model.edges) {
73
- if (e.from === key)
74
- connected.add(e.to);
75
- if (e.to === key)
76
- connected.add(e.from);
77
- }
78
- return connected;
79
- }
26
+ /**
27
+ * 按组织聚合前缀识别默认隐藏对象,不是能力或租户授权判断。
28
+ */
29
+ export const isSystem = (node) => /^(User|Role|Dept)(\.|$)/.test(node.id);
30
+ /**
31
+ * 完整本体普通节点的固定宽度,单位为画布单位,与 edgePath 端点计算保持一致。
32
+ */
80
33
  export const NODE_WIDTH = 190;
34
+ /**
35
+ * 完整本体普通节点高度,单位为画布单位;对象字段卡片使用独立动态高度。
36
+ */
81
37
  export const NODE_HEIGHT = 56;
82
38
  /** 按类型分组的平衡列 + 邻接排序。相同声明每次打开位置相同,没有持续运动的力导向
83
39
  * 动画;读长名称、比较刷新前后的关系时不会被随机布局打断。 */
40
+ /**
41
+ * 按语义列与邻接平均纵坐标计算确定性位置,避免随机布局干扰阅读。
42
+ * @param nodes 可见节点,不修改原数组。
43
+ * @param edges 可见关系。
44
+ * @param focusKey 小于等于 12 节点时以该节点作为中间列。
45
+ * @returns 节点 key 到坐标映射;没有持续动画或 DOM 副作用。
46
+ */
84
47
  export function layoutGraph(nodes, edges, focusKey) {
85
48
  const positions = new Map();
86
49
  // 小范围聚焦按关系方向排布:依赖方在左、当前节点居中、目标在右。
@@ -123,6 +86,13 @@ export function layoutGraph(nodes, edges, focusKey) {
123
86
  }
124
87
  return positions;
125
88
  }
89
+ /**
90
+ * 根据两个普通节点位置绘制曲线,同列及自环从侧面绕行。
91
+ * @param from 起点左上角。
92
+ * @param to 终点左上角。
93
+ * @param self 是否自环。
94
+ * @returns SVG d 属性,不绘制或修改节点。
95
+ */
126
96
  export function edgePath(from, to, self) {
127
97
  if (self)
128
98
  return `M${from.x + NODE_WIDTH - 25},${from.y} C${from.x + NODE_WIDTH + 50},${from.y - 65} ${from.x + NODE_WIDTH + 50},${from.y + 100} ${from.x + NODE_WIDTH - 25},${from.y + NODE_HEIGHT}`;