@pattern-stack/codegen 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/CHANGELOG.md +135 -0
  2. package/README.md +5 -5
  3. package/consumer-skills/codegen/SKILL.md +2 -2
  4. package/consumer-skills/events/typed-bus-and-outbox.md +1 -1
  5. package/consumer-skills/{sync → integration}/SKILL.md +29 -29
  6. package/consumer-skills/{sync → integration}/audit-and-detection.md +22 -22
  7. package/consumer-skills/{sync → integration}/change-sources-and-sinks.md +60 -60
  8. package/consumer-skills/subsystems/SKILL.md +64 -8
  9. package/consumer-skills/subsystems/wiring-and-order.md +7 -7
  10. package/dist/runtime/base-classes/index.d.ts +4 -4
  11. package/dist/runtime/base-classes/index.js +35 -35
  12. package/dist/runtime/base-classes/index.js.map +1 -1
  13. package/dist/runtime/base-classes/{synced-entity-repository.d.ts → integrated-entity-repository.d.ts} +15 -15
  14. package/dist/runtime/base-classes/{synced-entity-repository.js → integrated-entity-repository.js} +21 -21
  15. package/dist/runtime/base-classes/integrated-entity-repository.js.map +1 -0
  16. package/dist/runtime/base-classes/{synced-entity-service.d.ts → integrated-entity-service.d.ts} +6 -6
  17. package/dist/runtime/base-classes/{synced-entity-service.js → integrated-entity-service.js} +4 -4
  18. package/dist/runtime/base-classes/integrated-entity-service.js.map +1 -0
  19. package/dist/runtime/base-classes/{sync-upsert-config.d.ts → integration-upsert-config.d.ts} +13 -13
  20. package/dist/runtime/base-classes/integration-upsert-config.js +1 -0
  21. package/dist/runtime/base-classes/{junction-sync-repository.d.ts → junction-integration-repository.d.ts} +11 -11
  22. package/dist/runtime/base-classes/{junction-sync-repository.js → junction-integration-repository.js} +15 -15
  23. package/dist/runtime/base-classes/junction-integration-repository.js.map +1 -0
  24. package/dist/runtime/subsystems/auth/auth-oauth-state.schema.js.map +1 -1
  25. package/dist/runtime/subsystems/auth/auth.module.d.ts +4 -4
  26. package/dist/runtime/subsystems/auth/auth.module.js +3 -3
  27. package/dist/runtime/subsystems/auth/auth.module.js.map +1 -1
  28. package/dist/runtime/subsystems/auth/auth.tokens.d.ts +8 -8
  29. package/dist/runtime/subsystems/auth/auth.tokens.js +6 -6
  30. package/dist/runtime/subsystems/auth/auth.tokens.js.map +1 -1
  31. package/dist/runtime/subsystems/auth/backends/state-store.drizzle-backend.js.map +1 -1
  32. package/dist/runtime/subsystems/auth/controllers/auth.controller.d.ts +2 -2
  33. package/dist/runtime/subsystems/auth/controllers/auth.controller.js +3 -3
  34. package/dist/runtime/subsystems/auth/controllers/auth.controller.js.map +1 -1
  35. package/dist/runtime/subsystems/auth/index.d.ts +3 -3
  36. package/dist/runtime/subsystems/auth/index.js +40 -40
  37. package/dist/runtime/subsystems/auth/index.js.map +1 -1
  38. package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -1
  39. package/dist/runtime/subsystems/auth/protocols/auth-strategy.d.ts +3 -3
  40. package/dist/runtime/subsystems/auth/protocols/{integration-store.d.ts → connection-store.d.ts} +20 -20
  41. package/dist/runtime/subsystems/auth/protocols/connection-store.js +1 -0
  42. package/dist/runtime/subsystems/auth/protocols/provider-strategy.d.ts +3 -3
  43. package/dist/runtime/subsystems/auth/runtime/{integration-broken.error.d.ts → connection-broken.error.d.ts} +5 -5
  44. package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js +19 -0
  45. package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js.map +1 -0
  46. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.d.ts +10 -10
  47. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js +28 -28
  48. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js.map +1 -1
  49. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.d.ts +1 -1
  50. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js +3 -3
  51. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js.map +1 -1
  52. package/dist/runtime/subsystems/bridge/bridge.module.d.ts +0 -1
  53. package/dist/runtime/subsystems/bridge/bridge.module.js +294 -710
  54. package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
  55. package/dist/runtime/subsystems/bridge/index.d.ts +0 -1
  56. package/dist/runtime/subsystems/bridge/index.js +248 -664
  57. package/dist/runtime/subsystems/bridge/index.js.map +1 -1
  58. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +18 -10
  59. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
  60. package/dist/runtime/subsystems/events/events.module.js +43 -244
  61. package/dist/runtime/subsystems/events/events.module.js.map +1 -1
  62. package/dist/runtime/subsystems/events/index.d.ts +0 -1
  63. package/dist/runtime/subsystems/events/index.js +39 -241
  64. package/dist/runtime/subsystems/events/index.js.map +1 -1
  65. package/dist/runtime/subsystems/index.d.ts +7 -7
  66. package/dist/runtime/subsystems/index.js +222 -839
  67. package/dist/runtime/subsystems/index.js.map +1 -1
  68. package/dist/runtime/subsystems/{sync → integration}/build-change-source.d.ts +3 -3
  69. package/dist/runtime/subsystems/{sync → integration}/build-change-source.js +3 -3
  70. package/dist/runtime/subsystems/integration/build-change-source.js.map +1 -0
  71. package/dist/runtime/subsystems/{sync → integration}/deep-equal.differ.d.ts +2 -2
  72. package/dist/runtime/subsystems/{sync → integration}/deep-equal.differ.js +1 -1
  73. package/dist/runtime/subsystems/integration/deep-equal.differ.js.map +1 -0
  74. package/dist/runtime/subsystems/{sync → integration}/detection-config.schema.d.ts +3 -3
  75. package/dist/runtime/subsystems/{sync → integration}/detection-config.schema.js +1 -1
  76. package/dist/runtime/subsystems/integration/detection-config.schema.js.map +1 -0
  77. package/dist/runtime/subsystems/{sync/execute-sync.use-case.d.ts → integration/execute-integration.use-case.d.ts} +13 -13
  78. package/dist/runtime/subsystems/{sync/execute-sync.use-case.js → integration/execute-integration.use-case.js} +30 -30
  79. package/dist/runtime/subsystems/integration/execute-integration.use-case.js.map +1 -0
  80. package/dist/runtime/subsystems/integration/index.d.ts +28 -0
  81. package/dist/runtime/subsystems/{sync → integration}/index.js +171 -171
  82. package/dist/runtime/subsystems/integration/index.js.map +1 -0
  83. package/dist/runtime/subsystems/{sync/sync-audit.schema.d.ts → integration/integration-audit.schema.d.ts} +64 -64
  84. package/dist/runtime/subsystems/{sync/sync-audit.schema.js → integration/integration-audit.schema.js} +47 -47
  85. package/dist/runtime/subsystems/integration/integration-audit.schema.js.map +1 -0
  86. package/dist/runtime/subsystems/{sync/sync-change-source.protocol.d.ts → integration/integration-change-source.protocol.d.ts} +10 -10
  87. package/dist/runtime/subsystems/integration/integration-change-source.protocol.js +1 -0
  88. package/dist/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.d.ts → integration/integration-cursor-store.drizzle-backend.d.ts} +1 -1
  89. package/dist/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.js → integration/integration-cursor-store.drizzle-backend.js} +65 -65
  90. package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js.map +1 -0
  91. package/dist/runtime/subsystems/{sync/sync-cursor-store.memory-backend.d.ts → integration/integration-cursor-store.memory-backend.d.ts} +6 -6
  92. package/dist/runtime/subsystems/{sync/sync-cursor-store.memory-backend.js → integration/integration-cursor-store.memory-backend.js} +5 -5
  93. package/dist/runtime/subsystems/integration/integration-cursor-store.memory-backend.js.map +1 -0
  94. package/dist/runtime/subsystems/{sync/sync-cursor-store.protocol.d.ts → integration/integration-cursor-store.protocol.d.ts} +13 -13
  95. package/dist/runtime/subsystems/integration/integration-cursor-store.protocol.js +1 -0
  96. package/dist/runtime/subsystems/{sync/sync-errors.d.ts → integration/integration-errors.d.ts} +2 -2
  97. package/dist/runtime/subsystems/{sync/sync-errors.js → integration/integration-errors.js} +3 -3
  98. package/dist/runtime/subsystems/integration/integration-errors.js.map +1 -0
  99. package/dist/runtime/subsystems/{sync/sync-field-diff.protocol.d.ts → integration/integration-field-diff.protocol.d.ts} +2 -2
  100. package/dist/runtime/subsystems/{sync/sync-field-diff.protocol.js → integration/integration-field-diff.protocol.js} +2 -2
  101. package/dist/runtime/subsystems/integration/integration-field-diff.protocol.js.map +1 -0
  102. package/dist/runtime/subsystems/{sync/sync-loopback.protocol.d.ts → integration/integration-loopback.protocol.d.ts} +2 -2
  103. package/dist/runtime/subsystems/integration/integration-loopback.protocol.js +1 -0
  104. package/dist/runtime/subsystems/{sync/sync-middleware.protocol.d.ts → integration/integration-middleware.protocol.d.ts} +5 -5
  105. package/dist/runtime/subsystems/integration/integration-middleware.protocol.js +1 -0
  106. package/dist/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.d.ts → integration/integration-run-recorder.drizzle-backend.d.ts} +5 -5
  107. package/dist/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.js → integration/integration-run-recorder.drizzle-backend.js} +73 -73
  108. package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js.map +1 -0
  109. package/dist/runtime/subsystems/{sync/sync-run-recorder.memory-backend.d.ts → integration/integration-run-recorder.memory-backend.d.ts} +15 -15
  110. package/dist/runtime/subsystems/{sync/sync-run-recorder.memory-backend.js → integration/integration-run-recorder.memory-backend.js} +11 -11
  111. package/dist/runtime/subsystems/integration/integration-run-recorder.memory-backend.js.map +1 -0
  112. package/dist/runtime/subsystems/{sync/sync-run-recorder.protocol.d.ts → integration/integration-run-recorder.protocol.d.ts} +25 -25
  113. package/dist/runtime/subsystems/integration/integration-run-recorder.protocol.js +1 -0
  114. package/dist/runtime/subsystems/{sync/sync-sink.protocol.d.ts → integration/integration-sink.protocol.d.ts} +5 -5
  115. package/dist/runtime/subsystems/integration/integration-sink.protocol.js +1 -0
  116. package/dist/runtime/subsystems/{sync/sync.module.d.ts → integration/integration.module.d.ts} +24 -24
  117. package/dist/runtime/subsystems/{sync/sync.module.js → integration/integration.module.js} +132 -132
  118. package/dist/runtime/subsystems/integration/integration.module.js.map +1 -0
  119. package/dist/runtime/subsystems/integration/integration.tokens.d.ts +47 -0
  120. package/dist/runtime/subsystems/integration/integration.tokens.js +18 -0
  121. package/dist/runtime/subsystems/integration/integration.tokens.js.map +1 -0
  122. package/dist/runtime/subsystems/{sync → integration}/loopback.middleware.d.ts +5 -5
  123. package/dist/runtime/subsystems/{sync → integration}/loopback.middleware.js +1 -1
  124. package/dist/runtime/subsystems/integration/loopback.middleware.js.map +1 -0
  125. package/dist/runtime/subsystems/{sync → integration}/poll-change-source.d.ts +5 -5
  126. package/dist/runtime/subsystems/{sync → integration}/poll-change-source.js +1 -1
  127. package/dist/runtime/subsystems/integration/poll-change-source.js.map +1 -0
  128. package/dist/runtime/subsystems/{sync → integration}/webhook-change-source.d.ts +5 -5
  129. package/dist/runtime/subsystems/{sync → integration}/webhook-change-source.js +1 -1
  130. package/dist/runtime/subsystems/integration/webhook-change-source.js.map +1 -0
  131. package/dist/runtime/subsystems/jobs/bullmq.config.d.ts +22 -3
  132. package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -1
  133. package/dist/runtime/subsystems/jobs/index.d.ts +1 -4
  134. package/dist/runtime/subsystems/jobs/index.js +87 -506
  135. package/dist/runtime/subsystems/jobs/index.js.map +1 -1
  136. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
  137. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +3 -0
  138. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -1
  139. package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +10 -3
  140. package/dist/runtime/subsystems/jobs/job-worker.module.js +248 -664
  141. package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
  142. package/dist/runtime/subsystems/jobs/jobs-domain.module.d.ts +0 -1
  143. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +89 -391
  144. package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
  145. package/dist/runtime/subsystems/observability/index.d.ts +4 -4
  146. package/dist/runtime/subsystems/observability/index.js +11 -11
  147. package/dist/runtime/subsystems/observability/index.js.map +1 -1
  148. package/dist/runtime/subsystems/observability/observability.module.d.ts +2 -2
  149. package/dist/runtime/subsystems/observability/observability.module.js +11 -11
  150. package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
  151. package/dist/runtime/subsystems/observability/observability.protocol.d.ts +11 -11
  152. package/dist/runtime/subsystems/observability/observability.service.d.ts +6 -6
  153. package/dist/runtime/subsystems/observability/observability.service.js +11 -11
  154. package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
  155. package/dist/runtime/subsystems/observability/observability.tokens.d.ts +1 -1
  156. package/dist/runtime/subsystems/observability/observability.tokens.js.map +1 -1
  157. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +3 -3
  158. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.js.map +1 -1
  159. package/dist/runtime/subsystems/observability/reporters/index.d.ts +3 -3
  160. package/dist/runtime/subsystems/observability/reporters/index.js.map +1 -1
  161. package/dist/src/cli/index.js +412 -302
  162. package/dist/src/cli/index.js.map +1 -1
  163. package/dist/src/index.d.ts +22 -22
  164. package/dist/src/index.js +191 -191
  165. package/dist/src/index.js.map +1 -1
  166. package/examples/auth-integrations/README.md +32 -32
  167. package/examples/auth-integrations/definitions/entities/{integration.yaml → connection.yaml} +10 -10
  168. package/examples/auth-integrations/runtime/{integrations/adapters/integration-grant-sink.adapter.ts → connections/adapters/connection-grant-sink.adapter.ts} +7 -7
  169. package/examples/auth-integrations/runtime/{integrations/adapters/integration-reader.adapter.ts → connections/adapters/connection-reader.adapter.ts} +10 -10
  170. package/examples/auth-integrations/runtime/{integrations/adapters/integration-token-writer.adapter.ts → connections/adapters/connection-token-writer.adapter.ts} +11 -11
  171. package/examples/auth-integrations/runtime/connections/connections-auth.module.ts +81 -0
  172. package/examples/auth-integrations/runtime/{integrations/facade/integrations.service.ts → connections/facade/connections.service.ts} +35 -35
  173. package/examples/auth-integrations/runtime/{integrations → connections}/oauth/use-cases/create-or-update-from-oauth-grant.use-case.ts +11 -11
  174. package/examples/auth-integrations/runtime/{integrations/oauth/use-cases/disconnect-integration.use-case.ts → connections/oauth/use-cases/disconnect-connection.use-case.ts} +6 -6
  175. package/examples/auth-integrations/runtime/connections/oauth/use-cases/list-user-connections.use-case.ts +21 -0
  176. package/examples/auth-integrations/runtime/connections/oauth/use-cases/mark-connection-requires-reauth.use-case.ts +21 -0
  177. package/package.json +1 -1
  178. package/runtime/base-classes/index.ts +8 -8
  179. package/runtime/base-classes/{synced-entity-repository.ts → integrated-entity-repository.ts} +36 -36
  180. package/runtime/base-classes/{synced-entity-service.ts → integrated-entity-service.ts} +6 -6
  181. package/runtime/base-classes/{sync-upsert-config.ts → integration-upsert-config.ts} +12 -12
  182. package/runtime/base-classes/{junction-sync-repository.ts → junction-integration-repository.ts} +28 -28
  183. package/runtime/subsystems/auth/auth-oauth-state.schema.ts +1 -1
  184. package/runtime/subsystems/auth/auth.module.ts +4 -4
  185. package/runtime/subsystems/auth/auth.tokens.ts +7 -7
  186. package/runtime/subsystems/auth/controllers/auth.controller.ts +7 -7
  187. package/runtime/subsystems/auth/index.ts +19 -19
  188. package/runtime/subsystems/auth/protocols/auth-strategy.ts +3 -3
  189. package/runtime/subsystems/auth/protocols/{integration-store.ts → connection-store.ts} +19 -19
  190. package/runtime/subsystems/auth/protocols/provider-strategy.ts +2 -2
  191. package/runtime/subsystems/auth/runtime/{integration-broken.error.ts → connection-broken.error.ts} +5 -5
  192. package/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.ts +35 -35
  193. package/runtime/subsystems/auth/runtime/with-auth-retry.ts +3 -3
  194. package/runtime/subsystems/events/event-bus.drizzle-backend.ts +32 -10
  195. package/runtime/subsystems/events/events.module.ts +38 -6
  196. package/runtime/subsystems/events/index.ts +7 -1
  197. package/runtime/subsystems/index.ts +11 -11
  198. package/runtime/subsystems/{sync → integration}/build-change-source.ts +3 -3
  199. package/runtime/subsystems/{sync → integration}/deep-equal.differ.ts +7 -7
  200. package/runtime/subsystems/{sync → integration}/detection-config.schema.ts +3 -3
  201. package/runtime/subsystems/{sync/execute-sync.use-case.ts → integration/execute-integration.use-case.ts} +40 -40
  202. package/runtime/subsystems/{sync → integration}/index.ts +47 -47
  203. package/runtime/subsystems/{sync/sync-audit.schema.ts → integration/integration-audit.schema.ts} +61 -61
  204. package/runtime/subsystems/{sync/sync-change-source.protocol.ts → integration/integration-change-source.protocol.ts} +9 -9
  205. package/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.ts → integration/integration-cursor-store.drizzle-backend.ts} +30 -30
  206. package/runtime/subsystems/{sync/sync-cursor-store.memory-backend.ts → integration/integration-cursor-store.memory-backend.ts} +9 -9
  207. package/runtime/subsystems/{sync/sync-cursor-store.protocol.ts → integration/integration-cursor-store.protocol.ts} +13 -13
  208. package/runtime/subsystems/{sync/sync-errors.ts → integration/integration-errors.ts} +3 -3
  209. package/runtime/subsystems/{sync/sync-field-diff.protocol.ts → integration/integration-field-diff.protocol.ts} +2 -2
  210. package/runtime/subsystems/{sync/sync-loopback.protocol.ts → integration/integration-loopback.protocol.ts} +2 -2
  211. package/runtime/subsystems/{sync/sync-middleware.protocol.ts → integration/integration-middleware.protocol.ts} +6 -6
  212. package/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.ts → integration/integration-run-recorder.drizzle-backend.ts} +39 -39
  213. package/runtime/subsystems/{sync/sync-run-recorder.memory-backend.ts → integration/integration-run-recorder.memory-backend.ts} +23 -23
  214. package/runtime/subsystems/{sync/sync-run-recorder.protocol.ts → integration/integration-run-recorder.protocol.ts} +25 -25
  215. package/runtime/subsystems/{sync/sync-sink.protocol.ts → integration/integration-sink.protocol.ts} +4 -4
  216. package/runtime/subsystems/{sync/sync.module.ts → integration/integration.module.ts} +48 -48
  217. package/runtime/subsystems/integration/integration.tokens.ts +49 -0
  218. package/runtime/subsystems/{sync → integration}/loopback.middleware.ts +5 -5
  219. package/runtime/subsystems/{sync → integration}/poll-change-source.ts +7 -7
  220. package/runtime/subsystems/{sync → integration}/webhook-change-source.ts +7 -7
  221. package/runtime/subsystems/jobs/bullmq.config.ts +23 -3
  222. package/runtime/subsystems/jobs/index.ts +13 -8
  223. package/runtime/subsystems/jobs/job-worker.bullmq-backend.ts +5 -2
  224. package/runtime/subsystems/jobs/job-worker.module.ts +27 -7
  225. package/runtime/subsystems/jobs/jobs-domain.module.ts +27 -2
  226. package/runtime/subsystems/observability/index.ts +1 -1
  227. package/runtime/subsystems/observability/observability.module.ts +2 -2
  228. package/runtime/subsystems/observability/observability.protocol.ts +11 -11
  229. package/runtime/subsystems/observability/observability.service.ts +13 -13
  230. package/runtime/subsystems/observability/observability.tokens.ts +1 -1
  231. package/src/patterns/library/index.ts +4 -4
  232. package/src/patterns/library/{synced.pattern.ts → integrated.pattern.ts} +12 -12
  233. package/src/patterns/library/junction.pattern.ts +1 -1
  234. package/src/patterns/pattern-definition.ts +3 -3
  235. package/templates/entity/new/backend/modules/core/{sync-source.ejs.t → integration-source.ejs.t} +6 -6
  236. package/templates/entity/new/backend/modules/core/{sync-source.providers.ejs.t → integration-source.providers.ejs.t} +2 -2
  237. package/templates/entity/new/clean-lite-ps/entity.ejs.t +1 -1
  238. package/templates/entity/new/clean-lite-ps/module.ejs.t +1 -1
  239. package/templates/entity/new/clean-lite-ps/prompt-extension.js +33 -33
  240. package/templates/entity/new/clean-lite-ps/repository.ejs.t +27 -27
  241. package/templates/entity/new/frontend/collections/collection.ejs.t +26 -1
  242. package/templates/entity/new/frontend/collections/collections-base.ejs.t +11 -0
  243. package/templates/entity/new/frontend/entity/combined.ejs.t +31 -1
  244. package/templates/entity/new/prompt.js +27 -15
  245. package/templates/junction/new/entity.ejs.t +1 -1
  246. package/templates/junction/new/prompt.js +24 -24
  247. package/templates/junction/new/repository.ejs.t +19 -19
  248. package/templates/subsystem/auth/auth-oauth-state.schema.ejs.t +2 -2
  249. package/templates/subsystem/auth-config/prompt.js +1 -1
  250. package/templates/subsystem/auth-integrations/app-module-hook.ejs.t +5 -5
  251. package/templates/subsystem/bridge/prompt.js +1 -1
  252. package/templates/subsystem/events/domain-events.schema.ejs.t +43 -2
  253. package/templates/subsystem/integration/integration-audit.schema.ejs.t +192 -0
  254. package/templates/subsystem/{sync → integration}/prompt.js +12 -12
  255. package/templates/subsystem/{sync-config/codegen-config-sync-block.ejs.t → integration-config/codegen-config-integration-block.ejs.t} +7 -7
  256. package/templates/subsystem/integration-config/prompt.js +22 -0
  257. package/templates/subsystem/jobs/worker.ejs.t +2 -2
  258. package/templates/subsystem/observability/main-hook.ejs.t +1 -1
  259. package/templates/subsystem/observability/prompt.js +1 -1
  260. package/templates/subsystem/openapi-config/prompt.js +1 -1
  261. package/dist/runtime/base-classes/junction-sync-repository.js.map +0 -1
  262. package/dist/runtime/base-classes/sync-upsert-config.js +0 -1
  263. package/dist/runtime/base-classes/synced-entity-repository.js.map +0 -1
  264. package/dist/runtime/base-classes/synced-entity-service.js.map +0 -1
  265. package/dist/runtime/subsystems/auth/protocols/integration-store.js +0 -1
  266. package/dist/runtime/subsystems/auth/runtime/integration-broken.error.js +0 -19
  267. package/dist/runtime/subsystems/auth/runtime/integration-broken.error.js.map +0 -1
  268. package/dist/runtime/subsystems/sync/build-change-source.js.map +0 -1
  269. package/dist/runtime/subsystems/sync/deep-equal.differ.js.map +0 -1
  270. package/dist/runtime/subsystems/sync/detection-config.schema.js.map +0 -1
  271. package/dist/runtime/subsystems/sync/execute-sync.use-case.js.map +0 -1
  272. package/dist/runtime/subsystems/sync/index.d.ts +0 -28
  273. package/dist/runtime/subsystems/sync/index.js.map +0 -1
  274. package/dist/runtime/subsystems/sync/loopback.middleware.js.map +0 -1
  275. package/dist/runtime/subsystems/sync/poll-change-source.js.map +0 -1
  276. package/dist/runtime/subsystems/sync/sync-audit.schema.js.map +0 -1
  277. package/dist/runtime/subsystems/sync/sync-change-source.protocol.js +0 -1
  278. package/dist/runtime/subsystems/sync/sync-cursor-store.drizzle-backend.js.map +0 -1
  279. package/dist/runtime/subsystems/sync/sync-cursor-store.memory-backend.js.map +0 -1
  280. package/dist/runtime/subsystems/sync/sync-cursor-store.protocol.js +0 -1
  281. package/dist/runtime/subsystems/sync/sync-errors.js.map +0 -1
  282. package/dist/runtime/subsystems/sync/sync-field-diff.protocol.js.map +0 -1
  283. package/dist/runtime/subsystems/sync/sync-loopback.protocol.js +0 -1
  284. package/dist/runtime/subsystems/sync/sync-middleware.protocol.js +0 -1
  285. package/dist/runtime/subsystems/sync/sync-run-recorder.drizzle-backend.js.map +0 -1
  286. package/dist/runtime/subsystems/sync/sync-run-recorder.memory-backend.js.map +0 -1
  287. package/dist/runtime/subsystems/sync/sync-run-recorder.protocol.js +0 -1
  288. package/dist/runtime/subsystems/sync/sync-sink.protocol.js +0 -1
  289. package/dist/runtime/subsystems/sync/sync.module.js.map +0 -1
  290. package/dist/runtime/subsystems/sync/sync.tokens.d.ts +0 -47
  291. package/dist/runtime/subsystems/sync/sync.tokens.js +0 -18
  292. package/dist/runtime/subsystems/sync/sync.tokens.js.map +0 -1
  293. package/dist/runtime/subsystems/sync/webhook-change-source.js.map +0 -1
  294. package/examples/auth-integrations/runtime/integrations/integrations-auth.module.ts +0 -81
  295. package/examples/auth-integrations/runtime/integrations/oauth/use-cases/list-user-integrations.use-case.ts +0 -21
  296. package/examples/auth-integrations/runtime/integrations/oauth/use-cases/mark-integration-requires-reauth.use-case.ts +0 -21
  297. package/runtime/subsystems/sync/sync.tokens.ts +0 -49
  298. package/templates/subsystem/sync/sync-audit.schema.ejs.t +0 -192
  299. package/templates/subsystem/sync-config/prompt.js +0 -22
  300. /package/dist/runtime/base-classes/{sync-upsert-config.js.map → integration-upsert-config.js.map} +0 -0
  301. /package/dist/runtime/subsystems/auth/protocols/{integration-store.js.map → connection-store.js.map} +0 -0
  302. /package/dist/runtime/subsystems/{sync/sync-change-source.protocol.js.map → integration/integration-change-source.protocol.js.map} +0 -0
  303. /package/dist/runtime/subsystems/{sync/sync-cursor-store.protocol.js.map → integration/integration-cursor-store.protocol.js.map} +0 -0
  304. /package/dist/runtime/subsystems/{sync/sync-loopback.protocol.js.map → integration/integration-loopback.protocol.js.map} +0 -0
  305. /package/dist/runtime/subsystems/{sync/sync-middleware.protocol.js.map → integration/integration-middleware.protocol.js.map} +0 -0
  306. /package/dist/runtime/subsystems/{sync/sync-run-recorder.protocol.js.map → integration/integration-run-recorder.protocol.js.map} +0 -0
  307. /package/dist/runtime/subsystems/{sync/sync-sink.protocol.js.map → integration/integration-sink.protocol.js.map} +0 -0
