@pattern-stack/codegen 0.10.1 → 0.12.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 (279) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/README.md +5 -5
  3. package/consumer-skills/codegen/SKILL.md +2 -2
  4. package/consumer-skills/{sync → integration}/SKILL.md +29 -29
  5. package/consumer-skills/{sync → integration}/audit-and-detection.md +22 -22
  6. package/consumer-skills/{sync → integration}/change-sources-and-sinks.md +60 -60
  7. package/consumer-skills/subsystems/SKILL.md +8 -8
  8. package/consumer-skills/subsystems/wiring-and-order.md +7 -7
  9. package/dist/runtime/base-classes/index.d.ts +4 -4
  10. package/dist/runtime/base-classes/index.js +35 -35
  11. package/dist/runtime/base-classes/index.js.map +1 -1
  12. package/dist/runtime/base-classes/{synced-entity-repository.d.ts → integrated-entity-repository.d.ts} +15 -15
  13. package/dist/runtime/base-classes/{synced-entity-repository.js → integrated-entity-repository.js} +21 -21
  14. package/dist/runtime/base-classes/integrated-entity-repository.js.map +1 -0
  15. package/dist/runtime/base-classes/{synced-entity-service.d.ts → integrated-entity-service.d.ts} +6 -6
  16. package/dist/runtime/base-classes/{synced-entity-service.js → integrated-entity-service.js} +4 -4
  17. package/dist/runtime/base-classes/integrated-entity-service.js.map +1 -0
  18. package/dist/runtime/base-classes/{sync-upsert-config.d.ts → integration-upsert-config.d.ts} +13 -13
  19. package/dist/runtime/base-classes/integration-upsert-config.js +1 -0
  20. package/dist/runtime/base-classes/{junction-sync-repository.d.ts → junction-integration-repository.d.ts} +11 -11
  21. package/dist/runtime/base-classes/{junction-sync-repository.js → junction-integration-repository.js} +15 -15
  22. package/dist/runtime/base-classes/junction-integration-repository.js.map +1 -0
  23. package/dist/runtime/subsystems/auth/auth-oauth-state.schema.js.map +1 -1
  24. package/dist/runtime/subsystems/auth/auth.module.d.ts +4 -4
  25. package/dist/runtime/subsystems/auth/auth.module.js +3 -3
  26. package/dist/runtime/subsystems/auth/auth.module.js.map +1 -1
  27. package/dist/runtime/subsystems/auth/auth.tokens.d.ts +8 -8
  28. package/dist/runtime/subsystems/auth/auth.tokens.js +6 -6
  29. package/dist/runtime/subsystems/auth/auth.tokens.js.map +1 -1
  30. package/dist/runtime/subsystems/auth/backends/state-store.drizzle-backend.js.map +1 -1
  31. package/dist/runtime/subsystems/auth/controllers/auth.controller.d.ts +2 -2
  32. package/dist/runtime/subsystems/auth/controllers/auth.controller.js +3 -3
  33. package/dist/runtime/subsystems/auth/controllers/auth.controller.js.map +1 -1
  34. package/dist/runtime/subsystems/auth/index.d.ts +3 -3
  35. package/dist/runtime/subsystems/auth/index.js +40 -40
  36. package/dist/runtime/subsystems/auth/index.js.map +1 -1
  37. package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -1
  38. package/dist/runtime/subsystems/auth/protocols/auth-strategy.d.ts +3 -3
  39. package/dist/runtime/subsystems/auth/protocols/{integration-store.d.ts → connection-store.d.ts} +20 -20
  40. package/dist/runtime/subsystems/auth/protocols/connection-store.js +1 -0
  41. package/dist/runtime/subsystems/auth/protocols/provider-strategy.d.ts +3 -3
  42. package/dist/runtime/subsystems/auth/runtime/{integration-broken.error.d.ts → connection-broken.error.d.ts} +5 -5
  43. package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js +19 -0
  44. package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js.map +1 -0
  45. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.d.ts +10 -10
  46. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js +28 -28
  47. package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js.map +1 -1
  48. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.d.ts +1 -1
  49. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js +3 -3
  50. package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js.map +1 -1
  51. package/dist/runtime/subsystems/index.d.ts +11 -7
  52. package/dist/runtime/subsystems/index.js +1041 -67
  53. package/dist/runtime/subsystems/index.js.map +1 -1
  54. package/dist/runtime/subsystems/{sync → integration}/build-change-source.d.ts +3 -3
  55. package/dist/runtime/subsystems/{sync → integration}/build-change-source.js +3 -3
  56. package/dist/runtime/subsystems/integration/build-change-source.js.map +1 -0
  57. package/dist/runtime/subsystems/{sync → integration}/deep-equal.differ.d.ts +2 -2
  58. package/dist/runtime/subsystems/{sync → integration}/deep-equal.differ.js +1 -1
  59. package/dist/runtime/subsystems/integration/deep-equal.differ.js.map +1 -0
  60. package/dist/runtime/subsystems/{sync → integration}/detection-config.schema.d.ts +3 -3
  61. package/dist/runtime/subsystems/{sync → integration}/detection-config.schema.js +1 -1
  62. package/dist/runtime/subsystems/integration/detection-config.schema.js.map +1 -0
  63. package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.d.ts +25 -0
  64. package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.js +34 -0
  65. package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.js.map +1 -0
  66. package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.d.ts +53 -0
  67. package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.js +13 -0
  68. package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.js.map +1 -0
  69. package/dist/runtime/subsystems/{sync/execute-sync.use-case.d.ts → integration/execute-integration.use-case.d.ts} +13 -13
  70. package/dist/runtime/subsystems/{sync/execute-sync.use-case.js → integration/execute-integration.use-case.js} +30 -30
  71. package/dist/runtime/subsystems/integration/execute-integration.use-case.js.map +1 -0
  72. package/dist/runtime/subsystems/integration/index.d.ts +30 -0
  73. package/dist/runtime/subsystems/{sync → integration}/index.js +206 -171
  74. package/dist/runtime/subsystems/integration/index.js.map +1 -0
  75. package/dist/runtime/subsystems/{sync/sync-audit.schema.d.ts → integration/integration-audit.schema.d.ts} +64 -64
  76. package/dist/runtime/subsystems/{sync/sync-audit.schema.js → integration/integration-audit.schema.js} +47 -47
  77. package/dist/runtime/subsystems/integration/integration-audit.schema.js.map +1 -0
  78. package/dist/runtime/subsystems/{sync/sync-change-source.protocol.d.ts → integration/integration-change-source.protocol.d.ts} +10 -10
  79. package/dist/runtime/subsystems/integration/integration-change-source.protocol.js +1 -0
  80. package/dist/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.d.ts → integration/integration-cursor-store.drizzle-backend.d.ts} +1 -1
  81. package/dist/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.js → integration/integration-cursor-store.drizzle-backend.js} +65 -65
  82. package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js.map +1 -0
  83. package/dist/runtime/subsystems/{sync/sync-cursor-store.memory-backend.d.ts → integration/integration-cursor-store.memory-backend.d.ts} +6 -6
  84. package/dist/runtime/subsystems/{sync/sync-cursor-store.memory-backend.js → integration/integration-cursor-store.memory-backend.js} +5 -5
  85. package/dist/runtime/subsystems/integration/integration-cursor-store.memory-backend.js.map +1 -0
  86. package/dist/runtime/subsystems/{sync/sync-cursor-store.protocol.d.ts → integration/integration-cursor-store.protocol.d.ts} +13 -13
  87. package/dist/runtime/subsystems/integration/integration-cursor-store.protocol.js +1 -0
  88. package/dist/runtime/subsystems/{sync/sync-errors.d.ts → integration/integration-errors.d.ts} +2 -2
  89. package/dist/runtime/subsystems/{sync/sync-errors.js → integration/integration-errors.js} +3 -3
  90. package/dist/runtime/subsystems/integration/integration-errors.js.map +1 -0
  91. package/dist/runtime/subsystems/{sync/sync-field-diff.protocol.d.ts → integration/integration-field-diff.protocol.d.ts} +2 -2
  92. package/dist/runtime/subsystems/{sync/sync-field-diff.protocol.js → integration/integration-field-diff.protocol.js} +2 -2
  93. package/dist/runtime/subsystems/integration/integration-field-diff.protocol.js.map +1 -0
  94. package/dist/runtime/subsystems/{sync/sync-loopback.protocol.d.ts → integration/integration-loopback.protocol.d.ts} +2 -2
  95. package/dist/runtime/subsystems/integration/integration-loopback.protocol.js +1 -0
  96. package/dist/runtime/subsystems/{sync/sync-middleware.protocol.d.ts → integration/integration-middleware.protocol.d.ts} +5 -5
  97. package/dist/runtime/subsystems/integration/integration-middleware.protocol.js +1 -0
  98. package/dist/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.d.ts → integration/integration-run-recorder.drizzle-backend.d.ts} +5 -5
  99. package/dist/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.js → integration/integration-run-recorder.drizzle-backend.js} +73 -73
  100. package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js.map +1 -0
  101. package/dist/runtime/subsystems/{sync/sync-run-recorder.memory-backend.d.ts → integration/integration-run-recorder.memory-backend.d.ts} +15 -15
  102. package/dist/runtime/subsystems/{sync/sync-run-recorder.memory-backend.js → integration/integration-run-recorder.memory-backend.js} +11 -11
  103. package/dist/runtime/subsystems/integration/integration-run-recorder.memory-backend.js.map +1 -0
  104. package/dist/runtime/subsystems/{sync/sync-run-recorder.protocol.d.ts → integration/integration-run-recorder.protocol.d.ts} +25 -25
  105. package/dist/runtime/subsystems/integration/integration-run-recorder.protocol.js +1 -0
  106. package/dist/runtime/subsystems/{sync/sync-sink.protocol.d.ts → integration/integration-sink.protocol.d.ts} +5 -5
  107. package/dist/runtime/subsystems/integration/integration-sink.protocol.js +1 -0
  108. package/dist/runtime/subsystems/{sync/sync.module.d.ts → integration/integration.module.d.ts} +24 -24
  109. package/dist/runtime/subsystems/{sync/sync.module.js → integration/integration.module.js} +132 -132
  110. package/dist/runtime/subsystems/integration/integration.module.js.map +1 -0
  111. package/dist/runtime/subsystems/integration/integration.tokens.d.ts +60 -0
  112. package/dist/runtime/subsystems/integration/integration.tokens.js +20 -0
  113. package/dist/runtime/subsystems/integration/integration.tokens.js.map +1 -0
  114. package/dist/runtime/subsystems/{sync → integration}/loopback.middleware.d.ts +5 -5
  115. package/dist/runtime/subsystems/{sync → integration}/loopback.middleware.js +1 -1
  116. package/dist/runtime/subsystems/integration/loopback.middleware.js.map +1 -0
  117. package/dist/runtime/subsystems/{sync → integration}/poll-change-source.d.ts +5 -5
  118. package/dist/runtime/subsystems/{sync → integration}/poll-change-source.js +1 -1
  119. package/dist/runtime/subsystems/integration/poll-change-source.js.map +1 -0
  120. package/dist/runtime/subsystems/{sync → integration}/webhook-change-source.d.ts +5 -5
  121. package/dist/runtime/subsystems/{sync → integration}/webhook-change-source.js +1 -1
  122. package/dist/runtime/subsystems/integration/webhook-change-source.js.map +1 -0
  123. package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +1 -1
  124. package/dist/runtime/subsystems/observability/index.d.ts +4 -4
  125. package/dist/runtime/subsystems/observability/index.js +11 -11
  126. package/dist/runtime/subsystems/observability/index.js.map +1 -1
  127. package/dist/runtime/subsystems/observability/observability.module.d.ts +2 -2
  128. package/dist/runtime/subsystems/observability/observability.module.js +11 -11
  129. package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
  130. package/dist/runtime/subsystems/observability/observability.protocol.d.ts +11 -11
  131. package/dist/runtime/subsystems/observability/observability.service.d.ts +6 -6
  132. package/dist/runtime/subsystems/observability/observability.service.js +11 -11
  133. package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
  134. package/dist/runtime/subsystems/observability/observability.tokens.d.ts +1 -1
  135. package/dist/runtime/subsystems/observability/observability.tokens.js.map +1 -1
  136. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +3 -3
  137. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.js.map +1 -1
  138. package/dist/runtime/subsystems/observability/reporters/index.d.ts +3 -3
  139. package/dist/runtime/subsystems/observability/reporters/index.js.map +1 -1
  140. package/dist/src/cli/index.js +1336 -376
  141. package/dist/src/cli/index.js.map +1 -1
  142. package/dist/src/index.d.ts +70 -22
  143. package/dist/src/index.js +290 -194
  144. package/dist/src/index.js.map +1 -1
  145. package/examples/auth-integrations/README.md +32 -32
  146. package/examples/auth-integrations/definitions/entities/{integration.yaml → connection.yaml} +10 -10
  147. package/examples/auth-integrations/runtime/{integrations/adapters/integration-grant-sink.adapter.ts → connections/adapters/connection-grant-sink.adapter.ts} +7 -7
  148. package/examples/auth-integrations/runtime/{integrations/adapters/integration-reader.adapter.ts → connections/adapters/connection-reader.adapter.ts} +10 -10
  149. package/examples/auth-integrations/runtime/{integrations/adapters/integration-token-writer.adapter.ts → connections/adapters/connection-token-writer.adapter.ts} +11 -11
  150. package/examples/auth-integrations/runtime/connections/connections-auth.module.ts +81 -0
  151. package/examples/auth-integrations/runtime/{integrations/facade/integrations.service.ts → connections/facade/connections.service.ts} +35 -35
  152. package/examples/auth-integrations/runtime/{integrations → connections}/oauth/use-cases/create-or-update-from-oauth-grant.use-case.ts +11 -11
  153. 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
  154. package/examples/auth-integrations/runtime/connections/oauth/use-cases/list-user-connections.use-case.ts +21 -0
  155. package/examples/auth-integrations/runtime/connections/oauth/use-cases/mark-connection-requires-reauth.use-case.ts +21 -0
  156. package/package.json +9 -1
  157. package/runtime/base-classes/index.ts +8 -8
  158. package/runtime/base-classes/{synced-entity-repository.ts → integrated-entity-repository.ts} +36 -36
  159. package/runtime/base-classes/{synced-entity-service.ts → integrated-entity-service.ts} +6 -6
  160. package/runtime/base-classes/{sync-upsert-config.ts → integration-upsert-config.ts} +12 -12
  161. package/runtime/base-classes/{junction-sync-repository.ts → junction-integration-repository.ts} +28 -28
  162. package/runtime/subsystems/auth/auth-oauth-state.schema.ts +1 -1
  163. package/runtime/subsystems/auth/auth.module.ts +4 -4
  164. package/runtime/subsystems/auth/auth.tokens.ts +7 -7
  165. package/runtime/subsystems/auth/controllers/auth.controller.ts +7 -7
  166. package/runtime/subsystems/auth/index.ts +19 -19
  167. package/runtime/subsystems/auth/protocols/auth-strategy.ts +3 -3
  168. package/runtime/subsystems/auth/protocols/{integration-store.ts → connection-store.ts} +19 -19
  169. package/runtime/subsystems/auth/protocols/provider-strategy.ts +2 -2
  170. package/runtime/subsystems/auth/runtime/{integration-broken.error.ts → connection-broken.error.ts} +5 -5
  171. package/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.ts +35 -35
  172. package/runtime/subsystems/auth/runtime/with-auth-retry.ts +3 -3
  173. package/runtime/subsystems/index.ts +26 -11
  174. package/runtime/subsystems/{sync → integration}/build-change-source.ts +3 -3
  175. package/runtime/subsystems/{sync → integration}/deep-equal.differ.ts +7 -7
  176. package/runtime/subsystems/{sync → integration}/detection-config.schema.ts +3 -3
  177. package/runtime/subsystems/integration/entity-change-source-registry.memory.ts +40 -0
  178. package/runtime/subsystems/integration/entity-change-source-registry.protocol.ts +59 -0
  179. package/runtime/subsystems/{sync/execute-sync.use-case.ts → integration/execute-integration.use-case.ts} +40 -40
  180. package/runtime/subsystems/{sync → integration}/index.ts +56 -47
  181. package/runtime/subsystems/{sync/sync-audit.schema.ts → integration/integration-audit.schema.ts} +61 -61
  182. package/runtime/subsystems/{sync/sync-change-source.protocol.ts → integration/integration-change-source.protocol.ts} +9 -9
  183. package/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.ts → integration/integration-cursor-store.drizzle-backend.ts} +30 -30
  184. package/runtime/subsystems/{sync/sync-cursor-store.memory-backend.ts → integration/integration-cursor-store.memory-backend.ts} +9 -9
  185. package/runtime/subsystems/{sync/sync-cursor-store.protocol.ts → integration/integration-cursor-store.protocol.ts} +13 -13
  186. package/runtime/subsystems/{sync/sync-errors.ts → integration/integration-errors.ts} +3 -3
  187. package/runtime/subsystems/{sync/sync-field-diff.protocol.ts → integration/integration-field-diff.protocol.ts} +2 -2
  188. package/runtime/subsystems/{sync/sync-loopback.protocol.ts → integration/integration-loopback.protocol.ts} +2 -2
  189. package/runtime/subsystems/{sync/sync-middleware.protocol.ts → integration/integration-middleware.protocol.ts} +6 -6
  190. package/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.ts → integration/integration-run-recorder.drizzle-backend.ts} +39 -39
  191. package/runtime/subsystems/{sync/sync-run-recorder.memory-backend.ts → integration/integration-run-recorder.memory-backend.ts} +23 -23
  192. package/runtime/subsystems/{sync/sync-run-recorder.protocol.ts → integration/integration-run-recorder.protocol.ts} +25 -25
  193. package/runtime/subsystems/{sync/sync-sink.protocol.ts → integration/integration-sink.protocol.ts} +4 -4
  194. package/runtime/subsystems/{sync/sync.module.ts → integration/integration.module.ts} +48 -48
  195. package/runtime/subsystems/integration/integration.tokens.ts +63 -0
  196. package/runtime/subsystems/{sync → integration}/loopback.middleware.ts +5 -5
  197. package/runtime/subsystems/{sync → integration}/poll-change-source.ts +7 -7
  198. package/runtime/subsystems/{sync → integration}/webhook-change-source.ts +7 -7
  199. package/runtime/subsystems/observability/index.ts +1 -1
  200. package/runtime/subsystems/observability/observability.module.ts +2 -2
  201. package/runtime/subsystems/observability/observability.protocol.ts +11 -11
  202. package/runtime/subsystems/observability/observability.service.ts +13 -13
  203. package/runtime/subsystems/observability/observability.tokens.ts +1 -1
  204. package/src/patterns/library/index.ts +4 -4
  205. package/src/patterns/library/{synced.pattern.ts → integrated.pattern.ts} +12 -12
  206. package/src/patterns/library/junction.pattern.ts +1 -1
  207. package/src/patterns/pattern-definition.ts +3 -3
  208. package/templates/entity/new/backend/modules/core/{sync-source.ejs.t → integration-source.ejs.t} +6 -6
  209. package/templates/entity/new/clean-lite-ps/entity.ejs.t +12 -3
  210. package/templates/entity/new/clean-lite-ps/module.ejs.t +1 -1
  211. package/templates/entity/new/clean-lite-ps/prompt-extension.js +243 -60
  212. package/templates/entity/new/clean-lite-ps/repository.ejs.t +27 -27
  213. package/templates/entity/new/frontend/collections/collection.ejs.t +26 -1
  214. package/templates/entity/new/frontend/collections/collections-base.ejs.t +11 -0
  215. package/templates/entity/new/frontend/entity/combined.ejs.t +31 -1
  216. package/templates/entity/new/prompt.js +27 -15
  217. package/templates/junction/new/entity.ejs.t +1 -1
  218. package/templates/junction/new/prompt.js +24 -24
  219. package/templates/junction/new/repository.ejs.t +19 -19
  220. package/templates/subsystem/auth/auth-oauth-state.schema.ejs.t +2 -2
  221. package/templates/subsystem/auth-config/prompt.js +1 -1
  222. package/templates/subsystem/auth-integrations/app-module-hook.ejs.t +5 -5
  223. package/templates/subsystem/bridge/prompt.js +1 -1
  224. package/templates/subsystem/integration/integration-audit.schema.ejs.t +192 -0
  225. package/templates/subsystem/{sync → integration}/prompt.js +12 -12
  226. package/templates/subsystem/{sync-config/codegen-config-sync-block.ejs.t → integration-config/codegen-config-integration-block.ejs.t} +7 -7
  227. package/templates/subsystem/integration-config/prompt.js +22 -0
  228. package/templates/subsystem/jobs/worker.ejs.t +2 -2
  229. package/templates/subsystem/observability/main-hook.ejs.t +1 -1
  230. package/templates/subsystem/observability/prompt.js +1 -1
  231. package/templates/subsystem/openapi-config/prompt.js +1 -1
  232. package/dist/runtime/base-classes/junction-sync-repository.js.map +0 -1
  233. package/dist/runtime/base-classes/sync-upsert-config.js +0 -1
  234. package/dist/runtime/base-classes/synced-entity-repository.js.map +0 -1
  235. package/dist/runtime/base-classes/synced-entity-service.js.map +0 -1
  236. package/dist/runtime/subsystems/auth/protocols/integration-store.js +0 -1
  237. package/dist/runtime/subsystems/auth/runtime/integration-broken.error.js +0 -19
  238. package/dist/runtime/subsystems/auth/runtime/integration-broken.error.js.map +0 -1
  239. package/dist/runtime/subsystems/sync/build-change-source.js.map +0 -1
  240. package/dist/runtime/subsystems/sync/deep-equal.differ.js.map +0 -1
  241. package/dist/runtime/subsystems/sync/detection-config.schema.js.map +0 -1
  242. package/dist/runtime/subsystems/sync/execute-sync.use-case.js.map +0 -1
  243. package/dist/runtime/subsystems/sync/index.d.ts +0 -28
  244. package/dist/runtime/subsystems/sync/index.js.map +0 -1
  245. package/dist/runtime/subsystems/sync/loopback.middleware.js.map +0 -1
  246. package/dist/runtime/subsystems/sync/poll-change-source.js.map +0 -1
  247. package/dist/runtime/subsystems/sync/sync-audit.schema.js.map +0 -1
  248. package/dist/runtime/subsystems/sync/sync-change-source.protocol.js +0 -1
  249. package/dist/runtime/subsystems/sync/sync-cursor-store.drizzle-backend.js.map +0 -1
  250. package/dist/runtime/subsystems/sync/sync-cursor-store.memory-backend.js.map +0 -1
  251. package/dist/runtime/subsystems/sync/sync-cursor-store.protocol.js +0 -1
  252. package/dist/runtime/subsystems/sync/sync-errors.js.map +0 -1
  253. package/dist/runtime/subsystems/sync/sync-field-diff.protocol.js.map +0 -1
  254. package/dist/runtime/subsystems/sync/sync-loopback.protocol.js +0 -1
  255. package/dist/runtime/subsystems/sync/sync-middleware.protocol.js +0 -1
  256. package/dist/runtime/subsystems/sync/sync-run-recorder.drizzle-backend.js.map +0 -1
  257. package/dist/runtime/subsystems/sync/sync-run-recorder.memory-backend.js.map +0 -1
  258. package/dist/runtime/subsystems/sync/sync-run-recorder.protocol.js +0 -1
  259. package/dist/runtime/subsystems/sync/sync-sink.protocol.js +0 -1
  260. package/dist/runtime/subsystems/sync/sync.module.js.map +0 -1
  261. package/dist/runtime/subsystems/sync/sync.tokens.d.ts +0 -47
  262. package/dist/runtime/subsystems/sync/sync.tokens.js +0 -18
  263. package/dist/runtime/subsystems/sync/sync.tokens.js.map +0 -1
  264. package/dist/runtime/subsystems/sync/webhook-change-source.js.map +0 -1
  265. package/examples/auth-integrations/runtime/integrations/integrations-auth.module.ts +0 -81
  266. package/examples/auth-integrations/runtime/integrations/oauth/use-cases/list-user-integrations.use-case.ts +0 -21
  267. package/examples/auth-integrations/runtime/integrations/oauth/use-cases/mark-integration-requires-reauth.use-case.ts +0 -21
  268. package/runtime/subsystems/sync/sync.tokens.ts +0 -49
  269. package/templates/entity/new/backend/modules/core/sync-source.providers.ejs.t +0 -18
  270. package/templates/subsystem/sync/sync-audit.schema.ejs.t +0 -192
  271. package/templates/subsystem/sync-config/prompt.js +0 -22
  272. /package/dist/runtime/base-classes/{sync-upsert-config.js.map → integration-upsert-config.js.map} +0 -0
  273. /package/dist/runtime/subsystems/auth/protocols/{integration-store.js.map → connection-store.js.map} +0 -0
  274. /package/dist/runtime/subsystems/{sync/sync-change-source.protocol.js.map → integration/integration-change-source.protocol.js.map} +0 -0
  275. /package/dist/runtime/subsystems/{sync/sync-cursor-store.protocol.js.map → integration/integration-cursor-store.protocol.js.map} +0 -0
  276. /package/dist/runtime/subsystems/{sync/sync-loopback.protocol.js.map → integration/integration-loopback.protocol.js.map} +0 -0
  277. /package/dist/runtime/subsystems/{sync/sync-middleware.protocol.js.map → integration/integration-middleware.protocol.js.map} +0 -0
  278. /package/dist/runtime/subsystems/{sync/sync-run-recorder.protocol.js.map → integration/integration-run-recorder.protocol.js.map} +0 -0
  279. /package/dist/runtime/subsystems/{sync/sync-sink.protocol.js.map → integration/integration-sink.protocol.js.map} +0 -0
