@pattern-stack/codegen 0.15.1 → 0.15.3

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 (527) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/dist/chunk-27ETSJ2X.js +84 -0
  3. package/dist/chunk-27ETSJ2X.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-4H3PETLM.js +290 -0
  29. package/dist/chunk-4H3PETLM.js.map +1 -0
  30. package/dist/chunk-4JLJYWJC.js +308 -0
  31. package/dist/chunk-4JLJYWJC.js.map +1 -0
  32. package/dist/chunk-4KNXX6TI.js +29 -0
  33. package/dist/chunk-4KNXX6TI.js.map +1 -0
  34. package/dist/chunk-4LH67P4U.js +17 -0
  35. package/dist/chunk-4LH67P4U.js.map +1 -0
  36. package/dist/chunk-4MF3HKJA.js +94 -0
  37. package/dist/chunk-4MF3HKJA.js.map +1 -0
  38. package/dist/chunk-4MVGAMUA.js +40 -0
  39. package/dist/chunk-4MVGAMUA.js.map +1 -0
  40. package/dist/chunk-4RFHUZXU.js +635 -0
  41. package/dist/chunk-4RFHUZXU.js.map +1 -0
  42. package/dist/chunk-5A432NZJ.js +7 -0
  43. package/dist/chunk-5A432NZJ.js.map +1 -0
  44. package/dist/chunk-5Y7W3XR6.js +356 -0
  45. package/dist/chunk-5Y7W3XR6.js.map +1 -0
  46. package/dist/chunk-6DWFJNIK.js +15 -0
  47. package/dist/chunk-6DWFJNIK.js.map +1 -0
  48. package/dist/chunk-6I7ULIN6.js +15 -0
  49. package/dist/chunk-6I7ULIN6.js.map +1 -0
  50. package/dist/chunk-6XY6ZMMD.js +25 -0
  51. package/dist/chunk-6XY6ZMMD.js.map +1 -0
  52. package/dist/chunk-7B3RYX45.js +63 -0
  53. package/dist/chunk-7B3RYX45.js.map +1 -0
  54. package/dist/chunk-7C3FOSDI.js +1 -0
  55. package/dist/chunk-7C3FOSDI.js.map +1 -0
  56. package/dist/chunk-7KOW6PU6.js +59 -0
  57. package/dist/chunk-7KOW6PU6.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-7YGORYZD.js +112 -0
  61. package/dist/chunk-7YGORYZD.js.map +1 -0
  62. package/dist/chunk-AHV4GDYM.js +63 -0
  63. package/dist/chunk-AHV4GDYM.js.map +1 -0
  64. package/dist/chunk-AQFQ4BYM.js +81 -0
  65. package/dist/chunk-AQFQ4BYM.js.map +1 -0
  66. package/dist/chunk-AS3NAZB6.js +14 -0
  67. package/dist/chunk-AS3NAZB6.js.map +1 -0
  68. package/dist/chunk-BGULBWKJ.js +88 -0
  69. package/dist/chunk-BGULBWKJ.js.map +1 -0
  70. package/dist/chunk-BIO6F7YI.js +17 -0
  71. package/dist/chunk-BIO6F7YI.js.map +1 -0
  72. package/dist/chunk-BOPZWRJK.js +36 -0
  73. package/dist/chunk-BOPZWRJK.js.map +1 -0
  74. package/dist/chunk-BPARRK6F.js +14 -0
  75. package/dist/chunk-BPARRK6F.js.map +1 -0
  76. package/dist/chunk-CO6LUM72.js +59 -0
  77. package/dist/chunk-CO6LUM72.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-DV4RV2DC.js +59 -0
  81. package/dist/chunk-DV4RV2DC.js.map +1 -0
  82. package/dist/chunk-EDKJU5BO.js +11 -0
  83. package/dist/chunk-EDKJU5BO.js.map +1 -0
  84. package/dist/chunk-EO2QPOKH.js +116 -0
  85. package/dist/chunk-EO2QPOKH.js.map +1 -0
  86. package/dist/chunk-EOLLMEAH.js +155 -0
  87. package/dist/chunk-EOLLMEAH.js.map +1 -0
  88. package/dist/chunk-EWYCWP4H.js +14 -0
  89. package/dist/chunk-EWYCWP4H.js.map +1 -0
  90. package/dist/chunk-EXVDJMIY.js +33 -0
  91. package/dist/chunk-EXVDJMIY.js.map +1 -0
  92. package/dist/chunk-FASRXRX5.js +19 -0
  93. package/dist/chunk-FASRXRX5.js.map +1 -0
  94. package/dist/chunk-FBGHYQIZ.js +201 -0
  95. package/dist/chunk-FBGHYQIZ.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-GCYKMF22.js +81 -0
  101. package/dist/chunk-GCYKMF22.js.map +1 -0
  102. package/dist/chunk-GM3RMJIJ.js +92 -0
  103. package/dist/chunk-GM3RMJIJ.js.map +1 -0
  104. package/dist/chunk-GYGNEQSC.js +9 -0
  105. package/dist/chunk-GYGNEQSC.js.map +1 -0
  106. package/dist/chunk-H5NH7KPE.js +21 -0
  107. package/dist/chunk-H5NH7KPE.js.map +1 -0
  108. package/dist/chunk-HNWZFNKP.js +168 -0
  109. package/dist/chunk-HNWZFNKP.js.map +1 -0
  110. package/dist/chunk-HUH73XGI.js +1 -0
  111. package/dist/chunk-HUH73XGI.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-IYNSRIGR.js +122 -0
  123. package/dist/chunk-IYNSRIGR.js.map +1 -0
  124. package/dist/chunk-J37YWU7Y.js +19 -0
  125. package/dist/chunk-J37YWU7Y.js.map +1 -0
  126. package/dist/chunk-J6KZS54B.js +269 -0
  127. package/dist/chunk-J6KZS54B.js.map +1 -0
  128. package/dist/chunk-J6MN42LG.js +19 -0
  129. package/dist/chunk-J6MN42LG.js.map +1 -0
  130. package/dist/chunk-J7JMVS2B.js +53 -0
  131. package/dist/chunk-J7JMVS2B.js.map +1 -0
  132. package/dist/chunk-JRQO2IOF.js +65 -0
  133. package/dist/chunk-JRQO2IOF.js.map +1 -0
  134. package/dist/chunk-JWNHNUYL.js +96 -0
  135. package/dist/chunk-JWNHNUYL.js.map +1 -0
  136. package/dist/chunk-K2I6XIK5.js +122 -0
  137. package/dist/chunk-K2I6XIK5.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-O37C3YE6.js +111 -0
  167. package/dist/chunk-O37C3YE6.js.map +1 -0
  168. package/dist/chunk-OFRRBC7M.js +78 -0
  169. package/dist/chunk-OFRRBC7M.js.map +1 -0
  170. package/dist/chunk-OGIZXGPY.js +222 -0
  171. package/dist/chunk-OGIZXGPY.js.map +1 -0
  172. package/dist/chunk-OKXZ63IA.js +168 -0
  173. package/dist/chunk-OKXZ63IA.js.map +1 -0
  174. package/dist/chunk-OSQRXVG2.js +58 -0
  175. package/dist/chunk-OSQRXVG2.js.map +1 -0
  176. package/dist/chunk-OTDN3OUQ.js +215 -0
  177. package/dist/chunk-OTDN3OUQ.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-RDVTWIYY.js +212 -0
  189. package/dist/chunk-RDVTWIYY.js.map +1 -0
  190. package/dist/chunk-RFH7N6EP.js +36 -0
  191. package/dist/chunk-RFH7N6EP.js.map +1 -0
  192. package/dist/chunk-RHVN6NA7.js +134 -0
  193. package/dist/chunk-RHVN6NA7.js.map +1 -0
  194. package/dist/chunk-S7C6TIIF.js +21 -0
  195. package/dist/chunk-S7C6TIIF.js.map +1 -0
  196. package/dist/chunk-SNQ3TOWP.js +20 -0
  197. package/dist/chunk-SNQ3TOWP.js.map +1 -0
  198. package/dist/chunk-SOVM2VEK.js +14 -0
  199. package/dist/chunk-SOVM2VEK.js.map +1 -0
  200. package/dist/chunk-SQDOBLBP.js +13 -0
  201. package/dist/chunk-SQDOBLBP.js.map +1 -0
  202. package/dist/chunk-SR7F3TJY.js +130 -0
  203. package/dist/chunk-SR7F3TJY.js.map +1 -0
  204. package/dist/chunk-SZVPIHWE.js +129 -0
  205. package/dist/chunk-SZVPIHWE.js.map +1 -0
  206. package/dist/chunk-T4BIIU5E.js +89 -0
  207. package/dist/chunk-T4BIIU5E.js.map +1 -0
  208. package/dist/chunk-T6SCOJF4.js +92 -0
  209. package/dist/chunk-T6SCOJF4.js.map +1 -0
  210. package/dist/chunk-TNXH7BJS.js +48 -0
  211. package/dist/chunk-TNXH7BJS.js.map +1 -0
  212. package/dist/chunk-U64T4YZE.js +9 -0
  213. package/dist/chunk-U64T4YZE.js.map +1 -0
  214. package/dist/chunk-UQ5EHOH2.js +39 -0
  215. package/dist/chunk-UQ5EHOH2.js.map +1 -0
  216. package/dist/chunk-UTN4GBPQ.js +1 -0
  217. package/dist/chunk-UTN4GBPQ.js.map +1 -0
  218. package/dist/chunk-V4AF6DI4.js +16 -0
  219. package/dist/chunk-V4AF6DI4.js.map +1 -0
  220. package/dist/chunk-W72PRNJY.js +126 -0
  221. package/dist/chunk-W72PRNJY.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-WWGYCIJX.js +29 -0
  225. package/dist/chunk-WWGYCIJX.js.map +1 -0
  226. package/dist/chunk-X2GMTYPA.js +50 -0
  227. package/dist/chunk-X2GMTYPA.js.map +1 -0
  228. package/dist/chunk-XCEI7NUH.js +41 -0
  229. package/dist/chunk-XCEI7NUH.js.map +1 -0
  230. package/dist/chunk-Y7GDG744.js +88 -0
  231. package/dist/chunk-Y7GDG744.js.map +1 -0
  232. package/dist/chunk-Y7RRSEOC.js +9 -0
  233. package/dist/chunk-Y7RRSEOC.js.map +1 -0
  234. package/dist/chunk-YLPAPPLW.js +75 -0
  235. package/dist/chunk-YLPAPPLW.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/runtime/analytics/index.js +8 -41
  249. package/dist/runtime/analytics/index.js.map +1 -1
  250. package/dist/runtime/analytics/types.js +8 -41
  251. package/dist/runtime/analytics/types.js.map +1 -1
  252. package/dist/runtime/base-classes/activity-entity-repository.js +6 -312
  253. package/dist/runtime/base-classes/activity-entity-repository.js.map +1 -1
  254. package/dist/runtime/base-classes/activity-entity-service.js +6 -212
  255. package/dist/runtime/base-classes/activity-entity-service.js.map +1 -1
  256. package/dist/runtime/base-classes/base-read-use-cases.js +5 -27
  257. package/dist/runtime/base-classes/base-read-use-cases.js.map +1 -1
  258. package/dist/runtime/base-classes/base-repository.js +5 -277
  259. package/dist/runtime/base-classes/base-repository.js.map +1 -1
  260. package/dist/runtime/base-classes/base-service.js +5 -184
  261. package/dist/runtime/base-classes/base-service.js.map +1 -1
  262. package/dist/runtime/base-classes/index.js +59 -1076
  263. package/dist/runtime/base-classes/index.js.map +1 -1
  264. package/dist/runtime/base-classes/integrated-entity-repository.js +6 -486
  265. package/dist/runtime/base-classes/integrated-entity-repository.js.map +1 -1
  266. package/dist/runtime/base-classes/integrated-entity-service.js +6 -213
  267. package/dist/runtime/base-classes/integrated-entity-service.js.map +1 -1
  268. package/dist/runtime/base-classes/junction-integration-repository.js +8 -448
  269. package/dist/runtime/base-classes/junction-integration-repository.js.map +1 -1
  270. package/dist/runtime/base-classes/knowledge-entity-repository.js +6 -283
  271. package/dist/runtime/base-classes/knowledge-entity-repository.js.map +1 -1
  272. package/dist/runtime/base-classes/knowledge-entity-service.js +6 -190
  273. package/dist/runtime/base-classes/knowledge-entity-service.js.map +1 -1
  274. package/dist/runtime/base-classes/lifecycle-events.js +8 -70
  275. package/dist/runtime/base-classes/lifecycle-events.js.map +1 -1
  276. package/dist/runtime/base-classes/metadata-entity-repository.js +6 -330
  277. package/dist/runtime/base-classes/metadata-entity-repository.js.map +1 -1
  278. package/dist/runtime/base-classes/metadata-entity-service.js +6 -212
  279. package/dist/runtime/base-classes/metadata-entity-service.js.map +1 -1
  280. package/dist/runtime/base-classes/tenant-context.js +10 -36
  281. package/dist/runtime/base-classes/tenant-context.js.map +1 -1
  282. package/dist/runtime/base-classes/with-analytics.js +4 -7
  283. package/dist/runtime/base-classes/with-analytics.js.map +1 -1
  284. package/dist/runtime/constants/tokens.js +5 -3
  285. package/dist/runtime/constants/tokens.js.map +1 -1
  286. package/dist/runtime/eav-helpers.js +2 -0
  287. package/dist/runtime/eav-helpers.js.map +1 -1
  288. package/dist/runtime/pipes/zod-validation.pipe.js +3 -10
  289. package/dist/runtime/pipes/zod-validation.pipe.js.map +1 -1
  290. package/dist/runtime/shared/openapi/error-response.dto.js +5 -8
  291. package/dist/runtime/shared/openapi/error-response.dto.js.map +1 -1
  292. package/dist/runtime/shared/openapi/errors.js +5 -19
  293. package/dist/runtime/shared/openapi/errors.js.map +1 -1
  294. package/dist/runtime/shared/openapi/index.js +15 -106
  295. package/dist/runtime/shared/openapi/index.js.map +1 -1
  296. package/dist/runtime/shared/openapi/registry.js +6 -103
  297. package/dist/runtime/shared/openapi/registry.js.map +1 -1
  298. package/dist/runtime/shared/openapi/registry.tokens.js +4 -2
  299. package/dist/runtime/shared/openapi/registry.tokens.js.map +1 -1
  300. package/dist/runtime/subsystems/analytics/analytics.module.js +8 -117
  301. package/dist/runtime/subsystems/analytics/analytics.module.js.map +1 -1
  302. package/dist/runtime/subsystems/analytics/analytics.tokens.js +7 -8
  303. package/dist/runtime/subsystems/analytics/analytics.tokens.js.map +1 -1
  304. package/dist/runtime/subsystems/analytics/cube-backend.js +6 -71
  305. package/dist/runtime/subsystems/analytics/cube-backend.js.map +1 -1
  306. package/dist/runtime/subsystems/analytics/index.js +16 -117
  307. package/dist/runtime/subsystems/analytics/index.js.map +1 -1
  308. package/dist/runtime/subsystems/analytics/noop-backend.js +4 -21
  309. package/dist/runtime/subsystems/analytics/noop-backend.js.map +1 -1
  310. package/dist/runtime/subsystems/auth/auth-oauth-state.schema.js +4 -8
  311. package/dist/runtime/subsystems/auth/auth-oauth-state.schema.js.map +1 -1
  312. package/dist/runtime/subsystems/auth/auth.module.js +12 -359
  313. package/dist/runtime/subsystems/auth/auth.module.js.map +1 -1
  314. package/dist/runtime/subsystems/auth/auth.tokens.js +12 -13
  315. package/dist/runtime/subsystems/auth/auth.tokens.js.map +1 -1
  316. package/dist/runtime/subsystems/auth/backends/encryption-key/env.js +4 -49
  317. package/dist/runtime/subsystems/auth/backends/encryption-key/env.js.map +1 -1
  318. package/dist/runtime/subsystems/auth/backends/state-store.drizzle-backend.js +6 -64
  319. package/dist/runtime/subsystems/auth/backends/state-store.drizzle-backend.js.map +1 -1
  320. package/dist/runtime/subsystems/auth/backends/state-store.memory-backend.js +5 -47
  321. package/dist/runtime/subsystems/auth/backends/state-store.memory-backend.js.map +1 -1
  322. package/dist/runtime/subsystems/auth/controllers/auth.controller.js +5 -139
  323. package/dist/runtime/subsystems/auth/controllers/auth.controller.js.map +1 -1
  324. package/dist/runtime/subsystems/auth/index.js +53 -542
  325. package/dist/runtime/subsystems/auth/index.js.map +1 -1
  326. package/dist/runtime/subsystems/auth/middleware/requester-context.js +9 -65
  327. package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -1
  328. package/dist/runtime/subsystems/auth/protocols/oauth-state-store.js +4 -9
  329. package/dist/runtime/subsystems/auth/protocols/oauth-state-store.js.map +1 -1
  330. package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js +4 -15
  331. package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js.map +1 -1
  332. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js +5 -104
  333. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js.map +1 -1
  334. package/dist/runtime/subsystems/auth/runtime/session-expired.error.js +5 -16
  335. package/dist/runtime/subsystems/auth/runtime/session-expired.error.js.map +1 -1
  336. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js +5 -29
  337. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js.map +1 -1
  338. package/dist/runtime/subsystems/bridge/assert-tenant-id.js +5 -18
  339. package/dist/runtime/subsystems/bridge/assert-tenant-id.js.map +1 -1
  340. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js +12 -184
  341. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js.map +1 -1
  342. package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js +10 -448
  343. package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js.map +1 -1
  344. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js +5 -126
  345. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js.map +1 -1
  346. package/dist/runtime/subsystems/bridge/bridge-delivery.schema.js +6 -308
  347. package/dist/runtime/subsystems/bridge/bridge-delivery.schema.js.map +1 -1
  348. package/dist/runtime/subsystems/bridge/bridge-errors.js +6 -35
  349. package/dist/runtime/subsystems/bridge/bridge-errors.js.map +1 -1
  350. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +14 -606
  351. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js.map +1 -1
  352. package/dist/runtime/subsystems/bridge/bridge.module.js +35 -3476
  353. package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
  354. package/dist/runtime/subsystems/bridge/bridge.tokens.js +9 -7
  355. package/dist/runtime/subsystems/bridge/bridge.tokens.js.map +1 -1
  356. package/dist/runtime/subsystems/bridge/event-flow.service.js +11 -137
  357. package/dist/runtime/subsystems/bridge/event-flow.service.js.map +1 -1
  358. package/dist/runtime/subsystems/bridge/generated/registry.js +4 -2
  359. package/dist/runtime/subsystems/bridge/generated/registry.js.map +1 -1
  360. package/dist/runtime/subsystems/bridge/index.js +60 -3470
  361. package/dist/runtime/subsystems/bridge/index.js.map +1 -1
  362. package/dist/runtime/subsystems/bridge/reserved-pools.js +4 -6
  363. package/dist/runtime/subsystems/bridge/reserved-pools.js.map +1 -1
  364. package/dist/runtime/subsystems/cache/cache.drizzle-backend.js +10 -133
  365. package/dist/runtime/subsystems/cache/cache.drizzle-backend.js.map +1 -1
  366. package/dist/runtime/subsystems/cache/cache.memory-backend.js +6 -101
  367. package/dist/runtime/subsystems/cache/cache.memory-backend.js.map +1 -1
  368. package/dist/runtime/subsystems/cache/cache.module.js +10 -278
  369. package/dist/runtime/subsystems/cache/cache.module.js.map +1 -1
  370. package/dist/runtime/subsystems/cache/cache.schema.js +4 -14
  371. package/dist/runtime/subsystems/cache/cache.schema.js.map +1 -1
  372. package/dist/runtime/subsystems/cache/cache.tokens.js +6 -7
  373. package/dist/runtime/subsystems/cache/cache.tokens.js.map +1 -1
  374. package/dist/runtime/subsystems/cache/index.js +20 -278
  375. package/dist/runtime/subsystems/cache/index.js.map +1 -1
  376. package/dist/runtime/subsystems/events/domain-events.schema.js +3 -72
  377. package/dist/runtime/subsystems/events/domain-events.schema.js.map +1 -1
  378. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +9 -413
  379. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
  380. package/dist/runtime/subsystems/events/event-bus.memory-backend.js +7 -235
  381. package/dist/runtime/subsystems/events/event-bus.memory-backend.js.map +1 -1
  382. package/dist/runtime/subsystems/events/event-bus.redis-backend.js +8 -20
  383. package/dist/runtime/subsystems/events/event-bus.redis-backend.js.map +1 -1
  384. package/dist/runtime/subsystems/events/event-keyset-cursor.js +8 -30
  385. package/dist/runtime/subsystems/events/event-keyset-cursor.js.map +1 -1
  386. package/dist/runtime/subsystems/events/event-read.protocol.js +2 -0
  387. package/dist/runtime/subsystems/events/event-read.protocol.js.map +1 -1
  388. package/dist/runtime/subsystems/events/events-errors.js +4 -11
  389. package/dist/runtime/subsystems/events/events-errors.js.map +1 -1
  390. package/dist/runtime/subsystems/events/events.module.js +15 -949
  391. package/dist/runtime/subsystems/events/events.module.js.map +1 -1
  392. package/dist/runtime/subsystems/events/events.tokens.js +10 -11
  393. package/dist/runtime/subsystems/events/events.tokens.js.map +1 -1
  394. package/dist/runtime/subsystems/events/generated/bus.js +9 -240
  395. package/dist/runtime/subsystems/events/generated/bus.js.map +1 -1
  396. package/dist/runtime/subsystems/events/generated/index.js +23 -240
  397. package/dist/runtime/subsystems/events/generated/index.js.map +1 -1
  398. package/dist/runtime/subsystems/events/generated/registry.js +5 -82
  399. package/dist/runtime/subsystems/events/generated/registry.js.map +1 -1
  400. package/dist/runtime/subsystems/events/generated/schemas.js +12 -52
  401. package/dist/runtime/subsystems/events/generated/schemas.js.map +1 -1
  402. package/dist/runtime/subsystems/events/generated/types.js +1 -0
  403. package/dist/runtime/subsystems/events/index.js +32 -949
  404. package/dist/runtime/subsystems/events/index.js.map +1 -1
  405. package/dist/runtime/subsystems/index.d.ts +5 -1
  406. package/dist/runtime/subsystems/index.js +182 -5912
  407. package/dist/runtime/subsystems/index.js.map +1 -1
  408. package/dist/runtime/subsystems/integration/build-change-source.js +6 -178
  409. package/dist/runtime/subsystems/integration/build-change-source.js.map +1 -1
  410. package/dist/runtime/subsystems/integration/deep-equal.differ.js +4 -109
  411. package/dist/runtime/subsystems/integration/deep-equal.differ.js.map +1 -1
  412. package/dist/runtime/subsystems/integration/detection-config.schema.js +11 -78
  413. package/dist/runtime/subsystems/integration/detection-config.schema.js.map +1 -1
  414. package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.js +5 -30
  415. package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.js.map +1 -1
  416. package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.js +4 -9
  417. package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.js.map +1 -1
  418. package/dist/runtime/subsystems/integration/execute-integration.use-case.js +6 -239
  419. package/dist/runtime/subsystems/integration/execute-integration.use-case.js.map +1 -1
  420. package/dist/runtime/subsystems/integration/incremental-read.js +5 -144
  421. package/dist/runtime/subsystems/integration/incremental-read.js.map +1 -1
  422. package/dist/runtime/subsystems/integration/index.js +83 -1352
  423. package/dist/runtime/subsystems/integration/index.js.map +1 -1
  424. package/dist/runtime/subsystems/integration/integration-audit.schema.js +10 -155
  425. package/dist/runtime/subsystems/integration/integration-audit.schema.js.map +1 -1
  426. package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js +7 -270
  427. package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js.map +1 -1
  428. package/dist/runtime/subsystems/integration/integration-cursor-store.memory-backend.js +4 -65
  429. package/dist/runtime/subsystems/integration/integration-cursor-store.memory-backend.js.map +1 -1
  430. package/dist/runtime/subsystems/integration/integration-errors.js +5 -15
  431. package/dist/runtime/subsystems/integration/integration-errors.js.map +1 -1
  432. package/dist/runtime/subsystems/integration/integration-field-diff.protocol.js +5 -7
  433. package/dist/runtime/subsystems/integration/integration-field-diff.protocol.js.map +1 -1
  434. package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js +8 -303
  435. package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js.map +1 -1
  436. package/dist/runtime/subsystems/integration/integration-run-recorder.memory-backend.js +5 -125
  437. package/dist/runtime/subsystems/integration/integration-run-recorder.memory-backend.js.map +1 -1
  438. package/dist/runtime/subsystems/integration/integration.module.js +13 -700
  439. package/dist/runtime/subsystems/integration/integration.module.js.map +1 -1
  440. package/dist/runtime/subsystems/integration/integration.tokens.js +11 -9
  441. package/dist/runtime/subsystems/integration/integration.tokens.js.map +1 -1
  442. package/dist/runtime/subsystems/integration/loopback.middleware.js +4 -16
  443. package/dist/runtime/subsystems/integration/loopback.middleware.js.map +1 -1
  444. package/dist/runtime/subsystems/integration/poll-change-source.d.ts +1 -1
  445. package/dist/runtime/subsystems/integration/poll-change-source.js +4 -89
  446. package/dist/runtime/subsystems/integration/poll-change-source.js.map +1 -1
  447. package/dist/runtime/subsystems/integration/webhook-change-source.d.ts +4 -3
  448. package/dist/runtime/subsystems/integration/webhook-change-source.js +4 -70
  449. package/dist/runtime/subsystems/integration/webhook-change-source.js.map +1 -1
  450. package/dist/runtime/subsystems/jobs/bullmq.config.js +9 -140
  451. package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -1
  452. package/dist/runtime/subsystems/jobs/index.js +88 -2691
  453. package/dist/runtime/subsystems/jobs/index.js.map +1 -1
  454. package/dist/runtime/subsystems/jobs/job-handler.base.js +10 -49
  455. package/dist/runtime/subsystems/jobs/job-handler.base.js.map +1 -1
  456. package/dist/runtime/subsystems/jobs/job-orchestration.schema.js +13 -152
  457. package/dist/runtime/subsystems/jobs/job-orchestration.schema.js.map +1 -1
  458. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +36 -699
  459. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
  460. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +10 -564
  461. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js.map +1 -1
  462. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +10 -824
  463. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js.map +1 -1
  464. package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.js +9 -51
  465. package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.js.map +1 -1
  466. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +9 -416
  467. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js.map +1 -1
  468. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +9 -290
  469. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js.map +1 -1
  470. package/dist/runtime/subsystems/jobs/job-step-service.drizzle-backend.js +5 -213
  471. package/dist/runtime/subsystems/jobs/job-step-service.drizzle-backend.js.map +1 -1
  472. package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js +5 -131
  473. package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js.map +1 -1
  474. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +9 -175
  475. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -1
  476. package/dist/runtime/subsystems/jobs/job-worker.js +14 -613
  477. package/dist/runtime/subsystems/jobs/job-worker.js.map +1 -1
  478. package/dist/runtime/subsystems/jobs/job-worker.module.js +23 -2647
  479. package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
  480. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +19 -1897
  481. package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
  482. package/dist/runtime/subsystems/jobs/jobs-domain.tokens.js +8 -9
  483. package/dist/runtime/subsystems/jobs/jobs-domain.tokens.js.map +1 -1
  484. package/dist/runtime/subsystems/jobs/jobs-errors.js +10 -78
  485. package/dist/runtime/subsystems/jobs/jobs-errors.js.map +1 -1
  486. package/dist/runtime/subsystems/jobs/memory-job-store.js +4 -15
  487. package/dist/runtime/subsystems/jobs/memory-job-store.js.map +1 -1
  488. package/dist/runtime/subsystems/jobs/pool-config.loader.js +9 -124
  489. package/dist/runtime/subsystems/jobs/pool-config.loader.js.map +1 -1
  490. package/dist/runtime/subsystems/observability/index.js +21 -310
  491. package/dist/runtime/subsystems/observability/index.js.map +1 -1
  492. package/dist/runtime/subsystems/observability/observability-errors.js +4 -9
  493. package/dist/runtime/subsystems/observability/observability-errors.js.map +1 -1
  494. package/dist/runtime/subsystems/observability/observability.module.js +11 -300
  495. package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
  496. package/dist/runtime/subsystems/observability/observability.service.js +9 -197
  497. package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
  498. package/dist/runtime/subsystems/observability/observability.tokens.js +5 -3
  499. package/dist/runtime/subsystems/observability/observability.tokens.js.map +1 -1
  500. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.js +4 -84
  501. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.js.map +1 -1
  502. package/dist/runtime/subsystems/observability/reporters/index.js +5 -84
  503. package/dist/runtime/subsystems/observability/reporters/index.js.map +1 -1
  504. package/dist/runtime/subsystems/storage/index.js +15 -200
  505. package/dist/runtime/subsystems/storage/index.js.map +1 -1
  506. package/dist/runtime/subsystems/storage/storage.local-backend.js +4 -103
  507. package/dist/runtime/subsystems/storage/storage.local-backend.js.map +1 -1
  508. package/dist/runtime/subsystems/storage/storage.memory-backend.js +5 -68
  509. package/dist/runtime/subsystems/storage/storage.memory-backend.js.map +1 -1
  510. package/dist/runtime/subsystems/storage/storage.module.js +8 -200
  511. package/dist/runtime/subsystems/storage/storage.module.js.map +1 -1
  512. package/dist/runtime/subsystems/storage/storage.tokens.js +5 -6
  513. package/dist/runtime/subsystems/storage/storage.tokens.js.map +1 -1
  514. package/dist/runtime/subsystems/storage/storage.utils.js +4 -14
  515. package/dist/runtime/subsystems/storage/storage.utils.js.map +1 -1
  516. package/dist/runtime/subsystems/token-key.js +5 -3
  517. package/dist/runtime/subsystems/token-key.js.map +1 -1
  518. package/dist/src/cli/index.js +637 -5454
  519. package/dist/src/cli/index.js.map +1 -1
  520. package/dist/src/index.js +68 -4170
  521. package/dist/src/index.js.map +1 -1
  522. package/package.json +1 -1
  523. package/runtime/subsystems/bridge/bridge-outbox-drain-hook.ts +44 -21
  524. package/runtime/subsystems/index.ts +27 -0
  525. package/runtime/subsystems/integration/poll-change-source.ts +10 -7
  526. package/runtime/subsystems/integration/webhook-change-source.ts +12 -8
  527. package/runtime/subsystems/jobs/job-worker.ts +17 -11