@@ -9,25 +9,25 @@
9
9
  * AuthController,
10
10
  * ENCRYPTION_KEY,
11
11
  * OAUTH_STATE_STORE,
12
- * AUTH_INTEGRATION_READER,
13
- * AUTH_INTEGRATION_TOKEN_WRITER,
14
- * AUTH_INTEGRATION_GRANT_SINK,
12
+ * AUTH_CONNECTION_READER,
13
+ * AUTH_CONNECTION_TOKEN_WRITER,
14
+ * AUTH_CONNECTION_GRANT_SINK,
15
15
  * AUTH_USER_CONTEXT,
16
16
  * STRATEGY_REGISTRY,
17
17
  * AUTH_OPTIONS,
18
18
  * OAuth2RefreshStrategy,
19
19
  * withAuthRetry,
20
- * IntegrationBrokenError,
20
+ * ConnectionBrokenError,
21
21
  * SessionExpiredError,
22
22
  * OAuthStateError,
23
23
  * type IAuthStrategy,
24
24
  * type IEncryptionKey,
25
25
  * type IOAuthStateStore,
26
26
  * type OAuthStateRecord,
27
- * type IIntegrationReader,
28
- * type IIntegrationTokenWriter,
29
- * type IIntegrationGrantSink,
30
- * type IntegrationGrantInput,
27
+ * type IConnectionReader,
28
+ * type IConnectionTokenWriter,
29
+ * type IConnectionGrantSink,
30
+ * type ConnectionGrantInput,
31
31
  * type IUserContext,