@@ -0,0 +1,21 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { ConnectionService } from '../../connection.service';
3
+ import type { Connection } from '../../connection.entity';
4
+
5
+ /**
6
+ * Lists a user's connections newest-first. Used by the settings page
7
+ * (`GET /connections`) and any "which providers are connected?" UI.
8
+ *
9
+ * Returns rows with ciphertexts intact — callers should NOT pass these
10
+ * to the frontend. Use `ConnectionsService.listByUser` if you need
11
+ * the consumer-facing facade behavior (which strips ciphertexts before
12
+ * returning).
13
+ */
14
+ @Injectable()
15
+ export class ListUserConnectionsUseCase {
16
+ constructor(private readonly connections: ConnectionService) {}
17
+
18
+ async execute(userId: string): Promise<Connection[]> {
19
+ return this.connections.findByUserId(userId);
20
+ }
21
+ }
@@ -0,0 +1,21 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { ConnectionService } from '../../connection.service';
3
+ import type { Connection } from '../../connection.entity';
4
+
5
+ /**
6
+ * Flips an connection's status to `requires_reauth`. Called when the
7
+ * refresh path raises `ConnectionBrokenError` (refresh token rejected,
8
+ * scopes revoked, etc.) — see `OAuth2RefreshStrategy` + `withAuthRetry`.
9
+ *
10
+ * Idempotent: calling on an already-broken row is a no-op write.
11
+ */
12
+ @Injectable()
13
+ export class MarkConnectionRequiresReauthUseCase {
14
+ constructor(private readonly connections: ConnectionService) {}
15
+
16
+ async execute(connectionId: string): Promise<Connection> {
17
+ return this.connections.update(connectionId, {
18
+ status: 'requires_reauth',
19
+ });
20
+ }
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pattern-stack/codegen",
3
- "version": "0.10.1",
3
+ "version": "0.12.0",
4
4
  "description": "Entity-driven code generation for full-stack TypeScript applications",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -27,6 +27,10 @@
27
27
  "types": "./dist/src/index.d.ts",
28
28
  "default": "./dist/src/index.js"
29
29
  },