package/CHANGELOG.md CHANGED
@@ -4,6 +4,91 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.15.3] — 2026-06-03
8
+
9
+ Package-mode **inbound webhook drain** — the first real exercise of
10
+ `WebhookChangeSource` by a `runtime: package` consumer (swe-brain's Slack
11
+ inbound pipeline-parity drain, ADR-0009 §6). One latent transposition this path
12
+ exercises; the fix is framework-only.
13
+
14
+ ### Fixed
15
+
16
+ - **`WebhookChangeSource` (and the identically-shaped `PollChangeSource`) now
17
+ derive `Change<T>.externalId` from the mapping `source`, not `target`.** Both
18
+ primitives located the `DetectionConfig` mapping entry with `target ===
19
+ 'external_id'` correctly, then read the emitted record off
20
+ `mapping.target` — a transposition. Mapping semantics are `{ source: <field on
21
+ the emitted record>, target: <canonical column> }`, and `fetch()` reads
22
+ `record[externalIdSourceField]` off the emitted record, so it must use
23
+ `.source`. The two diverge only when the canonical record is vendor-neutral
24
+ camelCase (`source: 'externalId'` → `target: 'external_id'`): such a consumer
25
+ hit `record missing string 'external_id'` and the primitive was unusable. The
26
+ original unit fixtures masked it by keying records `external_id` (== the
27
+ target). Regression tests now cover the camelCase consumer shape directly.
28
+
29
+ ### Added
30
+
31
+ - **Webhook/poll/detection symbols re-exported from
32
+ `@pattern-stack/codegen/subsystems`.** `WebhookChangeSource`,
33
+ `WebhookChangeSourceOptions`, `WebhookFetchCallback`, `WebhookFetchContext`,
34
+ `WebhookCursor`, `buildChangeSource`, `DetectionConfigSchema`,
35
+ `DetectionConfig` (+ poll equivalents) were previously reachable only via the
36
+ deep `.../integration/index` path; they now ride the public barrel alongside
37
+ the curated `IncrementalReadBase` / `ExecuteIntegrationUseCase` forwards.
38
+
39
+ ## [0.15.2] — 2026-06-03
40
+
41
+ Package-mode **bridge *delivery*** — the first time a `runtime: package` consumer
42
+ (ADR-037) drives a real event→bridge→job round-trip end to end (webhook →
43
+ `domain_events` outbox → `bridge_delivery` → wrapper `@framework/bridge_delivery`
44
+ run → user `@JobHandler`). Three latent defects only this path exercises (codegen's
45
+ own tests are vendored — a single `tsc` compilation, a single in-memory Map, and a
46
+ mocked `tx` that never touches a real FK — so none of them ever surfaced). All three
47
+ fixes are framework-only; vendored mode is unaffected.
48
+
49
+ ### Fixed
50
+
51
+ - **Stateful module-singletons are no longer duplicated across dist entry
52
+ chunks** (`tsup.config.ts`: `splitting: false` → `splitting: true`). The
53
+ published bundle is ESM and multi-entry — `runtime/**/*.ts` each emit a physical
54
+ `dist/runtime/.../x.js` so the `./runtime/*` wildcard `exports` map resolves 1:1.
55
+ With splitting off, esbuild INLINED every shared module into each importing entry
56
+ chunk. Harmless for pure functions, but a correctness bug for a stateful
57
+ singleton: `runtime/subsystems/jobs/job-handler.base`'s `JOB_HANDLER_REGISTRY`
58
+ Map (and its `HandlerRegistry` read facade), which the `@JobHandler` decorator
59
+ mutates at import time, got a **second copy** inlined into the `bridge/*` chunk.
60
+ The framework's own `@JobHandler('@framework/bridge_delivery')`
61
+ (`BridgeDeliveryHandler`, bridge chunk) registered into the BRIDGE copy while the
62
+ jobs `JobWorker` read the JOBS copy → the worker never upserted the wrapper's
63
+ `job` row → the bridge's outbox-drain couldn't spawn the wrapper `job_run` (its
64
+ `job_type` FKs `job(type)`), so the `bridge_delivery` insert violated its
65
+ `wrapper_run_id → job_run` FK and looped forever. `splitting: true` hoists each
66
+ shared module into a SINGLE shared chunk that every entry imports, collapsing the
67
+ registry back to one Map. The named per-entry output files are preserved (each
68
+ entry stays a physical `dist/runtime/.../x.js`), so the wildcard `exports` map and
69
+ the deep consumer subpaths (`…/subsystems/jobs/index`, `…/bridge/index`,
70
+ `./subsystems`) still resolve. ESM-only build ⇒ no CJS output to regress. Guarded
71
+ by a new dist-grep regression test.
72
+ - **`BridgeOutboxDrainHook` now inserts the wrapper `job_run` BEFORE the
73
+ `bridge_delivery` that references it** (`bridge-outbox-drain-hook.ts`).
74
+ `bridge_delivery.wrapper_run_id → job_run(id)` is a plain (non-deferrable) FK, so
75
+ the referenced wrapper run must exist before the delivery row is inserted —
76
+ otherwise Postgres rejects the delivery insert immediately. The drain previously
77
+ inserted the delivery (with `wrapper_run_id` set) first, then the wrapper run; the
78
+ unit tests mocked `tx`, so the ordering was never validated against a real FK.
79
+ Idempotency is preserved: the delivery keeps its `ON CONFLICT (event_id,
80
+ trigger_id) DO NOTHING RETURNING`, and when it conflicts (outbox replay or
81
+ facade-eager Case B) the speculatively-inserted wrapper run is DELETEd in the same
82
+ tx, so a skipped delivery leaves no orphan `job_run`.
83
+ - **`JobWorker.nextStepSeq` no longer array-destructures the raw `db.execute()`
84
+ result** (`job-worker.ts`). `db.execute(sql\`…\`)` is driver-shape-dependent and
85
+ not uniformly array-iterable: `drizzle-orm/node-postgres` returns the pg `Result`
86
+ OBJECT (`{ rows, rowCount, … }`), so `const [row] = await this.db.execute(...)`
87
+ threw `TypeError: {} is not iterable`. Every wrapper `@framework/bridge_delivery`
88
+ run calls `ctx.step` → `nextStepSeq`, so the delivery failed on every attempt. The
89
+ result is now normalised to a row array before reading, tolerating both the
90
+ node-postgres `{ rows }` shape and a plain-array shape. Guarded by a new unit test.
91
+
7
92
  ## [0.15.1] — 2026-06-02