32
32
  * type IProviderStrategy,
33
33
  * type ProviderStrategyRegistry,
@@ -49,13 +49,13 @@ export type {
49
49
  } from './protocols/oauth-state-store';
50
50
  export { OAuthStateError } from './protocols/oauth-state-store';
51
51
  export type {
52
- DecryptedIntegration,
53
- IIntegrationReader,
54
- IIntegrationTokenWriter,
55
- IntegrationTokenUpdate,
56
- IIntegrationGrantSink,
57
- IntegrationGrantInput,
58
- } from './protocols/integration-store';
52
+ DecryptedConnection,
53
+ IConnectionReader,
54
+ IConnectionTokenWriter,
55
+ ConnectionTokenUpdate,
56
+ IConnectionGrantSink,
57
+ ConnectionGrantInput,
58
+ } from './protocols/connection-store';
59
59
  export type { IUserContext } from './protocols/user-context';
60
60
  export type {
61
61
  IProviderStrategy,
@@ -67,9 +67,9 @@ export type {
67
67
  export {
68
68
  ENCRYPTION_KEY,
69
69
  OAUTH_STATE_STORE,
70
- AUTH_INTEGRATION_READER,
71
- AUTH_INTEGRATION_TOKEN_WRITER,
72
- AUTH_INTEGRATION_GRANT_SINK,
70
+ AUTH_CONNECTION_READER,
71
+ AUTH_CONNECTION_TOKEN_WRITER,
72
+ AUTH_CONNECTION_GRANT_SINK,
73
73
  AUTH_USER_CONTEXT,
74
74
  STRATEGY_REGISTRY,
75
75
  AUTH_OPTIONS,
@@ -83,7 +83,7 @@ export {
83
83
  type FetchLike,
84
84
  } from './runtime/oauth2-refresh.strategy';
85
85
  export { withAuthRetry, type WithAuthRetryOptions } from './runtime/with-auth-retry';
86
- export { IntegrationBrokenError } from './runtime/integration-broken.error';
86
+ export { ConnectionBrokenError } from './runtime/connection-broken.error';
87
87
  export {
88
88
  SessionExpiredError,
89
89
  isSessionExpiredError,
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Auth subsystem — `IAuthStrategy` port.
3
3
  *
4
- * The credentials-resolution seam used by every integration adapter. Adapters
4
+ * The credentials-resolution seam used by every connection adapter. Adapters
5
5
  * depend on this interface; concrete strategies (SalesforceAuthStrategy,
6
6
  * HubSpotAuthStrategy, future Gmail/Calendar) typically extend the
7
7
  * `OAuth2RefreshStrategy` template-method base in `../runtime/`.
@@ -35,12 +35,12 @@ export interface AuthResolveOptions {
35
35
  }
36
36
 
37
37
  /**
38
- * Auth-strategy contract shared by every integration adapter. Implementations
38
+ * Auth-strategy contract shared by every connection adapter. Implementations
39
39
  * typically extend `OAuth2RefreshStrategy` and override four small hooks.
40
40
  */
41
41
  export interface IAuthStrategy {
42
42
  resolve(
43
- integrationId: string,
43
+ connectionId: string,
44
44
  opts?: AuthResolveOptions,
45
45
  ): Promise<AuthCredentials>;
46
46
  }
@@ -1,26 +1,26 @@
1
1
  /**
2
- * Auth subsystem — integration storage ports.
2
+ * Auth subsystem — connection storage ports.
3
3
  *
4
- * `OAuth2RefreshStrategy` reads decrypted integration rows and persists
4
+ * `OAuth2RefreshStrategy` reads decrypted connection rows and persists
5
5
  * refreshed tokens. The subsystem doesn't care what entity framework stores
6
6
  * those rows — consumers implement these narrow ports against whatever
7
- * `integrations` table their app uses.
7
+ * `connections` table their app uses.
8
8
  *
9
9
  * In the extraction-source app both ports are satisfied by a
10
- * pair of thin adapters over `IntegrationService` + `RefreshIntegrationUseCase`.
10
+ * pair of thin adapters over `ConnectionService` + `RefreshConnectionUseCase`.
11
11
  * The codegen-patterns `examples/auth-integrations/` starter (separate PR)
12
- * ships a canonical `integration.yaml` whose generated service + use case
12
+ * ships a canonical `connection.yaml` whose generated service + use case
13
13
  * satisfy the shape out of the box.
14
14
  */
15
15
 
16
16
  /**
17
- * An integration row with its secrets decrypted and ready to use.
17
+ * An connection row with its secrets decrypted and ready to use.
18
18
  *
19
19
  * Consumers produce this shape from their own storage by passing stored
20
20
  * ciphertexts through `IEncryptionKey.decrypt`. The subsystem never sees
21
21
  * the ciphertext form.
22
22
  */
23
- export interface DecryptedIntegration {
23
+ export interface DecryptedConnection {
24
24
  id: string;
25
25
  /** Provider slug — must match the strategy's `provider`. */
26
26
  provider: string;
@@ -35,13 +35,13 @@ export interface DecryptedIntegration {
35
35
  }
36
36
 
37
37
  /**
38
- * Read port — fetches a decrypted integration by id.
38
+ * Read port — fetches a decrypted connection by id.
39
39
  *
40
40
  * Adapters typically wrap a service/repo call that does the decryption
41
41
  * internally. `OAuth2RefreshStrategy.resolve()` calls this on every invocation.
42
42
  */
43
- export interface IIntegrationReader {
44
- findByIdDecrypted(integrationId: string): Promise<DecryptedIntegration | null>;
43
+ export interface IConnectionReader {
44
+ findByIdDecrypted(connectionId: string): Promise<DecryptedConnection | null>;
45
45
  }
46
46
 
47
47
  /**
@@ -54,15 +54,15 @@ export interface IIntegrationReader {
54
54
  * `refreshToken` semantics: `undefined` means "provider did not rotate; keep
55
55
  * existing ciphertext". A rotated token comes through as a string.
56
56
  */
57
- export interface IntegrationTokenUpdate {
58
- integrationId: string;
57
+ export interface ConnectionTokenUpdate {
58
+ connectionId: string;
59
59
  accessToken: string;
60
60
  refreshToken?: string;
61
61
  expiresAt: Date;
62
62
  }
63
63
 
64
- export interface IIntegrationTokenWriter {
65
- persistRefresh(update: IntegrationTokenUpdate): Promise<void>;
64
+ export interface IConnectionTokenWriter {
65
+ persistRefresh(update: ConnectionTokenUpdate): Promise<void>;
66
66
  }
67
67
 
68
68
  /**
@@ -71,10 +71,10 @@ export interface IIntegrationTokenWriter {
71
71
  * re-connected an existing one).
72
72
  *
73
73
  * `AuthController.callback` invokes this after `IProviderStrategy.exchangeCodeForTokens`.
74
- * The subsystem itself never imports a concrete `IntegrationsService` — the
74
+ * The subsystem itself never imports a concrete `ConnectionsService` — the
75
75
  * consumer's `auth-integrations` starter (or any equivalent) adapts this
76
76
  * port. Keeps the auth subsystem standalone: a non-codegen consumer can
77
- * satisfy the port against its own integrations storage.
77
+ * satisfy the port against its own connections storage.
78
78
  *
79
79
  * Semantics:
80
80
  * - Upserts on `(userId, provider)`. Repeated grants for the same pair
@@ -85,7 +85,7 @@ export interface IIntegrationTokenWriter {
85
85
  * them (e.g. some providers omit `expires_in`; not every flow returns
86
86
  * a refresh token on first grant).
87
87
  */
88
- export interface IntegrationGrantInput {
88
+ export interface ConnectionGrantInput {
89
89
  userId: string;
90
90
  /** Provider slug — must match the strategy's `provider`. */
91
91
  provider: string;
@@ -98,6 +98,6 @@ export interface IntegrationGrantInput {
98
98
  providerMetadata?: Record<string, unknown>;
99
99
  }
100
100
 
101
- export interface IIntegrationGrantSink {
102
- createOrUpdateFromOAuthGrant(input: IntegrationGrantInput): Promise<void>;
101
+ export interface IConnectionGrantSink {
102
+ createOrUpdateFromOAuthGrant(input: ConnectionGrantInput): Promise<void>;
103
103
  }
@@ -18,9 +18,9 @@
18
18
  * and dispatches by slug.
19
19
  *
20
20
  * **Naming convention:** interfaces that describe behavioral ports use the
21
- * `I` prefix (`IProviderStrategy`, `IIntegrationReader`, `IUserContext`,
21
+ * `I` prefix (`IProviderStrategy`, `IConnectionReader`, `IUserContext`,
22
22
  * `IOAuthStateStore`, `IEncryptionKey`). Plain data types / DTOs (e.g.
23
- * `ExchangedTokens`, `DecryptedIntegration`, `IntegrationGrantInput`) do
23
+ * `ExchangedTokens`, `DecryptedConnection`, `ConnectionGrantInput`) do
24
24
  * not. Abstract template-method classes (e.g. `OAuth2RefreshStrategy`) also
25
25
  * do not — the `I` is for interfaces only.
26
26
  */
@@ -2,20 +2,20 @@
2
2
  * Thrown when an OAuth2 provider returns `400 invalid_grant`/`invalid_token`
3
3
  * on refresh — the refresh token itself is dead (user revoked, org
4
4
  * deactivated, token expired beyond the provider's rotation window). The
5
- * integration should be marked broken so background sync stops picking it
5
+ * connection should be marked broken so background sync stops picking it
6
6
  * up; the user re-initiates OAuth.
7
7
  *
8
8
  * Shared across every OAuth2 strategy.
9
9
  */
10
- export class IntegrationBrokenError extends Error {
10
+ export class ConnectionBrokenError extends Error {
11
11
  constructor(
12
- readonly integrationId: string,
12
+ readonly connectionId: string,
13
13
  readonly errorCode: string,
14
14
  readonly errorDescription: string,
15
15
  ) {
16
16
  super(
17
- `Integration ${integrationId} broken: ${errorCode} - ${errorDescription}`,
17
+ `Connection ${connectionId} broken: ${errorCode} - ${errorDescription}`,
18
18
  );
19
- this.name = 'IntegrationBrokenError';
19
+ this.name = 'ConnectionBrokenError';
20
20
  }
21
21
  }
@@ -8,18 +8,18 @@
8
8
  * later" evidence.
9
9
  *
10
10
  * Subclass contract:
11
- * - `provider` — slug matched against `integrations.provider`
11
+ * - `provider` — slug matched against `connections.provider`
12
12
  * - `defaultExpiresInSec` — fallback when refresh response omits `expires_in`
13
13
  * - `tokenEndpoint()` — URL to POST the refresh grant
14
14
  * - `refreshBodyExtras()` — provider-specific body params
15
15
  * - `parseRefreshResponse()` — raw JSON → ParsedRefreshResponse
16
16
  * - `buildCredentials()` — stored or freshly-refreshed access token +
17
- * integration + optional raw refresh response
17
+ * connection + optional raw refresh response
18
18
  * → provider credentials
19
19
  *
20
20
  * Base handles: expiry check w/ 5-min safety window, `forceRefresh` escape
21
21
  * hatch, POST form-urlencoded body, OAuth2 error mapping to
22
- * `IntegrationBrokenError`, refresh-token rotation persistence, fetch +
22
+ * `ConnectionBrokenError`, refresh-token rotation persistence, fetch +
23
23
  * clock injection for tests.
24
24
  */
25
25
  import type {
@@ -28,11 +28,11 @@ import type {
28
28
  IAuthStrategy,
29
29
  } from '../protocols/auth-strategy';
30
30
  import type {
31
- DecryptedIntegration,
32
- IIntegrationReader,
33
- IIntegrationTokenWriter,
34
- } from '../protocols/integration-store';
35
- import { IntegrationBrokenError } from './integration-broken.error';
31
+ DecryptedConnection,
32
+ IConnectionReader,
33
+ IConnectionTokenWriter,
34
+ } from '../protocols/connection-store';
35
+ import { ConnectionBrokenError } from './connection-broken.error';
36
36
 
37
37
  export type FetchLike = (
38
38
  input: string | URL | Request,
@@ -43,8 +43,8 @@ export type FetchLike = (
43
43
  const REFRESH_SAFETY_MS = 5 * 60 * 1000;
44
44
 
45
45
  export interface OAuth2RefreshStrategyOptions {
46
- integrationReader: IIntegrationReader;
47
- tokenWriter: IIntegrationTokenWriter;
46
+ connectionReader: IConnectionReader;
47
+ tokenWriter: IConnectionTokenWriter;
48
48
  /** Injectable fetch for tests. Defaults to the global `fetch`. */
49
49
  fetch?: FetchLike;
50
50
  /** Injectable clock for tests. Defaults to `Date.now`. */
@@ -66,65 +66,65 @@ export abstract class OAuth2RefreshStrategy implements IAuthStrategy {
66
66
  protected abstract readonly provider: string;
67
67
  protected abstract readonly defaultExpiresInSec: number;
68
68
 
69
- protected readonly integrationReader: IIntegrationReader;
70
- protected readonly tokenWriter: IIntegrationTokenWriter;
69
+ protected readonly connectionReader: IConnectionReader;
70
+ protected readonly tokenWriter: IConnectionTokenWriter;
71
71
  protected readonly fetchImpl: FetchLike;
72
72
  protected readonly now: () => number;
73
73
 
74
74
  constructor(opts: OAuth2RefreshStrategyOptions) {
75
- this.integrationReader = opts.integrationReader;
75
+ this.connectionReader = opts.connectionReader;
76
76
  this.tokenWriter = opts.tokenWriter;
77
77
  this.fetchImpl = opts.fetch ?? fetch;
78
78
  this.now = opts.now ?? Date.now;
79
79
  }
80
80
 
81
81
  async resolve(
82
- integrationId: string,
82
+ connectionId: string,
83
83
  opts: AuthResolveOptions = {},
84
84
  ): Promise<AuthCredentials> {
85
- const integration =
86
- await this.integrationReader.findByIdDecrypted(integrationId);
87
- if (!integration) {
88
- throw new Error(`Integration ${integrationId} not found`);
85
+ const connection =
86
+ await this.connectionReader.findByIdDecrypted(connectionId);
87
+ if (!connection) {
88
+ throw new Error(`Connection ${connectionId} not found`);
89
89
  }
90
- if (integration.provider !== this.provider) {
90
+ if (connection.provider !== this.provider) {
91
91
  throw new Error(
92
- `${this.constructor.name} called for non-${this.provider} integration ${integrationId} (provider=${integration.provider})`,
92
+ `${this.constructor.name} called for non-${this.provider} connection ${connectionId} (provider=${connection.provider})`,
93
93
  );
94
94
  }
95
95
 
96
96
  const needsRefresh =
97
97
  opts.forceRefresh ||
98
- this.isExpiring(integration.expiresAt) ||
99
- !integration.accessToken;
98
+ this.isExpiring(connection.expiresAt) ||
99
+ !connection.accessToken;
100
100
 
101
101
  if (!needsRefresh) {
102
- return this.buildCredentials(integration.accessToken, integration);
102
+ return this.buildCredentials(connection.accessToken, connection);
103
103
  }
104
104
 
105
- if (!integration.refreshToken) {
106
- throw new IntegrationBrokenError(
107
- integrationId,
105
+ if (!connection.refreshToken) {
106
+ throw new ConnectionBrokenError(
107
+ connectionId,
108
108
  'no_refresh_token',
109
- 'Integration has no refresh token; user must reconnect',
109
+ 'Connection has no refresh token; user must reconnect',
110
110
  );
111
111
  }
112
112
 
113
113
  const { parsed, raw } = await this.executeRefresh(
114
- integrationId,
115
- integration.refreshToken,
114
+ connectionId,
115
+ connection.refreshToken,
116
116
  );
117
117
  const newExpiresAt = new Date(
118
118
  this.now() + (parsed.expiresInSec ?? this.defaultExpiresInSec) * 1000,
119
119
  );
120
120
  await this.tokenWriter.persistRefresh({
121
- integrationId,
121
+ connectionId,
122
122
  accessToken: parsed.accessToken,
123
123
  refreshToken: parsed.refreshToken ?? undefined,
124
124
  expiresAt: newExpiresAt,
125
125
  });
126
126
 
127
- return this.buildCredentials(parsed.accessToken, integration, raw);
127
+ return this.buildCredentials(parsed.accessToken, connection, raw);
128
128
  }
129
129
 
130
130
  protected abstract tokenEndpoint(): string;
@@ -132,12 +132,12 @@ export abstract class OAuth2RefreshStrategy implements IAuthStrategy {
132
132
  protected abstract parseRefreshResponse(raw: unknown): ParsedRefreshResponse;
133
133
  protected abstract buildCredentials(
134
134
  accessToken: string,
135
- integration: DecryptedIntegration,
135
+ connection: DecryptedConnection,
136
136
  refreshRaw?: unknown,
137
137
  ): AuthCredentials;
138
138
 
139
139
  private async executeRefresh(
140
- integrationId: string,
140
+ connectionId: string,
141
141
  refreshToken: string,
142
142
  ): Promise<{ parsed: ParsedRefreshResponse; raw: unknown }> {
143
143
  const body = new URLSearchParams({
@@ -160,8 +160,8 @@ export abstract class OAuth2RefreshStrategy implements IAuthStrategy {
160
160
  response.status === 400 &&
161
161
  (err.error === 'invalid_grant' || err.error === 'invalid_token')
162
162
  ) {
163
- throw new IntegrationBrokenError(
164
- integrationId,
163
+ throw new ConnectionBrokenError(
164
+ connectionId,
165
165
  err.error ?? 'invalid_grant',
166
166
  err.error_description ?? err.message ?? 'refresh token rejected',
167
167
  );
@@ -33,18 +33,18 @@ export interface WithAuthRetryOptions {
33
33
 
34
34
  export async function withAuthRetry<T>(
35
35
  authStrategy: IAuthStrategy,
36
- integrationId: string,
36
+ connectionId: string,
37
37
  op: (credentials: AuthCredentials) => Promise<T>,
38
38
  options: WithAuthRetryOptions = {},
39
39
  ): Promise<T> {
40
40
  const classify = options.isSessionExpired ?? isSessionExpiredError;
41
41
 
42
- let creds = await authStrategy.resolve(integrationId);
42
+ let creds = await authStrategy.resolve(connectionId);
43
43
  try {
44
44
  return await op(creds);
45
45
  } catch (e) {
46
46
  if (!classify(e)) throw e;
47
- creds = await authStrategy.resolve(integrationId, { forceRefresh: true });
47
+ creds = await authStrategy.resolve(connectionId, { forceRefresh: true });
48
48
  return op(creds);
49
49
  }
50
50
  }
@@ -59,17 +59,16 @@ const POLL_BATCH_SIZE = 50;
59
59
  * the per-event extraction logic in one place so publish/publishMany stay
60
60
  * in sync.
61
61
  */
62
- function toInsertValues(event: DomainEvent) {
62
+ function toInsertValues(event: DomainEvent, multiTenant: boolean) {
63
63
  const metadata = event.metadata ?? undefined;
64
64
  const pool = (metadata?.['pool'] as string | undefined) ?? null;
65
65
  const direction = (metadata?.['direction'] as string | undefined) ?? null;
66
- const tenantId = (metadata?.['tenantId'] as string | undefined) ?? null;
67
66
  // AUDIT-1: tier defaults to 'domain' when absent. The DB CHECK
68
67
  // constraint (`domain_events_tier_routing_check`) enforces the
69
68
  // tier ⇔ routing-fields invariant at the storage boundary; no
70
69
  // JS-side assertion is needed here.
71
70
  const tier = (metadata?.['tier'] as string | undefined) ?? 'domain';
72
- return {
71
+ const base = {
73
72
  id: event.id,
74
73
  type: event.type,
75
74
  aggregateId: event.aggregateId,
@@ -82,8 +81,14 @@ function toInsertValues(event: DomainEvent) {
82
81
  pool,
83
82
  direction,
84
83
  tier,
85
- tenantId,
86
84
  };
85
+ // EVT-8: `tenant_id` is a scaffold-time conditional column, emitted only
86
+ // when `events.multi_tenant: true`. Only write it when multi-tenancy is
87
+ // on — under single-tenant scaffolds the column does not exist, so the
88
+ // key must be omitted from the insert.
89
+ if (!multiTenant) return base;
90
+ const tenantId = (metadata?.['tenantId'] as string | undefined) ?? null;
91
+ return { ...base, tenantId };
87
92
  }
88
93
 
89
94
  /**
@@ -107,7 +112,11 @@ function toEventSummary(r: DomainEventRecord) {
107
112
  direction: r.direction,
108
113
  tier: r.tier,
109
114
  rootRunId: typeof rootRunId === 'string' ? rootRunId : null,
110
- tenantId: r.tenantId,
115
+ // EVT-8: `tenant_id` is a scaffold-time conditional column. Read it
116
+ // structurally so this projection typechecks against both the
117
+ // multi-tenant schema (column present) and the single-tenant schema
118
+ // (column absent → undefined → null).
119
+ tenantId: (r as { tenantId?: string | null }).tenantId ?? null,
111
120
  occurredAt:
112
121
  r.occurredAt instanceof Date
113
122
  ? r.occurredAt
@@ -175,13 +184,17 @@ export class DrizzleEventBus implements IEventBus, IEventReadPort, OnModuleInit,
175
184
 
176
185
  async publish(event: DomainEvent, tx?: DrizzleTransaction): Promise<void> {
177
186
  const client = (tx ?? this.db) as DrizzleClient;
178
- await client.insert(domainEvents).values(toInsertValues(event));
187
+ const multiTenant = this.opts.multiTenant ?? false;
188
+ await client.insert(domainEvents).values(toInsertValues(event, multiTenant));
179
189
  }
180
190
 
181
191
  async publishMany(events: DomainEvent[], tx?: DrizzleTransaction): Promise<void> {
182
192
  if (events.length === 0) return;
183
193
  const client = (tx ?? this.db) as DrizzleClient;
184
- await client.insert(domainEvents).values(events.map(toInsertValues));
194
+ const multiTenant = this.opts.multiTenant ?? false;
195
+ await client
196
+ .insert(domainEvents)
197
+ .values(events.map((e) => toInsertValues(e, multiTenant)));
185
198
  }
186
199
 
187
200
  async findById(eventId: string): Promise<DomainEvent | null> {
@@ -241,11 +254,20 @@ export class DrizzleEventBus implements IEventBus, IEventReadPort, OnModuleInit,
241
254
  sql`${domainEvents.metadata}->>'rootRunId' = ${query.rootRunId}`,
242
255
  );
243
256
  }
244
- if (query.tenantId !== undefined) {
257
+ // EVT-8: `tenant_id` is a scaffold-time conditional column (emitted only
258
+ // under `events.multi_tenant: true`). Guard the filter behind the same
259
+ // `multiTenant` flag, and read the column structurally so this backend
260
+ // typechecks against both the multi-tenant schema (column present) and
261
+ // the single-tenant schema (column absent). When multi-tenancy is off
262
+ // there is no `tenant_id` column to filter on.
263
+ if (this.opts.multiTenant && query.tenantId !== undefined) {
264
+ const tenantIdColumn = (
265
+ domainEvents as unknown as { tenantId: typeof domainEvents.pool }
266
+ ).tenantId;
245
267
  conditions.push(
246
268
  query.tenantId === null
247
- ? (sql`${domainEvents.tenantId} is null` as SQL<unknown>)
248
- : eq(domainEvents.tenantId, query.tenantId),
269
+ ? (sql`${tenantIdColumn} is null` as SQL<unknown>)
270
+ : eq(tenantIdColumn, query.tenantId),
249
271
  );
250
272
  }
251
273
 
@@ -57,9 +57,27 @@ import { DRIZZLE } from '../../constants/tokens';
57
57
  import type { DrizzleClient } from '../../types/drizzle';
58
58
  import { DrizzleEventBus } from './event-bus.drizzle-backend';
59
59
  import { MemoryEventBus } from './event-bus.memory-backend';
60
- import { RedisEventBus } from './event-bus.redis-backend';
60
+ // #6 — `RedisEventBus` is lazy-loaded only when `backend: 'redis'` is selected.
61
+ // The file is filtered out of the vendor set for non-redis installs (see
62
+ // `backendFileFilter` in src/cli/commands/subsystem.ts); the dynamic-string
63
+ // import below makes TS treat the specifier as `any` so the consumer's tsc
64
+ // never tries to resolve the absent file.
61
65
  import { TypedEventBus } from './generated/bus';
62
66
 
67
+ /**
68
+ * Lazy-load the Redis backend. Routed through a non-literal specifier so
69
+ * the consumer's `tsc` doesn't resolve `./event-bus.redis-backend` at type
70
+ * check time — important because that file is filtered out of drizzle/
71
+ * memory installs (#6).
72
+ */
73
+ async function loadRedisEventBus(): Promise<new (url: string) => object> {
74
+ // Non-literal specifier — TS gives this an `any` module type, sidestepping
75
+ // resolution of a file that may not be vendored.
76
+ const specifier = './event-bus.redis-backend';
77
+ const mod = (await import(specifier)) as { RedisEventBus: new (url: string) => object };
78
+ return mod.RedisEventBus;
79
+ }
80
+
63
81
  export interface EventsModuleOptions {
64
82
  backend: 'drizzle' | 'memory' | 'redis';
65
83
  /**
@@ -124,11 +142,11 @@ function buildTypedBusProviders(multiTenant: boolean): Provider[] {
124
142
  * drizzle backend is selected but no DRIZZLE provider is registered, we
125
143
  * throw a clear error instead of silently constructing a broken bus.
126
144
  */
127
- function buildEventBusAsync(
145
+ async function buildEventBusAsync(
128
146
  options: EventsModuleOptions,
129
147
  db: DrizzleClient | null,
130
148
  redisUrl: string,
131
- ): unknown {
149
+ ): Promise<unknown> {
132
150
  if (options.backend === 'drizzle') {
133
151
  if (!db) {
134
152
  throw new Error(
@@ -139,6 +157,9 @@ function buildEventBusAsync(
139
157
  return new DrizzleEventBus(db, options);
140
158
  }
141
159
  if (options.backend === 'redis') {
160
+ // #6: lazy import — the redis backend ships only with `--backend redis`
161
+ // installs; drizzle/memory consumers never touch the file.
162
+ const RedisEventBus = await loadRedisEventBus();
142
163
  return new RedisEventBus(redisUrl);
143
164
  }
144
165
  return new MemoryEventBus(options);
@@ -214,9 +235,20 @@ export class EventsModule {
214
235
  providers: [
215
236
  { provide: EVENTS_MODULE_OPTIONS, useValue: options },
216
237
  { provide: REDIS_URL, useValue: resolvedUrl },
217
- { provide: EVENT_BUS, useClass: RedisEventBus },
218
- // Register concrete class so NestJS can resolve lifecycle hooks
219
- RedisEventBus,
238
+ {
239
+ // #6: useFactory + dynamic import so the consumer's tsc never
240
+ // needs to resolve `event-bus.redis-backend.ts` for drizzle/
241
+ // memory installs (the file is filtered out by
242
+ // `backendFileFilter`). Nest awaits async factories + manages
243
+ // lifecycle on the returned instance, so we drop the old bare
244
+ // `RedisEventBus` provider entry.
245
+ provide: EVENT_BUS,
246
+ useFactory: async (url: string): Promise<object> => {
247
+ const RedisEventBus = await loadRedisEventBus();
248
+ return new RedisEventBus(url);
249
+ },
250
+ inject: [REDIS_URL],
251
+ },
220
252
  ...buildTypedBusProviders(multiTenant),
221
253
  ],
222
254
  exports: [EVENT_BUS, TYPED_EVENT_BUS, EVENTS_MULTI_TENANT],
@@ -23,6 +23,12 @@ export { EventsModule } from './events.module';
23
23
  export type { EventsModuleOptions } from './events.module';
24
24
  export { MemoryEventBus } from './event-bus.memory-backend';
25
25
  export { DrizzleEventBus } from './event-bus.drizzle-backend';
26
- export { RedisEventBus } from './event-bus.redis-backend';
26
+ // #6 backend-specific implementation classes are NOT re-exported here.
27
+ // `RedisEventBus` is only vendored when the consumer installs with
28
+ // `--backend redis`; surfacing it from this barrel would force the consumer's
29
+ // tsc to resolve `./event-bus.redis-backend` even on a drizzle/memory install
30
+ // (the file is filtered out → TS2307). Consumers who select redis import the
31
+ // class directly from `./event-bus.redis-backend` if they need it at all —
32
+ // `EventsModule.forRoot({ backend: 'redis' })` lazy-loads it internally.
27
33
  export { domainEvents } from './domain-events.schema';
28
34
  export type { DomainEventRecord } from './domain-events.schema';
@@ -46,7 +46,7 @@ export type {
46
46
  PoolStatusCount,
47
47
  JobRunFailure,
48
48
  StatusHistogram,
49
- SyncRunSummary,
49
+ IntegrationRunSummary,
50
50
  CursorSnapshot,
51
51
  } from './observability';
52
52
 
@@ -54,9 +54,9 @@ export type {
54
54
  export {
55
55
  ENCRYPTION_KEY,
56
56
  OAUTH_STATE_STORE,
57
- AUTH_INTEGRATION_READER,
58
- AUTH_INTEGRATION_TOKEN_WRITER,
59
- AUTH_INTEGRATION_GRANT_SINK,
57
+ AUTH_CONNECTION_READER,
58
+ AUTH_CONNECTION_TOKEN_WRITER,
59
+ AUTH_CONNECTION_GRANT_SINK,
60
60
  AUTH_USER_CONTEXT,
61
61
  STRATEGY_REGISTRY,
62
62
  AUTH_OPTIONS,
@@ -64,7 +64,7 @@ export {
64
64
  AuthController,
65
65
  OAuth2RefreshStrategy,
66
66
  withAuthRetry,
67
- IntegrationBrokenError,
67
+ ConnectionBrokenError,
68
68
  SessionExpiredError,
69
69
  isSessionExpiredError,
70
70
  OAuthStateError,
@@ -77,19 +77,19 @@ export type {
77
77
  IAuthStrategy,
78
78
  IEncryptionKey,
79
79
  IOAuthStateStore,
80
- IIntegrationReader,
81
- IIntegrationTokenWriter,
82
- IIntegrationGrantSink,
83
- IntegrationGrantInput,
80
+ IConnectionReader,
81
+ IConnectionTokenWriter,
82
+ IConnectionGrantSink,
83
+ ConnectionGrantInput,
84
84
  IUserContext,
85
85
  IProviderStrategy,
86
86
  ProviderStrategyRegistry,
87
87
  ExchangedTokens,
88
88
  AuthCredentials,
89
89
  AuthResolveOptions,
90
- DecryptedIntegration,
90
+ DecryptedConnection,
91
91
  OAuthStateRecord,
92
- IntegrationTokenUpdate,
92
+ ConnectionTokenUpdate,
93
93
  ParsedRefreshResponse,
94
94
  AuthOAuthState,
95
95
  } from './auth';