30
+ "./subsystems": {
31
+ "types": "./dist/runtime/subsystems/index.d.ts",
32
+ "default": "./dist/runtime/subsystems/index.js"
33
+ },
30
34
  "./runtime/*": {
31
35
  "types": "./dist/runtime/*.d.ts",
32
36
  "default": "./dist/runtime/*.js"
@@ -127,6 +131,10 @@
127
131
  ],
128
132
  "devDependencies": {
129
133
  "@anatine/zod-openapi": "^2.2.8",
134
+ "@pattern-stack/codegen-calendar": "workspace:*",
135
+ "@pattern-stack/codegen-crm": "workspace:*",
136
+ "@pattern-stack/codegen-mail": "workspace:*",
137
+ "@pattern-stack/codegen-transcript": "workspace:*",
130
138
  "@cubejs-client/core": "^1.0.0",
131
139
  "@nestjs/common": "10",
132
140
  "@nestjs/core": "10",
@@ -32,24 +32,24 @@ export type { EventCategory } from './lifecycle-events';
32
32
  export { BaseFindByIdUseCase, BaseListUseCase } from './base-read-use-cases';
33
33
  export type { IFindByIdService, IListService } from './base-read-use-cases';
34
34
 
35
- // Sync upsert config (consumed by SyncedEntityRepository + JunctionSyncRepository)
36
- export type { SyncUpsertConfig, SyncFkResolver } from './sync-upsert-config';
35
+ // Integration upsert config (consumed by IntegratedEntityRepository + JunctionIntegrationRepository)
36
+ export type { IntegrationUpsertConfig, IntegrationFkResolver } from './integration-upsert-config';
37
37
 
38
38
  // Family-specific repository base classes
39
- export { SyncedEntityRepository } from './synced-entity-repository';
39
+ export { IntegratedEntityRepository } from './integrated-entity-repository';
40
40
  export {
41
- JunctionSyncRepository,
41
+ JunctionIntegrationRepository,
42
42
  buildCompositeExternalId,
43
43
  parseCompositeExternalId,
44
- } from './junction-sync-repository';
45
- export type { JunctionSyncConfig } from './junction-sync-repository';
44
+ } from './junction-integration-repository';
45
+ export type { JunctionIntegrationConfig } from './junction-integration-repository';
46
46
  export { ActivityEntityRepository } from './activity-entity-repository';