8
93
 
9
94
  Package-mode **bridge/trigger event typing** — the fourth and final package-mode
@@ -0,0 +1,84 @@
1
+ import {
2
+ DrizzleCacheService
3
+ } from "./chunk-7YGORYZD.js";
4
+ import {
5
+ MemoryCacheService
6
+ } from "./chunk-IF5I3DAA.js";
7
+ import {
8
+ CACHE,
9
+ CACHE_DEFAULT_TTL
10
+ } from "./chunk-L6FTY45T.js";
11
+ import {
12
+ DRIZZLE
13
+ } from "./chunk-U64T4YZE.js";
14
+ import {
15
+ __decorateClass
16
+ } from "./chunk-2E224ZSN.js";
17
+
18
+ // runtime/subsystems/cache/cache.module.ts
19
+ import { Module } from "@nestjs/common";
20
+ var CACHE_MODULE_OPTIONS = "CACHE_MODULE_OPTIONS";
21
+ function buildCacheAsync(options, db) {
22
+ const defaultTtl = options.defaultTtl ?? null;
23
+ if (options.backend === "drizzle") {
24
+ if (!db) {
25
+ throw new Error(
26
+ "CacheModule.forRootAsync: backend: 'drizzle' selected but DRIZZLE provider is not available. Ensure DatabaseModule (or another provider exposing DRIZZLE) is imported before CacheModule.forRootAsync."
27
+ );
28
+ }
29
+ return new DrizzleCacheService(db, defaultTtl);
30
+ }
31
+ return new MemoryCacheService(defaultTtl);
32
+ }
33
+ var CacheModule = class {
34
+ static forRootAsync(asyncOptions) {
35
+ return {
36
+ module: CacheModule,
37
+ global: true,
38
+ imports: asyncOptions.imports ?? [],
39
+ providers: [
40
+ {
41
+ provide: CACHE_MODULE_OPTIONS,
42
+ useFactory: asyncOptions.useFactory,
43
+ inject: asyncOptions.inject ?? []
44
+ },
45
+ {
46
+ provide: CACHE,
47
+ useFactory: (options, db) => buildCacheAsync(options, db),
48
+ inject: [CACHE_MODULE_OPTIONS, { token: DRIZZLE, optional: true }]
49
+ },
50
+ // Alias the concrete classes to CACHE for typed injection.
51
+ { provide: DrizzleCacheService, useExisting: CACHE },
52
+ { provide: MemoryCacheService, useExisting: CACHE }
53
+ ],
54
+ exports: [CACHE]
55
+ };
56
+ }
57
+ static forRoot(options = { backend: "drizzle" }) {
58
+ const ConcreteClass = options.backend === "drizzle" ? DrizzleCacheService : MemoryCacheService;
59
+ const providers = options.defaultTtl !== void 0 ? [
60
+ // Register the concrete class as the canonical instance
61
+ ConcreteClass,
62
+ { provide: CACHE_DEFAULT_TTL, useValue: options.defaultTtl },
63
+ // CACHE token points to the same instance — no duplicate
64
+ { provide: CACHE, useExisting: ConcreteClass }
65
+ ] : [
66
+ ConcreteClass,
67
+ { provide: CACHE, useExisting: ConcreteClass }
68
+ ];
69
+ return {
70
+ module: CacheModule,
71
+ global: true,
72
+ providers,
73
+ exports: [CACHE]
74
+ };
75
+ }
76
+ };
77
+ CacheModule = __decorateClass([
78
+ Module({})
79
+ ], CacheModule);
80
+
81
+ export {
82
+ CacheModule
83
+ };
84
+ //# sourceMappingURL=chunk-27ETSJ2X.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/subsystems/cache/cache.module.ts"],"sourcesContent":["/**\n * CacheModule — DynamicModule factory for the cache subsystem.\n *\n * Usage in AppModule:\n * ```typescript\n * CacheModule.forRoot({ backend: 'drizzle', defaultTtl: 300 })\n * ```\n *\n * Usage in tests:\n * ```typescript\n * CacheModule.forRoot({ backend: 'memory' })\n * ```\n *\n * `global: true` means any module that needs ICacheService can inject CACHE\n * directly without importing CacheModule. Register once in AppModule.\n *\n * The drizzle backend requires DRIZZLE to be provided globally (e.g., via DatabaseModule).\n *\n * Async configuration (`forRootAsync`):\n * The async factory returns `CacheModuleOptions`; the CACHE provider then\n * receives DRIZZLE (for the drizzle backend) through Nest DI rather than\n * hand-constructing with `null` — see issue #108 which flagged the same\n * shape in `EventsModule.forRootAsync`. DRIZZLE is injected as optional\n * so memory-backend consumers are not required to wire DatabaseModule.\n */\nimport { Module, type DynamicModule } from '@nestjs/common';\nimport { CACHE, CACHE_DEFAULT_TTL } from './cache.tokens';\nimport { DRIZZLE } from '../../constants/tokens';\nimport type { DrizzleClient } from '../../types/drizzle';\nimport { DrizzleCacheService } from './cache.drizzle-backend';\nimport { MemoryCacheService } from './cache.memory-backend';\n\nexport interface CacheModuleOptions {\n backend: 'drizzle' | 'memory';\n /** Default TTL in seconds for entries that don't specify their own TTL. Null = no expiry. */\n defaultTtl?: number;\n}\n\nexport interface CacheModuleAsyncOptions {\n useFactory: (...args: unknown[]) => Promise<CacheModuleOptions> | CacheModuleOptions;\n inject?: unknown[];\n imports?: unknown[];\n}\n\n/** String token for the resolved CacheModuleOptions in the async path. */\nconst CACHE_MODULE_OPTIONS = 'CACHE_MODULE_OPTIONS' as const;\n\nfunction buildCacheAsync(\n options: CacheModuleOptions,\n db: DrizzleClient | null,\n): DrizzleCacheService | MemoryCacheService {\n const defaultTtl = options.defaultTtl ?? null;\n if (options.backend === 'drizzle') {\n if (!db) {\n throw new Error(\n \"CacheModule.forRootAsync: backend: 'drizzle' selected but DRIZZLE provider is not available. \" +\n 'Ensure DatabaseModule (or another provider exposing DRIZZLE) is imported before CacheModule.forRootAsync.',\n );\n }\n return new DrizzleCacheService(db, defaultTtl);\n }\n return new MemoryCacheService(defaultTtl);\n}\n\n@Module({})\nexport class CacheModule {\n static forRootAsync(asyncOptions: CacheModuleAsyncOptions): DynamicModule {\n return {\n module: CacheModule,\n global: true,\n imports: (asyncOptions.imports ?? []) as Parameters<typeof Module>[0]['imports'],\n providers: [\n {\n provide: CACHE_MODULE_OPTIONS,\n useFactory: asyncOptions.useFactory,\n inject: (asyncOptions.inject ?? []) as (string | symbol | Function)[],\n },\n {\n provide: CACHE,\n useFactory: (options: CacheModuleOptions, db: DrizzleClient | null) =>\n buildCacheAsync(options, db),\n inject: [CACHE_MODULE_OPTIONS, { token: DRIZZLE, optional: true }],\n },\n // Alias the concrete classes to CACHE for typed injection.\n { provide: DrizzleCacheService, useExisting: CACHE },\n { provide: MemoryCacheService, useExisting: CACHE },\n ],\n exports: [CACHE],\n };\n }\n\n static forRoot(options: CacheModuleOptions = { backend: 'drizzle' }): DynamicModule {\n const ConcreteClass = options.backend === 'drizzle' ? DrizzleCacheService : MemoryCacheService;\n\n const providers = options.defaultTtl !== undefined\n ? [\n // Register the concrete class as the canonical instance\n ConcreteClass,\n { provide: CACHE_DEFAULT_TTL, useValue: options.defaultTtl },\n // CACHE token points to the same instance — no duplicate\n { provide: CACHE, useExisting: ConcreteClass },\n ]\n : [\n ConcreteClass,\n { provide: CACHE, useExisting: ConcreteClass },\n ];\n\n return {\n module: CacheModule,\n global: true,\n providers,\n exports: [CACHE],\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,SAAS,cAAkC;AAoB3C,IAAM,uBAAuB;AAE7B,SAAS,gBACP,SACA,IAC0C;AAC1C,QAAM,aAAa,QAAQ,cAAc;AACzC,MAAI,QAAQ,YAAY,WAAW;AACjC,QAAI,CAAC,IAAI;AACP,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,WAAO,IAAI,oBAAoB,IAAI,UAAU;AAAA,EAC/C;AACA,SAAO,IAAI,mBAAmB,UAAU;AAC1C;AAGO,IAAM,cAAN,MAAkB;AAAA,EACvB,OAAO,aAAa,cAAsD;AACxE,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAU,aAAa,WAAW,CAAC;AAAA,MACnC,WAAW;AAAA,QACT;AAAA,UACE,SAAS;AAAA,UACT,YAAY,aAAa;AAAA,UACzB,QAAS,aAAa,UAAU,CAAC;AAAA,QACnC;AAAA,QACA;AAAA,UACE,SAAS;AAAA,UACT,YAAY,CAAC,SAA6B,OACxC,gBAAgB,SAAS,EAAE;AAAA,UAC7B,QAAQ,CAAC,sBAAsB,EAAE,OAAO,SAAS,UAAU,KAAK,CAAC;AAAA,QACnE;AAAA;AAAA,QAEA,EAAE,SAAS,qBAAqB,aAAa,MAAM;AAAA,QACnD,EAAE,SAAS,oBAAoB,aAAa,MAAM;AAAA,MACpD;AAAA,MACA,SAAS,CAAC,KAAK;AAAA,IACjB;AAAA,EACF;AAAA,EAEA,OAAO,QAAQ,UAA8B,EAAE,SAAS,UAAU,GAAkB;AAClF,UAAM,gBAAgB,QAAQ,YAAY,YAAY,sBAAsB;AAE5E,UAAM,YAAY,QAAQ,eAAe,SACrC;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,SAAS,mBAAmB,UAAU,QAAQ,WAAW;AAAA;AAAA,MAE3D,EAAE,SAAS,OAAO,aAAa,cAAc;AAAA,IAC/C,IACA;AAAA,MACE;AAAA,MACA,EAAE,SAAS,OAAO,aAAa,cAAc;AAAA,IAC/C;AAEJ,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,SAAS,CAAC,KAAK;AAAA,IACjB;AAAA,EACF;AACF;AAjDa,cAAN;AAAA,EADN,OAAO,CAAC,CAAC;AAAA,GACG;","names":[]}
@@ -0,0 +1,20 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __decorateClass = (decorators, target, key, kind) => {
5
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
6
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
7
+ if (decorator = decorators[i])
8
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
9
+ if (kind && result) __defProp(target, key, result);
10
+ return result;
11
+ };
12
+ var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
13
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
14
+
15
+ export {
16
+ __decorateClass,
17
+ __decorateParam,
18
+ __publicField
19
+ };
20
+ //# sourceMappingURL=chunk-2E224ZSN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,179 @@
1
+ import {
2
+ BaseRepository
3
+ } from "./chunk-J6KZS54B.js";
4
+
5
+ // runtime/base-classes/junction-integration-repository.ts
6
+ import { and, eq } from "drizzle-orm";
7
+ var JunctionIntegrationRepository = class extends BaseRepository {
8
+ /**
9
+ * Upsert ONE junction row by its composite identity, in a single transaction:
10
+ * 1. resolve the REQUIRED left FK (provider-scoped) — STRICT: missing → throws;
11
+ * 2. resolve the REQUIRED right FK (provider-scoped) — STRICT: missing → throws;
12
+ * 3. insert-or-update on the `(left, right[, role])` conflict target.
13
+ *
14
+ * Idempotent. Returns the composite externalId as the projection `id`.
15
+ *
16
+ * @param write parent external ids (`<left>ExternalId`/`<right>ExternalId`)
17
+ * + optional `role` + `userId`
18
+ * @param provider adapter/provider label used to scope the parent lookups
19
+ * @param tx optional outer transaction; when omitted we open our own
20
+ */
21
+ async integrationUpsertOne(write, provider, tx) {
22
+ const cfg = this.integrationConfig;
23
+ const w = write;
24
+ const leftWriteKey = `${cfg.left.column.replace(/Id$/, "")}ExternalId`;
25
+ const rightWriteKey = `${cfg.right.column.replace(/Id$/, "")}ExternalId`;
26
+ const run = async (db) => {
27
+ const leftId = await this.resolveStrict(
28
+ db,
29
+ cfg.left.refTable,
30
+ w[leftWriteKey],
31
+ provider,
32
+ cfg.left.column
33
+ );
34
+ const rightId = await this.resolveStrict(
35
+ db,
36
+ cfg.right.refTable,
37
+ w[rightWriteKey],
38
+ provider,
39
+ cfg.right.column
40
+ );
41
+ const now = /* @__PURE__ */ new Date();
42
+ const role = cfg.roleColumn ? w["role"] : void 0;
43
+ const values = {
44
+ [cfg.left.column]: leftId,
45
+ [cfg.right.column]: rightId,
46
+ ...cfg.roleColumn ? { [cfg.roleColumn]: role } : {},
47
+ ...this.behaviors.timestamps ? { updatedAt: now } : {}
48
+ };
49
+ const target = cfg.roleColumn ? [this.table[cfg.left.column], this.table[cfg.right.column], this.table[cfg.roleColumn]] : [this.table[cfg.left.column], this.table[cfg.right.column]];
50
+ const rows = await db.insert(this.table).values(values).onConflictDoUpdate({
51
+ target,
52
+ set: { ...this.behaviors.timestamps ? { updatedAt: now } : {} }
53
+ }).returning();
54
+ const saved = rows[0];
55
+ return this.toProjection(saved, w, provider);
56
+ };
57
+ return tx ? run(tx) : this.db.transaction((t) => run(t));
58
+ }
59
+ /**
60
+ * Canonical-projected lookup by the COMPOSITE externalId, differ-ready. Parses
61
+ * the composite, resolves BOTH parents NON-throwing (→ null), then selects by
62
+ * the identity tuple. Returns `null` on malformed composite / unresolved
63
+ * parent / no row (a missing "before" side is a create from the differ's view).
64
+ */
65
+ async findByExternalIdProjected(externalId, provider) {
66
+ const cfg = this.integrationConfig;
67
+ const parsed = parseCompositeExternalId(externalId, cfg.roleColumn !== null);
68
+ if (!parsed) return null;
69
+ const leftId = await this.resolveLoose(this.db, cfg.left.refTable, parsed.left, provider);
70
+ if (leftId === null) return null;
71
+ const rightId = await this.resolveLoose(this.db, cfg.right.refTable, parsed.right, provider);
72
+ if (rightId === null) return null;
73
+ const rows = await this.db.select().from(this.table).where(this.identityWhere(leftId, rightId, parsed.role)).limit(1);
74
+ const row = rows[0];
75
+ if (!row) return null;
76
+ const w = {
77
+ [`${cfg.left.column.replace(/Id$/, "")}ExternalId`]: parsed.left,
78
+ [`${cfg.right.column.replace(/Id$/, "")}ExternalId`]: parsed.right,
79
+ ...cfg.roleColumn ? { role: parsed.role } : {},
80
+ userId: ""
81
+ };
82
+ return this.toProjection(row, w, provider);
83
+ }
84
+ /**
85
+ * Hard-delete the junction by composite externalId. Junctions have no
86
+ * `deleted_at` and no external-linkage columns to clear, so a integration "delete"
87
+ * removes the row. Resolves both parents NON-throwing, then deletes by the
88
+ * identity tuple. Returns the composite id, or `null` when nothing matched.
89
+ */
90
+ async softDeleteByExternalId(externalId, provider, tx) {
91
+ const cfg = this.integrationConfig;
92
+ const parsed = parseCompositeExternalId(externalId, cfg.roleColumn !== null);
93
+ if (!parsed) return null;
94
+ const db = this.runner(tx);
95
+ const leftId = await this.resolveLoose(db, cfg.left.refTable, parsed.left, provider);
96
+ if (leftId === null) return null;
97
+ const rightId = await this.resolveLoose(db, cfg.right.refTable, parsed.right, provider);
98
+ if (rightId === null) return null;
99
+ const rows = await db.delete(this.table).where(this.identityWhere(leftId, rightId, parsed.role)).returning({ id: this.table[cfg.left.column] });
100
+ return rows[0] ? { id: externalId } : null;
101
+ }
102
+ /**
103
+ * Project a raw junction row to the differ shape: the COMPOSITE externalId
104
+ * `id` (junctions have no surrogate id) plus the local FK columns, role (when
105
+ * role-bearing) and timestamps — matching the emitted
106
+ * `<Junction>IntegrationProjection` interface (id + leftId + rightId + role? +
107
+ * createdAt + updatedAt). Junction projections are purely structural, so this
108
+ * is fully generic over `integrationConfig` — no per-junction override is emitted.
109
+ */
110
+ toProjection(row, write, _provider) {
111
+ const cfg = this.integrationConfig;
112
+ const r = row;
113
+ const leftExt = write[`${cfg.left.column.replace(/Id$/, "")}ExternalId`];
114
+ const rightExt = write[`${cfg.right.column.replace(/Id$/, "")}ExternalId`];
115
+ const role = cfg.roleColumn ? r[cfg.roleColumn] : void 0;
116
+ const out = {
117
+ id: buildCompositeExternalId(leftExt, rightExt, role),
118
+ [cfg.left.column]: r[cfg.left.column],
119
+ [cfg.right.column]: r[cfg.right.column]
120
+ };
121
+ if (cfg.roleColumn) out[cfg.roleColumn] = r[cfg.roleColumn];
122
+ out["createdAt"] = r["createdAt"];
123
+ out["updatedAt"] = r["updatedAt"];
124
+ return out;
125
+ }
126
+ /** Build the identity WHERE clause `(left, right[, role])`. */
127
+ identityWhere(leftId, rightId, role) {
128
+ const cfg = this.integrationConfig;
129
+ const conds = [
130
+ eq(this.table[cfg.left.column], leftId),
131
+ eq(this.table[cfg.right.column], rightId)
132
+ ];
133
+ if (cfg.roleColumn && role !== void 0) {
134
+ conds.push(eq(this.table[cfg.roleColumn], role));
135
+ }
136
+ return and(...conds);
137
+ }
138
+ /** Resolve a parent id (provider-scoped), throwing when unresolved. */
139
+ async resolveStrict(db, refTable, parentExternalId, provider, column) {
140
+ const id = await this.resolveLoose(db, refTable, parentExternalId, provider);
141
+ if (!id) {
142
+ throw new Error(
143
+ `${this.constructor.name}.integrationUpsertOne: unresolved parent '${parentExternalId}' (provider '${provider}') for '${column}' \u2014 parent not integrated yet`
144
+ );
145
+ }
146
+ return id;
147
+ }
148
+ /** Resolve a parent id (provider-scoped), returning null when unresolved. */
149
+ async resolveLoose(db, refTable, parentExternalId, provider) {
150
+ if (!parentExternalId) return null;
151
+ const rows = await db.select({ id: refTable["id"] }).from(refTable).where(
152
+ and(
153
+ eq(refTable["provider"], provider),
154
+ eq(refTable["externalId"], parentExternalId)
155
+ )
156
+ ).limit(1);
157
+ return rows[0]?.id ?? null;
158
+ }
159
+ };
160
+ function buildCompositeExternalId(leftExternalId, rightExternalId, role) {
161
+ return role !== void 0 ? `${leftExternalId}::${rightExternalId}::${role}` : `${leftExternalId}::${rightExternalId}`;
162
+ }
163
+ function parseCompositeExternalId(externalId, withRole) {
164
+ const parts = externalId.split("::");
165
+ const expected = withRole ? 3 : 2;
166
+ if (parts.length !== expected || parts.some((p) => p.length === 0)) return null;
167
+ return {
168
+ left: parts[0],
169
+ right: parts[1],
170
+ role: withRole ? parts[2] : void 0
171
+ };
172
+ }
173
+
174
+ export {
175
+ JunctionIntegrationRepository,
176
+ buildCompositeExternalId,
177
+ parseCompositeExternalId
178
+ };
179
+ //# sourceMappingURL=chunk-2FTZLDBP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/base-classes/junction-integration-repository.ts"],"sourcesContent":["/**\n * JunctionIntegrationRepository<TEntity, TIntegrationWrite, TIntegrationProjection>\n *\n * Base for junction repos that participate in inbound integration (#374). A junction's\n * integration identity is the tuple `(leftId, rightId[, role])` — there is no native\n * `external_id`/`provider` column, so the integration seam's externalId is a COMPOSITE\n * string `<leftExternalId>::<rightExternalId>[::<role>]` (see the static\n * build/parse helpers below).\n *\n * Both parent FKs are resolved STRICTLY in the write path (a missing parent\n * throws → the orchestrator records a failed item and continues). As of #372\n * role-bearing junctions carry a unique constraint over `(left, right, role)`,\n * so the upsert uses `onConflictDoUpdate` (not the legacy select-then-write).\n * Role-less junctions conflict on `(left, right)`.\n */\nimport { and, eq } from 'drizzle-orm';\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nimport type { PgTableWithColumns } from 'drizzle-orm/pg-core';\nimport type { DrizzleTx } from '../types/drizzle';\nimport { BaseRepository } from './base-repository';\n\nexport interface JunctionIntegrationConfig {\n /** Left endpoint: local FK column (camel) + strict parent table. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n left: { column: string; refTable: PgTableWithColumns<any> };\n /** Right endpoint: local FK column (camel) + strict parent table. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n right: { column: string; refTable: PgTableWithColumns<any> };\n /** Role column (camel), or null for a role-less (2-part composite) junction. */\n roleColumn: string | null;\n}\n\nexport abstract class JunctionIntegrationRepository<\n TEntity,\n TIntegrationWrite,\n TIntegrationProjection,\n> extends BaseRepository<TEntity> {\n /**\n * Declarative junction integration surface. Concrete repos declare this — the\n * template emits it with live parent-table handles.\n */\n protected abstract readonly integrationConfig: JunctionIntegrationConfig;\n\n /**\n * Upsert ONE junction row by its composite identity, in a single transaction:\n * 1. resolve the REQUIRED left FK (provider-scoped) — STRICT: missing → throws;\n * 2. resolve the REQUIRED right FK (provider-scoped) — STRICT: missing → throws;\n * 3. insert-or-update on the `(left, right[, role])` conflict target.\n *\n * Idempotent. Returns the composite externalId as the projection `id`.\n *\n * @param write parent external ids (`<left>ExternalId`/`<right>ExternalId`)\n * + optional `role` + `userId`\n * @param provider adapter/provider label used to scope the parent lookups\n * @param tx optional outer transaction; when omitted we open our own\n */\n async integrationUpsertOne(\n write: TIntegrationWrite,\n provider: string,\n tx?: DrizzleTx,\n ): Promise<TIntegrationProjection> {\n const cfg = this.integrationConfig;\n const w = write as Record<string, unknown>;\n const leftWriteKey = `${cfg.left.column.replace(/Id$/, '')}ExternalId`;\n const rightWriteKey = `${cfg.right.column.replace(/Id$/, '')}ExternalId`;\n\n const run = async (db: DrizzleTx): Promise<TIntegrationProjection> => {\n const leftId = await this.resolveStrict(\n db, cfg.left.refTable, w[leftWriteKey] as string, provider, cfg.left.column,\n );\n const rightId = await this.resolveStrict(\n db, cfg.right.refTable, w[rightWriteKey] as string, provider, cfg.right.column,\n );\n\n const now = new Date();\n const role = cfg.roleColumn ? (w['role'] as unknown) : undefined;\n const values: Record<string, unknown> = {\n [cfg.left.column]: leftId,\n [cfg.right.column]: rightId,\n ...(cfg.roleColumn ? { [cfg.roleColumn]: role } : {}),\n ...(this.behaviors.timestamps ? { updatedAt: now } : {}),\n };\n const target = cfg.roleColumn\n ? [this.table[cfg.left.column], this.table[cfg.right.column], this.table[cfg.roleColumn]]\n : [this.table[cfg.left.column], this.table[cfg.right.column]];\n\n const rows = await db\n .insert(this.table)\n .values(values as never)\n .onConflictDoUpdate({\n target,\n set: { ...(this.behaviors.timestamps ? { updatedAt: now } : {}) } as never,\n })\n .returning();\n\n const saved = rows[0] as Record<string, unknown>;\n return this.toProjection(saved as TEntity, w, provider);\n };\n\n return tx ? run(tx) : this.db.transaction((t) => run(t));\n }\n\n /**\n * Canonical-projected lookup by the COMPOSITE externalId, differ-ready. Parses\n * the composite, resolves BOTH parents NON-throwing (→ null), then selects by\n * the identity tuple. Returns `null` on malformed composite / unresolved\n * parent / no row (a missing \"before\" side is a create from the differ's view).\n */\n async findByExternalIdProjected(\n externalId: string,\n provider: string,\n ): Promise<TIntegrationProjection | null> {\n const cfg = this.integrationConfig;\n const parsed = parseCompositeExternalId(externalId, cfg.roleColumn !== null);\n if (!parsed) return null;\n\n const leftId = await this.resolveLoose(this.db, cfg.left.refTable, parsed.left, provider);\n if (leftId === null) return null;\n const rightId = await this.resolveLoose(this.db, cfg.right.refTable, parsed.right, provider);\n if (rightId === null) return null;\n\n const rows = await this.db\n .select()\n .from(this.table)\n .where(this.identityWhere(leftId, rightId, parsed.role))\n .limit(1);\n const row = rows[0] as TEntity | undefined;\n if (!row) return null;\n\n const w: Record<string, unknown> = {\n [`${cfg.left.column.replace(/Id$/, '')}ExternalId`]: parsed.left,\n [`${cfg.right.column.replace(/Id$/, '')}ExternalId`]: parsed.right,\n ...(cfg.roleColumn ? { role: parsed.role } : {}),\n userId: '',\n };\n return this.toProjection(row, w, provider);\n }\n\n /**\n * Hard-delete the junction by composite externalId. Junctions have no\n * `deleted_at` and no external-linkage columns to clear, so a integration \"delete\"\n * removes the row. Resolves both parents NON-throwing, then deletes by the\n * identity tuple. Returns the composite id, or `null` when nothing matched.\n */\n async softDeleteByExternalId(\n externalId: string,\n provider: string,\n tx?: DrizzleTx,\n ): Promise<{ id: string } | null> {\n const cfg = this.integrationConfig;\n const parsed = parseCompositeExternalId(externalId, cfg.roleColumn !== null);\n if (!parsed) return null;\n const db = this.runner(tx);\n\n const leftId = await this.resolveLoose(db, cfg.left.refTable, parsed.left, provider);\n if (leftId === null) return null;\n const rightId = await this.resolveLoose(db, cfg.right.refTable, parsed.right, provider);\n if (rightId === null) return null;\n\n const rows = await db\n .delete(this.table)\n .where(this.identityWhere(leftId, rightId, parsed.role))\n .returning({ id: this.table[cfg.left.column] });\n return rows[0] ? { id: externalId } : null;\n }\n\n /**\n * Project a raw junction row to the differ shape: the COMPOSITE externalId\n * `id` (junctions have no surrogate id) plus the local FK columns, role (when\n * role-bearing) and timestamps — matching the emitted\n * `<Junction>IntegrationProjection` interface (id + leftId + rightId + role? +\n * createdAt + updatedAt). Junction projections are purely structural, so this\n * is fully generic over `integrationConfig` — no per-junction override is emitted.\n */\n protected toProjection(\n row: TEntity,\n write: Record<string, unknown>,\n _provider: string,\n ): TIntegrationProjection {\n const cfg = this.integrationConfig;\n const r = row as Record<string, unknown>;\n const leftExt = write[`${cfg.left.column.replace(/Id$/, '')}ExternalId`] as string;\n const rightExt = write[`${cfg.right.column.replace(/Id$/, '')}ExternalId`] as string;\n const role = cfg.roleColumn ? (r[cfg.roleColumn] as string | undefined) : undefined;\n const out: Record<string, unknown> = {\n id: buildCompositeExternalId(leftExt, rightExt, role),\n [cfg.left.column]: r[cfg.left.column],\n [cfg.right.column]: r[cfg.right.column],\n };\n if (cfg.roleColumn) out[cfg.roleColumn] = r[cfg.roleColumn];\n out['createdAt'] = r['createdAt'];\n out['updatedAt'] = r['updatedAt'];\n return out as TIntegrationProjection;\n }\n\n /** Build the identity WHERE clause `(left, right[, role])`. */\n private identityWhere(leftId: string, rightId: string, role: string | undefined) {\n const cfg = this.integrationConfig;\n const conds = [\n eq(this.table[cfg.left.column], leftId),\n eq(this.table[cfg.right.column], rightId),\n ];\n if (cfg.roleColumn && role !== undefined) {\n conds.push(eq(this.table[cfg.roleColumn], role));\n }\n return and(...conds);\n }\n\n /** Resolve a parent id (provider-scoped), throwing when unresolved. */\n private async resolveStrict(\n db: DrizzleTx,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n refTable: PgTableWithColumns<any>,\n parentExternalId: string,\n provider: string,\n column: string,\n ): Promise<string> {\n const id = await this.resolveLoose(db, refTable, parentExternalId, provider);\n if (!id) {\n throw new Error(\n `${this.constructor.name}.integrationUpsertOne: unresolved parent ` +\n `'${parentExternalId}' (provider '${provider}') for '${column}' — ` +\n `parent not integrated yet`,\n );\n }\n return id;\n }\n\n /** Resolve a parent id (provider-scoped), returning null when unresolved. */\n private async resolveLoose(\n db: DrizzleTx,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n refTable: PgTableWithColumns<any>,\n parentExternalId: string | null | undefined,\n provider: string,\n ): Promise<string | null> {\n if (!parentExternalId) return null;\n const rows = await db\n .select({ id: refTable['id'] })\n .from(refTable)\n .where(\n and(\n eq(refTable['provider'], provider),\n eq(refTable['externalId'], parentExternalId),\n ),\n )\n .limit(1);\n return (rows[0]?.id as string | undefined) ?? null;\n }\n}\n\n// ============================================================================\n// Composite externalId — the junction integration seam's deterministic identity.\n//\n// Format: `<leftExternalId>::<rightExternalId>[::<role>]`\n// e.g. `hubspot:42::hubspot:99::employee` (role-bearing)\n// `hubspot:42::hubspot:99` (role-less)\n//\n// Vendor-prefixed ids use a SINGLE colon, so `::` is an unambiguous delimiter.\n// Kept static in the base (replacing the per-repo free functions) so every\n// junction's lookups + its ChangeSource share one definition.\n// ============================================================================\n\n/**\n * Build the composite externalId from the two parent external ids (+ role when\n * the junction is role-bearing).\n */\nexport function buildCompositeExternalId(\n leftExternalId: string,\n rightExternalId: string,\n role?: string,\n): string {\n return role !== undefined\n ? `${leftExternalId}::${rightExternalId}::${role}`\n : `${leftExternalId}::${rightExternalId}`;\n}\n\n/**\n * Parse a composite externalId. `withRole` selects the expected part count\n * (3 when role-bearing, else 2). Returns `null` when the shape doesn't match\n * or any part is empty.\n */\nexport function parseCompositeExternalId(\n externalId: string,\n withRole: boolean,\n): { left: string; right: string; role: string | undefined } | null {\n const parts = externalId.split('::');\n const expected = withRole ? 3 : 2;\n if (parts.length !== expected || parts.some((p) => p.length === 0)) return null;\n return {\n left: parts[0] as string,\n right: parts[1] as string,\n role: withRole ? (parts[2] as string) : undefined,\n };\n}\n"],"mappings":";;;;;AAeA,SAAS,KAAK,UAAU;AAiBjB,IAAe,gCAAf,cAIG,eAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAoBhC,MAAM,qBACJ,OACA,UACA,IACiC;AACjC,UAAM,MAAM,KAAK;AACjB,UAAM,IAAI;AACV,UAAM,eAAe,GAAG,IAAI,KAAK,OAAO,QAAQ,OAAO,EAAE,CAAC;AAC1D,UAAM,gBAAgB,GAAG,IAAI,MAAM,OAAO,QAAQ,OAAO,EAAE,CAAC;AAE5D,UAAM,MAAM,OAAO,OAAmD;AACpE,YAAM,SAAS,MAAM,KAAK;AAAA,QACxB;AAAA,QAAI,IAAI,KAAK;AAAA,QAAU,EAAE,YAAY;AAAA,QAAa;AAAA,QAAU,IAAI,KAAK;AAAA,MACvE;AACA,YAAM,UAAU,MAAM,KAAK;AAAA,QACzB;AAAA,QAAI,IAAI,MAAM;AAAA,QAAU,EAAE,aAAa;AAAA,QAAa;AAAA,QAAU,IAAI,MAAM;AAAA,MAC1E;AAEA,YAAM,MAAM,oBAAI,KAAK;AACrB,YAAM,OAAO,IAAI,aAAc,EAAE,MAAM,IAAgB;AACvD,YAAM,SAAkC;AAAA,QACtC,CAAC,IAAI,KAAK,MAAM,GAAG;AAAA,QACnB,CAAC,IAAI,MAAM,MAAM,GAAG;AAAA,QACpB,GAAI,IAAI,aAAa,EAAE,CAAC,IAAI,UAAU,GAAG,KAAK,IAAI,CAAC;AAAA,QACnD,GAAI,KAAK,UAAU,aAAa,EAAE,WAAW,IAAI,IAAI,CAAC;AAAA,MACxD;AACA,YAAM,SAAS,IAAI,aACf,CAAC,KAAK,MAAM,IAAI,KAAK,MAAM,GAAG,KAAK,MAAM,IAAI,MAAM,MAAM,GAAG,KAAK,MAAM,IAAI,UAAU,CAAC,IACtF,CAAC,KAAK,MAAM,IAAI,KAAK,MAAM,GAAG,KAAK,MAAM,IAAI,MAAM,MAAM,CAAC;AAE9D,YAAM,OAAO,MAAM,GAChB,OAAO,KAAK,KAAK,EACjB,OAAO,MAAe,EACtB,mBAAmB;AAAA,QAClB;AAAA,QACA,KAAK,EAAE,GAAI,KAAK,UAAU,aAAa,EAAE,WAAW,IAAI,IAAI,CAAC,EAAG;AAAA,MAClE,CAAC,EACA,UAAU;AAEb,YAAM,QAAQ,KAAK,CAAC;AACpB,aAAO,KAAK,aAAa,OAAkB,GAAG,QAAQ;AAAA,IACxD;AAEA,WAAO,KAAK,IAAI,EAAE,IAAI,KAAK,GAAG,YAAY,CAAC,MAAM,IAAI,CAAC,CAAC;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,0BACJ,YACA,UACwC;AACxC,UAAM,MAAM,KAAK;AACjB,UAAM,SAAS,yBAAyB,YAAY,IAAI,eAAe,IAAI;AAC3E,QAAI,CAAC,OAAQ,QAAO;AAEpB,UAAM,SAAS,MAAM,KAAK,aAAa,KAAK,IAAI,IAAI,KAAK,UAAU,OAAO,MAAM,QAAQ;AACxF,QAAI,WAAW,KAAM,QAAO;AAC5B,UAAM,UAAU,MAAM,KAAK,aAAa,KAAK,IAAI,IAAI,MAAM,UAAU,OAAO,OAAO,QAAQ;AAC3F,QAAI,YAAY,KAAM,QAAO;AAE7B,UAAM,OAAO,MAAM,KAAK,GACrB,OAAO,EACP,KAAK,KAAK,KAAK,EACf,MAAM,KAAK,cAAc,QAAQ,SAAS,OAAO,IAAI,CAAC,EACtD,MAAM,CAAC;AACV,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,CAAC,IAAK,QAAO;AAEjB,UAAM,IAA6B;AAAA,MACjC,CAAC,GAAG,IAAI,KAAK,OAAO,QAAQ,OAAO,EAAE,CAAC,YAAY,GAAG,OAAO;AAAA,MAC5D,CAAC,GAAG,IAAI,MAAM,OAAO,QAAQ,OAAO,EAAE,CAAC,YAAY,GAAG,OAAO;AAAA,MAC7D,GAAI,IAAI,aAAa,EAAE,MAAM,OAAO,KAAK,IAAI,CAAC;AAAA,MAC9C,QAAQ;AAAA,IACV;AACA,WAAO,KAAK,aAAa,KAAK,GAAG,QAAQ;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,uBACJ,YACA,UACA,IACgC;AAChC,UAAM,MAAM,KAAK;AACjB,UAAM,SAAS,yBAAyB,YAAY,IAAI,eAAe,IAAI;AAC3E,QAAI,CAAC,OAAQ,QAAO;AACpB,UAAM,KAAK,KAAK,OAAO,EAAE;AAEzB,UAAM,SAAS,MAAM,KAAK,aAAa,IAAI,IAAI,KAAK,UAAU,OAAO,MAAM,QAAQ;AACnF,QAAI,WAAW,KAAM,QAAO;AAC5B,UAAM,UAAU,MAAM,KAAK,aAAa,IAAI,IAAI,MAAM,UAAU,OAAO,OAAO,QAAQ;AACtF,QAAI,YAAY,KAAM,QAAO;AAE7B,UAAM,OAAO,MAAM,GAChB,OAAO,KAAK,KAAK,EACjB,MAAM,KAAK,cAAc,QAAQ,SAAS,OAAO,IAAI,CAAC,EACtD,UAAU,EAAE,IAAI,KAAK,MAAM,IAAI,KAAK,MAAM,EAAE,CAAC;AAChD,WAAO,KAAK,CAAC,IAAI,EAAE,IAAI,WAAW,IAAI;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUU,aACR,KACA,OACA,WACwB;AACxB,UAAM,MAAM,KAAK;AACjB,UAAM,IAAI;AACV,UAAM,UAAU,MAAM,GAAG,IAAI,KAAK,OAAO,QAAQ,OAAO,EAAE,CAAC,YAAY;AACvE,UAAM,WAAW,MAAM,GAAG,IAAI,MAAM,OAAO,QAAQ,OAAO,EAAE,CAAC,YAAY;AACzE,UAAM,OAAO,IAAI,aAAc,EAAE,IAAI,UAAU,IAA2B;AAC1E,UAAM,MAA+B;AAAA,MACnC,IAAI,yBAAyB,SAAS,UAAU,IAAI;AAAA,MACpD,CAAC,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,KAAK,MAAM;AAAA,MACpC,CAAC,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI,MAAM,MAAM;AAAA,IACxC;AACA,QAAI,IAAI,WAAY,KAAI,IAAI,UAAU,IAAI,EAAE,IAAI,UAAU;AAC1D,QAAI,WAAW,IAAI,EAAE,WAAW;AAChC,QAAI,WAAW,IAAI,EAAE,WAAW;AAChC,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,cAAc,QAAgB,SAAiB,MAA0B;AAC/E,UAAM,MAAM,KAAK;AACjB,UAAM,QAAQ;AAAA,MACZ,GAAG,KAAK,MAAM,IAAI,KAAK,MAAM,GAAG,MAAM;AAAA,MACtC,GAAG,KAAK,MAAM,IAAI,MAAM,MAAM,GAAG,OAAO;AAAA,IAC1C;AACA,QAAI,IAAI,cAAc,SAAS,QAAW;AACxC,YAAM,KAAK,GAAG,KAAK,MAAM,IAAI,UAAU,GAAG,IAAI,CAAC;AAAA,IACjD;AACA,WAAO,IAAI,GAAG,KAAK;AAAA,EACrB;AAAA;AAAA,EAGA,MAAc,cACZ,IAEA,UACA,kBACA,UACA,QACiB;AACjB,UAAM,KAAK,MAAM,KAAK,aAAa,IAAI,UAAU,kBAAkB,QAAQ;AAC3E,QAAI,CAAC,IAAI;AACP,YAAM,IAAI;AAAA,QACR,GAAG,KAAK,YAAY,IAAI,6CAClB,gBAAgB,gBAAgB,QAAQ,WAAW,MAAM;AAAA,MAEjE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,MAAc,aACZ,IAEA,UACA,kBACA,UACwB;AACxB,QAAI,CAAC,iBAAkB,QAAO;AAC9B,UAAM,OAAO,MAAM,GAChB,OAAO,EAAE,IAAI,SAAS,IAAI,EAAE,CAAC,EAC7B,KAAK,QAAQ,EACb;AAAA,MACC;AAAA,QACE,GAAG,SAAS,UAAU,GAAG,QAAQ;AAAA,QACjC,GAAG,SAAS,YAAY,GAAG,gBAAgB;AAAA,MAC7C;AAAA,IACF,EACC,MAAM,CAAC;AACV,WAAQ,KAAK,CAAC,GAAG,MAA6B;AAAA,EAChD;AACF;AAkBO,SAAS,yBACd,gBACA,iBACA,MACQ;AACR,SAAO,SAAS,SACZ,GAAG,cAAc,KAAK,eAAe,KAAK,IAAI,KAC9C,GAAG,cAAc,KAAK,eAAe;AAC3C;AAOO,SAAS,yBACd,YACA,UACkE;AAClE,QAAM,QAAQ,WAAW,MAAM,IAAI;AACnC,QAAM,WAAW,WAAW,IAAI;AAChC,MAAI,MAAM,WAAW,YAAY,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,EAAG,QAAO;AAC3E,SAAO;AAAA,IACL,MAAM,MAAM,CAAC;AAAA,IACb,OAAO,MAAM,CAAC;AAAA,IACd,MAAM,WAAY,MAAM,CAAC,IAAe;AAAA,EAC1C;AACF;","names":[]}
@@ -0,0 +1,20 @@
1
+ // runtime/subsystems/auth/runtime/connection-broken.error.ts
2
+ var ConnectionBrokenError = class extends Error {
3
+ constructor(connectionId, errorCode, errorDescription) {
4
+ super(
5
+ `Connection ${connectionId} broken: ${errorCode} - ${errorDescription}`
6
+ );
7
+ this.connectionId = connectionId;
8
+ this.errorCode = errorCode;
9
+ this.errorDescription = errorDescription;
10
+ this.name = "ConnectionBrokenError";
11
+ }
12
+ connectionId;
13
+ errorCode;
14
+ errorDescription;
15
+ };
16
+
17
+ export {
18
+ ConnectionBrokenError
19
+ };
20
+ //# sourceMappingURL=chunk-2N4UG4VD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/subsystems/auth/runtime/connection-broken.error.ts"],"sourcesContent":["/**\n * Thrown when an OAuth2 provider returns `400 invalid_grant`/`invalid_token`\n * on refresh — the refresh token itself is dead (user revoked, org\n * deactivated, token expired beyond the provider's rotation window). The\n * connection should be marked broken so background sync stops picking it\n * up; the user re-initiates OAuth.\n *\n * Shared across every OAuth2 strategy.\n */\nexport class ConnectionBrokenError extends Error {\n constructor(\n readonly connectionId: string,\n readonly errorCode: string,\n readonly errorDescription: string,\n ) {\n super(\n `Connection ${connectionId} broken: ${errorCode} - ${errorDescription}`,\n );\n this.name = 'ConnectionBrokenError';\n }\n}\n"],"mappings":";AASO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAC/C,YACW,cACA,WACA,kBACT;AACA;AAAA,MACE,cAAc,YAAY,YAAY,SAAS,MAAM,gBAAgB;AAAA,IACvE;AANS;AACA;AACA;AAKT,SAAK,OAAO;AAAA,EACd;AAAA,EARW;AAAA,EACA;AAAA,EACA;AAOb;","names":[]}
@@ -0,0 +1,92 @@
1
+ import {
2
+ jobRuns
3
+ } from "./chunk-OKXZ63IA.js";
4
+ import {
5
+ domainEvents
6
+ } from "./chunk-OFRRBC7M.js";
7
+
8
+ // runtime/subsystems/bridge/bridge-delivery.schema.ts
9
+ import {
10
+ index,
11
+ jsonb,
12
+ pgEnum,
13
+ pgTable,
14
+ text,
15
+ timestamp,
16
+ unique,
17
+ uuid
18
+ } from "drizzle-orm/pg-core";
19
+ import { sql } from "drizzle-orm";
20
+ var bridgeDeliveryStatusEnum = pgEnum("bridge_delivery_status", [
21
+ "pending",
22
+ "delivered",
23
+ "skipped",
24
+ "failed"
25
+ ]);
26
+ var bridgeDelivery = pgTable(
27
+ "bridge_delivery",
28
+ {
29
+ id: uuid("id").primaryKey().defaultRandom(),
30
+ /** FK to the source event in the outbox. */
31
+ eventId: uuid("event_id").notNull().references(() => domainEvents.id),
32
+ /**
33
+ * Stable codegen-emitted identifier for the (job, trigger) pair, of the
34
+ * form `<job_type>#<triggerIndex>` (BRIDGE-6). Forms the second half of
35
+ * the UNIQUE idempotency key.
36
+ */
37
+ triggerId: text("trigger_id").notNull(),
38
+ /**
39
+ * Wrapper `job_run.id` (the framework `@framework/bridge_delivery` run
40
+ * that drove this delivery). Nullable: the facade-eager path
41
+ * (`publishAndStart` Case B) pre-writes a delivered row with no wrapper.
42
+ */
43
+ wrapperRunId: uuid("wrapper_run_id").references(() => jobRuns.id),
44
+ /**
45
+ * Spawned user `job_run.id`. Null until status is `delivered`; remains
46
+ * null for `skipped` and `failed` deliveries.
47
+ */
48
+ userRunId: uuid("user_run_id").references(() => jobRuns.id),
49
+ status: bridgeDeliveryStatusEnum("status").notNull().default("pending"),
50
+ /** Populated when status=`skipped` (e.g. `'when_returned_false'`, `'trigger_unregistered'`). */
51
+ skipReason: text("skip_reason"),
52
+ /** Populated when status=`failed`. Mirrors `job_run.error` shape. */
53
+ error: jsonb("error").$type(),
54
+ /**
55
+ * Emitted unconditionally and nullable (JOB-8 / SYNC-6 precedent).
56
+ * Enforcement gated on `BRIDGE_MULTI_TENANT` at the service layer
57
+ * (BRIDGE-8); no DB constraint.
58
+ */
59
+ tenantId: text("tenant_id"),
60
+ attemptedAt: timestamp("attempted_at", { withTimezone: true }).notNull().defaultNow(),
61
+ deliveredAt: timestamp("delivered_at", { withTimezone: true })
62
+ },
63
+ (t) => ({
64
+ /**
65
+ * Idempotency ledger. Outbox replays and facade-vs-drain collisions both
66
+ * dedup through this constraint.
67
+ */
68
+ uqBridgeDeliveryEventTrigger: unique("uq_bridge_delivery_event_trigger").on(
69
+ t.eventId,
70
+ t.triggerId
71
+ ),
72
+ /** Lookup all deliveries for an event (fanout report, debugging). */
73
+ idxBridgeDeliveryEvent: index("idx_bridge_delivery_event").on(t.eventId),
74
+ /**
75
+ * Ops dashboard filter — only the actionable states. Partial index keeps
76
+ * it small at scale (the bulk of rows will be `delivered`).
77
+ */
78
+ idxBridgeDeliveryStatus: index("idx_bridge_delivery_status").on(t.status).where(sql`${t.status} IN ('pending','failed')`),
79
+ /**
80
+ * Reverse lookup from a spawned user run back to its delivery row.
81
+ * Partial — most rows in the bridge ledger but only successful
82
+ * deliveries have a `user_run_id`.
83
+ */
84
+ idxBridgeDeliveryUserRun: index("idx_bridge_delivery_user_run").on(t.userRunId).where(sql`${t.userRunId} IS NOT NULL`)
85
+ })
86
+ );
87
+
88
+ export {
89
+ bridgeDeliveryStatusEnum,
90
+ bridgeDelivery
91
+ };
92
+ //# sourceMappingURL=chunk-2TVVBC53.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/subsystems/bridge/bridge-delivery.schema.ts"],"sourcesContent":["/**\n * Drizzle schema for the `bridge_delivery` ledger (ADR-023 Phase 2, BRIDGE-1).\n *\n * The `bridge_delivery` table is the idempotency ledger for the event-to-job\n * bridge. Every (event, trigger) pair the bridge is asked to spawn produces\n * exactly one row; the `UNIQUE (event_id, trigger_id)` constraint guarantees\n * that:\n *\n * 1. Outbox replays of an event do not double-spawn user job runs — the\n * drain attempts to insert the duplicate, the constraint trips, and the\n * drain skips that trigger.\n * 2. The `IEventFlow.publishAndStart` facade can pre-write a\n * `(status='delivered')` row before the drain runs (Case B from ADR-023\n * §`publishAndStart` + existing `triggers:` collision); the drain then\n * hits UNIQUE on that trigger and skips it while still spawning any\n * other triggers for the same event normally.\n *\n * Status values:\n * - `pending` — wrapper run exists; user job not yet started.\n * - `delivered` — user job started; `user_run_id` populated.\n * - `skipped` — intentional no-op (`when:` returned false, or\n * facade-eager path pre-empted the bridge spawn).\n * - `failed` — wrapper exhausted retry policy; no auto-retry past that\n * (mirrors events outbox stance — ops eyes only).\n *\n * `wrapper_run_id` is **nullable**: the facade-eager path (Case B) pre-writes\n * `bridge_delivery` with no wrapper. The bridge-drain path always populates\n * it.\n *\n * `tenant_id` is emitted **unconditionally and nullable** (per JOB-8\n * 2026-04-20 reversal); enforcement is service-layer (BRIDGE-8) gated on the\n * `BRIDGE_MULTI_TENANT` DI token, not a DB constraint.\n *\n * Indexes:\n * - `bridge_delivery_event_idx` — lookup all deliveries for an event.\n * - `bridge_delivery_status_idx` — partial; ops dashboards filter by\n * `pending | failed`.\n * - `bridge_delivery_user_run_idx` — partial; reverse lookup from a\n * spawned user run back to its delivery row.\n *\n * No service logic, no DI wiring — this is the schema foundation. Backends\n * (memory + drizzle) and the framework handler land in BRIDGE-3 / BRIDGE-4 /\n * BRIDGE-5.\n */\nimport {\n index,\n jsonb,\n pgEnum,\n pgTable,\n text,\n timestamp,\n unique,\n uuid,\n} from 'drizzle-orm/pg-core';\nimport { sql } from 'drizzle-orm';\nimport type { InferSelectModel } from 'drizzle-orm';\n\nimport { domainEvents } from '../events/domain-events.schema';\nimport { jobRuns } from '../jobs/job-orchestration.schema';\n\n// ─── Enum ───────────────────────────────────────────────────────────────────\n\nexport const bridgeDeliveryStatusEnum = pgEnum('bridge_delivery_status', [\n 'pending',\n 'delivered',\n 'skipped',\n 'failed',\n]);\n\n// ─── Table ──────────────────────────────────────────────────────────────────\n\nexport const bridgeDelivery = pgTable(\n 'bridge_delivery',\n {\n id: uuid('id').primaryKey().defaultRandom(),\n /** FK to the source event in the outbox. */\n eventId: uuid('event_id')\n .notNull()\n .references(() => domainEvents.id),\n /**\n * Stable codegen-emitted identifier for the (job, trigger) pair, of the\n * form `<job_type>#<triggerIndex>` (BRIDGE-6). Forms the second half of\n * the UNIQUE idempotency key.\n */\n triggerId: text('trigger_id').notNull(),\n /**\n * Wrapper `job_run.id` (the framework `@framework/bridge_delivery` run\n * that drove this delivery). Nullable: the facade-eager path\n * (`publishAndStart` Case B) pre-writes a delivered row with no wrapper.\n */\n wrapperRunId: uuid('wrapper_run_id').references(() => jobRuns.id),\n /**\n * Spawned user `job_run.id`. Null until status is `delivered`; remains\n * null for `skipped` and `failed` deliveries.\n */\n userRunId: uuid('user_run_id').references(() => jobRuns.id),\n status: bridgeDeliveryStatusEnum('status').notNull().default('pending'),\n /** Populated when status=`skipped` (e.g. `'when_returned_false'`, `'trigger_unregistered'`). */\n skipReason: text('skip_reason'),\n /** Populated when status=`failed`. Mirrors `job_run.error` shape. */\n error: jsonb('error').$type<Record<string, unknown>>(),\n /**\n * Emitted unconditionally and nullable (JOB-8 / SYNC-6 precedent).\n * Enforcement gated on `BRIDGE_MULTI_TENANT` at the service layer\n * (BRIDGE-8); no DB constraint.\n */\n tenantId: text('tenant_id'),\n attemptedAt: timestamp('attempted_at', { withTimezone: true })\n .notNull()\n .defaultNow(),\n deliveredAt: timestamp('delivered_at', { withTimezone: true }),\n },\n (t) => ({\n /**\n * Idempotency ledger. Outbox replays and facade-vs-drain collisions both\n * dedup through this constraint.\n */\n uqBridgeDeliveryEventTrigger: unique('uq_bridge_delivery_event_trigger').on(\n t.eventId,\n t.triggerId,\n ),\n /** Lookup all deliveries for an event (fanout report, debugging). */\n idxBridgeDeliveryEvent: index('idx_bridge_delivery_event').on(t.eventId),\n /**\n * Ops dashboard filter — only the actionable states. Partial index keeps\n * it small at scale (the bulk of rows will be `delivered`).\n */\n idxBridgeDeliveryStatus: index('idx_bridge_delivery_status')\n .on(t.status)\n .where(sql`${t.status} IN ('pending','failed')`),\n /**\n * Reverse lookup from a spawned user run back to its delivery row.\n * Partial — most rows in the bridge ledger but only successful\n * deliveries have a `user_run_id`.\n */\n idxBridgeDeliveryUserRun: index('idx_bridge_delivery_user_run')\n .on(t.userRunId)\n .where(sql`${t.userRunId} IS NOT NULL`),\n }),\n);\n\nexport type BridgeDeliveryRecord = InferSelectModel<typeof bridgeDelivery>;\n"],"mappings":";;;;;;;;AA4CA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW;AAQb,IAAM,2BAA2B,OAAO,0BAA0B;AAAA,EACvE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAIM,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,IACE,IAAI,KAAK,IAAI,EAAE,WAAW,EAAE,cAAc;AAAA;AAAA,IAE1C,SAAS,KAAK,UAAU,EACrB,QAAQ,EACR,WAAW,MAAM,aAAa,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMnC,WAAW,KAAK,YAAY,EAAE,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMtC,cAAc,KAAK,gBAAgB,EAAE,WAAW,MAAM,QAAQ,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA,IAKhE,WAAW,KAAK,aAAa,EAAE,WAAW,MAAM,QAAQ,EAAE;AAAA,IAC1D,QAAQ,yBAAyB,QAAQ,EAAE,QAAQ,EAAE,QAAQ,SAAS;AAAA;AAAA,IAEtE,YAAY,KAAK,aAAa;AAAA;AAAA,IAE9B,OAAO,MAAM,OAAO,EAAE,MAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMrD,UAAU,KAAK,WAAW;AAAA,IAC1B,aAAa,UAAU,gBAAgB,EAAE,cAAc,KAAK,CAAC,EAC1D,QAAQ,EACR,WAAW;AAAA,IACd,aAAa,UAAU,gBAAgB,EAAE,cAAc,KAAK,CAAC;AAAA,EAC/D;AAAA,EACA,CAAC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKN,8BAA8B,OAAO,kCAAkC,EAAE;AAAA,MACvE,EAAE;AAAA,MACF,EAAE;AAAA,IACJ;AAAA;AAAA,IAEA,wBAAwB,MAAM,2BAA2B,EAAE,GAAG,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKvE,yBAAyB,MAAM,4BAA4B,EACxD,GAAG,EAAE,MAAM,EACX,MAAM,MAAM,EAAE,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMjD,0BAA0B,MAAM,8BAA8B,EAC3D,GAAG,EAAE,SAAS,EACd,MAAM,MAAM,EAAE,SAAS,cAAc;AAAA,EAC1C;AACF;","names":[]}
@@ -0,0 +1,37 @@
1
+ import {
2
+ BaseService
3
+ } from "./chunk-W72PRNJY.js";
4
+
5
+ // runtime/base-classes/integrated-entity-service.ts
6
+ var IntegratedEntityService = class extends BaseService {
7
+ /**
8
+ * Find a single entity by its external CRM identifier.
9
+ */
10
+ findByExternalId(externalId) {
11
+ return this.repository.findByExternalId(externalId);
12
+ }
13
+ /**
14
+ * Find multiple entities by external CRM identifiers.
15
+ */
16
+ findManyByExternalIds(externalIds) {
17
+ return this.repository.findManyByExternalIds(externalIds);
18
+ }
19
+ /**
20
+ * Find all entities owned by a specific user.
21
+ */
22
+ findAllByUser(userId) {
23
+ return this.repository.findAllByUserId(userId);
24
+ }
25
+ /**
26
+ * Find entities visible to a user (ownership + sharing rules).
27
+ * Concrete services may override with domain-specific visibility logic.
28
+ */
29
+ findVisibleByUser(userId) {
30
+ return this.repository.findVisibleByUserId(userId);
31
+ }
32
+ };
33
+
34
+ export {
35
+ IntegratedEntityService
36
+ };
37
+ //# sourceMappingURL=chunk-2VHZ7EKC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../runtime/base-classes/integrated-entity-service.ts"],"sourcesContent":["/**\n * IntegratedEntityService<TRepo, TEntity>\n *\n * Family-specific base service for Integrated entities.\n * Delegates to a CRM repository that provides external ID lookups\n * and user-scoped queries.\n */\nimport { BaseService, type IBaseRepository } from './base-service';\n\nexport interface IIntegratedEntityRepository<TEntity> extends IBaseRepository<TEntity> {\n findByExternalId(externalId: string): Promise<TEntity | null>;\n findManyByExternalIds(externalIds: string[]): Promise<TEntity[]>;\n findAllByUserId(userId: string): Promise<TEntity[]>;\n findVisibleByUserId(userId: string): Promise<TEntity[]>;\n integrationUpsert(inputs: Array<Partial<TEntity>>): Promise<TEntity[]>;\n}\n\nexport abstract class IntegratedEntityService<\n TRepo extends IIntegratedEntityRepository<TEntity>,\n TEntity,\n> extends BaseService<TRepo, TEntity> {\n /**\n * Find a single entity by its external CRM identifier.\n */\n findByExternalId(externalId: string): Promise<TEntity | null> {\n return this.repository.findByExternalId(externalId);\n }\n\n /**\n * Find multiple entities by external CRM identifiers.\n */\n findManyByExternalIds(externalIds: string[]): Promise<TEntity[]> {\n return this.repository.findManyByExternalIds(externalIds);\n }\n\n /**\n * Find all entities owned by a specific user.\n */\n findAllByUser(userId: string): Promise<TEntity[]> {\n return this.repository.findAllByUserId(userId);\n }\n\n /**\n * Find entities visible to a user (ownership + sharing rules).\n * Concrete services may override with domain-specific visibility logic.\n */\n findVisibleByUser(userId: string): Promise<TEntity[]> {\n return this.repository.findVisibleByUserId(userId);\n }\n}\n"],"mappings":";;;;;AAiBO,IAAe,0BAAf,cAGG,YAA4B;AAAA;AAAA;AAAA;AAAA,EAIpC,iBAAiB,YAA6C;AAC5D,WAAO,KAAK,WAAW,iBAAiB,UAAU;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKA,sBAAsB,aAA2C;AAC/D,WAAO,KAAK,WAAW,sBAAsB,WAAW;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,QAAoC;AAChD,WAAO,KAAK,WAAW,gBAAgB,MAAM;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,kBAAkB,QAAoC;AACpD,WAAO,KAAK,WAAW,oBAAoB,MAAM;AAAA,EACnD;AACF;","names":[]}