@pattern-stack/codegen 0.15.0 → 0.15.2

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 (562) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/dist/chunk-24CWKBK5.js +94 -0
  3. package/dist/chunk-24CWKBK5.js.map +1 -0
  4. package/dist/chunk-2E224ZSN.js +20 -0
  5. package/dist/chunk-2E224ZSN.js.map +1 -0
  6. package/dist/chunk-2FTZLDBP.js +179 -0
  7. package/dist/chunk-2FTZLDBP.js.map +1 -0
  8. package/dist/chunk-2N4UG4VD.js +20 -0
  9. package/dist/chunk-2N4UG4VD.js.map +1 -0
  10. package/dist/chunk-2TVVBC53.js +92 -0
  11. package/dist/chunk-2TVVBC53.js.map +1 -0
  12. package/dist/chunk-2VHZ7EKC.js +37 -0
  13. package/dist/chunk-2VHZ7EKC.js.map +1 -0
  14. package/dist/chunk-32BMMV4H.js +109 -0
  15. package/dist/chunk-32BMMV4H.js.map +1 -0
  16. package/dist/chunk-32DOFN3T.js +4042 -0
  17. package/dist/chunk-32DOFN3T.js.map +1 -0
  18. package/dist/chunk-36U5UGIO.js +107 -0
  19. package/dist/chunk-36U5UGIO.js.map +1 -0
  20. package/dist/chunk-3CJFPU6Q.js +14 -0
  21. package/dist/chunk-3CJFPU6Q.js.map +1 -0
  22. package/dist/chunk-3NMCDN7L.js +90 -0
  23. package/dist/chunk-3NMCDN7L.js.map +1 -0
  24. package/dist/chunk-3SZFUTXE.js +62 -0
  25. package/dist/chunk-3SZFUTXE.js.map +1 -0
  26. package/dist/chunk-4DOJBQTP.js +117 -0
  27. package/dist/chunk-4DOJBQTP.js.map +1 -0
  28. package/dist/chunk-4JLJYWJC.js +308 -0
  29. package/dist/chunk-4JLJYWJC.js.map +1 -0
  30. package/dist/chunk-4KNXX6TI.js +29 -0
  31. package/dist/chunk-4KNXX6TI.js.map +1 -0
  32. package/dist/chunk-4LH67P4U.js +17 -0
  33. package/dist/chunk-4LH67P4U.js.map +1 -0
  34. package/dist/chunk-4MVGAMUA.js +40 -0
  35. package/dist/chunk-4MVGAMUA.js.map +1 -0
  36. package/dist/chunk-4OMHBMZJ.js +75 -0
  37. package/dist/chunk-4OMHBMZJ.js.map +1 -0
  38. package/dist/chunk-4RFHUZXU.js +635 -0
  39. package/dist/chunk-4RFHUZXU.js.map +1 -0
  40. package/dist/chunk-5A432NZJ.js +7 -0
  41. package/dist/chunk-5A432NZJ.js.map +1 -0
  42. package/dist/chunk-5Y7W3XR6.js +356 -0
  43. package/dist/chunk-5Y7W3XR6.js.map +1 -0
  44. package/dist/chunk-6DWFJNIK.js +15 -0
  45. package/dist/chunk-6DWFJNIK.js.map +1 -0
  46. package/dist/chunk-6I7ULIN6.js +15 -0
  47. package/dist/chunk-6I7ULIN6.js.map +1 -0
  48. package/dist/chunk-6XY6ZMMD.js +25 -0
  49. package/dist/chunk-6XY6ZMMD.js.map +1 -0
  50. package/dist/chunk-7B3RYX45.js +63 -0
  51. package/dist/chunk-7B3RYX45.js.map +1 -0
  52. package/dist/chunk-7C3FOSDI.js +1 -0
  53. package/dist/chunk-7C3FOSDI.js.map +1 -0
  54. package/dist/chunk-7KOW6PU6.js +59 -0
  55. package/dist/chunk-7KOW6PU6.js.map +1 -0
  56. package/dist/chunk-7LKAMLV4.js +92 -0
  57. package/dist/chunk-7LKAMLV4.js.map +1 -0
  58. package/dist/chunk-7RELQJIN.js +22 -0
  59. package/dist/chunk-7RELQJIN.js.map +1 -0
  60. package/dist/chunk-AHV4GDYM.js +63 -0
  61. package/dist/chunk-AHV4GDYM.js.map +1 -0
  62. package/dist/chunk-AQFQ4BYM.js +81 -0
  63. package/dist/chunk-AQFQ4BYM.js.map +1 -0
  64. package/dist/chunk-AS3NAZB6.js +14 -0
  65. package/dist/chunk-AS3NAZB6.js.map +1 -0
  66. package/dist/chunk-BGULBWKJ.js +88 -0
  67. package/dist/chunk-BGULBWKJ.js.map +1 -0
  68. package/dist/chunk-BIO6F7YI.js +17 -0
  69. package/dist/chunk-BIO6F7YI.js.map +1 -0
  70. package/dist/chunk-BOPZWRJK.js +36 -0
  71. package/dist/chunk-BOPZWRJK.js.map +1 -0
  72. package/dist/chunk-BPARRK6F.js +14 -0
  73. package/dist/chunk-BPARRK6F.js.map +1 -0
  74. package/dist/chunk-CO6LUM72.js +59 -0
  75. package/dist/chunk-CO6LUM72.js.map +1 -0
  76. package/dist/chunk-COGHTKXY.js +84 -0
  77. package/dist/chunk-COGHTKXY.js.map +1 -0
  78. package/dist/chunk-DCCZB4UC.js +100 -0
  79. package/dist/chunk-DCCZB4UC.js.map +1 -0
  80. package/dist/chunk-DKKFTHHI.js +53 -0
  81. package/dist/chunk-DKKFTHHI.js.map +1 -0
  82. package/dist/chunk-DV4RV2DC.js +59 -0
  83. package/dist/chunk-DV4RV2DC.js.map +1 -0
  84. package/dist/chunk-EDKJU5BO.js +11 -0
  85. package/dist/chunk-EDKJU5BO.js.map +1 -0
  86. package/dist/chunk-EO2QPOKH.js +116 -0
  87. package/dist/chunk-EO2QPOKH.js.map +1 -0
  88. package/dist/chunk-EOLLMEAH.js +155 -0
  89. package/dist/chunk-EOLLMEAH.js.map +1 -0
  90. package/dist/chunk-EWYCWP4H.js +14 -0
  91. package/dist/chunk-EWYCWP4H.js.map +1 -0
  92. package/dist/chunk-EXVDJMIY.js +33 -0
  93. package/dist/chunk-EXVDJMIY.js.map +1 -0
  94. package/dist/chunk-FASRXRX5.js +19 -0
  95. package/dist/chunk-FASRXRX5.js.map +1 -0
  96. package/dist/chunk-FI34KYZ5.js +1 -0
  97. package/dist/chunk-FI34KYZ5.js.map +1 -0
  98. package/dist/chunk-FN2PYDPP.js +1 -0
  99. package/dist/chunk-FN2PYDPP.js.map +1 -0
  100. package/dist/chunk-GM3RMJIJ.js +92 -0
  101. package/dist/chunk-GM3RMJIJ.js.map +1 -0
  102. package/dist/chunk-GYGNEQSC.js +9 -0
  103. package/dist/chunk-GYGNEQSC.js.map +1 -0
  104. package/dist/chunk-H5NH7KPE.js +21 -0
  105. package/dist/chunk-H5NH7KPE.js.map +1 -0
  106. package/dist/chunk-HNWZFNKP.js +168 -0
  107. package/dist/chunk-HNWZFNKP.js.map +1 -0
  108. package/dist/chunk-HUH73XGI.js +1 -0
  109. package/dist/chunk-HUH73XGI.js.map +1 -0
  110. package/dist/chunk-I6MG4M3F.js +201 -0
  111. package/dist/chunk-I6MG4M3F.js.map +1 -0
  112. package/dist/chunk-I6MVCB5A.js +39 -0
  113. package/dist/chunk-I6MVCB5A.js.map +1 -0
  114. package/dist/chunk-IBGER4YK.js +12 -0
  115. package/dist/chunk-IBGER4YK.js.map +1 -0
  116. package/dist/chunk-IF5I3DAA.js +92 -0
  117. package/dist/chunk-IF5I3DAA.js.map +1 -0
  118. package/dist/chunk-IP4OO26U.js +54 -0
  119. package/dist/chunk-IP4OO26U.js.map +1 -0
  120. package/dist/chunk-IWAOY6KC.js +1 -0
  121. package/dist/chunk-IWAOY6KC.js.map +1 -0
  122. package/dist/chunk-J37YWU7Y.js +19 -0
  123. package/dist/chunk-J37YWU7Y.js.map +1 -0
  124. package/dist/chunk-J6KZS54B.js +269 -0
  125. package/dist/chunk-J6KZS54B.js.map +1 -0
  126. package/dist/chunk-J6MN42LG.js +19 -0
  127. package/dist/chunk-J6MN42LG.js.map +1 -0
  128. package/dist/chunk-JRQO2IOF.js +65 -0
  129. package/dist/chunk-JRQO2IOF.js.map +1 -0
  130. package/dist/chunk-JRVNVKN6.js +212 -0
  131. package/dist/chunk-JRVNVKN6.js.map +1 -0
  132. package/dist/chunk-JWNHNUYL.js +96 -0
  133. package/dist/chunk-JWNHNUYL.js.map +1 -0
  134. package/dist/chunk-K2I6XIK5.js +122 -0
  135. package/dist/chunk-K2I6XIK5.js.map +1 -0
  136. package/dist/chunk-KMZCQASO.js +111 -0
  137. package/dist/chunk-KMZCQASO.js.map +1 -0
  138. package/dist/chunk-KVOWSC5S.js +1 -0
  139. package/dist/chunk-KVOWSC5S.js.map +1 -0
  140. package/dist/chunk-KYR3B3OW.js +79 -0
  141. package/dist/chunk-KYR3B3OW.js.map +1 -0
  142. package/dist/chunk-L3LZWWSX.js +61 -0
  143. package/dist/chunk-L3LZWWSX.js.map +1 -0
  144. package/dist/chunk-L4SDDEEU.js +1 -0
  145. package/dist/chunk-L4SDDEEU.js.map +1 -0
  146. package/dist/chunk-L6FTY45T.js +13 -0
  147. package/dist/chunk-L6FTY45T.js.map +1 -0
  148. package/dist/chunk-L7BNNRGI.js +134 -0
  149. package/dist/chunk-L7BNNRGI.js.map +1 -0
  150. package/dist/chunk-LG57S2SC.js +150 -0
  151. package/dist/chunk-LG57S2SC.js.map +1 -0
  152. package/dist/chunk-M6QLSLPO.js +97 -0
  153. package/dist/chunk-M6QLSLPO.js.map +1 -0
  154. package/dist/chunk-MZ6GV4YF.js +21 -0
  155. package/dist/chunk-MZ6GV4YF.js.map +1 -0
  156. package/dist/chunk-N5OTOWTP.js +55 -0
  157. package/dist/chunk-N5OTOWTP.js.map +1 -0
  158. package/dist/chunk-NN7XZEGF.js +14 -0
  159. package/dist/chunk-NN7XZEGF.js.map +1 -0
  160. package/dist/chunk-NPFPZ2HO.js +13 -0
  161. package/dist/chunk-NPFPZ2HO.js.map +1 -0
  162. package/dist/chunk-NXXDZ6ZF.js +42 -0
  163. package/dist/chunk-NXXDZ6ZF.js.map +1 -0
  164. package/dist/chunk-NYBCQZC7.js +11 -0
  165. package/dist/chunk-NYBCQZC7.js.map +1 -0
  166. package/dist/chunk-OFRRBC7M.js +78 -0
  167. package/dist/chunk-OFRRBC7M.js.map +1 -0
  168. package/dist/chunk-OGIZXGPY.js +222 -0
  169. package/dist/chunk-OGIZXGPY.js.map +1 -0
  170. package/dist/chunk-OKXZ63IA.js +168 -0
  171. package/dist/chunk-OKXZ63IA.js.map +1 -0
  172. package/dist/chunk-OSQRXVG2.js +58 -0
  173. package/dist/chunk-OSQRXVG2.js.map +1 -0
  174. package/dist/chunk-OTDN3OUQ.js +215 -0
  175. package/dist/chunk-OTDN3OUQ.js.map +1 -0
  176. package/dist/chunk-OZZJDRGW.js +122 -0
  177. package/dist/chunk-OZZJDRGW.js.map +1 -0
  178. package/dist/chunk-PNZSGAB2.js +114 -0
  179. package/dist/chunk-PNZSGAB2.js.map +1 -0
  180. package/dist/chunk-PRWIX6UW.js +21 -0
  181. package/dist/chunk-PRWIX6UW.js.map +1 -0
  182. package/dist/chunk-PSXUNOVU.js +7 -0
  183. package/dist/chunk-PSXUNOVU.js.map +1 -0
  184. package/dist/chunk-QLTJSCE6.js +44 -0
  185. package/dist/chunk-QLTJSCE6.js.map +1 -0
  186. package/dist/chunk-RC23QROE.js +447 -0
  187. package/dist/chunk-RC23QROE.js.map +1 -0
  188. package/dist/chunk-RFH7N6EP.js +36 -0
  189. package/dist/chunk-RFH7N6EP.js.map +1 -0
  190. package/dist/chunk-RHVN6NA7.js +134 -0
  191. package/dist/chunk-RHVN6NA7.js.map +1 -0
  192. package/dist/chunk-S7C6TIIF.js +21 -0
  193. package/dist/chunk-S7C6TIIF.js.map +1 -0
  194. package/dist/chunk-SNQ3TOWP.js +20 -0
  195. package/dist/chunk-SNQ3TOWP.js.map +1 -0
  196. package/dist/chunk-SOVM2VEK.js +14 -0
  197. package/dist/chunk-SOVM2VEK.js.map +1 -0
  198. package/dist/chunk-SQDOBLBP.js +13 -0
  199. package/dist/chunk-SQDOBLBP.js.map +1 -0
  200. package/dist/chunk-SR7F3TJY.js +130 -0
  201. package/dist/chunk-SR7F3TJY.js.map +1 -0
  202. package/dist/chunk-SZVPIHWE.js +129 -0
  203. package/dist/chunk-SZVPIHWE.js.map +1 -0
  204. package/dist/chunk-T4BIIU5E.js +89 -0
  205. package/dist/chunk-T4BIIU5E.js.map +1 -0
  206. package/dist/chunk-T6C4LFLC.js +112 -0
  207. package/dist/chunk-T6C4LFLC.js.map +1 -0
  208. package/dist/chunk-TNXH7BJS.js +48 -0
  209. package/dist/chunk-TNXH7BJS.js.map +1 -0
  210. package/dist/chunk-U64T4YZE.js +9 -0
  211. package/dist/chunk-U64T4YZE.js.map +1 -0
  212. package/dist/chunk-UQ5EHOH2.js +39 -0
  213. package/dist/chunk-UQ5EHOH2.js.map +1 -0
  214. package/dist/chunk-UTN4GBPQ.js +1 -0
  215. package/dist/chunk-UTN4GBPQ.js.map +1 -0
  216. package/dist/chunk-V4AF6DI4.js +16 -0
  217. package/dist/chunk-V4AF6DI4.js.map +1 -0
  218. package/dist/chunk-W72PRNJY.js +126 -0
  219. package/dist/chunk-W72PRNJY.js.map +1 -0
  220. package/dist/chunk-WEVWJKOW.js +81 -0
  221. package/dist/chunk-WEVWJKOW.js.map +1 -0
  222. package/dist/chunk-WL67FZGF.js +21 -0
  223. package/dist/chunk-WL67FZGF.js.map +1 -0
  224. package/dist/chunk-WPXNN6QS.js +290 -0
  225. package/dist/chunk-WPXNN6QS.js.map +1 -0
  226. package/dist/chunk-WRUUSZDJ.js +29 -0
  227. package/dist/chunk-WRUUSZDJ.js.map +1 -0
  228. package/dist/chunk-X2GMTYPA.js +50 -0
  229. package/dist/chunk-X2GMTYPA.js.map +1 -0
  230. package/dist/chunk-XCEI7NUH.js +41 -0
  231. package/dist/chunk-XCEI7NUH.js.map +1 -0
  232. package/dist/chunk-Y7GDG744.js +88 -0
  233. package/dist/chunk-Y7GDG744.js.map +1 -0
  234. package/dist/chunk-Y7RRSEOC.js +9 -0
  235. package/dist/chunk-Y7RRSEOC.js.map +1 -0
  236. package/dist/chunk-YPWODKD5.js +184 -0
  237. package/dist/chunk-YPWODKD5.js.map +1 -0
  238. package/dist/chunk-YSLTTQLC.js +25 -0
  239. package/dist/chunk-YSLTTQLC.js.map +1 -0
  240. package/dist/chunk-YTN6BKWA.js +121 -0
  241. package/dist/chunk-YTN6BKWA.js.map +1 -0
  242. package/dist/chunk-Z7PQCAVK.js +200 -0
  243. package/dist/chunk-Z7PQCAVK.js.map +1 -0
  244. package/dist/chunk-ZUKFQL6E.js +47 -0
  245. package/dist/chunk-ZUKFQL6E.js.map +1 -0
  246. package/dist/chunk-ZUMULSEQ.js +1 -0
  247. package/dist/chunk-ZUMULSEQ.js.map +1 -0
  248. package/dist/{job-orchestrator.protocol-CARhMLCO.d.ts → job-orchestrator.protocol-DubMVbm9.d.ts} +1 -1
  249. package/dist/runtime/analytics/index.js +8 -41
  250. package/dist/runtime/analytics/index.js.map +1 -1
  251. package/dist/runtime/analytics/types.js +8 -41
  252. package/dist/runtime/analytics/types.js.map +1 -1
  253. package/dist/runtime/base-classes/activity-entity-repository.js +6 -312
  254. package/dist/runtime/base-classes/activity-entity-repository.js.map +1 -1
  255. package/dist/runtime/base-classes/activity-entity-service.js +6 -212
  256. package/dist/runtime/base-classes/activity-entity-service.js.map +1 -1
  257. package/dist/runtime/base-classes/base-read-use-cases.js +5 -27
  258. package/dist/runtime/base-classes/base-read-use-cases.js.map +1 -1
  259. package/dist/runtime/base-classes/base-repository.js +5 -277
  260. package/dist/runtime/base-classes/base-repository.js.map +1 -1
  261. package/dist/runtime/base-classes/base-service.js +5 -184
  262. package/dist/runtime/base-classes/base-service.js.map +1 -1
  263. package/dist/runtime/base-classes/index.js +59 -1076
  264. package/dist/runtime/base-classes/index.js.map +1 -1
  265. package/dist/runtime/base-classes/integrated-entity-repository.js +6 -486
  266. package/dist/runtime/base-classes/integrated-entity-repository.js.map +1 -1
  267. package/dist/runtime/base-classes/integrated-entity-service.js +6 -213
  268. package/dist/runtime/base-classes/integrated-entity-service.js.map +1 -1
  269. package/dist/runtime/base-classes/junction-integration-repository.js +8 -448
  270. package/dist/runtime/base-classes/junction-integration-repository.js.map +1 -1
  271. package/dist/runtime/base-classes/knowledge-entity-repository.js +6 -283
  272. package/dist/runtime/base-classes/knowledge-entity-repository.js.map +1 -1
  273. package/dist/runtime/base-classes/knowledge-entity-service.js +6 -190
  274. package/dist/runtime/base-classes/knowledge-entity-service.js.map +1 -1
  275. package/dist/runtime/base-classes/lifecycle-events.js +8 -70
  276. package/dist/runtime/base-classes/lifecycle-events.js.map +1 -1
  277. package/dist/runtime/base-classes/metadata-entity-repository.js +6 -330
  278. package/dist/runtime/base-classes/metadata-entity-repository.js.map +1 -1
  279. package/dist/runtime/base-classes/metadata-entity-service.js +6 -212
  280. package/dist/runtime/base-classes/metadata-entity-service.js.map +1 -1
  281. package/dist/runtime/base-classes/tenant-context.js +10 -36
  282. package/dist/runtime/base-classes/tenant-context.js.map +1 -1
  283. package/dist/runtime/base-classes/with-analytics.js +4 -7
  284. package/dist/runtime/base-classes/with-analytics.js.map +1 -1
  285. package/dist/runtime/constants/tokens.js +5 -3
  286. package/dist/runtime/constants/tokens.js.map +1 -1
  287. package/dist/runtime/eav-helpers.js +2 -0
  288. package/dist/runtime/eav-helpers.js.map +1 -1
  289. package/dist/runtime/pipes/zod-validation.pipe.js +3 -10
  290. package/dist/runtime/pipes/zod-validation.pipe.js.map +1 -1
  291. package/dist/runtime/shared/openapi/error-response.dto.js +5 -8
  292. package/dist/runtime/shared/openapi/error-response.dto.js.map +1 -1
  293. package/dist/runtime/shared/openapi/errors.js +5 -19
  294. package/dist/runtime/shared/openapi/errors.js.map +1 -1
  295. package/dist/runtime/shared/openapi/index.js +15 -106
  296. package/dist/runtime/shared/openapi/index.js.map +1 -1
  297. package/dist/runtime/shared/openapi/registry.js +6 -103
  298. package/dist/runtime/shared/openapi/registry.js.map +1 -1
  299. package/dist/runtime/shared/openapi/registry.tokens.js +4 -2
  300. package/dist/runtime/shared/openapi/registry.tokens.js.map +1 -1
  301. package/dist/runtime/subsystems/analytics/analytics.module.js +8 -117
  302. package/dist/runtime/subsystems/analytics/analytics.module.js.map +1 -1
  303. package/dist/runtime/subsystems/analytics/analytics.tokens.js +7 -8
  304. package/dist/runtime/subsystems/analytics/analytics.tokens.js.map +1 -1
  305. package/dist/runtime/subsystems/analytics/cube-backend.js +6 -71
  306. package/dist/runtime/subsystems/analytics/cube-backend.js.map +1 -1
  307. package/dist/runtime/subsystems/analytics/index.js +16 -117
  308. package/dist/runtime/subsystems/analytics/index.js.map +1 -1
  309. package/dist/runtime/subsystems/analytics/noop-backend.js +4 -21
  310. package/dist/runtime/subsystems/analytics/noop-backend.js.map +1 -1
  311. package/dist/runtime/subsystems/auth/auth-oauth-state.schema.js +4 -8
  312. package/dist/runtime/subsystems/auth/auth-oauth-state.schema.js.map +1 -1
  313. package/dist/runtime/subsystems/auth/auth.module.js +12 -359
  314. package/dist/runtime/subsystems/auth/auth.module.js.map +1 -1
  315. package/dist/runtime/subsystems/auth/auth.tokens.js +12 -13
  316. package/dist/runtime/subsystems/auth/auth.tokens.js.map +1 -1
  317. package/dist/runtime/subsystems/auth/backends/encryption-key/env.js +4 -49
  318. package/dist/runtime/subsystems/auth/backends/encryption-key/env.js.map +1 -1
  319. package/dist/runtime/subsystems/auth/backends/state-store.drizzle-backend.js +6 -64
  320. package/dist/runtime/subsystems/auth/backends/state-store.drizzle-backend.js.map +1 -1
  321. package/dist/runtime/subsystems/auth/backends/state-store.memory-backend.js +5 -47
  322. package/dist/runtime/subsystems/auth/backends/state-store.memory-backend.js.map +1 -1
  323. package/dist/runtime/subsystems/auth/controllers/auth.controller.js +5 -139
  324. package/dist/runtime/subsystems/auth/controllers/auth.controller.js.map +1 -1
  325. package/dist/runtime/subsystems/auth/index.js +53 -542
  326. package/dist/runtime/subsystems/auth/index.js.map +1 -1
  327. package/dist/runtime/subsystems/auth/middleware/requester-context.js +9 -65
  328. package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -1
  329. package/dist/runtime/subsystems/auth/protocols/oauth-state-store.js +4 -9
  330. package/dist/runtime/subsystems/auth/protocols/oauth-state-store.js.map +1 -1
  331. package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js +4 -15
  332. package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js.map +1 -1
  333. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js +5 -104
  334. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js.map +1 -1
  335. package/dist/runtime/subsystems/auth/runtime/session-expired.error.js +5 -16
  336. package/dist/runtime/subsystems/auth/runtime/session-expired.error.js.map +1 -1
  337. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js +5 -29
  338. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js.map +1 -1
  339. package/dist/runtime/subsystems/bridge/assert-tenant-id.js +5 -18
  340. package/dist/runtime/subsystems/bridge/assert-tenant-id.js.map +1 -1
  341. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.d.ts +2 -2
  342. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js +12 -184
  343. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js.map +1 -1
  344. package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.d.ts +1 -1
  345. package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js +10 -448
  346. package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js.map +1 -1
  347. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.d.ts +1 -1
  348. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js +5 -126
  349. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js.map +1 -1
  350. package/dist/runtime/subsystems/bridge/bridge-delivery.schema.js +6 -308
  351. package/dist/runtime/subsystems/bridge/bridge-delivery.schema.js.map +1 -1
  352. package/dist/runtime/subsystems/bridge/bridge-errors.js +6 -35
  353. package/dist/runtime/subsystems/bridge/bridge-errors.js.map +1 -1
  354. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.d.ts +1 -1
  355. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +14 -606
  356. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js.map +1 -1
  357. package/dist/runtime/subsystems/bridge/bridge.module.d.ts +2 -2
  358. package/dist/runtime/subsystems/bridge/bridge.module.js +35 -3476
  359. package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
  360. package/dist/runtime/subsystems/bridge/bridge.protocol.d.ts +1 -1
  361. package/dist/runtime/subsystems/bridge/bridge.tokens.js +9 -7
  362. package/dist/runtime/subsystems/bridge/bridge.tokens.js.map +1 -1
  363. package/dist/runtime/subsystems/bridge/event-flow.service.d.ts +2 -2
  364. package/dist/runtime/subsystems/bridge/event-flow.service.js +11 -137
  365. package/dist/runtime/subsystems/bridge/event-flow.service.js.map +1 -1
  366. package/dist/runtime/subsystems/bridge/generated/registry.d.ts +1 -1
  367. package/dist/runtime/subsystems/bridge/generated/registry.js +4 -2
  368. package/dist/runtime/subsystems/bridge/generated/registry.js.map +1 -1
  369. package/dist/runtime/subsystems/bridge/index.d.ts +2 -2
  370. package/dist/runtime/subsystems/bridge/index.js +60 -3470
  371. package/dist/runtime/subsystems/bridge/index.js.map +1 -1
  372. package/dist/runtime/subsystems/bridge/reserved-pools.js +4 -6
  373. package/dist/runtime/subsystems/bridge/reserved-pools.js.map +1 -1
  374. package/dist/runtime/subsystems/cache/cache.drizzle-backend.js +10 -133
  375. package/dist/runtime/subsystems/cache/cache.drizzle-backend.js.map +1 -1
  376. package/dist/runtime/subsystems/cache/cache.memory-backend.js +6 -101
  377. package/dist/runtime/subsystems/cache/cache.memory-backend.js.map +1 -1
  378. package/dist/runtime/subsystems/cache/cache.module.js +10 -278
  379. package/dist/runtime/subsystems/cache/cache.module.js.map +1 -1
  380. package/dist/runtime/subsystems/cache/cache.schema.js +4 -14
  381. package/dist/runtime/subsystems/cache/cache.schema.js.map +1 -1
  382. package/dist/runtime/subsystems/cache/cache.tokens.js +6 -7
  383. package/dist/runtime/subsystems/cache/cache.tokens.js.map +1 -1
  384. package/dist/runtime/subsystems/cache/index.js +20 -278
  385. package/dist/runtime/subsystems/cache/index.js.map +1 -1
  386. package/dist/runtime/subsystems/events/domain-events.schema.js +3 -72
  387. package/dist/runtime/subsystems/events/domain-events.schema.js.map +1 -1
  388. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.d.ts +1 -1
  389. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +9 -413
  390. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
  391. package/dist/runtime/subsystems/events/event-bus.memory-backend.js +7 -235
  392. package/dist/runtime/subsystems/events/event-bus.memory-backend.js.map +1 -1
  393. package/dist/runtime/subsystems/events/event-bus.redis-backend.js +8 -20
  394. package/dist/runtime/subsystems/events/event-bus.redis-backend.js.map +1 -1
  395. package/dist/runtime/subsystems/events/event-keyset-cursor.js +8 -30
  396. package/dist/runtime/subsystems/events/event-keyset-cursor.js.map +1 -1
  397. package/dist/runtime/subsystems/events/event-read.protocol.js +2 -0
  398. package/dist/runtime/subsystems/events/event-read.protocol.js.map +1 -1
  399. package/dist/runtime/subsystems/events/event-registry.d.ts +77 -0
  400. package/dist/runtime/subsystems/events/event-registry.js +1 -0
  401. package/dist/runtime/subsystems/events/event-registry.js.map +1 -0
  402. package/dist/runtime/subsystems/events/events-errors.js +4 -11
  403. package/dist/runtime/subsystems/events/events-errors.js.map +1 -1
  404. package/dist/runtime/subsystems/events/events.module.js +15 -949
  405. package/dist/runtime/subsystems/events/events.module.js.map +1 -1
  406. package/dist/runtime/subsystems/events/events.tokens.js +10 -11
  407. package/dist/runtime/subsystems/events/events.tokens.js.map +1 -1
  408. package/dist/runtime/subsystems/events/generated/bus.js +9 -240
  409. package/dist/runtime/subsystems/events/generated/bus.js.map +1 -1
  410. package/dist/runtime/subsystems/events/generated/index.js +23 -240
  411. package/dist/runtime/subsystems/events/generated/index.js.map +1 -1
  412. package/dist/runtime/subsystems/events/generated/registry.js +5 -82
  413. package/dist/runtime/subsystems/events/generated/registry.js.map +1 -1
  414. package/dist/runtime/subsystems/events/generated/schemas.js +12 -52
  415. package/dist/runtime/subsystems/events/generated/schemas.js.map +1 -1
  416. package/dist/runtime/subsystems/events/generated/types.js +1 -0
  417. package/dist/runtime/subsystems/events/index.d.ts +1 -0
  418. package/dist/runtime/subsystems/events/index.js +32 -949
  419. package/dist/runtime/subsystems/events/index.js.map +1 -1
  420. package/dist/runtime/subsystems/index.d.ts +2 -2
  421. package/dist/runtime/subsystems/index.js +171 -5912
  422. package/dist/runtime/subsystems/index.js.map +1 -1
  423. package/dist/runtime/subsystems/integration/build-change-source.js +6 -178
  424. package/dist/runtime/subsystems/integration/build-change-source.js.map +1 -1
  425. package/dist/runtime/subsystems/integration/deep-equal.differ.js +4 -109
  426. package/dist/runtime/subsystems/integration/deep-equal.differ.js.map +1 -1
  427. package/dist/runtime/subsystems/integration/detection-config.schema.js +11 -78
  428. package/dist/runtime/subsystems/integration/detection-config.schema.js.map +1 -1
  429. package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.js +5 -30
  430. package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.js.map +1 -1
  431. package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.js +4 -9
  432. package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.js.map +1 -1
  433. package/dist/runtime/subsystems/integration/execute-integration.use-case.js +6 -239
  434. package/dist/runtime/subsystems/integration/execute-integration.use-case.js.map +1 -1
  435. package/dist/runtime/subsystems/integration/incremental-read.js +5 -144
  436. package/dist/runtime/subsystems/integration/incremental-read.js.map +1 -1
  437. package/dist/runtime/subsystems/integration/index.js +83 -1352
  438. package/dist/runtime/subsystems/integration/index.js.map +1 -1
  439. package/dist/runtime/subsystems/integration/integration-audit.schema.js +10 -155
  440. package/dist/runtime/subsystems/integration/integration-audit.schema.js.map +1 -1
  441. package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js +7 -270
  442. package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js.map +1 -1
  443. package/dist/runtime/subsystems/integration/integration-cursor-store.memory-backend.js +4 -65
  444. package/dist/runtime/subsystems/integration/integration-cursor-store.memory-backend.js.map +1 -1
  445. package/dist/runtime/subsystems/integration/integration-errors.js +5 -15
  446. package/dist/runtime/subsystems/integration/integration-errors.js.map +1 -1
  447. package/dist/runtime/subsystems/integration/integration-field-diff.protocol.js +5 -7
  448. package/dist/runtime/subsystems/integration/integration-field-diff.protocol.js.map +1 -1
  449. package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js +8 -303
  450. package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js.map +1 -1
  451. package/dist/runtime/subsystems/integration/integration-run-recorder.memory-backend.js +5 -125
  452. package/dist/runtime/subsystems/integration/integration-run-recorder.memory-backend.js.map +1 -1
  453. package/dist/runtime/subsystems/integration/integration.module.js +13 -700
  454. package/dist/runtime/subsystems/integration/integration.module.js.map +1 -1
  455. package/dist/runtime/subsystems/integration/integration.tokens.js +11 -9
  456. package/dist/runtime/subsystems/integration/integration.tokens.js.map +1 -1
  457. package/dist/runtime/subsystems/integration/loopback.middleware.js +4 -16
  458. package/dist/runtime/subsystems/integration/loopback.middleware.js.map +1 -1
  459. package/dist/runtime/subsystems/integration/poll-change-source.js +4 -89
  460. package/dist/runtime/subsystems/integration/poll-change-source.js.map +1 -1
  461. package/dist/runtime/subsystems/integration/webhook-change-source.js +4 -70
  462. package/dist/runtime/subsystems/integration/webhook-change-source.js.map +1 -1
  463. package/dist/runtime/subsystems/jobs/bullmq.config.js +9 -140
  464. package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -1
  465. package/dist/runtime/subsystems/jobs/index.d.ts +2 -2
  466. package/dist/runtime/subsystems/jobs/index.js +88 -2691
  467. package/dist/runtime/subsystems/jobs/index.js.map +1 -1
  468. package/dist/runtime/subsystems/jobs/job-handler.base.d.ts +2 -2
  469. package/dist/runtime/subsystems/jobs/job-handler.base.js +10 -49
  470. package/dist/runtime/subsystems/jobs/job-handler.base.js.map +1 -1
  471. package/dist/runtime/subsystems/jobs/job-orchestration.schema.js +13 -152
  472. package/dist/runtime/subsystems/jobs/job-orchestration.schema.js.map +1 -1
  473. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.d.ts +2 -2
  474. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +36 -699
  475. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
  476. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.d.ts +2 -2
  477. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +10 -564
  478. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js.map +1 -1
  479. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.d.ts +2 -2
  480. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +10 -824
  481. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js.map +1 -1
  482. package/dist/runtime/subsystems/jobs/job-orchestrator.protocol.d.ts +2 -2
  483. package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.d.ts +2 -2
  484. package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.js +9 -51
  485. package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.js.map +1 -1
  486. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.d.ts +2 -2
  487. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +9 -416
  488. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js.map +1 -1
  489. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.d.ts +2 -2
  490. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +9 -290
  491. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js.map +1 -1
  492. package/dist/runtime/subsystems/jobs/job-run-service.protocol.d.ts +2 -2
  493. package/dist/runtime/subsystems/jobs/job-step-service.drizzle-backend.js +5 -213
  494. package/dist/runtime/subsystems/jobs/job-step-service.drizzle-backend.js.map +1 -1
  495. package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js +5 -131
  496. package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js.map +1 -1
  497. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.d.ts +2 -2
  498. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +9 -175
  499. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -1
  500. package/dist/runtime/subsystems/jobs/job-worker.d.ts +2 -2
  501. package/dist/runtime/subsystems/jobs/job-worker.js +14 -613
  502. package/dist/runtime/subsystems/jobs/job-worker.js.map +1 -1
  503. package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +2 -2
  504. package/dist/runtime/subsystems/jobs/job-worker.module.js +23 -2647
  505. package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
  506. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +19 -1897
  507. package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
  508. package/dist/runtime/subsystems/jobs/jobs-domain.tokens.js +8 -9
  509. package/dist/runtime/subsystems/jobs/jobs-domain.tokens.js.map +1 -1
  510. package/dist/runtime/subsystems/jobs/jobs-errors.d.ts +2 -2
  511. package/dist/runtime/subsystems/jobs/jobs-errors.js +10 -78
  512. package/dist/runtime/subsystems/jobs/jobs-errors.js.map +1 -1
  513. package/dist/runtime/subsystems/jobs/memory-job-store.js +4 -15
  514. package/dist/runtime/subsystems/jobs/memory-job-store.js.map +1 -1
  515. package/dist/runtime/subsystems/jobs/pool-config.loader.js +9 -124
  516. package/dist/runtime/subsystems/jobs/pool-config.loader.js.map +1 -1
  517. package/dist/runtime/subsystems/observability/index.d.ts +2 -2
  518. package/dist/runtime/subsystems/observability/index.js +21 -310
  519. package/dist/runtime/subsystems/observability/index.js.map +1 -1
  520. package/dist/runtime/subsystems/observability/observability-errors.js +4 -9
  521. package/dist/runtime/subsystems/observability/observability-errors.js.map +1 -1
  522. package/dist/runtime/subsystems/observability/observability.module.js +11 -300
  523. package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
  524. package/dist/runtime/subsystems/observability/observability.protocol.d.ts +2 -2
  525. package/dist/runtime/subsystems/observability/observability.service.d.ts +2 -2
  526. package/dist/runtime/subsystems/observability/observability.service.js +9 -197
  527. package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
  528. package/dist/runtime/subsystems/observability/observability.tokens.js +5 -3
  529. package/dist/runtime/subsystems/observability/observability.tokens.js.map +1 -1
  530. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +2 -2
  531. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.js +4 -84
  532. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.js.map +1 -1
  533. package/dist/runtime/subsystems/observability/reporters/index.d.ts +2 -2
  534. package/dist/runtime/subsystems/observability/reporters/index.js +5 -84
  535. package/dist/runtime/subsystems/observability/reporters/index.js.map +1 -1
  536. package/dist/runtime/subsystems/storage/index.js +15 -200
  537. package/dist/runtime/subsystems/storage/index.js.map +1 -1
  538. package/dist/runtime/subsystems/storage/storage.local-backend.js +4 -103
  539. package/dist/runtime/subsystems/storage/storage.local-backend.js.map +1 -1
  540. package/dist/runtime/subsystems/storage/storage.memory-backend.js +5 -68
  541. package/dist/runtime/subsystems/storage/storage.memory-backend.js.map +1 -1
  542. package/dist/runtime/subsystems/storage/storage.module.js +8 -200
  543. package/dist/runtime/subsystems/storage/storage.module.js.map +1 -1
  544. package/dist/runtime/subsystems/storage/storage.tokens.js +5 -6
  545. package/dist/runtime/subsystems/storage/storage.tokens.js.map +1 -1
  546. package/dist/runtime/subsystems/storage/storage.utils.js +4 -14
  547. package/dist/runtime/subsystems/storage/storage.utils.js.map +1 -1
  548. package/dist/runtime/subsystems/token-key.js +5 -3
  549. package/dist/runtime/subsystems/token-key.js.map +1 -1
  550. package/dist/src/cli/index.js +653 -5444
  551. package/dist/src/cli/index.js.map +1 -1
  552. package/dist/src/index.js +68 -4170
  553. package/dist/src/index.js.map +1 -1
  554. package/package.json +1 -1
  555. package/runtime/subsystems/bridge/bridge-delivery-handler.ts +1 -1
  556. package/runtime/subsystems/bridge/bridge-outbox-drain-hook.ts +45 -22
  557. package/runtime/subsystems/bridge/bridge.protocol.ts +1 -1
  558. package/runtime/subsystems/bridge/event-flow.service.ts +1 -1
  559. package/runtime/subsystems/events/event-registry.ts +77 -0
  560. package/runtime/subsystems/events/index.ts +12 -0
  561. package/runtime/subsystems/jobs/job-handler.base.ts +1 -1
  562. package/runtime/subsystems/jobs/job-worker.ts +17 -11
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/subsystems/bridge/bridge-errors.ts"],"sourcesContent":["/**\n * Typed errors for the bridge subsystem (ADR-023 Phase 2, BRIDGE-2).\n *\n * All thrown by the three enforcement sites named in ADR-023 §Multi-tenancy:\n * - `EventFlowService.publishAndStart` entry (BRIDGE-7)\n * - `BridgeDeliveryHandler.handle` entry (BRIDGE-5)\n * - `DrizzleBridgeDeliveryRepo.insertDelivery` pre-write (BRIDGE-4)\n *\n * Same shape as `runtime/subsystems/jobs/jobs-errors.ts` and\n * `runtime/subsystems/events/events-errors.ts` so consumers can catch them\n * with the same exception-filter pattern across all three subsystems.\n */\n\n/**\n * Thrown when `BridgeModule` was configured with `multiTenant: true` but\n * the caller did not pass a `tenantId` at one of the three enforcement\n * sites listed above.\n *\n * **Strict enforcement rationale (mirrors JOB-8 / SYNC-6 stance, locked\n * 2026-04-18 for jobs; same rationale applies here).** Cross-tenant data\n * leakage is the worst class of bug a multi-tenant system can ship;\n * surfacing the misuse loudly at the call site (rather than silently\n * defaulting to `null` or to \"the last tenant seen\") prevents both\n * accidental global writes and sneaky reads that return a union of tenants.\n *\n * - `undefined` `tenantId` → throw this error.\n * - Explicit `null` `tenantId` → passes; opts the call into cross-tenant\n * work (e.g. a system housekeeping event with no owning tenant). The\n * `bridge_delivery` row is persisted with `tenant_id = NULL`.\n *\n * The `callSite` constructor argument names which of the three enforcement\n * sites threw — review reports and ops dashboards rely on a stable site\n * name, so use the canonical strings: `'EventFlowService.publishAndStart'`,\n * `'BridgeDeliveryHandler.handle'`,\n * `'DrizzleBridgeDeliveryRepo.insertDelivery'`.\n */\nexport class MissingTenantIdError extends Error {\n override readonly name = 'MissingTenantIdError';\n constructor(public readonly callSite: string) {\n super(\n `MissingTenantIdError: BridgeModule was configured with ` +\n `multiTenant=true but ${callSite} was called without tenantId ` +\n `(undefined). Pass an explicit tenantId, or pass null for ` +\n `cross-tenant work.`,\n );\n }\n}\n\n/**\n * Synthetic error thrown by `MemoryBridgeDeliveryRepo.insertDelivery` when\n * a duplicate `(event_id, trigger_id)` insert hits the simulated UNIQUE\n * constraint (BRIDGE-3).\n *\n * Carries a `constraint` field equal to the Drizzle constraint name\n * declared in BRIDGE-1's schema (`uq_bridge_delivery_event_trigger`) so\n * call sites can branch on the same discriminator regardless of which\n * backend is wired up. This matters because ADR-023 explicitly leans on\n * the constraint as the dedup mechanism in two places — outbox replay\n * and `publishAndStart` Case B — and BRIDGE-4 / BRIDGE-7 will share a\n * type-check path with BRIDGE-3-driven tests.\n *\n * The Drizzle backend (BRIDGE-4) does NOT throw this error: it uses\n * `INSERT … ON CONFLICT (event_id, trigger_id) DO NOTHING RETURNING id`\n * per the BRIDGE-4 spec recommendation, so collisions surface as an empty\n * result set rather than an exception. The error exists so the memory\n * backend can faithfully model the \"duplicate raises\" behaviour for tests\n * that want to assert the constraint actually fires.\n */\n/**\n * Thrown by `BridgeModule.onModuleInit` when `JobWorkerModule` is wired\n * alongside the bridge but its active `pools` list does not include one\n * or more of the three reserved bridge pools (`events_inbound`,\n * `events_change`, `events_outbound`).\n *\n * Without a worker polling those pools, the wrapper `job_run` rows the\n * outbox drain inserts (BRIDGE-4) sit `pending` forever — a silent\n * footgun where `eventFlow.publish(...)` returns success but no user\n * job ever spawns. The boot-time check converts that into a fail-fast.\n *\n * Operators can either (a) add `...BRIDGE_RESERVED_POOLS` to their\n * `JobWorkerModule.forRoot({ pools })` configuration so the same\n * process polls the reserved pools, or (b) run a separate worker\n * process per reserved pool for lane isolation (ADR-022 §Pool\n * isolation).\n */\nexport class BridgeReservedPoolsNotPolledError extends Error {\n override readonly name = 'BridgeReservedPoolsNotPolledError';\n constructor(public readonly missingPools: readonly string[]) {\n super(\n `BridgeModule loaded but JobWorkerModule is not polling reserved ` +\n `pool '${missingPools[0]}'. Add ...BRIDGE_RESERVED_POOLS to your ` +\n `JobWorkerModule.forRoot({ pools }) configuration. Missing pools: ` +\n `${missingPools.join(', ')}. (Bridge-fanout wrappers will sit ` +\n `pending forever without these pollers.)`,\n );\n }\n}\n\nexport class UniqueConstraintError extends Error {\n override readonly name = 'UniqueConstraintError';\n constructor(\n public readonly constraint: string,\n public readonly eventId: string,\n public readonly triggerId: string,\n ) {\n super(\n `UniqueConstraintError: duplicate insert into bridge_delivery for ` +\n `(event_id='${eventId}', trigger_id='${triggerId}') — violates ` +\n `constraint '${constraint}'.`,\n );\n }\n}\n"],"mappings":";AAoCO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAE9C,YAA4B,UAAkB;AAC5C;AAAA,MACE,+EAC0B,QAAQ;AAAA,IAGpC;AAN0B;AAAA,EAO5B;AAAA,EAP4B;AAAA,EADV,OAAO;AAS3B;AAuCO,IAAM,oCAAN,cAAgD,MAAM;AAAA,EAE3D,YAA4B,cAAiC;AAC3D;AAAA,MACE,yEACW,aAAa,CAAC,CAAC,4GAErB,aAAa,KAAK,IAAI,CAAC;AAAA,IAE9B;AAP0B;AAAA,EAQ5B;AAAA,EAR4B;AAAA,EADV,OAAO;AAU3B;AAEO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAE/C,YACkB,YACA,SACA,WAChB;AACA;AAAA,MACE,+EACgB,OAAO,kBAAkB,SAAS,kCACjC,UAAU;AAAA,IAC7B;AARgB;AACA;AACA;AAAA,EAOlB;AAAA,EATkB;AAAA,EACA;AAAA,EACA;AAAA,EAJA,OAAO;AAY3B;","names":[]}
@@ -0,0 +1,11 @@
1
+ import {
2
+ tokenKey
3
+ } from "./chunk-GYGNEQSC.js";
4
+
5
+ // runtime/subsystems/storage/storage.tokens.ts
6
+ var STORAGE = Symbol.for(tokenKey("storage", "storage"));
7
+
8
+ export {
9
+ STORAGE
10
+ };
11
+ //# sourceMappingURL=chunk-NYBCQZC7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/subsystems/storage/storage.tokens.ts"],"sourcesContent":["/**\n * Injection token for the storage service.\n *\n * Usage in use cases:\n * ```typescript\n * constructor(@Inject(STORAGE) private readonly storage: IStorageService) {}\n * ```\n *\n * ADR-037: namespaced `Symbol.for(...)` key (via `tokenKey()`) so the token matches\n * by value across import boundaries (package vs vendored runtime copy).\n */\nimport { tokenKey } from '../token-key';\n\nexport const STORAGE = Symbol.for(tokenKey('storage', 'storage'));\n"],"mappings":";;;;;AAaO,IAAM,UAAU,OAAO,IAAI,SAAS,WAAW,SAAS,CAAC;","names":[]}
@@ -0,0 +1,78 @@
1
+ // runtime/subsystems/events/domain-events.schema.ts
2
+ import {
3
+ check,
4
+ index,
5
+ jsonb,
6
+ pgTable,
7
+ text,
8
+ timestamp,
9
+ uuid
10
+ } from "drizzle-orm/pg-core";
11
+ import { sql } from "drizzle-orm";
12
+ var domainEvents = pgTable(
13
+ "domain_events",
14
+ {
15
+ id: uuid("id").primaryKey(),
16
+ type: text("type").notNull(),
17
+ aggregateId: text("aggregate_id").notNull(),
18
+ aggregateType: text("aggregate_type").notNull(),
19
+ payload: jsonb("payload").notNull().$type(),
20
+ occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull(),
21
+ processedAt: timestamp("processed_at", { withTimezone: true }),
22
+ /** Lifecycle status: pending | processed | failed */
23
+ status: text("status").notNull().default("pending"),
24
+ /** Error message from the last failed dispatch attempt. */
25
+ error: text("error"),
26
+ metadata: jsonb("metadata").$type(),
27
+ /** Routing pool (e.g. `events_inbound`, `events_change`, `events_outbound`). Populated by DrizzleEventBus.publish() in EVT-4. NULL when `tier='audit'`. */
28
+ pool: text("pool"),
29
+ /** Routing direction: `inbound` | `change` | `outbound`. Populated by DrizzleEventBus.publish() in EVT-4. NULL when `tier='audit'`. */
30
+ direction: text("direction"),
31
+ /**
32
+ * Event tier: `'domain'` (default) or `'audit'`. Audit-tier rows are
33
+ * observability-only and have null `pool`/`direction` by construction —
34
+ * enforced by the `domain_events_tier_routing_check` CHECK constraint
35
+ * declared below. (AUDIT-1)
36
+ */
37
+ tier: text("tier").notNull().default("domain"),
38
+ // conditional: emitted only when events.multi_tenant: true
39
+ tenantId: text("tenant_id")
40
+ },
41
+ (t) => ({
42
+ /** Polling drain filter (existing — promoted from comment to declaration in EVT-1). */
43
+ idxDomainEventsStatusOccurredAt: index("idx_domain_events_status_occurred_at").on(
44
+ t.status,
45
+ t.occurredAt
46
+ ),
47
+ /** Event replay per aggregate (existing — promoted from comment to declaration in EVT-1). */
48
+ idxDomainEventsAggregate: index("idx_domain_events_aggregate").on(
49
+ t.aggregateId,
50
+ t.aggregateType
51
+ ),
52
+ /** Per-pool drain filter (EVT-1). Enables DrizzleEventBus to drain a single pool without scanning all events. */
53
+ idxDomainEventsPoolStatusOccurredAt: index(
54
+ "idx_domain_events_pool_status_occurred_at"
55
+ ).on(t.pool, t.status, t.occurredAt),
56
+ /** Per-tier filter (AUDIT-1). Backs the observability viewer's tier toggle. */
57
+ idxDomainEventsTierStatusOccurredAt: index(
58
+ "idx_domain_events_tier_status_occurred_at"
59
+ ).on(t.tier, t.status, t.occurredAt),
60
+ /**
61
+ * Tier ↔ routing-fields invariant (AUDIT-1):
62
+ * - `tier` is one of `'domain' | 'audit'`.
63
+ * - `tier='audit'` ⇔ `pool IS NULL AND direction IS NULL`.
64
+ * - `tier='domain'` ⇒ `pool` and `direction` are populated (the
65
+ * DrizzleEventBus inserts always supply them; the bus stamps them
66
+ * in AUDIT-3).
67
+ */
68
+ tierRoutingCheck: check(
69
+ "domain_events_tier_routing_check",
70
+ sql`${t.tier} in ('domain','audit') AND ((${t.tier} = 'audit') = (${t.pool} is null and ${t.direction} is null))`
71
+ )
72
+ })
73
+ );
74
+
75
+ export {
76
+ domainEvents
77
+ };
78
+ //# sourceMappingURL=chunk-OFRRBC7M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/subsystems/events/domain-events.schema.ts"],"sourcesContent":["/**\n * Drizzle schema for the domain_events outbox table.\n *\n * This table backs the DrizzleEventBus. Events are inserted within the\n * same database transaction as the domain write (outbox pattern). A\n * polling process reads unprocessed rows and dispatches to subscribers.\n *\n * First-class routing columns (EVT-1):\n * - `pool` — populated by DrizzleEventBus.publish() (EVT-4); enables\n * pool-filtered drain queries without unpacking metadata JSON.\n * NULL when `tier='audit'` (audit events are not routed).\n * - `direction` — `inbound` | `change` | `outbound`; mirrors the routing\n * dimension used by jobs' reserved `events_inbound` /\n * `events_change` / `events_outbound` pools.\n * NULL when `tier='audit'`.\n * - `tenant_id` — conditional: emitted only when `events.multi_tenant: true`\n * in `codegen.config.yaml`. The runtime source declares it\n * unconditionally; EVT-8's scaffold template handles the\n * config-driven include/exclude.\n *\n * Audit-tier column (AUDIT-1):\n * - `tier` — `'domain'` | `'audit'`. Defaults to `'domain'`. Audit-tier\n * rows are observability-only (subscribers may observe but\n * the bridge MUST NOT spawn jobs from them); they have null\n * `pool` and `direction` by construction. The CHECK\n * constraint `domain_events_tier_routing_check` enforces\n * `tier='audit' ⇔ (pool IS NULL AND direction IS NULL)`.\n *\n * The `metadata` JSON column continues to carry these values for protocol\n * stability; the first-class columns are an optimization for drain filtering.\n *\n * Indexes (declared below in the index callback):\n * - (status, occurred_at) — polling drain filter\n * - (aggregate_id, aggregate_type) — event replay per aggregate\n * - (pool, status, occurred_at) — per-pool drain filter (EVT-1)\n * - (tier, status, occurred_at) — per-tier filter for the observability\n * viewer's tier toggle (AUDIT-1).\n */\nimport {\n check,\n index,\n jsonb,\n pgTable,\n text,\n timestamp,\n uuid,\n} from 'drizzle-orm/pg-core';\nimport { sql } from 'drizzle-orm';\nimport type { InferSelectModel } from 'drizzle-orm';\n\nexport const domainEvents = pgTable(\n 'domain_events',\n {\n id: uuid('id').primaryKey(),\n type: text('type').notNull(),\n aggregateId: text('aggregate_id').notNull(),\n aggregateType: text('aggregate_type').notNull(),\n payload: jsonb('payload').notNull().$type<Record<string, unknown>>(),\n occurredAt: timestamp('occurred_at', { withTimezone: true }).notNull(),\n processedAt: timestamp('processed_at', { withTimezone: true }),\n /** Lifecycle status: pending | processed | failed */\n status: text('status').notNull().default('pending'),\n /** Error message from the last failed dispatch attempt. */\n error: text('error'),\n metadata: jsonb('metadata').$type<Record<string, unknown>>(),\n /** Routing pool (e.g. `events_inbound`, `events_change`, `events_outbound`). Populated by DrizzleEventBus.publish() in EVT-4. NULL when `tier='audit'`. */\n pool: text('pool'),\n /** Routing direction: `inbound` | `change` | `outbound`. Populated by DrizzleEventBus.publish() in EVT-4. NULL when `tier='audit'`. */\n direction: text('direction'),\n /**\n * Event tier: `'domain'` (default) or `'audit'`. Audit-tier rows are\n * observability-only and have null `pool`/`direction` by construction —\n * enforced by the `domain_events_tier_routing_check` CHECK constraint\n * declared below. (AUDIT-1)\n */\n tier: text('tier').notNull().default('domain'),\n // conditional: emitted only when events.multi_tenant: true\n tenantId: text('tenant_id'),\n },\n (t) => ({\n /** Polling drain filter (existing — promoted from comment to declaration in EVT-1). */\n idxDomainEventsStatusOccurredAt: index('idx_domain_events_status_occurred_at').on(\n t.status,\n t.occurredAt,\n ),\n /** Event replay per aggregate (existing — promoted from comment to declaration in EVT-1). */\n idxDomainEventsAggregate: index('idx_domain_events_aggregate').on(\n t.aggregateId,\n t.aggregateType,\n ),\n /** Per-pool drain filter (EVT-1). Enables DrizzleEventBus to drain a single pool without scanning all events. */\n idxDomainEventsPoolStatusOccurredAt: index(\n 'idx_domain_events_pool_status_occurred_at',\n ).on(t.pool, t.status, t.occurredAt),\n /** Per-tier filter (AUDIT-1). Backs the observability viewer's tier toggle. */\n idxDomainEventsTierStatusOccurredAt: index(\n 'idx_domain_events_tier_status_occurred_at',\n ).on(t.tier, t.status, t.occurredAt),\n /**\n * Tier ↔ routing-fields invariant (AUDIT-1):\n * - `tier` is one of `'domain' | 'audit'`.\n * - `tier='audit'` ⇔ `pool IS NULL AND direction IS NULL`.\n * - `tier='domain'` ⇒ `pool` and `direction` are populated (the\n * DrizzleEventBus inserts always supply them; the bus stamps them\n * in AUDIT-3).\n */\n tierRoutingCheck: check(\n 'domain_events_tier_routing_check',\n sql`${t.tier} in ('domain','audit') AND ((${t.tier} = 'audit') = (${t.pool} is null and ${t.direction} is null))`,\n ),\n }),\n);\n\nexport type DomainEventRecord = InferSelectModel<typeof domainEvents>;\n"],"mappings":";AAsCA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW;AAGb,IAAM,eAAe;AAAA,EAC1B;AAAA,EACA;AAAA,IACE,IAAI,KAAK,IAAI,EAAE,WAAW;AAAA,IAC1B,MAAM,KAAK,MAAM,EAAE,QAAQ;AAAA,IAC3B,aAAa,KAAK,cAAc,EAAE,QAAQ;AAAA,IAC1C,eAAe,KAAK,gBAAgB,EAAE,QAAQ;AAAA,IAC9C,SAAS,MAAM,SAAS,EAAE,QAAQ,EAAE,MAA+B;AAAA,IACnE,YAAY,UAAU,eAAe,EAAE,cAAc,KAAK,CAAC,EAAE,QAAQ;AAAA,IACrE,aAAa,UAAU,gBAAgB,EAAE,cAAc,KAAK,CAAC;AAAA;AAAA,IAE7D,QAAQ,KAAK,QAAQ,EAAE,QAAQ,EAAE,QAAQ,SAAS;AAAA;AAAA,IAElD,OAAO,KAAK,OAAO;AAAA,IACnB,UAAU,MAAM,UAAU,EAAE,MAA+B;AAAA;AAAA,IAE3D,MAAM,KAAK,MAAM;AAAA;AAAA,IAEjB,WAAW,KAAK,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO3B,MAAM,KAAK,MAAM,EAAE,QAAQ,EAAE,QAAQ,QAAQ;AAAA;AAAA,IAE7C,UAAU,KAAK,WAAW;AAAA,EAC5B;AAAA,EACA,CAAC,OAAO;AAAA;AAAA,IAEN,iCAAiC,MAAM,sCAAsC,EAAE;AAAA,MAC7E,EAAE;AAAA,MACF,EAAE;AAAA,IACJ;AAAA;AAAA,IAEA,0BAA0B,MAAM,6BAA6B,EAAE;AAAA,MAC7D,EAAE;AAAA,MACF,EAAE;AAAA,IACJ;AAAA;AAAA,IAEA,qCAAqC;AAAA,MACnC;AAAA,IACF,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;AAAA;AAAA,IAEnC,qCAAqC;AAAA,MACnC;AAAA,IACF,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IASnC,kBAAkB;AAAA,MAChB;AAAA,MACA,MAAM,EAAE,IAAI,gCAAgC,EAAE,IAAI,kBAAkB,EAAE,IAAI,gBAAgB,EAAE,SAAS;AAAA,IACvG;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,222 @@
1
+ import {
2
+ assertTenantId
3
+ } from "./chunk-MZ6GV4YF.js";
4
+ import {
5
+ INTEGRATION_CHANGE_SOURCE,
6
+ INTEGRATION_CURSOR_STORE,
7
+ INTEGRATION_FIELD_DIFFER,
8
+ INTEGRATION_MULTI_TENANT,
9
+ INTEGRATION_RUN_RECORDER,
10
+ INTEGRATION_SINK
11
+ } from "./chunk-S7C6TIIF.js";
12
+ import {
13
+ __decorateClass,
14
+ __decorateParam
15
+ } from "./chunk-2E224ZSN.js";
16
+
17
+ // runtime/subsystems/integration/execute-integration.use-case.ts
18
+ import { Inject, Injectable, Logger, Optional } from "@nestjs/common";
19
+ var ExecuteIntegrationUseCase = class {
20
+ constructor(source, cursors, differ, sink, recorder, multiTenant = false) {
21
+ this.source = source;
22
+ this.cursors = cursors;
23
+ this.differ = differ;
24
+ this.sink = sink;
25
+ this.recorder = recorder;
26
+ this.multiTenant = multiTenant;
27
+ }
28
+ source;
29
+ cursors;
30
+ differ;
31
+ sink;
32
+ recorder;
33
+ multiTenant;
34
+ logger = new Logger(ExecuteIntegrationUseCase.name);
35
+ async execute(input) {
36
+ assertTenantId(input.tenantId, {
37
+ multiTenant: this.multiTenant,
38
+ operation: "execute"
39
+ });
40
+ const source = input.sourceOverride ?? this.source;
41
+ const startedAt = Date.now();
42
+ const cursorBefore = await this.cursors.get(input.subscription.id, input.tenantId);
43
+ const { id: runId } = await this.recorder.startRun({
44
+ subscriptionId: input.subscription.id,
45
+ direction: input.direction,
46
+ action: input.action,
47
+ cursorBefore,
48
+ tenantId: input.tenantId
49
+ });
50
+ let recordsFound = 0;
51
+ let recordsProcessed = 0;
52
+ let recordsFailed = 0;
53
+ let latestCursor = cursorBefore;
54
+ let cursorAdvanced = false;
55
+ let runError = null;
56
+ let status = "no_changes";
57
+ try {
58
+ for await (const change of source.listChanges(input.subscription, cursorBefore)) {
59
+ recordsFound++;
60
+ latestCursor = change.cursor;
61
+ cursorAdvanced = true;
62
+ try {
63
+ await this.processChange(runId, input, change);
64
+ recordsProcessed++;
65
+ } catch (err) {
66
+ recordsFailed++;
67
+ const message = err instanceof Error ? err.message : String(err);
68
+ this.logger.warn(
69
+ `integration item failed: subscription=${input.subscription.id} externalId=${change.externalId}: ${message}`
70
+ );
71
+ await this.recorder.recordItem({
72
+ integrationRunId: runId,
73
+ entityType: input.subscription.domain,
74
+ externalId: change.externalId,
75
+ operation: change.operation === "deleted" ? "deleted" : "updated",
76
+ status: "failed",
77
+ changedFields: {},
78
+ error: message,
79
+ tenantId: input.tenantId
80
+ });
81
+ }
82
+ }
83
+ if (recordsFailed > 0 && recordsProcessed === 0 && recordsFound > 0) {
84
+ status = "failed";
85
+ runError = `all ${recordsFailed} records failed`;
86
+ } else if (recordsFound === 0) {
87
+ status = "no_changes";
88
+ } else {
89
+ status = "success";
90
+ }
91
+ } catch (err) {
92
+ status = "failed";
93
+ runError = err instanceof Error ? err.message : String(err);
94
+ this.logger.error(
95
+ `integration source failed: subscription=${input.subscription.id}: ${runError}`
96
+ );
97
+ }
98
+ if (cursorAdvanced && latestCursor !== null && latestCursor !== void 0) {
99
+ try {
100
+ await this.cursors.put(input.subscription.id, latestCursor, input.tenantId);
101
+ } catch (err) {
102
+ const message = err instanceof Error ? err.message : String(err);
103
+ this.logger.error(
104
+ `cursor put failed: subscription=${input.subscription.id}: ${message}`
105
+ );
106
+ if (status !== "failed") {
107
+ status = "failed";
108
+ runError = `cursor put failed: ${message}`;
109
+ }
110
+ }
111
+ }
112
+ const durationMs = Date.now() - startedAt;
113
+ await this.recorder.completeRun(runId, {
114
+ status,
115
+ recordsFound,
116
+ recordsProcessed,
117
+ cursorAfter: cursorAdvanced ? latestCursor : cursorBefore,
118
+ durationMs,
119
+ error: runError
120
+ });
121
+ return {
122
+ runId,
123
+ status,
124
+ recordsFound,
125
+ recordsProcessed,
126
+ recordsFailed,
127
+ cursorBefore,
128
+ cursorAfter: cursorAdvanced ? latestCursor : cursorBefore,
129
+ durationMs,
130
+ error: runError
131
+ };
132
+ }
133
+ async processChange(runId, input, change) {
134
+ if (change.operation === "deleted") {
135
+ const result = await this.sink.softDeleteByExternalId(
136
+ input.userId,
137
+ change.externalId
138
+ );
139
+ await this.recorder.recordItem({
140
+ integrationRunId: runId,
141
+ entityType: input.subscription.domain,
142
+ externalId: change.externalId,
143
+ localId: result?.id ?? null,
144
+ operation: result ? "deleted" : "noop",
145
+ status: "success",
146
+ changedFields: {},
147
+ tenantId: input.tenantId
148
+ });
149
+ return;
150
+ }
151
+ const existing = await this.sink.findByExternalId(
152
+ input.userId,
153
+ change.externalId
154
+ );
155
+ const diff = this.differ.diff(
156
+ existing,
157
+ change.record,
158
+ change.providerChangedFields
159
+ );
160
+ if (diff === "noop") {
161
+ if (!this.sink.reprojectsOnNoop) {
162
+ await this.recorder.recordItem({
163
+ integrationRunId: runId,
164
+ entityType: input.subscription.domain,
165
+ externalId: change.externalId,
166
+ localId: null,
167
+ operation: "noop",
168
+ status: "success",
169
+ changedFields: {},
170
+ tenantId: input.tenantId
171
+ });
172
+ return;
173
+ }
174
+ const { id: noopLocalId } = await this.sink.upsertByExternalId(
175
+ input.userId,
176
+ change.record,
177
+ input.provider
178
+ );
179
+ await this.recorder.recordItem({
180
+ integrationRunId: runId,
181
+ entityType: input.subscription.domain,
182
+ externalId: change.externalId,
183
+ localId: noopLocalId,
184
+ operation: "noop",
185
+ status: "success",
186
+ changedFields: {},
187
+ tenantId: input.tenantId
188
+ });
189
+ return;
190
+ }
191
+ const { id: localId } = await this.sink.upsertByExternalId(
192
+ input.userId,
193
+ change.record,
194
+ input.provider
195
+ );
196
+ await this.recorder.recordItem({
197
+ integrationRunId: runId,
198
+ entityType: input.subscription.domain,
199
+ externalId: change.externalId,
200
+ localId,
201
+ operation: existing === null ? "created" : "updated",
202
+ status: "success",
203
+ changedFields: diff,
204
+ tenantId: input.tenantId
205
+ });
206
+ }
207
+ };
208
+ ExecuteIntegrationUseCase = __decorateClass([
209
+ Injectable(),
210
+ __decorateParam(0, Inject(INTEGRATION_CHANGE_SOURCE)),
211
+ __decorateParam(1, Inject(INTEGRATION_CURSOR_STORE)),
212
+ __decorateParam(2, Inject(INTEGRATION_FIELD_DIFFER)),
213
+ __decorateParam(3, Inject(INTEGRATION_SINK)),
214
+ __decorateParam(4, Inject(INTEGRATION_RUN_RECORDER)),
215
+ __decorateParam(5, Optional()),
216
+ __decorateParam(5, Inject(INTEGRATION_MULTI_TENANT))
217
+ ], ExecuteIntegrationUseCase);
218
+
219
+ export {
220
+ ExecuteIntegrationUseCase
221
+ };
222
+ //# sourceMappingURL=chunk-OGIZXGPY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/subsystems/integration/execute-integration.use-case.ts"],"sourcesContent":["/**\n * ExecuteIntegrationUseCase — the generic integration orchestrator (SYNC-5).\n *\n * One class. Reused across every `(provider, detection-mode, canonical-entity)`\n * tuple. Parameterized over `T` so canonical records stay typed end-to-end.\n *\n * Flow per run:\n *\n * 1. `recorder.startRun(...)` — opens a `integration_runs` row in 'running'.\n * 2. for each change yielded by `source.listChanges(subscription, cursorBefore)`:\n * a. differ.diff(existing, incoming) → 'noop' short-circuits to\n * a noop audit row (no sink write).\n * b. sink.upsertByExternalId / softDeleteByExternalId → records\n * the local id on the audit row.\n * c. per-item try/catch — a failed item increments the failed\n * counter and records `status: 'failed'` with `error`, but\n * does NOT abort the run.\n * d. advance `latestCursor = change.cursor` as the iterator moves.\n * 3. `cursors.put(subscription.id, latestCursor)` when the loop completes\n * AND at least one cursor advance happened. On exceptions from the\n * source iterator (auth expiry, network error), we persist the\n * last-good cursor so the next run resumes from the last known\n * successful position.\n * 4. `finally { recorder.completeRun(...) }` — always terminates the run.\n *\n * Loopback suppression — when a consumer's writes echo back on the next\n * inbound poll/CDC/webhook — is composed into the source's middleware\n * chain via `createLoopbackMiddleware(store)` (#226-5 / ADR-033). The\n * orchestrator no longer special-cases echoes: middleware drops them\n * before they reach this loop. Consumers that don't have outbound\n * writeback paths simply omit the middleware.\n *\n * ## Generics\n *\n * - `T` = canonical record shape from the adapter side. Same `T` flows\n * through `IChangeSource<T>`, `IFieldDiffer<T>`, `IIntegrationSink<T>`.\n *\n * ## No CRM bleed\n *\n * Per the SYNC-5 issue's extraction notes (HS-9 finding), this orchestrator\n * is strictly provider-agnostic:\n * - `entityType` is `string` throughout; no `'opportunity' | 'account' | ...`\n * narrowing leaks into the use case\n * - the upstream consumer's `IntegrationRunRecorderService` class injection replaced with the\n * `IIntegrationRunRecorder` protocol (backend lands in SYNC-4)\n */\nimport { Inject, Injectable, Logger, Optional } from '@nestjs/common';\nimport type { IChangeSource, Change } from './integration-change-source.protocol';\nimport type { ICursorStore } from './integration-cursor-store.protocol';\nimport type { IFieldDiffer, FieldDiff } from './integration-field-diff.protocol';\nimport type { IIntegrationSink } from './integration-sink.protocol';\nimport type { IIntegrationRunRecorder } from './integration-run-recorder.protocol';\nimport { assertTenantId } from './integration-errors';\nimport {\n INTEGRATION_CHANGE_SOURCE,\n INTEGRATION_CURSOR_STORE,\n INTEGRATION_FIELD_DIFFER,\n INTEGRATION_MULTI_TENANT,\n INTEGRATION_RUN_RECORDER,\n INTEGRATION_SINK,\n} from './integration.tokens';\n\n// ============================================================================\n// Inputs + result\n// ============================================================================\n\nexport interface ExecuteIntegrationInput<T> {\n /** The subscription whose cursor/identity frames this run. */\n readonly subscription: {\n readonly id: string;\n readonly domain: string; // entityType — used on audit rows\n readonly externalRef?: string | null;\n };\n /** Per-run user context; threaded through sink writes. */\n readonly userId: string;\n /** Provider label persisted on saved rows, e.g. `'salesforce-crm'`. */\n readonly provider: string;\n /** Run direction — almost always `'inbound'`. Reserved for writeback. */\n readonly direction: 'inbound' | 'outbound';\n /** Detection mode — maps 1:1 to `integration_runs.action`. */\n readonly action: 'poll' | 'cdc' | 'webhook' | 'manual' | 'writeback';\n /** Multi-tenant deployments pass the tenant id through. */\n readonly tenantId?: string | null;\n /**\n * Optional override — inject a specific change source for this run when\n * the DI-bound source is not the one to use (e.g. manual backfill with\n * a custom cursor). Defaults to the DI-resolved `INTEGRATION_CHANGE_SOURCE`.\n */\n readonly sourceOverride?: IChangeSource<T>;\n}\n\nexport interface ExecuteIntegrationResult {\n readonly runId: string;\n readonly status: 'success' | 'no_changes' | 'failed';\n readonly recordsFound: number;\n readonly recordsProcessed: number;\n readonly recordsFailed: number;\n readonly cursorBefore: unknown | null;\n readonly cursorAfter: unknown | null;\n readonly durationMs: number;\n readonly error?: string | null;\n}\n\n// ============================================================================\n// ExecuteIntegrationUseCase\n// ============================================================================\n\n@Injectable()\nexport class ExecuteIntegrationUseCase<T extends Record<string, unknown>> {\n private readonly logger = new Logger(ExecuteIntegrationUseCase.name);\n\n constructor(\n @Inject(INTEGRATION_CHANGE_SOURCE) private readonly source: IChangeSource<T>,\n @Inject(INTEGRATION_CURSOR_STORE) private readonly cursors: ICursorStore,\n @Inject(INTEGRATION_FIELD_DIFFER) private readonly differ: IFieldDiffer<T>,\n @Inject(INTEGRATION_SINK) private readonly sink: IIntegrationSink<T>,\n @Inject(INTEGRATION_RUN_RECORDER) private readonly recorder: IIntegrationRunRecorder,\n @Optional()\n @Inject(INTEGRATION_MULTI_TENANT)\n private readonly multiTenant: boolean = false,\n ) {}\n\n async execute(input: ExecuteIntegrationInput<T>): Promise<ExecuteIntegrationResult> {\n // Defense-in-depth tenancy guard — fire BEFORE startRun so a rejected\n // input never leaves a dangling `status=running` row. Backends also\n // enforce (SYNC-4), but failing fast at the orchestrator boundary is\n // cheaper for observability, metrics, and manual cleanup.\n assertTenantId(input.tenantId, {\n multiTenant: this.multiTenant,\n operation: 'execute',\n });\n\n const source = input.sourceOverride ?? this.source;\n const startedAt = Date.now();\n const cursorBefore = await this.cursors.get(input.subscription.id, input.tenantId);\n\n const { id: runId } = await this.recorder.startRun({\n subscriptionId: input.subscription.id,\n direction: input.direction,\n action: input.action,\n cursorBefore,\n tenantId: input.tenantId,\n });\n\n let recordsFound = 0;\n let recordsProcessed = 0;\n let recordsFailed = 0;\n let latestCursor: unknown | null = cursorBefore;\n let cursorAdvanced = false;\n let runError: string | null = null;\n let status: 'success' | 'no_changes' | 'failed' = 'no_changes';\n\n try {\n for await (const change of source.listChanges(input.subscription, cursorBefore)) {\n recordsFound++;\n latestCursor = change.cursor;\n cursorAdvanced = true;\n\n try {\n await this.processChange(runId, input, change);\n recordsProcessed++;\n } catch (err) {\n recordsFailed++;\n const message = err instanceof Error ? err.message : String(err);\n this.logger.warn(\n `integration item failed: subscription=${input.subscription.id} externalId=${change.externalId}: ${message}`,\n );\n await this.recorder.recordItem({\n integrationRunId: runId,\n entityType: input.subscription.domain,\n externalId: change.externalId,\n operation: change.operation === 'deleted' ? 'deleted' : 'updated',\n status: 'failed',\n changedFields: {},\n error: message,\n tenantId: input.tenantId,\n });\n }\n }\n\n if (recordsFailed > 0 && recordsProcessed === 0 && recordsFound > 0) {\n // Every record we saw failed — call the run a failure, not a\n // success. Partial success (some processed, some failed) still\n // counts as 'success' so the cursor advances.\n status = 'failed';\n runError = `all ${recordsFailed} records failed`;\n } else if (recordsFound === 0) {\n status = 'no_changes';\n } else {\n status = 'success';\n }\n } catch (err) {\n // Source iterator itself threw — cursor DOES NOT advance past the\n // last-successful cursor. `latestCursor` still holds the last\n // `change.cursor` we observed, which is the furthest we know to\n // have delivered. Persist it (below) so next run resumes there.\n status = 'failed';\n runError = err instanceof Error ? err.message : String(err);\n this.logger.error(\n `integration source failed: subscription=${input.subscription.id}: ${runError}`,\n );\n }\n\n // Persist cursor advance only when something actually moved. Never\n // overwrite a valid cursor with `null` on a no-change run.\n if (cursorAdvanced && latestCursor !== null && latestCursor !== undefined) {\n try {\n await this.cursors.put(input.subscription.id, latestCursor, input.tenantId);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n this.logger.error(\n `cursor put failed: subscription=${input.subscription.id}: ${message}`,\n );\n if (status !== 'failed') {\n status = 'failed';\n runError = `cursor put failed: ${message}`;\n }\n }\n }\n\n const durationMs = Date.now() - startedAt;\n\n await this.recorder.completeRun(runId, {\n status,\n recordsFound,\n recordsProcessed,\n cursorAfter: cursorAdvanced ? latestCursor : cursorBefore,\n durationMs,\n error: runError,\n });\n\n return {\n runId,\n status,\n recordsFound,\n recordsProcessed,\n recordsFailed,\n cursorBefore,\n cursorAfter: cursorAdvanced ? latestCursor : cursorBefore,\n durationMs,\n error: runError,\n };\n }\n\n private async processChange(\n runId: string,\n input: ExecuteIntegrationInput<T>,\n change: Change<T>,\n ): Promise<void> {\n // Deletion branch — no diff, no upsert; soft-delete via sink.\n if (change.operation === 'deleted') {\n const result = await this.sink.softDeleteByExternalId(\n input.userId,\n change.externalId,\n );\n await this.recorder.recordItem({\n integrationRunId: runId,\n entityType: input.subscription.domain,\n externalId: change.externalId,\n localId: result?.id ?? null,\n operation: result ? 'deleted' : 'noop',\n status: 'success',\n changedFields: {},\n tenantId: input.tenantId,\n });\n return;\n }\n\n // Create/update path — diff against local state, short-circuit on noop.\n const existing = await this.sink.findByExternalId(\n input.userId,\n change.externalId,\n );\n const diff = this.differ.diff(\n existing,\n change.record,\n change.providerChangedFields,\n );\n\n if (diff === 'noop') {\n // Sinks that declare `reprojectsOnNoop` reproject side data the differ\n // can't see (e.g. EAV field_values) — so fall through to the idempotent\n // upsert instead of short-circuiting. The canonical state is unchanged,\n // so the audit `operation` stays `'noop'`, but we capture the local id\n // returned by the upsert. Sinks without the flag keep today's behavior.\n if (!this.sink.reprojectsOnNoop) {\n await this.recorder.recordItem({\n integrationRunId: runId,\n entityType: input.subscription.domain,\n externalId: change.externalId,\n localId: null,\n operation: 'noop',\n status: 'success',\n changedFields: {},\n tenantId: input.tenantId,\n });\n return;\n }\n\n const { id: noopLocalId } = await this.sink.upsertByExternalId(\n input.userId,\n change.record,\n input.provider,\n );\n await this.recorder.recordItem({\n integrationRunId: runId,\n entityType: input.subscription.domain,\n externalId: change.externalId,\n localId: noopLocalId,\n operation: 'noop',\n status: 'success',\n changedFields: {},\n tenantId: input.tenantId,\n });\n return;\n }\n\n const { id: localId } = await this.sink.upsertByExternalId(\n input.userId,\n change.record,\n input.provider,\n );\n\n await this.recorder.recordItem({\n integrationRunId: runId,\n entityType: input.subscription.domain,\n externalId: change.externalId,\n localId,\n operation: existing === null ? 'created' : 'updated',\n status: 'success',\n changedFields: diff as FieldDiff,\n tenantId: input.tenantId,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA8CA,SAAS,QAAQ,YAAY,QAAQ,gBAAgB;AA8D9C,IAAM,4BAAN,MAAmE;AAAA,EAGxE,YACsD,QACD,SACA,QACR,MACQ,UAGlC,cAAuB,OACxC;AARoD;AACD;AACA;AACR;AACQ;AAGlC;AAAA,EAChB;AAAA,EARmD;AAAA,EACD;AAAA,EACA;AAAA,EACR;AAAA,EACQ;AAAA,EAGlC;AAAA,EAVF,SAAS,IAAI,OAAO,0BAA0B,IAAI;AAAA,EAanE,MAAM,QAAQ,OAAsE;AAKlF,mBAAe,MAAM,UAAU;AAAA,MAC7B,aAAa,KAAK;AAAA,MAClB,WAAW;AAAA,IACb,CAAC;AAED,UAAM,SAAS,MAAM,kBAAkB,KAAK;AAC5C,UAAM,YAAY,KAAK,IAAI;AAC3B,UAAM,eAAe,MAAM,KAAK,QAAQ,IAAI,MAAM,aAAa,IAAI,MAAM,QAAQ;AAEjF,UAAM,EAAE,IAAI,MAAM,IAAI,MAAM,KAAK,SAAS,SAAS;AAAA,MACjD,gBAAgB,MAAM,aAAa;AAAA,MACnC,WAAW,MAAM;AAAA,MACjB,QAAQ,MAAM;AAAA,MACd;AAAA,MACA,UAAU,MAAM;AAAA,IAClB,CAAC;AAED,QAAI,eAAe;AACnB,QAAI,mBAAmB;AACvB,QAAI,gBAAgB;AACpB,QAAI,eAA+B;AACnC,QAAI,iBAAiB;AACrB,QAAI,WAA0B;AAC9B,QAAI,SAA8C;AAElD,QAAI;AACF,uBAAiB,UAAU,OAAO,YAAY,MAAM,cAAc,YAAY,GAAG;AAC/E;AACA,uBAAe,OAAO;AACtB,yBAAiB;AAEjB,YAAI;AACF,gBAAM,KAAK,cAAc,OAAO,OAAO,MAAM;AAC7C;AAAA,QACF,SAAS,KAAK;AACZ;AACA,gBAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,eAAK,OAAO;AAAA,YACV,yCAAyC,MAAM,aAAa,EAAE,eAAe,OAAO,UAAU,KAAK,OAAO;AAAA,UAC5G;AACA,gBAAM,KAAK,SAAS,WAAW;AAAA,YAC7B,kBAAkB;AAAA,YAClB,YAAY,MAAM,aAAa;AAAA,YAC/B,YAAY,OAAO;AAAA,YACnB,WAAW,OAAO,cAAc,YAAY,YAAY;AAAA,YACxD,QAAQ;AAAA,YACR,eAAe,CAAC;AAAA,YAChB,OAAO;AAAA,YACP,UAAU,MAAM;AAAA,UAClB,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI,gBAAgB,KAAK,qBAAqB,KAAK,eAAe,GAAG;AAInE,iBAAS;AACT,mBAAW,OAAO,aAAa;AAAA,MACjC,WAAW,iBAAiB,GAAG;AAC7B,iBAAS;AAAA,MACX,OAAO;AACL,iBAAS;AAAA,MACX;AAAA,IACF,SAAS,KAAK;AAKZ,eAAS;AACT,iBAAW,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC1D,WAAK,OAAO;AAAA,QACV,2CAA2C,MAAM,aAAa,EAAE,KAAK,QAAQ;AAAA,MAC/E;AAAA,IACF;AAIA,QAAI,kBAAkB,iBAAiB,QAAQ,iBAAiB,QAAW;AACzE,UAAI;AACF,cAAM,KAAK,QAAQ,IAAI,MAAM,aAAa,IAAI,cAAc,MAAM,QAAQ;AAAA,MAC5E,SAAS,KAAK;AACZ,cAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,aAAK,OAAO;AAAA,UACV,mCAAmC,MAAM,aAAa,EAAE,KAAK,OAAO;AAAA,QACtE;AACA,YAAI,WAAW,UAAU;AACvB,mBAAS;AACT,qBAAW,sBAAsB,OAAO;AAAA,QAC1C;AAAA,MACF;AAAA,IACF;AAEA,UAAM,aAAa,KAAK,IAAI,IAAI;AAEhC,UAAM,KAAK,SAAS,YAAY,OAAO;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,iBAAiB,eAAe;AAAA,MAC7C;AAAA,MACA,OAAO;AAAA,IACT,CAAC;AAED,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,aAAa,iBAAiB,eAAe;AAAA,MAC7C;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,cACZ,OACA,OACA,QACe;AAEf,QAAI,OAAO,cAAc,WAAW;AAClC,YAAM,SAAS,MAAM,KAAK,KAAK;AAAA,QAC7B,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AACA,YAAM,KAAK,SAAS,WAAW;AAAA,QAC7B,kBAAkB;AAAA,QAClB,YAAY,MAAM,aAAa;AAAA,QAC/B,YAAY,OAAO;AAAA,QACnB,SAAS,QAAQ,MAAM;AAAA,QACvB,WAAW,SAAS,YAAY;AAAA,QAChC,QAAQ;AAAA,QACR,eAAe,CAAC;AAAA,QAChB,UAAU,MAAM;AAAA,MAClB,CAAC;AACD;AAAA,IACF;AAGA,UAAM,WAAW,MAAM,KAAK,KAAK;AAAA,MAC/B,MAAM;AAAA,MACN,OAAO;AAAA,IACT;AACA,UAAM,OAAO,KAAK,OAAO;AAAA,MACvB;AAAA,MACA,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAEA,QAAI,SAAS,QAAQ;AAMnB,UAAI,CAAC,KAAK,KAAK,kBAAkB;AAC/B,cAAM,KAAK,SAAS,WAAW;AAAA,UAC7B,kBAAkB;AAAA,UAClB,YAAY,MAAM,aAAa;AAAA,UAC/B,YAAY,OAAO;AAAA,UACnB,SAAS;AAAA,UACT,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,eAAe,CAAC;AAAA,UAChB,UAAU,MAAM;AAAA,QAClB,CAAC;AACD;AAAA,MACF;AAEA,YAAM,EAAE,IAAI,YAAY,IAAI,MAAM,KAAK,KAAK;AAAA,QAC1C,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AACA,YAAM,KAAK,SAAS,WAAW;AAAA,QAC7B,kBAAkB;AAAA,QAClB,YAAY,MAAM,aAAa;AAAA,QAC/B,YAAY,OAAO;AAAA,QACnB,SAAS;AAAA,QACT,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,eAAe,CAAC;AAAA,QAChB,UAAU,MAAM;AAAA,MAClB,CAAC;AACD;AAAA,IACF;AAEA,UAAM,EAAE,IAAI,QAAQ,IAAI,MAAM,KAAK,KAAK;AAAA,MACtC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,MAAM;AAAA,IACR;AAEA,UAAM,KAAK,SAAS,WAAW;AAAA,MAC7B,kBAAkB;AAAA,MAClB,YAAY,MAAM,aAAa;AAAA,MAC/B,YAAY,OAAO;AAAA,MACnB;AAAA,MACA,WAAW,aAAa,OAAO,YAAY;AAAA,MAC3C,QAAQ;AAAA,MACR,eAAe;AAAA,MACf,UAAU,MAAM;AAAA,IAClB,CAAC;AAAA,EACH;AACF;AAlOa,4BAAN;AAAA,EADN,WAAW;AAAA,EAKP,0BAAO,yBAAyB;AAAA,EAChC,0BAAO,wBAAwB;AAAA,EAC/B,0BAAO,wBAAwB;AAAA,EAC/B,0BAAO,gBAAgB;AAAA,EACvB,0BAAO,wBAAwB;AAAA,EAC/B,4BAAS;AAAA,EACT,0BAAO,wBAAwB;AAAA,GAVvB;","names":[]}
@@ -0,0 +1,168 @@
1
+ // runtime/subsystems/jobs/job-orchestration.schema.ts
2
+ import {
3
+ pgEnum,
4
+ pgTable,
5
+ uuid,
6
+ text,
7
+ jsonb,
8
+ integer,
9
+ timestamp,
10
+ index,
11
+ uniqueIndex
12
+ } from "drizzle-orm/pg-core";
13
+ import { sql } from "drizzle-orm";
14
+ var jobRunStatusEnum = pgEnum("job_run_status", [
15
+ "pending",
16
+ "running",
17
+ "waiting",
18
+ "completed",
19
+ "failed",
20
+ "timed_out",
21
+ "canceled"
22
+ ]);
23
+ var jobStepKindEnum = pgEnum("job_step_kind", ["task"]);
24
+ var jobStepStatusEnum = pgEnum("job_step_status", [
25
+ "pending",
26
+ "running",
27
+ "completed",
28
+ "failed",
29
+ "skipped"
30
+ ]);
31
+ var collisionModeEnum = pgEnum("job_collision_mode", [
32
+ "queue",
33
+ "reject",
34
+ "replace"
35
+ ]);
36
+ var replayFromEnum = pgEnum("job_replay_from", [
37
+ "scratch",
38
+ "last_step",
39
+ "last_checkpoint"
40
+ ]);
41
+ var parentClosePolicyEnum = pgEnum("job_parent_close_policy", [
42
+ "terminate",
43
+ "cancel",
44
+ "abandon"
45
+ ]);
46
+ var waitKindEnum = pgEnum("job_wait_kind", ["signal"]);
47
+ var triggerSourceEnum = pgEnum("job_trigger_source", [
48
+ "manual",
49
+ "schedule",
50
+ "event",
51
+ "parent"
52
+ ]);
53
+ var jobs = pgTable("job", {
54
+ type: text("type").primaryKey(),
55
+ version: integer("version").notNull().default(1),
56
+ pool: text("pool").notNull(),
57
+ scopeEntityType: text("scope_entity_type"),
58
+ retryPolicy: jsonb("retry_policy").notNull().$type(),
59
+ timeoutMs: integer("timeout_ms"),
60
+ concurrencyKeyTemplate: text("concurrency_key_template"),
61
+ collisionMode: collisionModeEnum("collision_mode").notNull().default("queue"),
62
+ dedupeKeyTemplate: text("dedupe_key_template"),
63
+ dedupeWindowMs: integer("dedupe_window_ms"),
64
+ priorityDefault: integer("priority_default").notNull().default(0),
65
+ replayFrom: replayFromEnum("replay_from").notNull().default("last_checkpoint"),
66
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
67
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
68
+ });
69
+ var jobRuns = pgTable(
70
+ "job_run",
71
+ {
72
+ id: uuid("id").primaryKey().defaultRandom(),
73
+ jobType: text("job_type").notNull().references(() => jobs.type),
74
+ jobVersion: integer("job_version").notNull(),
75
+ parentRunId: uuid("parent_run_id").references(() => jobRuns.id),
76
+ /**
77
+ * Service generates `id` client-side via randomUUID() and sets
78
+ * root_run_id = id for root runs (single INSERT, no self-FK race).
79
+ */
80
+ rootRunId: uuid("root_run_id").notNull(),
81
+ parentClosePolicy: parentClosePolicyEnum("parent_close_policy").notNull().default("terminate"),
82
+ scopeEntityType: text("scope_entity_type"),
83
+ scopeEntityId: text("scope_entity_id"),
84
+ tenantId: text("tenant_id"),
85
+ tags: jsonb("tags").notNull().default({}).$type(),
86
+ pool: text("pool").notNull(),
87
+ priority: integer("priority").notNull().default(0),
88
+ concurrencyKey: text("concurrency_key"),
89
+ dedupeKey: text("dedupe_key"),
90
+ status: jobRunStatusEnum("status").notNull().default("pending"),
91
+ input: jsonb("input").notNull().$type(),
92
+ output: jsonb("output").$type(),
93
+ error: jsonb("error").$type(),
94
+ triggerSource: triggerSourceEnum("trigger_source").notNull(),
95
+ triggerRef: text("trigger_ref"),
96
+ runAt: timestamp("run_at", { withTimezone: true }).notNull().defaultNow(),
97
+ startedAt: timestamp("started_at", { withTimezone: true }),
98
+ finishedAt: timestamp("finished_at", { withTimezone: true }),
99
+ claimedAt: timestamp("claimed_at", { withTimezone: true }),
100
+ attempts: integer("attempts").notNull().default(0),
101
+ // Phase 3 placeholder — see ADR-025
102
+ waitKind: waitKindEnum("wait_kind"),
103
+ // Phase 3 placeholder — see ADR-025
104
+ resumeToken: text("resume_token"),
105
+ // Phase 3 placeholder — see ADR-025
106
+ waitDeadline: timestamp("wait_deadline", { withTimezone: true }),
107
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
108
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
109
+ },
110
+ (t) => ({
111
+ /** Claim query: ORDER BY priority DESC, run_at ASC. */
112
+ idxJobRunClaim: index("idx_job_run_claim").on(t.status, t.pool, t.runAt),
113
+ /** Tree traversal / cascade cancel. */
114
+ idxJobRunRoot: index("idx_job_run_root").on(t.rootRunId),
115
+ /** listForScope query. */
116
+ idxJobRunScope: index("idx_job_run_scope").on(t.scopeEntityType, t.scopeEntityId),
117
+ /** Idempotency collapse — partial index. */
118
+ idxJobRunDedupe: index("idx_job_run_dedupe").on(t.jobType, t.dedupeKey).where(sql`${t.dedupeKey} IS NOT NULL`),
119
+ /** Collision check — partial index. */
120
+ idxJobRunConcurrency: index("idx_job_run_concurrency").on(t.concurrencyKey).where(
121
+ sql`${t.concurrencyKey} IS NOT NULL AND ${t.status} IN ('pending','running')`
122
+ )
123
+ })
124
+ );
125
+ var jobSteps = pgTable(
126
+ "job_step",
127
+ {
128
+ id: uuid("id").primaryKey().defaultRandom(),
129
+ jobRunId: uuid("job_run_id").notNull().references(() => jobRuns.id),
130
+ stepId: text("step_id").notNull(),
131
+ kind: jobStepKindEnum("kind").notNull().default("task"),
132
+ /**
133
+ * Monotonic within run. integer (max ~2B per run) is sufficient —
134
+ * downgraded from ADR-022's bigint; revisit only if a single run
135
+ * ever exceeds 2 billion steps.
136
+ */
137
+ seq: integer("seq").notNull(),
138
+ status: jobStepStatusEnum("status").notNull().default("pending"),
139
+ input: jsonb("input").$type(),
140
+ /** Memoised on success for replay. */
141
+ output: jsonb("output").$type(),
142
+ error: jsonb("error").$type(),
143
+ attempts: integer("attempts").notNull().default(0),
144
+ startedAt: timestamp("started_at", { withTimezone: true }),
145
+ finishedAt: timestamp("finished_at", { withTimezone: true })
146
+ },
147
+ (t) => ({
148
+ /** No duplicate step IDs per run. */
149
+ idxJobStepRunStep: uniqueIndex("idx_job_step_run_step").on(t.jobRunId, t.stepId),
150
+ /** Ordered timeline reads. */
151
+ idxJobStepTimeline: index("idx_job_step_timeline").on(t.jobRunId, t.seq)
152
+ })
153
+ );
154
+
155
+ export {
156
+ jobRunStatusEnum,
157
+ jobStepKindEnum,
158
+ jobStepStatusEnum,
159
+ collisionModeEnum,
160
+ replayFromEnum,
161
+ parentClosePolicyEnum,
162
+ waitKindEnum,
163
+ triggerSourceEnum,
164
+ jobs,
165
+ jobRuns,
166
+ jobSteps
167
+ };
168
+ //# sourceMappingURL=chunk-OKXZ63IA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/subsystems/jobs/job-orchestration.schema.ts"],"sourcesContent":["/**\n * Drizzle schema for the job orchestration domain (ADR-022).\n *\n * Three tables model the lifecycle of a durable job:\n * - `job` — definitions keyed by handler type (e.g. 'onboarding').\n * - `job_run` — one row per attempt to execute a job; worker claims\n * rows directly via SELECT ... FOR UPDATE SKIP LOCKED.\n * - `job_step` — individual steps within a run; memoises output for replay.\n *\n * Phase 1 ships only this layer. There is no `job_queue` table, no executor\n * port — see ADR-022 and `.claude/skills/jobs/SKILL.md` for the rationale.\n */\nimport {\n pgEnum,\n pgTable,\n uuid,\n text,\n jsonb,\n integer,\n timestamp,\n index,\n uniqueIndex,\n} from 'drizzle-orm/pg-core';\nimport { sql } from 'drizzle-orm';\nimport type { InferSelectModel } from 'drizzle-orm';\n\n// ─── Internal $type<> helpers ───────────────────────────────────────────────\n// Annotation types for jsonb columns only. JOB-2 defines the public protocol\n// types; these remain private to this file.\n\ntype RetryPolicy = {\n attempts: number;\n backoff: 'fixed' | 'exponential';\n baseMs: number;\n nonRetryableErrors?: string[];\n};\n\ntype JobRunError = {\n message: string;\n stack?: string;\n retryable: boolean;\n attempt: number;\n};\n\n// ─── Enums ──────────────────────────────────────────────────────────────────\n\nexport const jobRunStatusEnum = pgEnum('job_run_status', [\n 'pending',\n 'running',\n 'waiting',\n 'completed',\n 'failed',\n 'timed_out',\n 'canceled',\n]);\n\n// extended in ADR-027: tool_call | llm_call | wait | checkpoint | message\nexport const jobStepKindEnum = pgEnum('job_step_kind', ['task']);\n\nexport const jobStepStatusEnum = pgEnum('job_step_status', [\n 'pending',\n 'running',\n 'completed',\n 'failed',\n 'skipped',\n]);\n\nexport const collisionModeEnum = pgEnum('job_collision_mode', [\n 'queue',\n 'reject',\n 'replace',\n]);\n\nexport const replayFromEnum = pgEnum('job_replay_from', [\n 'scratch',\n 'last_step',\n 'last_checkpoint',\n]);\n\nexport const parentClosePolicyEnum = pgEnum('job_parent_close_policy', [\n 'terminate',\n 'cancel',\n 'abandon',\n]);\n\n// Phase 3 placeholder — see ADR-025\nexport const waitKindEnum = pgEnum('job_wait_kind', ['signal']);\n\n// Phase 2 may add more sources; requires Atlas migration\nexport const triggerSourceEnum = pgEnum('job_trigger_source', [\n 'manual',\n 'schedule',\n 'event',\n 'parent',\n]);\n\n// ─── job ────────────────────────────────────────────────────────────────────\n\nexport const jobs = pgTable('job', {\n type: text('type').primaryKey(),\n version: integer('version').notNull().default(1),\n pool: text('pool').notNull(),\n scopeEntityType: text('scope_entity_type'),\n retryPolicy: jsonb('retry_policy').notNull().$type<RetryPolicy>(),\n timeoutMs: integer('timeout_ms'),\n concurrencyKeyTemplate: text('concurrency_key_template'),\n collisionMode: collisionModeEnum('collision_mode').notNull().default('queue'),\n dedupeKeyTemplate: text('dedupe_key_template'),\n dedupeWindowMs: integer('dedupe_window_ms'),\n priorityDefault: integer('priority_default').notNull().default(0),\n replayFrom: replayFromEnum('replay_from').notNull().default('last_checkpoint'),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\n});\n\nexport type JobDefinitionRow = InferSelectModel<typeof jobs>;\n\n// ─── job_run ────────────────────────────────────────────────────────────────\n\nexport const jobRuns = pgTable(\n 'job_run',\n {\n id: uuid('id').primaryKey().defaultRandom(),\n jobType: text('job_type').notNull().references(() => jobs.type),\n jobVersion: integer('job_version').notNull(),\n parentRunId: uuid('parent_run_id').references((): any => jobRuns.id),\n /**\n * Service generates `id` client-side via randomUUID() and sets\n * root_run_id = id for root runs (single INSERT, no self-FK race).\n */\n rootRunId: uuid('root_run_id').notNull(),\n parentClosePolicy: parentClosePolicyEnum('parent_close_policy')\n .notNull()\n .default('terminate'),\n scopeEntityType: text('scope_entity_type'),\n scopeEntityId: text('scope_entity_id'),\n tenantId: text('tenant_id'),\n tags: jsonb('tags').notNull().default({}).$type<Record<string, string>>(),\n pool: text('pool').notNull(),\n priority: integer('priority').notNull().default(0),\n concurrencyKey: text('concurrency_key'),\n dedupeKey: text('dedupe_key'),\n status: jobRunStatusEnum('status').notNull().default('pending'),\n input: jsonb('input').notNull().$type<Record<string, unknown>>(),\n output: jsonb('output').$type<Record<string, unknown>>(),\n error: jsonb('error').$type<JobRunError>(),\n triggerSource: triggerSourceEnum('trigger_source').notNull(),\n triggerRef: text('trigger_ref'),\n runAt: timestamp('run_at', { withTimezone: true }).notNull().defaultNow(),\n startedAt: timestamp('started_at', { withTimezone: true }),\n finishedAt: timestamp('finished_at', { withTimezone: true }),\n claimedAt: timestamp('claimed_at', { withTimezone: true }),\n attempts: integer('attempts').notNull().default(0),\n // Phase 3 placeholder — see ADR-025\n waitKind: waitKindEnum('wait_kind'),\n // Phase 3 placeholder — see ADR-025\n resumeToken: text('resume_token'),\n // Phase 3 placeholder — see ADR-025\n waitDeadline: timestamp('wait_deadline', { withTimezone: true }),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),\n },\n (t) => ({\n /** Claim query: ORDER BY priority DESC, run_at ASC. */\n idxJobRunClaim: index('idx_job_run_claim').on(t.status, t.pool, t.runAt),\n /** Tree traversal / cascade cancel. */\n idxJobRunRoot: index('idx_job_run_root').on(t.rootRunId),\n /** listForScope query. */\n idxJobRunScope: index('idx_job_run_scope').on(t.scopeEntityType, t.scopeEntityId),\n /** Idempotency collapse — partial index. */\n idxJobRunDedupe: index('idx_job_run_dedupe')\n .on(t.jobType, t.dedupeKey)\n .where(sql`${t.dedupeKey} IS NOT NULL`),\n /** Collision check — partial index. */\n idxJobRunConcurrency: index('idx_job_run_concurrency')\n .on(t.concurrencyKey)\n .where(\n sql`${t.concurrencyKey} IS NOT NULL AND ${t.status} IN ('pending','running')`,\n ),\n }),\n);\n\nexport type JobRunRow = InferSelectModel<typeof jobRuns>;\n\n// ─── job_step ───────────────────────────────────────────────────────────────\n\nexport const jobSteps = pgTable(\n 'job_step',\n {\n id: uuid('id').primaryKey().defaultRandom(),\n jobRunId: uuid('job_run_id').notNull().references(() => jobRuns.id),\n stepId: text('step_id').notNull(),\n kind: jobStepKindEnum('kind').notNull().default('task'),\n /**\n * Monotonic within run. integer (max ~2B per run) is sufficient —\n * downgraded from ADR-022's bigint; revisit only if a single run\n * ever exceeds 2 billion steps.\n */\n seq: integer('seq').notNull(),\n status: jobStepStatusEnum('status').notNull().default('pending'),\n input: jsonb('input').$type<Record<string, unknown>>(),\n /** Memoised on success for replay. */\n output: jsonb('output').$type<Record<string, unknown>>(),\n error: jsonb('error').$type<JobRunError>(),\n attempts: integer('attempts').notNull().default(0),\n startedAt: timestamp('started_at', { withTimezone: true }),\n finishedAt: timestamp('finished_at', { withTimezone: true }),\n },\n (t) => ({\n /** No duplicate step IDs per run. */\n idxJobStepRunStep: uniqueIndex('idx_job_step_run_step').on(t.jobRunId, t.stepId),\n /** Ordered timeline reads. */\n idxJobStepTimeline: index('idx_job_step_timeline').on(t.jobRunId, t.seq),\n }),\n);\n\nexport type JobStepRow = InferSelectModel<typeof jobSteps>;\n"],"mappings":"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","names":[]}
@@ -0,0 +1,58 @@
1
+ import {
2
+ AUTH_USER_CONTEXT
3
+ } from "./chunk-6XY6ZMMD.js";
4
+ import {
5
+ withRequester
6
+ } from "./chunk-ZUKFQL6E.js";
7
+
8
+ // runtime/subsystems/auth/middleware/requester-context.ts
9
+ async function resolveRequesterContext(userContext, req) {
10
+ if (typeof userContext.resolveRequester === "function") {
11
+ const ctx = await userContext.resolveRequester(req);
12
+ return ctx?.userId ? ctx : void 0;
13
+ }
14
+ const userId = await userContext.getCurrentUserId(req);
15
+ return userId ? { userId, organizationId: null } : void 0;
16
+ }
17
+ function makeRequesterContextMiddleware(userContext, options = {}) {
18
+ const onUnresolved = options.onUnresolved ?? "unscoped";
19
+ return (req, _res, next) => {
20
+ resolveRequesterContext(userContext, req).then(
21
+ (ctx) => {
22
+ if (!ctx) {
23
+ next();
24
+ return;
25
+ }
26
+ withRequester(ctx, async () => {
27
+ next();
28
+ });
29
+ },
30
+ (err) => {
31
+ if (onUnresolved === "reject") {
32
+ next(err);
33
+ return;
34
+ }
35
+ next();
36
+ }
37
+ );
38
+ };
39
+ }
40
+ function installRequesterContext(app, options = {}) {
41
+ const userContext = app.get(AUTH_USER_CONTEXT, {
42
+ strict: false
43
+ });
44
+ if (!userContext) {
45
+ console.warn(
46
+ "[auth] installRequesterContext: AUTH_USER_CONTEXT is not bound \u2014 request scoping NOT installed. Provide an IUserContext under AUTH_USER_CONTEXT in your AppModule to enable ambient tenant scoping."
47
+ );
48
+ return;
49
+ }
50
+ app.use(makeRequesterContextMiddleware(userContext, options));
51
+ }
52
+
53
+ export {
54
+ resolveRequesterContext,
55
+ makeRequesterContextMiddleware,
56
+ installRequesterContext
57
+ };
58
+ //# sourceMappingURL=chunk-OSQRXVG2.js.map