47
47
  export { MetadataEntityRepository } from './metadata-entity-repository';
48
48
  export { KnowledgeEntityRepository } from './knowledge-entity-repository';
49
49
 
50
50
  // Family-specific service base classes
51
- export { SyncedEntityService } from './synced-entity-service';
52
- export type { ISyncedEntityRepository } from './synced-entity-service';
51
+ export { IntegratedEntityService } from './integrated-entity-service';
52
+ export type { IIntegratedEntityRepository } from './integrated-entity-service';
53
53
  export { ActivityEntityService } from './activity-entity-service';
54
54
  export type { IActivityEntityRepository } from './activity-entity-service';
55
55
  export { MetadataEntityService } from './metadata-entity-service';
@@ -1,31 +1,31 @@
1
1
  /**
2
- * SyncedEntityRepository<TEntity, TSyncWrite, TSyncProjection>
2
+ * IntegratedEntityRepository<TEntity, TIntegrationWrite, TIntegrationProjection>
3
3
  *
4
- * Family-specific base for Synced entities (contacts, accounts, opportunities).
5
- * Adds external ID lookups, user-scoped queries, and the generic inbound-sync
4
+ * Family-specific base for Integrated entities (contacts, accounts, opportunities).
5
+ * Adds external ID lookups, user-scoped queries, and the generic inbound-integration
6
6
  * write surface (canonical→Drizzle upsert + provider-scoped FK resolution +
7
- * EAV dual-write seam), driven by the concrete repo's `syncConfig`.
7
+ * EAV dual-write seam), driven by the concrete repo's `integrationConfig`.
8
8
  *
9
9
  * The type params default so pre-existing single-param subclasses keep
10
- * compiling; `pattern: Synced` repos declare all three plus `syncConfig`.
10
+ * compiling; `pattern: Integrated` repos declare all three plus `integrationConfig`.
11
11
  */
