@mantajs/core 0.1.7 → 0.2.0-beta.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 (566) hide show
  1. package/dist/adapters/auth-mock.d.ts +44 -0
  2. package/dist/adapters/auth-mock.d.ts.map +1 -0
  3. package/dist/adapters/auth-mock.js +160 -0
  4. package/dist/adapters/auth-mock.js.map +1 -0
  5. package/dist/adapters/cache-memory.d.ts +11 -0
  6. package/dist/adapters/cache-memory.d.ts.map +1 -0
  7. package/dist/adapters/cache-memory.js +32 -0
  8. package/dist/adapters/cache-memory.js.map +1 -0
  9. package/dist/adapters/database-memory.d.ts +24 -0
  10. package/dist/adapters/database-memory.d.ts.map +1 -0
  11. package/dist/adapters/database-memory.js +141 -0
  12. package/dist/adapters/database-memory.js.map +1 -0
  13. package/dist/adapters/eventbus-memory.d.ts +37 -0
  14. package/dist/adapters/eventbus-memory.d.ts.map +1 -0
  15. package/dist/adapters/eventbus-memory.js +166 -0
  16. package/dist/adapters/eventbus-memory.js.map +1 -0
  17. package/dist/adapters/file-memory.d.ts +24 -0
  18. package/dist/adapters/file-memory.d.ts.map +1 -0
  19. package/dist/adapters/file-memory.js +77 -0
  20. package/dist/adapters/file-memory.js.map +1 -0
  21. package/dist/adapters/http-memory.d.ts +23 -0
  22. package/dist/adapters/http-memory.d.ts.map +1 -0
  23. package/dist/adapters/http-memory.js +149 -0
  24. package/dist/adapters/http-memory.js.map +1 -0
  25. package/dist/adapters/index.d.ts +14 -0
  26. package/dist/adapters/index.d.ts.map +1 -0
  27. package/dist/adapters/index.js +15 -0
  28. package/dist/adapters/index.js.map +1 -0
  29. package/dist/adapters/job-scheduler-memory.d.ts +20 -0
  30. package/dist/adapters/job-scheduler-memory.d.ts.map +1 -0
  31. package/dist/adapters/job-scheduler-memory.js +103 -0
  32. package/dist/adapters/job-scheduler-memory.js.map +1 -0
  33. package/dist/adapters/locking-memory.d.ts +20 -0
  34. package/dist/adapters/locking-memory.d.ts.map +1 -0
  35. package/dist/adapters/locking-memory.js +85 -0
  36. package/dist/adapters/locking-memory.js.map +1 -0
  37. package/dist/adapters/logger-test.d.ts +30 -0
  38. package/dist/adapters/logger-test.d.ts.map +1 -0
  39. package/dist/adapters/logger-test.js +77 -0
  40. package/dist/adapters/logger-test.js.map +1 -0
  41. package/dist/adapters/notification-memory.d.ts +27 -0
  42. package/dist/adapters/notification-memory.d.ts.map +1 -0
  43. package/dist/adapters/notification-memory.js +69 -0
  44. package/dist/adapters/notification-memory.js.map +1 -0
  45. package/dist/adapters/relational-query-memory.d.ts +47 -0
  46. package/dist/adapters/relational-query-memory.d.ts.map +1 -0
  47. package/dist/adapters/relational-query-memory.js +263 -0
  48. package/dist/adapters/relational-query-memory.js.map +1 -0
  49. package/dist/adapters/repository-factory-memory.d.ts +17 -0
  50. package/dist/adapters/repository-factory-memory.d.ts.map +1 -0
  51. package/dist/adapters/repository-factory-memory.js +32 -0
  52. package/dist/adapters/repository-factory-memory.js.map +1 -0
  53. package/dist/adapters/repository-memory.d.ts +30 -0
  54. package/dist/adapters/repository-memory.d.ts.map +1 -0
  55. package/dist/adapters/repository-memory.js +183 -0
  56. package/dist/adapters/repository-memory.js.map +1 -0
  57. package/dist/ai/index.d.ts +53 -0
  58. package/dist/ai/index.d.ts.map +1 -0
  59. package/dist/ai/index.js +48 -0
  60. package/dist/ai/index.js.map +1 -0
  61. package/dist/app/index.d.ts +97 -0
  62. package/dist/app/index.d.ts.map +1 -0
  63. package/dist/app/index.js +217 -0
  64. package/dist/app/index.js.map +1 -0
  65. package/dist/app/request-context.d.ts +35 -0
  66. package/dist/app/request-context.d.ts.map +1 -0
  67. package/dist/app/request-context.js +32 -0
  68. package/dist/app/request-context.js.map +1 -0
  69. package/dist/auth/auth-module-service.d.ts +62 -0
  70. package/dist/auth/auth-module-service.d.ts.map +1 -0
  71. package/dist/auth/auth-module-service.js +210 -0
  72. package/dist/auth/auth-module-service.js.map +1 -0
  73. package/dist/auth/index.d.ts +7 -0
  74. package/dist/auth/index.d.ts.map +1 -0
  75. package/dist/auth/index.js +5 -0
  76. package/dist/auth/index.js.map +1 -0
  77. package/dist/auth/middleware.d.ts +19 -0
  78. package/dist/auth/middleware.d.ts.map +1 -0
  79. package/dist/auth/middleware.js +61 -0
  80. package/dist/auth/middleware.js.map +1 -0
  81. package/dist/auth/models/auth-identity.d.ts +11 -0
  82. package/dist/auth/models/auth-identity.d.ts.map +1 -0
  83. package/dist/auth/models/auth-identity.js +12 -0
  84. package/dist/auth/models/auth-identity.js.map +1 -0
  85. package/dist/auth/providers/emailpass.d.ts +7 -0
  86. package/dist/auth/providers/emailpass.d.ts.map +1 -0
  87. package/dist/auth/providers/emailpass.js +94 -0
  88. package/dist/auth/providers/emailpass.js.map +1 -0
  89. package/dist/auth/providers/types.d.ts +66 -0
  90. package/dist/auth/providers/types.d.ts.map +1 -0
  91. package/dist/auth/providers/types.js +3 -0
  92. package/dist/auth/providers/types.js.map +1 -0
  93. package/dist/auth/types.d.ts +36 -0
  94. package/dist/auth/types.d.ts.map +1 -0
  95. package/dist/auth/types.js +3 -0
  96. package/dist/auth/types.js.map +1 -0
  97. package/dist/command/define-command-graph.d.ts +63 -0
  98. package/dist/command/define-command-graph.d.ts.map +1 -0
  99. package/dist/command/define-command-graph.js +80 -0
  100. package/dist/command/define-command-graph.js.map +1 -0
  101. package/dist/command/dml-to-zod.d.ts +34 -0
  102. package/dist/command/dml-to-zod.d.ts.map +1 -0
  103. package/dist/command/dml-to-zod.js +140 -0
  104. package/dist/command/dml-to-zod.js.map +1 -0
  105. package/dist/command/generate-entity-commands.d.ts +68 -0
  106. package/dist/command/generate-entity-commands.d.ts.map +1 -0
  107. package/dist/command/generate-entity-commands.js +350 -0
  108. package/dist/command/generate-entity-commands.js.map +1 -0
  109. package/dist/command/index.d.ts +54 -0
  110. package/dist/command/index.d.ts.map +1 -0
  111. package/dist/command/index.js +338 -0
  112. package/dist/command/index.js.map +1 -0
  113. package/dist/command/types.d.ts +131 -0
  114. package/dist/command/types.d.ts.map +1 -0
  115. package/dist/command/types.js +2 -0
  116. package/dist/command/types.js.map +1 -0
  117. package/dist/config/built-in-presets.d.ts +20 -0
  118. package/dist/config/built-in-presets.d.ts.map +1 -0
  119. package/dist/config/built-in-presets.js +70 -0
  120. package/dist/config/built-in-presets.js.map +1 -0
  121. package/dist/config/config-manager.d.ts +117 -0
  122. package/dist/config/config-manager.d.ts.map +1 -0
  123. package/dist/config/config-manager.js +245 -0
  124. package/dist/config/config-manager.js.map +1 -0
  125. package/dist/config/define-config.d.ts +20 -0
  126. package/dist/config/define-config.d.ts.map +1 -0
  127. package/dist/config/define-config.js +64 -0
  128. package/dist/config/define-config.js.map +1 -0
  129. package/dist/config/feature-flags.d.ts +48 -0
  130. package/dist/config/feature-flags.d.ts.map +1 -0
  131. package/dist/config/feature-flags.js +97 -0
  132. package/dist/config/feature-flags.js.map +1 -0
  133. package/dist/config/index.d.ts +9 -0
  134. package/dist/config/index.d.ts.map +1 -0
  135. package/dist/config/index.js +8 -0
  136. package/dist/config/index.js.map +1 -0
  137. package/dist/config/presets.d.ts +38 -0
  138. package/dist/config/presets.d.ts.map +1 -0
  139. package/dist/config/presets.js +29 -0
  140. package/dist/config/presets.js.map +1 -0
  141. package/dist/config/types.d.ts +707 -0
  142. package/dist/config/types.d.ts.map +1 -0
  143. package/dist/config/types.js +112 -0
  144. package/dist/config/types.js.map +1 -0
  145. package/dist/context/index.d.ts +95 -0
  146. package/dist/context/index.d.ts.map +1 -0
  147. package/dist/context/index.js +26 -0
  148. package/dist/context/index.js.map +1 -0
  149. package/dist/context/registry.d.ts +32 -0
  150. package/dist/context/registry.d.ts.map +1 -0
  151. package/dist/context/registry.js +142 -0
  152. package/dist/context/registry.js.map +1 -0
  153. package/dist/db/index.d.ts +2 -0
  154. package/dist/db/index.d.ts.map +1 -0
  155. package/dist/db/index.js +4 -0
  156. package/dist/db/index.js.map +1 -0
  157. package/dist/db/schema.d.ts +839 -0
  158. package/dist/db/schema.d.ts.map +1 -0
  159. package/dist/db/schema.js +106 -0
  160. package/dist/db/schema.js.map +1 -0
  161. package/dist/dml/entity.d.ts +132 -0
  162. package/dist/dml/entity.d.ts.map +1 -0
  163. package/dist/dml/entity.js +110 -0
  164. package/dist/dml/entity.js.map +1 -0
  165. package/dist/dml/from-zod.d.ts +13 -0
  166. package/dist/dml/from-zod.d.ts.map +1 -0
  167. package/dist/dml/from-zod.js +81 -0
  168. package/dist/dml/from-zod.js.map +1 -0
  169. package/dist/dml/generator/index.d.ts +62 -0
  170. package/dist/dml/generator/index.d.ts.map +1 -0
  171. package/dist/dml/generator/index.js +208 -0
  172. package/dist/dml/generator/index.js.map +1 -0
  173. package/dist/dml/index.d.ts +11 -0
  174. package/dist/dml/index.d.ts.map +1 -0
  175. package/dist/dml/index.js +13 -0
  176. package/dist/dml/index.js.map +1 -0
  177. package/dist/dml/infer.d.ts +36 -0
  178. package/dist/dml/infer.d.ts.map +1 -0
  179. package/dist/dml/infer.js +5 -0
  180. package/dist/dml/infer.js.map +1 -0
  181. package/dist/dml/model.d.ts +58 -0
  182. package/dist/dml/model.d.ts.map +1 -0
  183. package/dist/dml/model.js +95 -0
  184. package/dist/dml/model.js.map +1 -0
  185. package/dist/dml/modifiers.d.ts +9 -0
  186. package/dist/dml/modifiers.d.ts.map +1 -0
  187. package/dist/dml/modifiers.js +25 -0
  188. package/dist/dml/modifiers.js.map +1 -0
  189. package/dist/dml/properties/array.d.ts +7 -0
  190. package/dist/dml/properties/array.d.ts.map +1 -0
  191. package/dist/dml/properties/array.js +5 -0
  192. package/dist/dml/properties/array.js.map +1 -0
  193. package/dist/dml/properties/autoincrement.d.ts +7 -0
  194. package/dist/dml/properties/autoincrement.d.ts.map +1 -0
  195. package/dist/dml/properties/autoincrement.js +5 -0
  196. package/dist/dml/properties/autoincrement.js.map +1 -0
  197. package/dist/dml/properties/base.d.ts +124 -0
  198. package/dist/dml/properties/base.d.ts.map +1 -0
  199. package/dist/dml/properties/base.js +76 -0
  200. package/dist/dml/properties/base.js.map +1 -0
  201. package/dist/dml/properties/big-number.d.ts +7 -0
  202. package/dist/dml/properties/big-number.d.ts.map +1 -0
  203. package/dist/dml/properties/big-number.js +5 -0
  204. package/dist/dml/properties/big-number.js.map +1 -0
  205. package/dist/dml/properties/boolean.d.ts +7 -0
  206. package/dist/dml/properties/boolean.d.ts.map +1 -0
  207. package/dist/dml/properties/boolean.js +5 -0
  208. package/dist/dml/properties/boolean.js.map +1 -0
  209. package/dist/dml/properties/computed.d.ts +9 -0
  210. package/dist/dml/properties/computed.d.ts.map +1 -0
  211. package/dist/dml/properties/computed.js +22 -0
  212. package/dist/dml/properties/computed.js.map +1 -0
  213. package/dist/dml/properties/date-time.d.ts +7 -0
  214. package/dist/dml/properties/date-time.d.ts.map +1 -0
  215. package/dist/dml/properties/date-time.js +5 -0
  216. package/dist/dml/properties/date-time.js.map +1 -0
  217. package/dist/dml/properties/enum.d.ts +12 -0
  218. package/dist/dml/properties/enum.d.ts.map +1 -0
  219. package/dist/dml/properties/enum.js +14 -0
  220. package/dist/dml/properties/enum.js.map +1 -0
  221. package/dist/dml/properties/float.d.ts +7 -0
  222. package/dist/dml/properties/float.d.ts.map +1 -0
  223. package/dist/dml/properties/float.js +5 -0
  224. package/dist/dml/properties/float.js.map +1 -0
  225. package/dist/dml/properties/index.d.ts +15 -0
  226. package/dist/dml/properties/index.d.ts.map +1 -0
  227. package/dist/dml/properties/index.js +15 -0
  228. package/dist/dml/properties/index.js.map +1 -0
  229. package/dist/dml/properties/json.d.ts +7 -0
  230. package/dist/dml/properties/json.d.ts.map +1 -0
  231. package/dist/dml/properties/json.js +6 -0
  232. package/dist/dml/properties/json.js.map +1 -0
  233. package/dist/dml/properties/nullable.d.ts +23 -0
  234. package/dist/dml/properties/nullable.d.ts.map +1 -0
  235. package/dist/dml/properties/nullable.js +46 -0
  236. package/dist/dml/properties/nullable.js.map +1 -0
  237. package/dist/dml/properties/number.d.ts +10 -0
  238. package/dist/dml/properties/number.d.ts.map +1 -0
  239. package/dist/dml/properties/number.js +13 -0
  240. package/dist/dml/properties/number.js.map +1 -0
  241. package/dist/dml/properties/primary-key.d.ts +14 -0
  242. package/dist/dml/properties/primary-key.d.ts.map +1 -0
  243. package/dist/dml/properties/primary-key.js +23 -0
  244. package/dist/dml/properties/primary-key.js.map +1 -0
  245. package/dist/dml/properties/text.d.ts +15 -0
  246. package/dist/dml/properties/text.d.ts.map +1 -0
  247. package/dist/dml/properties/text.js +19 -0
  248. package/dist/dml/properties/text.js.map +1 -0
  249. package/dist/dml/relations/belongs-to.d.ts +20 -0
  250. package/dist/dml/relations/belongs-to.d.ts.map +1 -0
  251. package/dist/dml/relations/belongs-to.js +29 -0
  252. package/dist/dml/relations/belongs-to.js.map +1 -0
  253. package/dist/dml/relations/has-many.d.ts +16 -0
  254. package/dist/dml/relations/has-many.d.ts.map +1 -0
  255. package/dist/dml/relations/has-many.js +25 -0
  256. package/dist/dml/relations/has-many.js.map +1 -0
  257. package/dist/dml/relations/has-one.d.ts +26 -0
  258. package/dist/dml/relations/has-one.d.ts.map +1 -0
  259. package/dist/dml/relations/has-one.js +46 -0
  260. package/dist/dml/relations/has-one.js.map +1 -0
  261. package/dist/dml/relations/many-to-many.d.ts +9 -0
  262. package/dist/dml/relations/many-to-many.d.ts.map +1 -0
  263. package/dist/dml/relations/many-to-many.js +11 -0
  264. package/dist/dml/relations/many-to-many.js.map +1 -0
  265. package/dist/errors/manta-error.d.ts +68 -0
  266. package/dist/errors/manta-error.d.ts.map +1 -0
  267. package/dist/errors/manta-error.js +80 -0
  268. package/dist/errors/manta-error.js.map +1 -0
  269. package/dist/events/index.d.ts +3 -0
  270. package/dist/events/index.d.ts.map +1 -0
  271. package/dist/events/index.js +3 -0
  272. package/dist/events/index.js.map +1 -0
  273. package/dist/events/message-aggregator.d.ts +25 -0
  274. package/dist/events/message-aggregator.d.ts.map +1 -0
  275. package/dist/events/message-aggregator.js +35 -0
  276. package/dist/events/message-aggregator.js.map +1 -0
  277. package/dist/events/types.d.ts +42 -0
  278. package/dist/events/types.d.ts.map +1 -0
  279. package/dist/events/types.js +3 -0
  280. package/dist/events/types.js.map +1 -0
  281. package/dist/index.d.ts +55 -0
  282. package/dist/index.d.ts.map +1 -0
  283. package/dist/index.js +53 -0
  284. package/dist/index.js.map +1 -0
  285. package/dist/job/index.d.ts +52 -0
  286. package/dist/job/index.d.ts.map +1 -0
  287. package/dist/job/index.js +31 -0
  288. package/dist/job/index.js.map +1 -0
  289. package/dist/link/index.d.ts +97 -0
  290. package/dist/link/index.d.ts.map +1 -0
  291. package/dist/link/index.js +185 -0
  292. package/dist/link/index.js.map +1 -0
  293. package/dist/middleware/define-middleware.d.ts +54 -0
  294. package/dist/middleware/define-middleware.d.ts.map +1 -0
  295. package/dist/middleware/define-middleware.js +40 -0
  296. package/dist/middleware/define-middleware.js.map +1 -0
  297. package/dist/middleware/index.d.ts +56 -0
  298. package/dist/middleware/index.d.ts.map +1 -0
  299. package/dist/middleware/index.js +50 -0
  300. package/dist/middleware/index.js.map +1 -0
  301. package/dist/module/index.d.ts +56 -0
  302. package/dist/module/index.d.ts.map +1 -0
  303. package/dist/module/index.js +52 -0
  304. package/dist/module/index.js.map +1 -0
  305. package/dist/module/versioning.d.ts +27 -0
  306. package/dist/module/versioning.d.ts.map +1 -0
  307. package/dist/module/versioning.js +64 -0
  308. package/dist/module/versioning.js.map +1 -0
  309. package/dist/naming.d.ts +39 -0
  310. package/dist/naming.d.ts.map +1 -0
  311. package/dist/naming.js +95 -0
  312. package/dist/naming.js.map +1 -0
  313. package/dist/ports/analytics.d.ts +7 -0
  314. package/dist/ports/analytics.d.ts.map +1 -0
  315. package/dist/ports/analytics.js +3 -0
  316. package/dist/ports/analytics.js.map +1 -0
  317. package/dist/ports/auth.d.ts +27 -0
  318. package/dist/ports/auth.d.ts.map +1 -0
  319. package/dist/ports/auth.js +3 -0
  320. package/dist/ports/auth.js.map +1 -0
  321. package/dist/ports/cache.d.ts +35 -0
  322. package/dist/ports/cache.d.ts.map +1 -0
  323. package/dist/ports/cache.js +3 -0
  324. package/dist/ports/cache.js.map +1 -0
  325. package/dist/ports/database.d.ts +40 -0
  326. package/dist/ports/database.d.ts.map +1 -0
  327. package/dist/ports/database.js +3 -0
  328. package/dist/ports/database.js.map +1 -0
  329. package/dist/ports/event-bus.d.ts +85 -0
  330. package/dist/ports/event-bus.d.ts.map +1 -0
  331. package/dist/ports/event-bus.js +3 -0
  332. package/dist/ports/event-bus.js.map +1 -0
  333. package/dist/ports/file.d.ts +62 -0
  334. package/dist/ports/file.d.ts.map +1 -0
  335. package/dist/ports/file.js +3 -0
  336. package/dist/ports/file.js.map +1 -0
  337. package/dist/ports/http.d.ts +20 -0
  338. package/dist/ports/http.d.ts.map +1 -0
  339. package/dist/ports/http.js +3 -0
  340. package/dist/ports/http.js.map +1 -0
  341. package/dist/ports/in-memory-progress-channel.d.ts +9 -0
  342. package/dist/ports/in-memory-progress-channel.d.ts.map +1 -0
  343. package/dist/ports/in-memory-progress-channel.js +19 -0
  344. package/dist/ports/in-memory-progress-channel.js.map +1 -0
  345. package/dist/ports/in-memory-queue.d.ts +24 -0
  346. package/dist/ports/in-memory-queue.d.ts.map +1 -0
  347. package/dist/ports/in-memory-queue.js +63 -0
  348. package/dist/ports/in-memory-queue.js.map +1 -0
  349. package/dist/ports/index.d.ts +27 -0
  350. package/dist/ports/index.d.ts.map +1 -0
  351. package/dist/ports/index.js +6 -0
  352. package/dist/ports/index.js.map +1 -0
  353. package/dist/ports/job-scheduler.d.ts +42 -0
  354. package/dist/ports/job-scheduler.d.ts.map +1 -0
  355. package/dist/ports/job-scheduler.js +3 -0
  356. package/dist/ports/job-scheduler.js.map +1 -0
  357. package/dist/ports/locking.d.ts +43 -0
  358. package/dist/ports/locking.d.ts.map +1 -0
  359. package/dist/ports/locking.js +3 -0
  360. package/dist/ports/locking.js.map +1 -0
  361. package/dist/ports/logger.d.ts +65 -0
  362. package/dist/ports/logger.d.ts.map +1 -0
  363. package/dist/ports/logger.js +3 -0
  364. package/dist/ports/logger.js.map +1 -0
  365. package/dist/ports/notification.d.ts +71 -0
  366. package/dist/ports/notification.d.ts.map +1 -0
  367. package/dist/ports/notification.js +3 -0
  368. package/dist/ports/notification.js.map +1 -0
  369. package/dist/ports/progress-channel.d.ts +46 -0
  370. package/dist/ports/progress-channel.d.ts.map +1 -0
  371. package/dist/ports/progress-channel.js +6 -0
  372. package/dist/ports/progress-channel.js.map +1 -0
  373. package/dist/ports/queue.d.ts +21 -0
  374. package/dist/ports/queue.d.ts.map +1 -0
  375. package/dist/ports/queue.js +15 -0
  376. package/dist/ports/queue.js.map +1 -0
  377. package/dist/ports/relational-query.d.ts +37 -0
  378. package/dist/ports/relational-query.d.ts.map +1 -0
  379. package/dist/ports/relational-query.js +3 -0
  380. package/dist/ports/relational-query.js.map +1 -0
  381. package/dist/ports/repository-factory.d.ts +21 -0
  382. package/dist/ports/repository-factory.d.ts.map +1 -0
  383. package/dist/ports/repository-factory.js +4 -0
  384. package/dist/ports/repository-factory.js.map +1 -0
  385. package/dist/ports/repository.d.ts +73 -0
  386. package/dist/ports/repository.d.ts.map +1 -0
  387. package/dist/ports/repository.js +3 -0
  388. package/dist/ports/repository.js.map +1 -0
  389. package/dist/ports/schema-generator.d.ts +15 -0
  390. package/dist/ports/schema-generator.d.ts.map +1 -0
  391. package/dist/ports/schema-generator.js +4 -0
  392. package/dist/ports/schema-generator.js.map +1 -0
  393. package/dist/ports/search.d.ts +7 -0
  394. package/dist/ports/search.d.ts.map +1 -0
  395. package/dist/ports/search.js +3 -0
  396. package/dist/ports/search.js.map +1 -0
  397. package/dist/ports/types.d.ts +112 -0
  398. package/dist/ports/types.d.ts.map +1 -0
  399. package/dist/ports/types.js +26 -0
  400. package/dist/ports/types.js.map +1 -0
  401. package/dist/ports/workflow-store.d.ts +111 -0
  402. package/dist/ports/workflow-store.d.ts.map +1 -0
  403. package/dist/ports/workflow-store.js +5 -0
  404. package/dist/ports/workflow-store.js.map +1 -0
  405. package/dist/query/define-query-graph.d.ts +55 -0
  406. package/dist/query/define-query-graph.d.ts.map +1 -0
  407. package/dist/query/define-query-graph.js +59 -0
  408. package/dist/query/define-query-graph.js.map +1 -0
  409. package/dist/query/define-query.d.ts +79 -0
  410. package/dist/query/define-query.d.ts.map +1 -0
  411. package/dist/query/define-query.js +77 -0
  412. package/dist/query/define-query.js.map +1 -0
  413. package/dist/query/extend-query-graph.d.ts +36 -0
  414. package/dist/query/extend-query-graph.d.ts.map +1 -0
  415. package/dist/query/extend-query-graph.js +34 -0
  416. package/dist/query/extend-query-graph.js.map +1 -0
  417. package/dist/query/index.d.ts +181 -0
  418. package/dist/query/index.d.ts.map +1 -0
  419. package/dist/query/index.js +288 -0
  420. package/dist/query/index.js.map +1 -0
  421. package/dist/service/define.d.ts +97 -0
  422. package/dist/service/define.d.ts.map +1 -0
  423. package/dist/service/define.js +45 -0
  424. package/dist/service/define.js.map +1 -0
  425. package/dist/service/index.d.ts +52 -0
  426. package/dist/service/index.d.ts.map +1 -0
  427. package/dist/service/index.js +281 -0
  428. package/dist/service/index.js.map +1 -0
  429. package/dist/service/instantiate.d.ts +15 -0
  430. package/dist/service/instantiate.d.ts.map +1 -0
  431. package/dist/service/instantiate.js +143 -0
  432. package/dist/service/instantiate.js.map +1 -0
  433. package/dist/service/snapshot-repository.d.ts +31 -0
  434. package/dist/service/snapshot-repository.d.ts.map +1 -0
  435. package/dist/service/snapshot-repository.js +114 -0
  436. package/dist/service/snapshot-repository.js.map +1 -0
  437. package/dist/service/types.d.ts +39 -0
  438. package/dist/service/types.d.ts.map +1 -0
  439. package/dist/service/types.js +3 -0
  440. package/dist/service/types.js.map +1 -0
  441. package/dist/strict-mode/index.d.ts +42 -0
  442. package/dist/strict-mode/index.d.ts.map +1 -0
  443. package/dist/strict-mode/index.js +84 -0
  444. package/dist/strict-mode/index.js.map +1 -0
  445. package/dist/subscriber/index.d.ts +117 -0
  446. package/dist/subscriber/index.d.ts.map +1 -0
  447. package/dist/subscriber/index.js +76 -0
  448. package/dist/subscriber/index.js.map +1 -0
  449. package/dist/testing/relational-query-suite.d.ts +22 -0
  450. package/dist/testing/relational-query-suite.d.ts.map +1 -0
  451. package/dist/testing/relational-query-suite.js +233 -0
  452. package/dist/testing/relational-query-suite.js.map +1 -0
  453. package/dist/user/auto-routes.d.ts +32 -0
  454. package/dist/user/auto-routes.d.ts.map +1 -0
  455. package/dist/user/auto-routes.js +424 -0
  456. package/dist/user/auto-routes.js.map +1 -0
  457. package/dist/user/define-user.d.ts +54 -0
  458. package/dist/user/define-user.d.ts.map +1 -0
  459. package/dist/user/define-user.js +103 -0
  460. package/dist/user/define-user.js.map +1 -0
  461. package/dist/user/index.d.ts +7 -0
  462. package/dist/user/index.d.ts.map +1 -0
  463. package/dist/user/index.js +5 -0
  464. package/dist/user/index.js.map +1 -0
  465. package/dist/user/models/user.d.ts +15 -0
  466. package/dist/user/models/user.d.ts.map +1 -0
  467. package/dist/user/models/user.js +16 -0
  468. package/dist/user/models/user.js.map +1 -0
  469. package/dist/user/user-module-service.d.ts +55 -0
  470. package/dist/user/user-module-service.d.ts.map +1 -0
  471. package/dist/user/user-module-service.js +100 -0
  472. package/dist/user/user-module-service.js.map +1 -0
  473. package/dist/workflows/ai-step.d.ts +2 -0
  474. package/dist/workflows/ai-step.d.ts.map +1 -0
  475. package/dist/workflows/ai-step.js +54 -0
  476. package/dist/workflows/ai-step.js.map +1 -0
  477. package/dist/workflows/create-step.d.ts +16 -0
  478. package/dist/workflows/create-step.d.ts.map +1 -0
  479. package/dist/workflows/create-step.js +194 -0
  480. package/dist/workflows/create-step.js.map +1 -0
  481. package/dist/workflows/create-workflow.d.ts +16 -0
  482. package/dist/workflows/create-workflow.d.ts.map +1 -0
  483. package/dist/workflows/create-workflow.js +21 -0
  484. package/dist/workflows/create-workflow.js.map +1 -0
  485. package/dist/workflows/define-workflow.d.ts +55 -0
  486. package/dist/workflows/define-workflow.d.ts.map +1 -0
  487. package/dist/workflows/define-workflow.js +72 -0
  488. package/dist/workflows/define-workflow.js.map +1 -0
  489. package/dist/workflows/emit-event-step.d.ts +17 -0
  490. package/dist/workflows/emit-event-step.d.ts.map +1 -0
  491. package/dist/workflows/emit-event-step.js +46 -0
  492. package/dist/workflows/emit-event-step.js.map +1 -0
  493. package/dist/workflows/for-each.d.ts +6 -0
  494. package/dist/workflows/for-each.d.ts.map +1 -0
  495. package/dist/workflows/for-each.js +79 -0
  496. package/dist/workflows/for-each.js.map +1 -0
  497. package/dist/workflows/index.d.ts +15 -0
  498. package/dist/workflows/index.d.ts.map +1 -0
  499. package/dist/workflows/index.js +12 -0
  500. package/dist/workflows/index.js.map +1 -0
  501. package/dist/workflows/manager.d.ts +99 -0
  502. package/dist/workflows/manager.d.ts.map +1 -0
  503. package/dist/workflows/manager.js +450 -0
  504. package/dist/workflows/manager.js.map +1 -0
  505. package/dist/workflows/orphan-reaper.d.ts +50 -0
  506. package/dist/workflows/orphan-reaper.d.ts.map +1 -0
  507. package/dist/workflows/orphan-reaper.js +69 -0
  508. package/dist/workflows/orphan-reaper.js.map +1 -0
  509. package/dist/workflows/progress-helper.d.ts +20 -0
  510. package/dist/workflows/progress-helper.d.ts.map +1 -0
  511. package/dist/workflows/progress-helper.js +48 -0
  512. package/dist/workflows/progress-helper.js.map +1 -0
  513. package/dist/workflows/step.d.ts +103 -0
  514. package/dist/workflows/step.d.ts.map +1 -0
  515. package/dist/workflows/step.js +949 -0
  516. package/dist/workflows/step.js.map +1 -0
  517. package/dist/workflows/types.d.ts +215 -0
  518. package/dist/workflows/types.d.ts.map +1 -0
  519. package/dist/workflows/types.js +9 -0
  520. package/dist/workflows/types.js.map +1 -0
  521. package/dist/workflows/yield.d.ts +12 -0
  522. package/dist/workflows/yield.d.ts.map +1 -0
  523. package/dist/workflows/yield.js +29 -0
  524. package/dist/workflows/yield.js.map +1 -0
  525. package/docs/00-overview.md +254 -0
  526. package/docs/01-getting-started.md +224 -0
  527. package/docs/02-models.md +163 -0
  528. package/docs/03-services.md +208 -0
  529. package/docs/04-users.md +165 -0
  530. package/docs/05-commands.md +501 -0
  531. package/docs/06-queries.md +342 -0
  532. package/docs/07-events.md +248 -0
  533. package/docs/08-links.md +182 -0
  534. package/docs/09-agents.md +142 -0
  535. package/docs/10-spa.md +327 -0
  536. package/docs/11-config.md +481 -0
  537. package/docs/12-constraints.md +183 -0
  538. package/docs/13-testing.md +345 -0
  539. package/docs/14-adapters.md +204 -0
  540. package/docs/15-hosts.md +163 -0
  541. package/docs/16-reference.md +274 -0
  542. package/docs/17-dashboard.md +619 -0
  543. package/docs/AGENT.md +501 -0
  544. package/package.json +49 -52
  545. package/.medusa/server/src/admin/index.js +0 -5493
  546. package/.medusa/server/src/admin/index.mjs +0 -5491
  547. package/.medusa/server/src/api/admin/companies/[id]/route.js +0 -39
  548. package/.medusa/server/src/api/admin/companies/middlewares.js +0 -41
  549. package/.medusa/server/src/api/admin/companies/route.js +0 -37
  550. package/.medusa/server/src/api/admin/companies/validators.js +0 -29
  551. package/.medusa/server/src/api/admin/employees/middlewares.js +0 -15
  552. package/.medusa/server/src/api/admin/employees/route.js +0 -21
  553. package/.medusa/server/src/api/middlewares.js +0 -9
  554. package/.medusa/server/src/index.js +0 -5
  555. package/.medusa/server/src/modules/company/index.js +0 -13
  556. package/.medusa/server/src/modules/company/migrations/Migration20260126141741.js +0 -26
  557. package/.medusa/server/src/modules/company/models/company.js +0 -24
  558. package/.medusa/server/src/modules/company/models/employee.js +0 -15
  559. package/.medusa/server/src/modules/company/models/index.js +0 -11
  560. package/.medusa/server/src/modules/company/service.js +0 -11
  561. package/.medusa/server/src/workflows/create-company.js +0 -10
  562. package/.medusa/server/src/workflows/delete-company.js +0 -10
  563. package/.medusa/server/src/workflows/steps/create-company.js +0 -16
  564. package/.medusa/server/src/workflows/steps/delete-company.js +0 -30
  565. package/.medusa/server/src/workflows/steps/update-company.js +0 -30
  566. package/.medusa/server/src/workflows/update-company.js +0 -10