12
12
  import { and, eq, inArray } from 'drizzle-orm';
13
13
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
14
  import type { PgTableWithColumns } from 'drizzle-orm/pg-core';
15
15
  import type { DrizzleTx } from '../types/drizzle';
16
16
  import { BaseRepository } from './base-repository';
17
- import type { SyncUpsertConfig, SyncFkResolver } from './sync-upsert-config';
17
+ import type { IntegrationUpsertConfig, IntegrationFkResolver } from './integration-upsert-config';
18
18
 
19
- export abstract class SyncedEntityRepository<
19
+ export abstract class IntegratedEntityRepository<
20
20
  TEntity,
21
- TSyncWrite = Partial<TEntity>,
22
- TSyncProjection = TEntity,
21
+ TIntegrationWrite = Partial<TEntity>,
22
+ TIntegrationProjection = TEntity,
23
23
  > extends BaseRepository<TEntity> {
24
24
  /**
25
- * Declarative sync write surface. Concrete (`pattern: Synced`) repositories
25
+ * Declarative integration write surface. Concrete (`pattern: Integrated`) repositories
26
26
  * declare this — the template emits it from the entity's fields + FKs.
27
27
  */
28
- protected abstract readonly syncConfig: SyncUpsertConfig;
28
+ protected abstract readonly integrationConfig: IntegrationUpsertConfig;
29
29
 
30
30
  /**
31
31
  * Find a single entity by its external CRM identifier.
@@ -57,21 +57,21 @@ export abstract class SyncedEntityRepository<
57
57
  }
58
58
 
59
59
  // ==========================================================================
60
- // Inbound sync (#374) — canonical→Drizzle write + provider-scoped FK
60
+ // Inbound integration (#374) — canonical→Drizzle write + provider-scoped FK
61
61
  // resolution + EAV dual-write seam, all inside a SINGLE transaction.
62
- // Driven entirely by `this.syncConfig`; the per-entity shape lives there.
62
+ // Driven entirely by `this.integrationConfig`; the per-entity shape lives there.
63
63
  // ==========================================================================
64
64
 
65
65
  /**
66
66
  * Upsert ONE entity by its `(provider, externalId)` identity, in a single
67
67
  * transaction:
68
- * 1. resolve each `syncConfig.fkResolvers` FK (provider-scoped). Strict
68
+ * 1. resolve each `integrationConfig.fkResolvers` FK (provider-scoped). Strict
69
69
  * resolvers throw on unresolved; non-strict leave the column null.
70
70
  * 2. insert-or-update the canonical columns via `onConflictDoUpdate` on the
71
71
  * `conflictTarget`. Resolved FKs are only written into `set` when
72
72
  * non-null this run (no-clobber).
73
73
  * 3. EAV dual-write of `write.fields` via `writeCustomFields` when
74
- * `syncConfig.eav` and the bag is non-empty (same tx).
74
+ * `integrationConfig.eav` and the bag is non-empty (same tx).
75
75
  *
76
76
  * Idempotent: a second call with the same identity updates in place. Returns
77
77
  * the canonical projection (so the orchestrator records `local_id`).
@@ -80,15 +80,15 @@ export abstract class SyncedEntityRepository<
80
80
  * @param provider adapter/provider label persisted + used to scope lookups
81
81
  * @param tx optional outer transaction; when omitted we open our own
82
82
  */
83
- async syncUpsertOne(
84
- write: TSyncWrite,
83
+ async integrationUpsertOne(
84
+ write: TIntegrationWrite,
85
85
  provider: string,
86
86
  tx?: DrizzleTx,
87
- ): Promise<TSyncProjection> {
88
- const cfg = this.syncConfig;
87
+ ): Promise<TIntegrationProjection> {
88
+ const cfg = this.integrationConfig;
89
89
  const w = write as Record<string, unknown>;
90
90
 
91
- const run = async (db: DrizzleTx): Promise<TSyncProjection> => {
91
+ const run = async (db: DrizzleTx): Promise<TIntegrationProjection> => {
92
92
  // 1. FK resolution (provider-scoped). Strict → throw; else opportunistic null.
93
93
  const resolvedFks: Record<string, string | null> = {};
94
94
  for (const fk of cfg.fkResolvers) {
@@ -155,7 +155,7 @@ export abstract class SyncedEntityRepository<
155
155
  async findByExternalIdProjected(
156
156
  externalId: string,
157
157
  provider: string,
158
- ): Promise<TSyncProjection | null> {
158
+ ): Promise<TIntegrationProjection | null> {
159
159
  const rows = await this.db
160
160
  .select()
161
161
  .from(this.table)
@@ -171,7 +171,7 @@ export abstract class SyncedEntityRepository<
171
171
  }
172
172
 
173
173
  /**
174
- * Sync "delete" by external id, provider-scoped. When `softDelete: true`,
174
+ * Integration "delete" by external id, provider-scoped. When `softDelete: true`,
175
175
  * sets `deletedAt`. When `softDelete: false`, tombstone-by-clearing: null out
176
176
  * `external_id`/`provider` so the row no longer matches future inbound
177
177
  * changes while preserving local-id references. Returns `{ id }` or `null`.
@@ -182,7 +182,7 @@ export abstract class SyncedEntityRepository<
182
182
  tx?: DrizzleTx,
183
183
  ): Promise<{ id: string } | null> {
184
184
  const db = this.runner(tx);
185
- const set = this.syncConfig.softDelete
185
+ const set = this.integrationConfig.softDelete
186
186
  ? { deletedAt: new Date(), updatedAt: new Date() }
187
187
  : { externalId: null, provider: null, updatedAt: new Date() };
188
188
  const rows = await db
@@ -199,20 +199,20 @@ export abstract class SyncedEntityRepository<
199
199
  }
200
200
 
201
201
  /**
202
- * Batch sync upsert — concretizes the former abstract stub. Delegates to
203
- * `syncUpsertOne` per input inside one transaction. Inputs are raw partial
202
+ * Batch integration upsert — concretizes the former abstract stub. Delegates to
203
+ * `integrationUpsertOne` per input inside one transaction. Inputs are raw partial
204
204
  * rows: provider is read from each input's own `provider` column; rows
205
205
  * missing `externalId`/`provider` are skipped.
206
206
  */
207
- async syncUpsert(inputs: Array<Partial<TEntity>>): Promise<TEntity[]> {
207
+ async integrationUpsert(inputs: Array<Partial<TEntity>>): Promise<TEntity[]> {
208
208
  if (inputs.length === 0) return [];
209
209
  return this.db.transaction(async (tx) => {
210
210
  const out: TEntity[] = [];
211
211
  for (const input of inputs) {
212
212
  const rec = input as Record<string, unknown>;
213
213
  if (!rec['externalId'] || !rec['provider']) continue;
214
- const proj = await this.syncUpsertOne(
215
- input as unknown as TSyncWrite,
214
+ const proj = await this.integrationUpsertOne(
215
+ input as unknown as TIntegrationWrite,
216
216
  rec['provider'] as string,
217
217
  tx,
218
218
  );
@@ -230,14 +230,14 @@ export abstract class SyncedEntityRepository<
230
230
 
231
231
  /**
232
232
  * Project a raw row to the canonical differ shape — a generic pick over
233
- * `syncConfig.projectionColumns`. Override only for synthesized projections
233
+ * `integrationConfig.projectionColumns`. Override only for synthesized projections
234
234
  * (e.g. junctions); entities use this verbatim.
235
235
  */
236
- protected toProjection(row: TEntity): TSyncProjection {
236
+ protected toProjection(row: TEntity): TIntegrationProjection {
237
237
  const r = row as Record<string, unknown>;
238
238
  const out: Record<string, unknown> = {};
239
- for (const col of this.syncConfig.projectionColumns) out[col] = r[col];
240
- return out as TSyncProjection;
239
+ for (const col of this.integrationConfig.projectionColumns) out[col] = r[col];
240
+ return out as TIntegrationProjection;
241
241
  }
242
242
 
243
243
  /**
@@ -263,7 +263,7 @@ export abstract class SyncedEntityRepository<
263
263
  */
264
264
  private async resolveFk(
265
265
  db: DrizzleTx,
266
- fk: SyncFkResolver,
266
+ fk: IntegrationFkResolver,
267
267
  rawExternalId: unknown,
268
268
  provider: string,
269
269
  ): Promise<string | null> {
@@ -271,7 +271,7 @@ export abstract class SyncedEntityRepository<
271
271
  if (!parentExternalId) {
272
272
  if (fk.strict) {
273
273
  throw new Error(
274
- `${this.constructor.name}.syncUpsertOne: missing required parent ` +
274
+ `${this.constructor.name}.integrationUpsertOne: missing required parent ` +
275
275
  `external id for '${fk.column}' (writeKey '${fk.writeKey}')`,
276
276
  );
277
277
  }
@@ -293,9 +293,9 @@ export abstract class SyncedEntityRepository<
293
293
  const id = (rows[0]?.id as string | undefined) ?? null;
294
294
  if (id === null && fk.strict) {
295
295
  throw new Error(
296
- `${this.constructor.name}.syncUpsertOne: unresolved parent ` +
296
+ `${this.constructor.name}.integrationUpsertOne: unresolved parent ` +
297
297
  `'${parentExternalId}' (provider '${provider}') for '${fk.column}' — ` +
298
- `parent not synced yet`,
298
+ `parent not integrated yet`,
299
299
  );
300
300
  }
301
301
  return id;
@@ -1,22 +1,22 @@
1
1
  /**
2
- * SyncedEntityService<TRepo, TEntity>
2
+ * IntegratedEntityService<TRepo, TEntity>
3
3
  *
4
- * Family-specific base service for Synced entities.
4
+ * Family-specific base service for Integrated entities.
5
5
  * Delegates to a CRM repository that provides external ID lookups
6
6
  * and user-scoped queries.
7
7
  */
8
8
  import { BaseService, type IBaseRepository } from './base-service';
9
9
 
10
- export interface ISyncedEntityRepository<TEntity> extends IBaseRepository<TEntity> {
10
+ export interface IIntegratedEntityRepository<TEntity> extends IBaseRepository<TEntity> {
11
11
  findByExternalId(externalId: string): Promise<TEntity | null>;
12
12
  findManyByExternalIds(externalIds: string[]): Promise<TEntity[]>;
13
13
  findAllByUserId(userId: string): Promise<TEntity[]>;
14
14
  findVisibleByUserId(userId: string): Promise<TEntity[]>;
15
- syncUpsert(inputs: Array<Partial<TEntity>>): Promise<TEntity[]>;
15
+ integrationUpsert(inputs: Array<Partial<TEntity>>): Promise<TEntity[]>;
16
16
  }
17
17
 
18
- export abstract class SyncedEntityService<
19
- TRepo extends ISyncedEntityRepository<TEntity>,
18
+ export abstract class IntegratedEntityService<
19
+ TRepo extends IIntegratedEntityRepository<TEntity>,
20
20
  TEntity,
21
21
  > extends BaseService<TRepo, TEntity> {
22
22
  /**
@@ -1,14 +1,14 @@
1
1
  /**
2
- * SyncUpsertConfig + SyncFkResolver
2
+ * IntegrationUpsertConfig + IntegrationFkResolver
3
3
  *
4
- * Declarative description of an entity's inbound-sync write surface, consumed
5
- * by `SyncedEntityRepository.syncUpsertOne` / `findByExternalIdProjected` /
6
- * `softDeleteByExternalId` / `toProjection`. Each `pattern: Synced` repository
7
- * declares a concrete `syncConfig: SyncUpsertConfig` (emitted by the template),
4
+ * Declarative description of an entity's inbound-integration write surface, consumed
5
+ * by `IntegratedEntityRepository.integrationUpsertOne` / `findByExternalIdProjected` /
6
+ * `softDeleteByExternalId` / `toProjection`. Each `pattern: Integrated` repository
7
+ * declares a concrete `integrationConfig: IntegrationUpsertConfig` (emitted by the template),
8
8
  * the same idiom as `behaviors: BehaviorConfig`.
9
9
  *
10
- * Named `SyncUpsertConfig` (not `SyncConfig`) to avoid colliding with the sync
11
- * subsystem's `DetectionConfig`/`SyncConfig` surface.
10
+ * Named `IntegrationUpsertConfig` (not `IntegrationConfig`) to avoid colliding with the integration
11
+ * subsystem's `DetectionConfig`/`IntegrationConfig` surface.
12
12
  *
13
13
  * The generic upsert separates three column roles:
14
14
  * - identity (`conflictTarget`) — only in `values`, never in `set`
@@ -27,10 +27,10 @@ import type { PgTableWithColumns } from 'drizzle-orm/pg-core';
27
27
  * posture); falsy leaves the column null this run (opportunistic, entity
28
28
  * posture).
29
29
  */
30
- export interface SyncFkResolver {
30
+ export interface IntegrationFkResolver {
31
31
  /** Local FK column — camel key into `this.table`, e.g. `'parentAccountId'`. */
32
32
  column: string;
33
- /** Key on `TSyncWrite` carrying the parent external id (see Decision 4). */
33
+ /** Key on `TIntegrationWrite` carrying the parent external id (see Decision 4). */
34
34
  writeKey: string;
35
35
  /** Parent table to resolve against; `'self'` → `this.table`. */
36
36
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -39,7 +39,7 @@ export interface SyncFkResolver {
39
39
  strict?: boolean;
40
40
  }
41
41
 
42
- export interface SyncUpsertConfig {
42
+ export interface IntegrationUpsertConfig {
43
43
  /** Camel keys into `this.table` forming the conflict target, e.g. `['provider', 'externalId']`. */
44
44
  conflictTarget: string[];
45
45
  /**
@@ -48,10 +48,10 @@ export interface SyncUpsertConfig {
48
48
  */
49
49
  writeColumns: string[];
50
50
  /** Conditional, provider-scoped FK resolvers. */
51
- fkResolvers: SyncFkResolver[];
51
+ fkResolvers: IntegrationFkResolver[];
52
52
  /** Columns picked into the projection (camel), incl. id/externalId/timestamps. */
53
53
  projectionColumns: string[];
54
- /** When true, `syncUpsertOne` calls `writeCustomFields` for a non-empty `fields` bag. */
54
+ /** When true, `integrationUpsertOne` calls `writeCustomFields` for a non-empty `fields` bag. */
55
55
  eav: boolean;
56
56
  /** When true, deletes set `deletedAt`; when false, tombstone-by-clearing external_id/provider. */
57
57
  softDelete: boolean;
@@ -1,9 +1,9 @@
1
1
  /**
2
- * JunctionSyncRepository<TEntity, TSyncWrite, TSyncProjection>
2
+ * JunctionIntegrationRepository<TEntity, TIntegrationWrite, TIntegrationProjection>
3
3
  *
4
- * Base for junction repos that participate in inbound sync (#374). A junction's
5
- * sync identity is the tuple `(leftId, rightId[, role])` — there is no native
6
- * `external_id`/`provider` column, so the sync seam's externalId is a COMPOSITE
4
+ * Base for junction repos that participate in inbound integration (#374). A junction's
5
+ * integration identity is the tuple `(leftId, rightId[, role])` — there is no native
6
+ * `external_id`/`provider` column, so the integration seam's externalId is a COMPOSITE
7
7
  * string `<leftExternalId>::<rightExternalId>[::<role>]` (see the static
8
8
  * build/parse helpers below).
9
9
  *
@@ -19,7 +19,7 @@ import type { PgTableWithColumns } from 'drizzle-orm/pg-core';
19
19
  import type { DrizzleTx } from '../types/drizzle';
20
20
  import { BaseRepository } from './base-repository';
21
21
 
22
- export interface JunctionSyncConfig {
22
+ export interface JunctionIntegrationConfig {
23
23
  /** Left endpoint: local FK column (camel) + strict parent table. */
24
24
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
25
  left: { column: string; refTable: PgTableWithColumns<any> };
@@ -30,16 +30,16 @@ export interface JunctionSyncConfig {
30
30
  roleColumn: string | null;
31
31
  }
32
32
 
33
- export abstract class JunctionSyncRepository<
33
+ export abstract class JunctionIntegrationRepository<
34
34
  TEntity,
35
- TSyncWrite,
36
- TSyncProjection,
35
+ TIntegrationWrite,
36
+ TIntegrationProjection,
37
37
  > extends BaseRepository<TEntity> {
38
38
  /**
39
- * Declarative junction sync surface. Concrete repos declare this — the
39
+ * Declarative junction integration surface. Concrete repos declare this — the
40
40
  * template emits it with live parent-table handles.
41
41
  */
42
- protected abstract readonly syncConfig: JunctionSyncConfig;
42
+ protected abstract readonly integrationConfig: JunctionIntegrationConfig;
43
43
 
44
44
  /**
45
45
  * Upsert ONE junction row by its composite identity, in a single transaction:
@@ -54,17 +54,17 @@ export abstract class JunctionSyncRepository<
54
54
  * @param provider adapter/provider label used to scope the parent lookups
55
55
  * @param tx optional outer transaction; when omitted we open our own
56
56
  */
57
- async syncUpsertOne(
58
- write: TSyncWrite,
57
+ async integrationUpsertOne(
58
+ write: TIntegrationWrite,
59
59
  provider: string,
60
60
  tx?: DrizzleTx,
61
- ): Promise<TSyncProjection> {
62
- const cfg = this.syncConfig;
61
+ ): Promise<TIntegrationProjection> {
62
+ const cfg = this.integrationConfig;
63
63
  const w = write as Record<string, unknown>;
64
64
  const leftWriteKey = `${cfg.left.column.replace(/Id$/, '')}ExternalId`;
65
65
  const rightWriteKey = `${cfg.right.column.replace(/Id$/, '')}ExternalId`;
66
66
 
67
- const run = async (db: DrizzleTx): Promise<TSyncProjection> => {
67
+ const run = async (db: DrizzleTx): Promise<TIntegrationProjection> => {
68
68
  const leftId = await this.resolveStrict(
69
69
  db, cfg.left.refTable, w[leftWriteKey] as string, provider, cfg.left.column,
70
70
  );
@@ -109,8 +109,8 @@ export abstract class JunctionSyncRepository<
109
109
  async findByExternalIdProjected(
110
110
  externalId: string,
111
111
  provider: string,
112
- ): Promise<TSyncProjection | null> {
113
- const cfg = this.syncConfig;
112
+ ): Promise<TIntegrationProjection | null> {
113
+ const cfg = this.integrationConfig;
114
114
  const parsed = parseCompositeExternalId(externalId, cfg.roleColumn !== null);
115
115
  if (!parsed) return null;
116
116
 
@@ -138,7 +138,7 @@ export abstract class JunctionSyncRepository<
138
138
 
139
139
  /**
140
140
  * Hard-delete the junction by composite externalId. Junctions have no
141
- * `deleted_at` and no external-linkage columns to clear, so a sync "delete"
141
+ * `deleted_at` and no external-linkage columns to clear, so a integration "delete"
142
142
  * removes the row. Resolves both parents NON-throwing, then deletes by the
143
143
  * identity tuple. Returns the composite id, or `null` when nothing matched.
144
144
  */
@@ -147,7 +147,7 @@ export abstract class JunctionSyncRepository<
147
147
  provider: string,
148
148
  tx?: DrizzleTx,
149
149
  ): Promise<{ id: string } | null> {
150
- const cfg = this.syncConfig;
150
+ const cfg = this.integrationConfig;
151
151
  const parsed = parseCompositeExternalId(externalId, cfg.roleColumn !== null);
152
152
  if (!parsed) return null;
153
153
  const db = this.runner(tx);
@@ -168,16 +168,16 @@ export abstract class JunctionSyncRepository<
168
168
  * Project a raw junction row to the differ shape: the COMPOSITE externalId
169
169
  * `id` (junctions have no surrogate id) plus the local FK columns, role (when
170
170
  * role-bearing) and timestamps — matching the emitted
171
- * `<Junction>SyncProjection` interface (id + leftId + rightId + role? +
171
+ * `<Junction>IntegrationProjection` interface (id + leftId + rightId + role? +
172
172
  * createdAt + updatedAt). Junction projections are purely structural, so this
173
- * is fully generic over `syncConfig` — no per-junction override is emitted.
173
+ * is fully generic over `integrationConfig` — no per-junction override is emitted.
174
174
  */
175
175
  protected toProjection(
176
176
  row: TEntity,
177
177
  write: Record<string, unknown>,
178
178
  _provider: string,
179
- ): TSyncProjection {
180
- const cfg = this.syncConfig;
179
+ ): TIntegrationProjection {
180
+ const cfg = this.integrationConfig;
181
181
  const r = row as Record<string, unknown>;
182
182
  const leftExt = write[`${cfg.left.column.replace(/Id$/, '')}ExternalId`] as string;
183
183
  const rightExt = write[`${cfg.right.column.replace(/Id$/, '')}ExternalId`] as string;
@@ -190,12 +190,12 @@ export abstract class JunctionSyncRepository<
190
190
  if (cfg.roleColumn) out[cfg.roleColumn] = r[cfg.roleColumn];
191
191
  out['createdAt'] = r['createdAt'];
192
192
  out['updatedAt'] = r['updatedAt'];
193
- return out as TSyncProjection;
193
+ return out as TIntegrationProjection;
194
194
  }
195
195
 
196
196
  /** Build the identity WHERE clause `(left, right[, role])`. */
197
197
  private identityWhere(leftId: string, rightId: string, role: string | undefined) {
198
- const cfg = this.syncConfig;
198
+ const cfg = this.integrationConfig;
199
199
  const conds = [
200
200
  eq(this.table[cfg.left.column], leftId),
201
201
  eq(this.table[cfg.right.column], rightId),
@@ -218,9 +218,9 @@ export abstract class JunctionSyncRepository<
218
218
  const id = await this.resolveLoose(db, refTable, parentExternalId, provider);
219
219
  if (!id) {
220
220
  throw new Error(
221
- `${this.constructor.name}.syncUpsertOne: unresolved parent ` +
221
+ `${this.constructor.name}.integrationUpsertOne: unresolved parent ` +
222
222
  `'${parentExternalId}' (provider '${provider}') for '${column}' — ` +
223
- `parent not synced yet`,
223
+ `parent not integrated yet`,
224
224
  );
225
225
  }
226
226
  return id;
@@ -250,7 +250,7 @@ export abstract class JunctionSyncRepository<
250
250
  }
251
251
 
252
252
  // ============================================================================
253
- // Composite externalId — the junction sync seam's deterministic identity.
253
+ // Composite externalId — the junction integration seam's deterministic identity.
254
254
  //
255
255
  // Format: `<leftExternalId>::<rightExternalId>[::<role>]`
256
256
  // e.g. `hubspot:42::hubspot:99::employee` (role-bearing)
@@ -15,7 +15,7 @@
15
15
  * - `expires_at` — TTL boundary; entries past this are treated as absent.
16
16
  *
17
17
  * Convention: schema files live at the root of the subsystem dir
18
- * (mirrors `cache.schema.ts`, `sync-audit.schema.ts`, `domain-events.schema.ts`).
18
+ * (mirrors `cache.schema.ts`, `integration-audit.schema.ts`, `domain-events.schema.ts`).
19
19
  */
20
20
  import { pgTable, text, timestamp } from 'drizzle-orm/pg-core';
21
21
  import type { InferSelectModel } from 'drizzle-orm';
@@ -9,17 +9,17 @@
9
9
  * - `AUTH_OPTIONS` → resolved options bag (used by AuthController
10
10
  * for `redirectUriBase`).
11
11
  *
12
- * The integration-store ports (`AUTH_INTEGRATION_READER`,
13
- * `AUTH_INTEGRATION_TOKEN_WRITER`, `AUTH_INTEGRATION_GRANT_SINK`),
12
+ * The connection-store ports (`AUTH_CONNECTION_READER`,
13
+ * `AUTH_CONNECTION_TOKEN_WRITER`, `AUTH_CONNECTION_GRANT_SINK`),
14
14
  * `AUTH_USER_CONTEXT`, and `STRATEGY_REGISTRY` are deliberately **not**
15
15
  * wired here — they are always consumer-specific:
16
- * - integration-store ports adapt the consumer's `integrations` storage;
16
+ * - connection-store ports adapt the consumer's `connections` storage;
17
17
  * - `IUserContext` adapts the app's session/JWT scheme;
18
18
  * - `STRATEGY_REGISTRY` is populated from the per-provider strategy
19
19
  * classes the consumer maintains.
20
20
  *
21
21
  * Consumers provide them in their app module (or by importing the
22
- * `auth-integrations` starter, which binds the three integration-store
22
+ * `auth-integrations` starter, which binds the three connection-store
23
23
  * ports off a single canonical entity).
24
24
  *
25
25
  * Usage in AppModule:
@@ -10,9 +10,9 @@
10
10
  * constructor(
11
11
  * @Inject(ENCRYPTION_KEY) private readonly key: IEncryptionKey,
12
12
  * @Inject(OAUTH_STATE_STORE) private readonly states: IOAuthStateStore,
13
- * @Inject(AUTH_INTEGRATION_READER) private readonly reader: IIntegrationReader,
14
- * @Inject(AUTH_INTEGRATION_TOKEN_WRITER) private readonly writer: IIntegrationTokenWriter,
15
- * @Inject(AUTH_INTEGRATION_GRANT_SINK) private readonly grants: IIntegrationGrantSink,
13
+ * @Inject(AUTH_CONNECTION_READER) private readonly reader: IConnectionReader,
14
+ * @Inject(AUTH_CONNECTION_TOKEN_WRITER) private readonly writer: IConnectionTokenWriter,
15
+ * @Inject(AUTH_CONNECTION_GRANT_SINK) private readonly grants: IConnectionGrantSink,
16
16
  * @Inject(AUTH_USER_CONTEXT) private readonly userCtx: IUserContext,
17
17
  * @Inject(STRATEGY_REGISTRY) private readonly registry: ProviderStrategyRegistry,
18
18
  * ) {}
@@ -20,7 +20,7 @@
20
20
  *
21
21
  * `IAuthStrategy` implementations are provider-specific and registered under
22
22
  * provider-specific tokens (e.g. `SALESFORCE_AUTH_STRATEGY`,
23
- * `HUBSPOT_AUTH_STRATEGY`) by each integration module — this subsystem does
23
+ * `HUBSPOT_AUTH_STRATEGY`) by each connection module — this subsystem does
24
24
  * not mandate a single `AUTH_STRATEGY` token because an app typically has
25
25
  * many concurrent strategies, one per provider. They are dispatched through
26
26
  * `STRATEGY_REGISTRY` (a `ReadonlyMap<slug, IProviderStrategy>`), populated
@@ -28,9 +28,9 @@
28
28
  */
29
29
  export const ENCRYPTION_KEY = Symbol('ENCRYPTION_KEY');
30
30
  export const OAUTH_STATE_STORE = Symbol('OAUTH_STATE_STORE');
31
- export const AUTH_INTEGRATION_READER = Symbol('AUTH_INTEGRATION_READER');
32
- export const AUTH_INTEGRATION_TOKEN_WRITER = Symbol('AUTH_INTEGRATION_TOKEN_WRITER');
33
- export const AUTH_INTEGRATION_GRANT_SINK = Symbol('AUTH_INTEGRATION_GRANT_SINK');
31
+ export const AUTH_CONNECTION_READER = Symbol('AUTH_CONNECTION_READER');
32
+ export const AUTH_CONNECTION_TOKEN_WRITER = Symbol('AUTH_CONNECTION_TOKEN_WRITER');
33
+ export const AUTH_CONNECTION_GRANT_SINK = Symbol('AUTH_CONNECTION_GRANT_SINK');
34
34
  export const AUTH_USER_CONTEXT = Symbol('AUTH_USER_CONTEXT');
35
35
  export const STRATEGY_REGISTRY = Symbol('STRATEGY_REGISTRY');
36
36
  /**