@@ -0,0 +1,165 @@
1
+ # Users — defineUserModel()
2
+
3
+ `defineUserModel()` is an augmented `defineModel()` for entities that represent users who can log in. It creates a regular entity (with services, links, workflows, query graph access) AND auto-generates auth routes, middleware, and an invite system.
4
+
5
+ Use it **instead of** `defineModel()` in a module's `entities/{entity}/model.ts`.
6
+
7
+ ## Declaration
8
+
9
+ ```typescript
10
+ // src/modules/admin/entities/admin/model.ts
11
+ export default defineUserModel('admin', {
12
+ role: field.enum(['super_admin', 'editor', 'viewer']),
13
+ department: field.text().nullable(),
14
+ })
15
+ ```
16
+
17
+ ```typescript
18
+ // src/modules/customer/entities/customer/model.ts
19
+ export default defineUserModel('customer', {
20
+ company_name: field.text().nullable(),
21
+ phone: field.text().nullable(),
22
+ has_account: field.boolean().default(false),
23
+ })
24
+ ```
25
+
26
+ The entity works exactly like a `defineModel` entity — it can have a `service.ts`, be used in `defineLink`, appear in `defineWorkflow`, and is accessible in the query graph. The only difference is the auto-generated auth layer.
27
+
28
+ ## What it generates
29
+
30
+ ### Tables
31
+
32
+ **`admin_user`** — base fields + your custom fields:
33
+
34
+ | Column | Type | Notes |
35
+ |--------|------|-------|
36
+ | `id` | UUID | Primary key |
37
+ | `email` | text | Unique, indexed |
38
+ | `first_name` | text | Nullable |
39
+ | `last_name` | text | Nullable |
40
+ | `avatar_url` | text | Nullable |
41
+ | `metadata` | JSON | Nullable |
42
+ | `role` | enum | Custom field |
43
+ | `department` | text | Custom field |
44
+ | `created_at` | timestamp | Auto |
45
+ | `updated_at` | timestamp | Auto |
46
+ | `deleted_at` | timestamp | Soft-delete |
47
+
48
+ **`admin_invite`** — invitation records:
49
+
50
+ | Column | Type | Notes |
51
+ |--------|------|-------|
52
+ | `id` | UUID | Primary key |
53
+ | `email` | text | Indexed |
54
+ | `accepted` | boolean | Default: false |
55
+ | `token` | text | Random UUID, 7-day expiry |
56
+ | `expires_at` | timestamp | |
57
+ | `metadata` | JSON | Nullable |
58
+
59
+ ### Auth routes
60
+
61
+ All on `/api/admin/`:
62
+
63
+ | Route | Method | Auth | Description |
64
+ |-------|--------|------|-------------|
65
+ | `/login` | POST | Public | Email/password → JWT (`{ id, type: 'admin' }`) |
66
+ | `/logout` | DELETE | Public | Blacklists token in cache |
67
+ | `/refresh` | POST | Public | Exchange refresh token for new JWT |
68
+ | `/forgot-password` | POST | Public | Generates reset token |
69
+ | `/reset-password` | POST | Public | Validates token + resets password |
70
+ | `/accept-invite` | POST | Public | Accepts invite, creates user + auth |
71
+ | `/me` | GET | Required | Returns current user from `admin_user` |
72
+ | `/users` | GET | Required | Lists all `admin_user` records |
73
+ | `/create-user` | POST | Required | Creates user + auth identity |
74
+ | `/update-user` | POST | Required | Updates user fields |
75
+ | `/delete-user` | POST | Required | Soft-deletes user |
76
+ | `/create-invite` | POST | Required | Creates invitation with 7-day token |
77
+ | `/refresh-invite` | POST | Required | Regenerates invite token |
78
+
79
+ ### Middleware
80
+
81
+ All `/api/admin/*` routes (except public auth routes):
82
+ 1. Verify JWT Bearer token
83
+ 2. Check `auth.type === 'admin'`
84
+ 3. Reject with 401/403 if invalid
85
+
86
+ ### Dev seed
87
+
88
+ In dev mode: `admin@manta.local` / `admin` created automatically.
89
+
90
+ ## Multiple user types
91
+
92
+ ```typescript
93
+ // src/modules/admin/entities/admin/model.ts
94
+ export default defineUserModel('admin', {
95
+ role: field.enum(['super_admin', 'editor']),
96
+ })
97
+
98
+ // src/modules/customer/entities/customer/model.ts — in a module with other entities
99
+ export default defineUserModel('customer', {
100
+ company_name: field.text().nullable(),
101
+ phone: field.text().nullable(),
102
+ })
103
+ // The customer module can also have: customer-address, customer-group entities,
104
+ // links, workflows — defineUserModel is just a model, in a regular module.
105
+ ```
106
+
107
+ Each user type has independent: tables, auth routes, middleware, JWT actor type.
108
+
109
+ ## Override auto-generated routes
110
+
111
+ Create a command in `src/commands/{context}/` with the same name:
112
+
113
+ ```typescript
114
+ // src/commands/admin/login.ts — replaces auto-generated login
115
+ export default defineCommand({
116
+ name: 'login',
117
+ description: 'Custom admin login with 2FA',
118
+ input: z.object({ email: z.string(), password: z.string(), totp: z.string() }),
119
+ workflow: async (input, { step }) => {
120
+ // Custom 2FA logic
121
+ },
122
+ })
123
+ ```
124
+
125
+ ## Override middleware
126
+
127
+ Create `src/middleware/{context}.ts`:
128
+
129
+ ```typescript
130
+ // src/middleware/admin.ts — replaces auto-generated middleware
131
+ export default defineMiddleware(async (req, next) => {
132
+ const auth = await req.verifyAuth('admin')
133
+ if (!auth) throw new MantaError('UNAUTHORIZED')
134
+
135
+ // Custom RBAC
136
+ if (auth.entity.role === 'viewer' && req.method !== 'GET') {
137
+ throw new MantaError('FORBIDDEN', 'Viewers have read-only access')
138
+ }
139
+
140
+ return next()
141
+ })
142
+ ```
143
+
144
+ ## Auth context in handlers
145
+
146
+ Commands and queries receive the authenticated user:
147
+
148
+ ```typescript
149
+ workflow: async (input, { step, auth, headers }) => {
150
+ // auth.id — user ID (from admin_user.id)
151
+ // auth.type — 'admin'
152
+ // auth.email — user email
153
+ // headers['x-property-id'] — custom header
154
+ }
155
+ ```
156
+
157
+ ## JWT structure
158
+
159
+ The JWT is signed with `JWT_SECRET` (env variable). It contains:
160
+ - `id` — user ID from the context's user table
161
+ - `type` — context name (e.g., 'admin')
162
+ - `auth_identity_id` — internal auth identity reference
163
+ - `email` — user email
164
+
165
+ The JWT cannot be tampered with (signature verification). Token expiry: 1h access + 30d refresh.
@@ -0,0 +1,501 @@
1
+ # Commands — defineCommand()
2
+
3
+ ## What is a command
4
+
5
+ A command is the **entry point for all mutations** in Manta. It's a compensable workflow that automatically becomes:
6
+
7
+ - `POST /api/{context}/command/{name}` — HTTP endpoint
8
+ - AI tool schema — JSON Schema from Zod for Claude, GPT, etc.
9
+ - Dashboard action — Clickable in admin UI
10
+ - CLI command — `manta exec {name}`
11
+ - Sub-workflow — callable from other commands via `step.command.{name}()`
12
+
13
+ **You don't define routes. You define commands. The framework handles the rest.**
14
+
15
+ ## defineCommand()
16
+
17
+ ```typescript
18
+ export default defineCommand({
19
+ name: 'create-product',
20
+ description: 'Create a product with inventory setup and activation',
21
+ input: z.object({
22
+ title: z.string(),
23
+ sku: z.string(),
24
+ price: z.number().min(0),
25
+ initialStock: z.number().default(0),
26
+ reorderPoint: z.number().default(10),
27
+ }),
28
+ workflow: async (input, { step }) => {
29
+ // Step 1 — Create product (auto-compensated: delete on rollback)
30
+ const product = await step.service.catalog.create({
31
+ title: input.title,
32
+ sku: input.sku,
33
+ price: input.price,
34
+ status: 'draft',
35
+ })
36
+
37
+ // Step 2 — Create inventory (auto-compensated)
38
+ const inventory = await step.service.inventory.create({
39
+ quantity: input.initialStock,
40
+ reorder_point: input.reorderPoint,
41
+ warehouse: 'default',
42
+ })
43
+
44
+ // Step 3 — Link product to inventory (auto-resolved IDs)
45
+ await step.service.catalog.link.inventoryItem()
46
+
47
+ // Step 4 — Activate product (auto-compensated via snapshot)
48
+ await step.service.catalog.activate(product.id)
49
+
50
+ // Step 5 — Emit events (buffered until workflow commits)
51
+ await step.emit('product.created', {
52
+ id: product.id,
53
+ sku: input.sku,
54
+ title: input.title,
55
+ price: input.price,
56
+ })
57
+
58
+ return {
59
+ product: { id: product.id, sku: input.sku, status: 'active' },
60
+ inventory: { id: inventory.id, quantity: input.initialStock },
61
+ }
62
+ },
63
+ })
64
+ ```
65
+
66
+ **Required fields:**
67
+ - `name` — Unique command identifier (kebab-case)
68
+ - `description` — Used for AI tool discovery and documentation
69
+ - `input` — Zod schema (validates input + generates JSON Schema)
70
+ - `workflow` — Async function receiving `(input, { step, log, auth, headers })`
71
+
72
+ ## The step object
73
+
74
+ The workflow context provides `{ step, log, auth, headers }`:
75
+ - `step` — the fundamental unit of a workflow (typed, constrained, auto-compensated)
76
+ - `log` — structured logger
77
+ - `auth` — `AuthContext | null` (authenticated user, with `id` and `type`)
78
+ - `headers` — raw request headers
79
+
80
+ An AI cannot make mistakes with `step` — there are only 4 things you can do:
81
+
82
+ ### step.service — Call service methods
83
+
84
+ ```typescript
85
+ // CRUD (auto-compensated: create → delete on rollback)
86
+ const product = await step.service.catalog.create({ title: 'Widget', sku: 'W-001', price: 999 })
87
+ await step.service.catalog.update(product.id, { price: 1099 })
88
+ await step.service.catalog.delete(product.id)
89
+
90
+ // Custom compensable methods
91
+ await step.service.catalog.activate(product.id)
92
+ await step.service.inventory.adjustQuantity(inventoryId, -1)
93
+ ```
94
+
95
+ Every `step.service.*` call is:
96
+ - **Checkpointed** — saved to storage, skipped on retry
97
+ - **Compensated** — rollback registered in LIFO order
98
+ - **Typed** — autocomplete from codegen (`.manta/types/`)
99
+
100
+ ### step.service.MODULE.link — Create links
101
+
102
+ ```typescript
103
+ // After creating both entities:
104
+ const product = await step.service.catalog.create({...})
105
+ const inventory = await step.service.inventory.create({...})
106
+
107
+ // Link them — IDs auto-resolved from previous creates
108
+ await step.service.catalog.link.inventoryItem()
109
+ ```
110
+
111
+ The framework tracks the last created entity ID per type. `link.inventoryItem()` automatically resolves the Product ID and InventoryItem ID from the workflow context.
112
+
113
+ ### step.command — Call sub-commands
114
+
115
+ ```typescript
116
+ // Execute another command as a sub-command
117
+ const result = await step.command.createProduct({
118
+ title: 'Widget',
119
+ sku: 'W-001',
120
+ price: 999,
121
+ })
122
+ ```
123
+
124
+ The sub-command runs within the same compensation chain. If it fails, all its steps are compensated along with the parent.
125
+
126
+ ### step.workflow — Call module workflows
127
+
128
+ ```typescript
129
+ // Execute a module workflow (defined with defineWorkflow)
130
+ const result = await step.workflow.catalog.categorizeProduct({
131
+ productId: product.id,
132
+ categoryId: 'cat_123',
133
+ })
134
+ ```
135
+
136
+ Module workflows are defined in `src/modules/{mod}/workflows/` with `defineWorkflow()`. They are scoped to a single module and contain pure business logic (no auth context). Commands invoke them via `step.workflow.MODULE.NAME(input)`.
137
+
138
+ ### step.action — External actions with compensation
139
+
140
+ ```typescript
141
+ // For external API calls where you MUST provide compensation
142
+ const chargeResult = await step.action('charge-payment', {
143
+ invoke: async (input) => {
144
+ const charge = await stripe.charges.create({ amount: input.amount })
145
+ return { chargeId: charge.id }
146
+ },
147
+ compensate: async (result) => {
148
+ await stripe.refunds.create({ charge: result.chargeId })
149
+ },
150
+ })({ amount: 4999 })
151
+ ```
152
+
153
+ `step.action()` **requires** a `compensate` function. No exceptions. This ensures external side-effects are always reversible.
154
+
155
+ ### step.emit — Fire events
156
+
157
+ ```typescript
158
+ await step.emit('product.created', { id: product.id, sku: input.sku })
159
+ await step.emit('inventory.stocked', { productId: product.id, quantity: 100 })
160
+ ```
161
+
162
+ Events are **buffered** until the workflow commits. If the workflow fails and compensates, events are NOT emitted. Subscribers only see events from successful workflows.
163
+
164
+ ## What happens automatically
165
+
166
+ When you define a command:
167
+
168
+ 1. **Input validation** — Zod schema validates before workflow runs. Invalid input returns HTTP 400 with Zod error details.
169
+ 2. **Checkpoint storage** — Each step result is saved. If the process crashes, the workflow resumes from the last completed step.
170
+ 3. **Compensation (rollback)** — If any step fails, all completed steps compensate in reverse order (LIFO).
171
+ 4. **Retry** — 3 attempts with exponential backoff (configurable).
172
+ 5. **Event buffering** — `step.emit()` events are held until the workflow succeeds, then emitted together.
173
+ 6. **HTTP endpoint** — `POST /api/{context}/command/create-product` with Zod-validated JSON body.
174
+ 7. **AI tool schema** — `GET /api/{context}/tools` returns JSON Schema for all exposed commands.
175
+ 8. **OpenAPI** — `GET /api/openapi.json` includes the command with full schema.
176
+
177
+ ## Two types of commands
178
+
179
+ ### Application commands (cross-module)
180
+
181
+ Located in `src/commands/`. These orchestrate multiple modules:
182
+
183
+ ```
184
+ src/commands/create-product.ts
185
+ src/commands/checkout.ts
186
+ ```
187
+
188
+ They can call any module's service via `step.service.*`:
189
+
190
+ ```typescript
191
+ // src/commands/create-product.ts
192
+ workflow: async (input, { step }) => {
193
+ const product = await step.service.catalog.create({...})
194
+ const inventory = await step.service.inventory.create({...})
195
+ await step.service.catalog.link.inventoryItem()
196
+ // ↑ Cross-module: catalog + inventory
197
+ }
198
+ ```
199
+
200
+ ### Module workflows (scoped — defineWorkflow)
201
+
202
+ For intra-module business logic that orchestrates multiple entities within a module, use `defineWorkflow()` in `src/modules/{name}/workflows/`:
203
+
204
+ ```
205
+ src/modules/catalog/workflows/categorize-product.ts
206
+ src/modules/catalog/workflows/activate-and-publish.ts
207
+ ```
208
+
209
+ ```typescript
210
+ // src/modules/catalog/workflows/activate-and-publish.ts
211
+ export default defineWorkflow({
212
+ name: 'activate-and-publish',
213
+ input: z.object({ id: z.string() }),
214
+ workflow: async (input, { step, log }) => {
215
+ // Can only use step.service.catalog.* — scoped to this module
216
+ await step.service.catalog.activate(input.id)
217
+ await step.emit('product.activated', { id: input.id })
218
+ log.info(`Product ${input.id} activated`)
219
+ return { id: input.id, status: 'active' }
220
+ },
221
+ })
222
+ ```
223
+
224
+ **Key differences from defineCommand:**
225
+ - Receives `{ step, log }` — NO `auth`, NO `headers` (pure business logic)
226
+ - NOT an HTTP endpoint — only callable from commands via `step.workflow.MODULE.NAME(input)`
227
+ - Scoped to one module — the step proxy only resolves the module's own entities
228
+ - Has compensation (same step proxy as commands)
229
+
230
+ ### Calling module workflows from commands
231
+
232
+ Application commands invoke module workflows via `step.workflow`:
233
+
234
+ ```typescript
235
+ // src/commands/admin/create-and-activate.ts
236
+ workflow: async (input, { step, auth }) => {
237
+ const product = await step.service.catalog.create({...})
238
+ // Call the module workflow — runs in same compensation chain
239
+ await step.workflow.catalog.activateAndPublish({ id: product.id })
240
+ }
241
+ ```
242
+
243
+ The module workflow runs within the parent's compensation chain. If it fails, all steps compensate.
244
+
245
+ ## Long-running commands — progress, cancel, and the 300ms race
246
+
247
+ Any command can take longer than 300ms. Some (data imports, event replays, snapshot rebuilds) take minutes. The framework handles all three regimes through a single primitive — `useCommand` on the client — so you never branch your UI on "is this long or short".
248
+
249
+ > **Full design**: `WORKFLOW_PROGRESS.md` at the repo root. This section summarizes the developer-facing surface.
250
+
251
+ ### The 300ms race
252
+
253
+ When a client calls a command, the engine races the workflow against a 300ms timer:
254
+
255
+ - **If the workflow completes within 300ms** → full result returned inline. The client sees a normal sub-second request, no runId is exposed, nothing to observe.
256
+ - **Otherwise** → the HTTP response is `202 Accepted` with envelope `{ runId, status: 'running' }`. The workflow continues in the background; the client uses the runId to observe progress.
257
+
258
+ This threshold is NOT configurable. It aligns with the UX threshold where users start perceiving latency. 90%+ of commands finish inside the window and never expose a runId.
259
+
260
+ ### Step context helpers
261
+
262
+ Step handlers receive an extended `ctx` with three helpers. All are optional (only populated when the runtime has a store/channel wired) and zero-cost when unused.
263
+
264
+ #### `ctx.progress(current, total, message?)`
265
+
266
+ Report in-flight progress. **Fire-and-forget, synchronous return, never throws.**
267
+
268
+ ```ts
269
+ step('import-products', async (input, ctx) => {
270
+ for (let i = 0; i < products.length; i++) {
271
+ await importOne(products[i])
272
+ ctx.progress?.(i + 1, products.length, `Imported ${products[i].title}`)
273
+ }
274
+ })
275
+ ```
276
+
277
+ Signature:
278
+ ```ts
279
+ progress?: (current: number, total: number | null, message?: string) => void
280
+ ```
281
+
282
+ Invariants:
283
+ 1. **Never awaited** — calling `ctx.progress()` adds zero latency to the step's hot loop.
284
+ 2. **Never throws** — channel errors are logged, not propagated. A dead Redis must not fail a workflow.
285
+ 3. **No throttle at the call site** — call it as often as you want. The channel adapter copes (Upstash handles volumes trivially; the DB fallback throttles internally at 500ms).
286
+ 4. Pass `total: null` when the total is unknown (e.g. paginated API reads).
287
+
288
+ Progress is written to a liveness channel (Redis or DB fallback), **not** to Postgres. It's ephemeral by design — latest snapshot overrides previous, no history retained.
289
+
290
+ #### `ctx.signal` — cooperative cancellation
291
+
292
+ Standard `AbortSignal`. Aborted when `DELETE /api/admin/_workflow/:id` is called or the eventbus publishes `workflow:cancel:{runId}`.
293
+
294
+ **Contract for step authors**: any long-running step MUST respect `ctx.signal`. Either:
295
+
296
+ ```ts
297
+ // Pass through to I/O — preferred
298
+ await fetch(url, { signal: ctx.signal })
299
+
300
+ // Or check between work units
301
+ if (ctx.signal?.aborted) throw new CancelledError()
302
+ ```
303
+
304
+ Node cannot forcibly interrupt a running promise — cooperation is required. `ctx.forEach` (below) handles this automatically, so in practice most devs never manually check the signal.
305
+
306
+ On abort → the step is expected to throw → compensation runs in reverse order for all already-succeeded steps → overall status becomes `cancelled`.
307
+
308
+ #### `ctx.forEach(items, opts, handler)` — batched iteration with progress + cancel
309
+
310
+ Recommended default for any iterative long-running work. Combines batching, progress, and cancel into one idiom.
311
+
312
+ ```ts
313
+ step('replay-events', async (input, ctx) => {
314
+ await ctx.forEach?.(events, { batchSize: 500 }, async (batch, info) => {
315
+ for (const event of batch) applyEventToSnapshot(event, snapshot)
316
+ // ctx.progress() is called automatically after each batch completes
317
+ // ctx.signal.aborted is checked automatically between batches
318
+ })
319
+ })
320
+ ```
321
+
322
+ Signature:
323
+ ```ts
324
+ forEach?: <T>(
325
+ items: T[] | AsyncIterable<T>,
326
+ opts: { batchSize: number; message?: (info: ForEachInfo) => string },
327
+ handler: (batch: T[], info: ForEachInfo) => Promise<void>,
328
+ ) => Promise<void>
329
+
330
+ interface ForEachInfo {
331
+ done: number
332
+ total: number | null // null for unbounded AsyncIterable
333
+ batchIndex: number
334
+ }
335
+ ```
336
+
337
+ Accepting `AsyncIterable` lets streams (paginated API responses, DB cursors) flow through without buffering the full list in memory — critical for workflows over millions of rows.
338
+
339
+ ### Client — `useCommand`
340
+
341
+ One hook, all durations. The shape doesn't change between short and long commands.
342
+
343
+ ```tsx
344
+ const { run, runId, status, steps, progress, result, error, cancel } = useCommand<Input, Output>('command-name')
345
+
346
+ async function onSubmit() {
347
+ const res = await run(input)
348
+ if ('runId' in res) {
349
+ navigate(`/admin/_runs/${res.runId}`) // long workflow — observe it
350
+ }
351
+ // else: inline result, show inline
352
+ }
353
+ ```
354
+
355
+ | Field | Type | Semantics |
356
+ |---|---|---|
357
+ | `run(input)` | `(input) => Promise<RunResult>` | Kicks off the command. Returns inline result or `{ runId }`. |
358
+ | `runId` | `string \| undefined` | Present when the workflow is async. Triggers polling. |
359
+ | `status` | `'idle' \| 'running' \| 'succeeded' \| 'failed' \| 'cancelled'` | Overall workflow status. |
360
+ | `steps` | `StepState[] \| undefined` | Ordered step timeline with per-step status + timestamps. |
361
+ | `progress` | `ProgressSnapshot \| undefined` | Live snapshot from the active step (from liveness channel). |
362
+ | `result` | `Output \| undefined` | Final result on success. |
363
+ | `error` | `MantaError \| undefined` | Error details on failure. |
364
+ | `cancel()` | `() => Promise<void>` | `DELETE /api/admin/_workflow/:runId`. No-op if terminal. |
365
+
366
+ Polling: **1000ms fixed** whenever `runId` is set and status is non-terminal. Stops automatically on terminal status.
367
+
368
+ **Read-only mode** — for pages that observe an existing run without calling `run()`:
369
+ ```ts
370
+ const status = useCommand('command-name', { runId: 'abc-123' })
371
+ // Polls immediately, never calls run()
372
+ ```
373
+
374
+ ### Dashboard integration — `<WorkflowStatus>` and `/admin/_runs/:runId`
375
+
376
+ The framework ships a generic run viewer out of the box. Every long command is observable at `/admin/_runs/:runId` with zero frontend code:
377
+
378
+ - Command name + status badge
379
+ - Ordered step timeline (pending / running / succeeded / failed / cancelled / compensated)
380
+ - Progress bar for the active step (determinate if `total > 0`, indeterminate spinner with message otherwise)
381
+ - Cancel button while `status === 'running'`
382
+ - Error detail panel on failure
383
+ - Collapsible result JSON on success
384
+
385
+ The `<WorkflowStatus runId={id} />` component is exported from `@mantajs/dashboard` so you can embed the same renderer in a custom page (e.g. a cart detail view showing the active "rebuild-snapshot" run inline).
386
+
387
+ When a user clicks a `PageHeader.CommandButton` or submits a form built from a command spec, the framework:
388
+ 1. Calls `run(input)`.
389
+ 2. If the response is `{ runId }` → navigates to `/admin/_runs/:runId`.
390
+ 3. If the response is an inline result → shows inline success/error.
391
+
392
+ No client-side branching needed.
393
+
394
+ ### HTTP routes (framework-owned)
395
+
396
+ | Route | Purpose |
397
+ |---|---|
398
+ | `POST /api/{context}/command/{name}` | Start command. Returns inline result OR `202 { runId, status: 'running' }`. |
399
+ | `GET /api/admin/_workflow/:id` | Merged snapshot — durable state (Postgres `workflow_runs`) + live progress (Redis or DB fallback). Returns 404 if runId unknown. |
400
+ | `DELETE /api/admin/_workflow/:id` | Requests cancellation. Idempotent. Publishes `workflow:cancel:{runId}` on the eventbus so cross-worker instances pick it up. |
401
+
402
+ These three routes are the entire API surface. `useCommand` is the only thing a frontend dev ever calls.
403
+
404
+ ### Ports
405
+
406
+ Two ports power the feature. Both are auto-wired; you never configure them explicitly.
407
+
408
+ #### `IWorkflowStorePort` — durable
409
+
410
+ ```ts
411
+ interface IWorkflowStorePort {
412
+ create(run: NewWorkflowRun): Promise<void>
413
+ updateStep(runId: string, stepName: string, patch: Partial<StepState>): Promise<void>
414
+ updateStatus(runId: string, status: WorkflowStatus, fields?: { output?; error?; completed_at?: Date }): Promise<void>
415
+ requestCancel(runId: string): Promise<void>
416
+ get(runId: string): Promise<WorkflowRun | null>
417
+ }
418
+ ```
419
+
420
+ Writes state transitions (O(steps) per workflow) to Postgres via `DrizzleWorkflowStore`. Table `workflow_runs` — created by `ensureFrameworkTables` in dev. **Append-on-miss semantics**: `updateStep` appends a new step if the name is not yet in the array (see port JSDoc).
421
+
422
+ #### `IProgressChannelPort` — ephemeral
423
+
424
+ ```ts
425
+ interface IProgressChannelPort {
426
+ set(runId: string, snapshot: ProgressSnapshot): Promise<void> // never throws
427
+ get(runId: string): Promise<ProgressSnapshot | null>
428
+ clear(runId: string): Promise<void>
429
+ }
430
+ ```
431
+
432
+ Auto-selection at bootstrap — `selectProgressChannel` in `init-infra.ts`:
433
+
434
+ | Adapter | Chosen when | Behavior |
435
+ |---|---|---|
436
+ | `UpstashProgressChannel` | `adapter-cache-upstash` configured | Single `SET` with TTL. Sub-ms. Preferred for prod. |
437
+ | `DbProgressChannel` | Postgres available, no cache | Throttled at 500ms to avoid write amplification. `workflow_progress` table. |
438
+ | `InMemoryProgressChannel` | Tests / no durable store | Process-local map. |
439
+
440
+ ### Execution model — Node vs serverless
441
+
442
+ Manta's workflow engine runs **in-process**. The `WorkflowManager` is constructed per-request (per `wire-commands.ts`), and the per-run AbortController map lives in that instance. This has two implications:
443
+
444
+ **Node long-running host (default today, `host-nitro`)** — commands that take >300ms continue executing in the Node process that received the HTTP call. This is the happy path:
445
+ - Progress writes stream live.
446
+ - Cancel via `DELETE` aborts the same AbortController that the handler holds.
447
+ - Compensation runs normally on failure.
448
+
449
+ **Serverless (Vercel, etc.)** — function durations cap at 10s (hobby) / 60s (pro) / 15min (fluid). A workflow that outlives its invocation will be killed by the platform, leaving `workflow_runs.status = 'running'` indefinitely. V1 relies on Node long-running. For Vercel, see `WP-F04` in `BACKLOG.md` — a cron-based orphan-reaper is on the roadmap.
450
+
451
+ #### Cross-instance cancel
452
+
453
+ On serverless hosts, a workflow started on worker A can receive its `DELETE` on worker B. The per-run AbortController only exists in-memory on worker A, so we need a side channel to reach across workers.
454
+
455
+ **Mechanism**:
456
+
457
+ 1. `DELETE /api/admin/_workflow/:id` writes `cancel_requested_at = now()` on `workflow_runs` (durable — survives worker death).
458
+ 2. The same handler publishes `workflow:cancel:{runId}` on the event bus.
459
+ 3. Every `WorkflowManager.run()` subscribes to `workflow:cancel:{runId}` at run start. If the payload matches a runId it's currently executing, it aborts its local AbortController.
460
+ 4. The next step boundary sees `ctx.signal.aborted = true`, throws, compensation runs.
461
+
462
+ ```
463
+ Worker A Event Bus Worker B (running run X)
464
+ ──────── ───────── ────────────────────────
465
+ DELETE /run/X ──► store.requestCancel(X)
466
+ └► publish 'workflow:cancel:X' ──────► subscription fires
467
+ └► abortControllers[X].abort()
468
+ └► next ctx.signal check
469
+ └► throw → compensate
470
+ ```
471
+
472
+ **Requires**: a multi-worker event bus. `adapter-eventbus-upstash` is the supported choice for serverless deployments. In single-worker setups (dev, tests) `InMemoryEventBus` works trivially.
473
+
474
+ **Fallback without event bus** — the step-boundary check still works: each step transition reads `workflow_runs.cancel_requested_at` via `store.get(runId)` before continuing. Cancel is still honored, just with up to one extra step of latency (the current step runs to completion). See `WORKFLOW_PROGRESS.md` §10.3 for the full rationale.
475
+
476
+ ### Reference use case — PostHog cart snapshot rebuild
477
+
478
+ The motivating scenario (see `demo/commerce/src/commands/admin/rebuild-carts.ts`):
479
+
480
+ 1. `fetch-events` — paginated reads from PostHog API. `fetch(url, { signal: ctx.signal })`. Reports `ctx.progress(fetched, null, "Fetched N events")` (total unknown until last page).
481
+ 2. `replay-events` — `ctx.forEach(events, { batchSize: 500 }, handler)`. Progress + cancel free. Compensation is no-op by design (destructive rebuild, non-reversible).
482
+ 3. `persist-stats` — single DB write.
483
+
484
+ Admin flow:
485
+ - Click "Reconstruire" on cart list page.
486
+ - Workflow > 300ms → `{ runId }` returned → navigate to `/admin/_runs/:runId`.
487
+ - Live step timeline + progress bar + cancel button.
488
+ - Close tab, come back 10min later, reopen the URL → same page restores from DB + liveness channel.
489
+
490
+ ## Validation errors
491
+
492
+ | Error | Cause | Fix |
493
+ |-------|-------|-----|
494
+ | `Command name is required` | Missing name | Add `name: 'my-command'` |
495
+ | `Command "X" requires a description` | Missing description | Add `description: '...'` (used for AI tool discovery) |
496
+ | `Command "X" requires an input Zod schema` | Missing input | Add `input: z.object({})` (use empty for no-input commands) |
497
+ | `Command "X" workflow must be an async function` | workflow is not a function | Add `workflow: async (input, { step }) => {...}` |
498
+ | `Command "X" is already registered` | Duplicate name | Rename one of the commands |
499
+ | `Cannot link: no Product created yet` | Link before create | Call `step.service.catalog.create()` before `step.service.catalog.link.*()` |
500
+ | `Service "X" has no method "Y"` | Typo in method name | Check the service's `defineService()` for available methods |
501
+ | `step.action("X") requires a compensate function` | Missing compensate | Add `compensate: async (result) => {...}` to the action config |