@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.
- package/CHANGELOG.md +122 -0
- package/README.md +5 -5
- package/consumer-skills/codegen/SKILL.md +2 -2
- package/consumer-skills/{sync → integration}/SKILL.md +29 -29
- package/consumer-skills/{sync → integration}/audit-and-detection.md +22 -22
- package/consumer-skills/{sync → integration}/change-sources-and-sinks.md +60 -60
- package/consumer-skills/subsystems/SKILL.md +8 -8
- package/consumer-skills/subsystems/wiring-and-order.md +7 -7
- package/dist/runtime/base-classes/index.d.ts +4 -4
- package/dist/runtime/base-classes/index.js +35 -35
- package/dist/runtime/base-classes/index.js.map +1 -1
- package/dist/runtime/base-classes/{synced-entity-repository.d.ts → integrated-entity-repository.d.ts} +15 -15
- package/dist/runtime/base-classes/{synced-entity-repository.js → integrated-entity-repository.js} +21 -21
- package/dist/runtime/base-classes/integrated-entity-repository.js.map +1 -0
- package/dist/runtime/base-classes/{synced-entity-service.d.ts → integrated-entity-service.d.ts} +6 -6
- package/dist/runtime/base-classes/{synced-entity-service.js → integrated-entity-service.js} +4 -4
- package/dist/runtime/base-classes/integrated-entity-service.js.map +1 -0
- package/dist/runtime/base-classes/{sync-upsert-config.d.ts → integration-upsert-config.d.ts} +13 -13
- package/dist/runtime/base-classes/integration-upsert-config.js +1 -0
- package/dist/runtime/base-classes/{junction-sync-repository.d.ts → junction-integration-repository.d.ts} +11 -11
- package/dist/runtime/base-classes/{junction-sync-repository.js → junction-integration-repository.js} +15 -15
- package/dist/runtime/base-classes/junction-integration-repository.js.map +1 -0
- package/dist/runtime/subsystems/auth/auth-oauth-state.schema.js.map +1 -1
- package/dist/runtime/subsystems/auth/auth.module.d.ts +4 -4
- package/dist/runtime/subsystems/auth/auth.module.js +3 -3
- package/dist/runtime/subsystems/auth/auth.module.js.map +1 -1
- package/dist/runtime/subsystems/auth/auth.tokens.d.ts +8 -8
- package/dist/runtime/subsystems/auth/auth.tokens.js +6 -6
- package/dist/runtime/subsystems/auth/auth.tokens.js.map +1 -1
- package/dist/runtime/subsystems/auth/backends/state-store.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/auth/controllers/auth.controller.d.ts +2 -2
- package/dist/runtime/subsystems/auth/controllers/auth.controller.js +3 -3
- package/dist/runtime/subsystems/auth/controllers/auth.controller.js.map +1 -1
- package/dist/runtime/subsystems/auth/index.d.ts +3 -3
- package/dist/runtime/subsystems/auth/index.js +40 -40
- package/dist/runtime/subsystems/auth/index.js.map +1 -1
- package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -1
- package/dist/runtime/subsystems/auth/protocols/auth-strategy.d.ts +3 -3
- package/dist/runtime/subsystems/auth/protocols/{integration-store.d.ts → connection-store.d.ts} +20 -20
- package/dist/runtime/subsystems/auth/protocols/connection-store.js +1 -0
- package/dist/runtime/subsystems/auth/protocols/provider-strategy.d.ts +3 -3
- package/dist/runtime/subsystems/auth/runtime/{integration-broken.error.d.ts → connection-broken.error.d.ts} +5 -5
- package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js +19 -0
- package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js.map +1 -0
- package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.d.ts +10 -10
- package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js +28 -28
- package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js.map +1 -1
- package/dist/runtime/subsystems/auth/runtime/with-auth-retry.d.ts +1 -1
- package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js +3 -3
- package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js.map +1 -1
- package/dist/runtime/subsystems/index.d.ts +11 -7
- package/dist/runtime/subsystems/index.js +1041 -67
- package/dist/runtime/subsystems/index.js.map +1 -1
- package/dist/runtime/subsystems/{sync → integration}/build-change-source.d.ts +3 -3
- package/dist/runtime/subsystems/{sync → integration}/build-change-source.js +3 -3
- package/dist/runtime/subsystems/integration/build-change-source.js.map +1 -0
- package/dist/runtime/subsystems/{sync → integration}/deep-equal.differ.d.ts +2 -2
- package/dist/runtime/subsystems/{sync → integration}/deep-equal.differ.js +1 -1
- package/dist/runtime/subsystems/integration/deep-equal.differ.js.map +1 -0
- package/dist/runtime/subsystems/{sync → integration}/detection-config.schema.d.ts +3 -3
- package/dist/runtime/subsystems/{sync → integration}/detection-config.schema.js +1 -1
- package/dist/runtime/subsystems/integration/detection-config.schema.js.map +1 -0
- package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.d.ts +25 -0
- package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.js +34 -0
- package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.js.map +1 -0
- package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.d.ts +53 -0
- package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.js +13 -0
- package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.js.map +1 -0
- package/dist/runtime/subsystems/{sync/execute-sync.use-case.d.ts → integration/execute-integration.use-case.d.ts} +13 -13
- package/dist/runtime/subsystems/{sync/execute-sync.use-case.js → integration/execute-integration.use-case.js} +30 -30
- package/dist/runtime/subsystems/integration/execute-integration.use-case.js.map +1 -0
- package/dist/runtime/subsystems/integration/index.d.ts +30 -0
- package/dist/runtime/subsystems/{sync → integration}/index.js +206 -171
- package/dist/runtime/subsystems/integration/index.js.map +1 -0
- package/dist/runtime/subsystems/{sync/sync-audit.schema.d.ts → integration/integration-audit.schema.d.ts} +64 -64
- package/dist/runtime/subsystems/{sync/sync-audit.schema.js → integration/integration-audit.schema.js} +47 -47
- package/dist/runtime/subsystems/integration/integration-audit.schema.js.map +1 -0
- package/dist/runtime/subsystems/{sync/sync-change-source.protocol.d.ts → integration/integration-change-source.protocol.d.ts} +10 -10
- package/dist/runtime/subsystems/integration/integration-change-source.protocol.js +1 -0
- package/dist/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.d.ts → integration/integration-cursor-store.drizzle-backend.d.ts} +1 -1
- package/dist/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.js → integration/integration-cursor-store.drizzle-backend.js} +65 -65
- package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js.map +1 -0
- package/dist/runtime/subsystems/{sync/sync-cursor-store.memory-backend.d.ts → integration/integration-cursor-store.memory-backend.d.ts} +6 -6
- package/dist/runtime/subsystems/{sync/sync-cursor-store.memory-backend.js → integration/integration-cursor-store.memory-backend.js} +5 -5
- package/dist/runtime/subsystems/integration/integration-cursor-store.memory-backend.js.map +1 -0
- package/dist/runtime/subsystems/{sync/sync-cursor-store.protocol.d.ts → integration/integration-cursor-store.protocol.d.ts} +13 -13
- package/dist/runtime/subsystems/integration/integration-cursor-store.protocol.js +1 -0
- package/dist/runtime/subsystems/{sync/sync-errors.d.ts → integration/integration-errors.d.ts} +2 -2
- package/dist/runtime/subsystems/{sync/sync-errors.js → integration/integration-errors.js} +3 -3
- package/dist/runtime/subsystems/integration/integration-errors.js.map +1 -0
- package/dist/runtime/subsystems/{sync/sync-field-diff.protocol.d.ts → integration/integration-field-diff.protocol.d.ts} +2 -2
- package/dist/runtime/subsystems/{sync/sync-field-diff.protocol.js → integration/integration-field-diff.protocol.js} +2 -2
- package/dist/runtime/subsystems/integration/integration-field-diff.protocol.js.map +1 -0
- package/dist/runtime/subsystems/{sync/sync-loopback.protocol.d.ts → integration/integration-loopback.protocol.d.ts} +2 -2
- package/dist/runtime/subsystems/integration/integration-loopback.protocol.js +1 -0
- package/dist/runtime/subsystems/{sync/sync-middleware.protocol.d.ts → integration/integration-middleware.protocol.d.ts} +5 -5
- package/dist/runtime/subsystems/integration/integration-middleware.protocol.js +1 -0
- package/dist/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.d.ts → integration/integration-run-recorder.drizzle-backend.d.ts} +5 -5
- package/dist/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.js → integration/integration-run-recorder.drizzle-backend.js} +73 -73
- package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js.map +1 -0
- package/dist/runtime/subsystems/{sync/sync-run-recorder.memory-backend.d.ts → integration/integration-run-recorder.memory-backend.d.ts} +15 -15
- package/dist/runtime/subsystems/{sync/sync-run-recorder.memory-backend.js → integration/integration-run-recorder.memory-backend.js} +11 -11
- package/dist/runtime/subsystems/integration/integration-run-recorder.memory-backend.js.map +1 -0
- package/dist/runtime/subsystems/{sync/sync-run-recorder.protocol.d.ts → integration/integration-run-recorder.protocol.d.ts} +25 -25
- package/dist/runtime/subsystems/integration/integration-run-recorder.protocol.js +1 -0
- package/dist/runtime/subsystems/{sync/sync-sink.protocol.d.ts → integration/integration-sink.protocol.d.ts} +5 -5
- package/dist/runtime/subsystems/integration/integration-sink.protocol.js +1 -0
- package/dist/runtime/subsystems/{sync/sync.module.d.ts → integration/integration.module.d.ts} +24 -24
- package/dist/runtime/subsystems/{sync/sync.module.js → integration/integration.module.js} +132 -132
- package/dist/runtime/subsystems/integration/integration.module.js.map +1 -0
- package/dist/runtime/subsystems/integration/integration.tokens.d.ts +60 -0
- package/dist/runtime/subsystems/integration/integration.tokens.js +20 -0
- package/dist/runtime/subsystems/integration/integration.tokens.js.map +1 -0
- package/dist/runtime/subsystems/{sync → integration}/loopback.middleware.d.ts +5 -5
- package/dist/runtime/subsystems/{sync → integration}/loopback.middleware.js +1 -1
- package/dist/runtime/subsystems/integration/loopback.middleware.js.map +1 -0
- package/dist/runtime/subsystems/{sync → integration}/poll-change-source.d.ts +5 -5
- package/dist/runtime/subsystems/{sync → integration}/poll-change-source.js +1 -1
- package/dist/runtime/subsystems/integration/poll-change-source.js.map +1 -0
- package/dist/runtime/subsystems/{sync → integration}/webhook-change-source.d.ts +5 -5
- package/dist/runtime/subsystems/{sync → integration}/webhook-change-source.js +1 -1
- package/dist/runtime/subsystems/integration/webhook-change-source.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +1 -1
- package/dist/runtime/subsystems/observability/index.d.ts +4 -4
- package/dist/runtime/subsystems/observability/index.js +11 -11
- package/dist/runtime/subsystems/observability/index.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.module.d.ts +2 -2
- package/dist/runtime/subsystems/observability/observability.module.js +11 -11
- package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.protocol.d.ts +11 -11
- package/dist/runtime/subsystems/observability/observability.service.d.ts +6 -6
- package/dist/runtime/subsystems/observability/observability.service.js +11 -11
- package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.tokens.d.ts +1 -1
- package/dist/runtime/subsystems/observability/observability.tokens.js.map +1 -1
- package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +3 -3
- package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.js.map +1 -1
- package/dist/runtime/subsystems/observability/reporters/index.d.ts +3 -3
- package/dist/runtime/subsystems/observability/reporters/index.js.map +1 -1
- package/dist/src/cli/index.js +1336 -376
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/index.d.ts +70 -22
- package/dist/src/index.js +290 -194
- package/dist/src/index.js.map +1 -1
- package/examples/auth-integrations/README.md +32 -32
- package/examples/auth-integrations/definitions/entities/{integration.yaml → connection.yaml} +10 -10
- package/examples/auth-integrations/runtime/{integrations/adapters/integration-grant-sink.adapter.ts → connections/adapters/connection-grant-sink.adapter.ts} +7 -7
- package/examples/auth-integrations/runtime/{integrations/adapters/integration-reader.adapter.ts → connections/adapters/connection-reader.adapter.ts} +10 -10
- package/examples/auth-integrations/runtime/{integrations/adapters/integration-token-writer.adapter.ts → connections/adapters/connection-token-writer.adapter.ts} +11 -11
- package/examples/auth-integrations/runtime/connections/connections-auth.module.ts +81 -0
- package/examples/auth-integrations/runtime/{integrations/facade/integrations.service.ts → connections/facade/connections.service.ts} +35 -35
- package/examples/auth-integrations/runtime/{integrations → connections}/oauth/use-cases/create-or-update-from-oauth-grant.use-case.ts +11 -11
- 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
- package/examples/auth-integrations/runtime/connections/oauth/use-cases/list-user-connections.use-case.ts +21 -0
- package/examples/auth-integrations/runtime/connections/oauth/use-cases/mark-connection-requires-reauth.use-case.ts +21 -0
- package/package.json +9 -1
- package/runtime/base-classes/index.ts +8 -8
- package/runtime/base-classes/{synced-entity-repository.ts → integrated-entity-repository.ts} +36 -36
- package/runtime/base-classes/{synced-entity-service.ts → integrated-entity-service.ts} +6 -6
- package/runtime/base-classes/{sync-upsert-config.ts → integration-upsert-config.ts} +12 -12
- package/runtime/base-classes/{junction-sync-repository.ts → junction-integration-repository.ts} +28 -28
- package/runtime/subsystems/auth/auth-oauth-state.schema.ts +1 -1
- package/runtime/subsystems/auth/auth.module.ts +4 -4
- package/runtime/subsystems/auth/auth.tokens.ts +7 -7
- package/runtime/subsystems/auth/controllers/auth.controller.ts +7 -7
- package/runtime/subsystems/auth/index.ts +19 -19
- package/runtime/subsystems/auth/protocols/auth-strategy.ts +3 -3
- package/runtime/subsystems/auth/protocols/{integration-store.ts → connection-store.ts} +19 -19
- package/runtime/subsystems/auth/protocols/provider-strategy.ts +2 -2
- package/runtime/subsystems/auth/runtime/{integration-broken.error.ts → connection-broken.error.ts} +5 -5
- package/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.ts +35 -35
- package/runtime/subsystems/auth/runtime/with-auth-retry.ts +3 -3
- package/runtime/subsystems/index.ts +26 -11
- package/runtime/subsystems/{sync → integration}/build-change-source.ts +3 -3
- package/runtime/subsystems/{sync → integration}/deep-equal.differ.ts +7 -7
- package/runtime/subsystems/{sync → integration}/detection-config.schema.ts +3 -3
- package/runtime/subsystems/integration/entity-change-source-registry.memory.ts +40 -0
- package/runtime/subsystems/integration/entity-change-source-registry.protocol.ts +59 -0
- package/runtime/subsystems/{sync/execute-sync.use-case.ts → integration/execute-integration.use-case.ts} +40 -40
- package/runtime/subsystems/{sync → integration}/index.ts +56 -47
- package/runtime/subsystems/{sync/sync-audit.schema.ts → integration/integration-audit.schema.ts} +61 -61
- package/runtime/subsystems/{sync/sync-change-source.protocol.ts → integration/integration-change-source.protocol.ts} +9 -9
- package/runtime/subsystems/{sync/sync-cursor-store.drizzle-backend.ts → integration/integration-cursor-store.drizzle-backend.ts} +30 -30
- package/runtime/subsystems/{sync/sync-cursor-store.memory-backend.ts → integration/integration-cursor-store.memory-backend.ts} +9 -9
- package/runtime/subsystems/{sync/sync-cursor-store.protocol.ts → integration/integration-cursor-store.protocol.ts} +13 -13
- package/runtime/subsystems/{sync/sync-errors.ts → integration/integration-errors.ts} +3 -3
- package/runtime/subsystems/{sync/sync-field-diff.protocol.ts → integration/integration-field-diff.protocol.ts} +2 -2
- package/runtime/subsystems/{sync/sync-loopback.protocol.ts → integration/integration-loopback.protocol.ts} +2 -2
- package/runtime/subsystems/{sync/sync-middleware.protocol.ts → integration/integration-middleware.protocol.ts} +6 -6
- package/runtime/subsystems/{sync/sync-run-recorder.drizzle-backend.ts → integration/integration-run-recorder.drizzle-backend.ts} +39 -39
- package/runtime/subsystems/{sync/sync-run-recorder.memory-backend.ts → integration/integration-run-recorder.memory-backend.ts} +23 -23
- package/runtime/subsystems/{sync/sync-run-recorder.protocol.ts → integration/integration-run-recorder.protocol.ts} +25 -25
- package/runtime/subsystems/{sync/sync-sink.protocol.ts → integration/integration-sink.protocol.ts} +4 -4
- package/runtime/subsystems/{sync/sync.module.ts → integration/integration.module.ts} +48 -48
- package/runtime/subsystems/integration/integration.tokens.ts +63 -0
- package/runtime/subsystems/{sync → integration}/loopback.middleware.ts +5 -5
- package/runtime/subsystems/{sync → integration}/poll-change-source.ts +7 -7
- package/runtime/subsystems/{sync → integration}/webhook-change-source.ts +7 -7
- package/runtime/subsystems/observability/index.ts +1 -1
- package/runtime/subsystems/observability/observability.module.ts +2 -2
- package/runtime/subsystems/observability/observability.protocol.ts +11 -11
- package/runtime/subsystems/observability/observability.service.ts +13 -13
- package/runtime/subsystems/observability/observability.tokens.ts +1 -1
- package/src/patterns/library/index.ts +4 -4
- package/src/patterns/library/{synced.pattern.ts → integrated.pattern.ts} +12 -12
- package/src/patterns/library/junction.pattern.ts +1 -1
- package/src/patterns/pattern-definition.ts +3 -3
- package/templates/entity/new/backend/modules/core/{sync-source.ejs.t → integration-source.ejs.t} +6 -6
- package/templates/entity/new/clean-lite-ps/entity.ejs.t +12 -3
- package/templates/entity/new/clean-lite-ps/module.ejs.t +1 -1
- package/templates/entity/new/clean-lite-ps/prompt-extension.js +243 -60
- package/templates/entity/new/clean-lite-ps/repository.ejs.t +27 -27
- package/templates/entity/new/frontend/collections/collection.ejs.t +26 -1
- package/templates/entity/new/frontend/collections/collections-base.ejs.t +11 -0
- package/templates/entity/new/frontend/entity/combined.ejs.t +31 -1
- package/templates/entity/new/prompt.js +27 -15
- package/templates/junction/new/entity.ejs.t +1 -1
- package/templates/junction/new/prompt.js +24 -24
- package/templates/junction/new/repository.ejs.t +19 -19
- package/templates/subsystem/auth/auth-oauth-state.schema.ejs.t +2 -2
- package/templates/subsystem/auth-config/prompt.js +1 -1
- package/templates/subsystem/auth-integrations/app-module-hook.ejs.t +5 -5
- package/templates/subsystem/bridge/prompt.js +1 -1
- package/templates/subsystem/integration/integration-audit.schema.ejs.t +192 -0
- package/templates/subsystem/{sync → integration}/prompt.js +12 -12
- package/templates/subsystem/{sync-config/codegen-config-sync-block.ejs.t → integration-config/codegen-config-integration-block.ejs.t} +7 -7
- package/templates/subsystem/integration-config/prompt.js +22 -0
- package/templates/subsystem/jobs/worker.ejs.t +2 -2
- package/templates/subsystem/observability/main-hook.ejs.t +1 -1
- package/templates/subsystem/observability/prompt.js +1 -1
- package/templates/subsystem/openapi-config/prompt.js +1 -1
- package/dist/runtime/base-classes/junction-sync-repository.js.map +0 -1
- package/dist/runtime/base-classes/sync-upsert-config.js +0 -1
- package/dist/runtime/base-classes/synced-entity-repository.js.map +0 -1
- package/dist/runtime/base-classes/synced-entity-service.js.map +0 -1
- package/dist/runtime/subsystems/auth/protocols/integration-store.js +0 -1
- package/dist/runtime/subsystems/auth/runtime/integration-broken.error.js +0 -19
- package/dist/runtime/subsystems/auth/runtime/integration-broken.error.js.map +0 -1
- package/dist/runtime/subsystems/sync/build-change-source.js.map +0 -1
- package/dist/runtime/subsystems/sync/deep-equal.differ.js.map +0 -1
- package/dist/runtime/subsystems/sync/detection-config.schema.js.map +0 -1
- package/dist/runtime/subsystems/sync/execute-sync.use-case.js.map +0 -1
- package/dist/runtime/subsystems/sync/index.d.ts +0 -28
- package/dist/runtime/subsystems/sync/index.js.map +0 -1
- package/dist/runtime/subsystems/sync/loopback.middleware.js.map +0 -1
- package/dist/runtime/subsystems/sync/poll-change-source.js.map +0 -1
- package/dist/runtime/subsystems/sync/sync-audit.schema.js.map +0 -1
- package/dist/runtime/subsystems/sync/sync-change-source.protocol.js +0 -1
- package/dist/runtime/subsystems/sync/sync-cursor-store.drizzle-backend.js.map +0 -1
- package/dist/runtime/subsystems/sync/sync-cursor-store.memory-backend.js.map +0 -1
- package/dist/runtime/subsystems/sync/sync-cursor-store.protocol.js +0 -1
- package/dist/runtime/subsystems/sync/sync-errors.js.map +0 -1
- package/dist/runtime/subsystems/sync/sync-field-diff.protocol.js.map +0 -1
- package/dist/runtime/subsystems/sync/sync-loopback.protocol.js +0 -1
- package/dist/runtime/subsystems/sync/sync-middleware.protocol.js +0 -1
- package/dist/runtime/subsystems/sync/sync-run-recorder.drizzle-backend.js.map +0 -1
- package/dist/runtime/subsystems/sync/sync-run-recorder.memory-backend.js.map +0 -1
- package/dist/runtime/subsystems/sync/sync-run-recorder.protocol.js +0 -1
- package/dist/runtime/subsystems/sync/sync-sink.protocol.js +0 -1
- package/dist/runtime/subsystems/sync/sync.module.js.map +0 -1
- package/dist/runtime/subsystems/sync/sync.tokens.d.ts +0 -47
- package/dist/runtime/subsystems/sync/sync.tokens.js +0 -18
- package/dist/runtime/subsystems/sync/sync.tokens.js.map +0 -1
- package/dist/runtime/subsystems/sync/webhook-change-source.js.map +0 -1
- package/examples/auth-integrations/runtime/integrations/integrations-auth.module.ts +0 -81
- package/examples/auth-integrations/runtime/integrations/oauth/use-cases/list-user-integrations.use-case.ts +0 -21
- package/examples/auth-integrations/runtime/integrations/oauth/use-cases/mark-integration-requires-reauth.use-case.ts +0 -21
- package/runtime/subsystems/sync/sync.tokens.ts +0 -49
- package/templates/entity/new/backend/modules/core/sync-source.providers.ejs.t +0 -18
- package/templates/subsystem/sync/sync-audit.schema.ejs.t +0 -192
- package/templates/subsystem/sync-config/prompt.js +0 -22
- /package/dist/runtime/base-classes/{sync-upsert-config.js.map → integration-upsert-config.js.map} +0 -0
- /package/dist/runtime/subsystems/auth/protocols/{integration-store.js.map → connection-store.js.map} +0 -0
- /package/dist/runtime/subsystems/{sync/sync-change-source.protocol.js.map → integration/integration-change-source.protocol.js.map} +0 -0
- /package/dist/runtime/subsystems/{sync/sync-cursor-store.protocol.js.map → integration/integration-cursor-store.protocol.js.map} +0 -0
- /package/dist/runtime/subsystems/{sync/sync-loopback.protocol.js.map → integration/integration-loopback.protocol.js.map} +0 -0
- /package/dist/runtime/subsystems/{sync/sync-middleware.protocol.js.map → integration/integration-middleware.protocol.js.map} +0 -0
- /package/dist/runtime/subsystems/{sync/sync-run-recorder.protocol.js.map → integration/integration-run-recorder.protocol.js.map} +0 -0
- /package/dist/runtime/subsystems/{sync/sync-sink.protocol.js.map → integration/integration-sink.protocol.js.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Integration subsystem — cursor-store protocol (port)
|
|
3
3
|
*
|
|
4
4
|
* Subscription-addressed cursor persistence. The subscription row IS the
|
|
5
5
|
* cursor owner — addressable by id, scoped by
|
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Cursor shape is opaque at this seam; strategies type it internally
|
|
9
9
|
* (polling: `{ systemModstamp }`, CDC: `{ replayId }`, webhook: `{ ts }`).
|
|
10
|
-
* The Drizzle backend stores this as `
|
|
10
|
+
* The Drizzle backend stores this as `integration_subscriptions.cursor` jsonb.
|
|
11
11
|
*
|
|
12
12
|
* ## Multi-tenancy (SYNC-4)
|
|
13
13
|
*
|
|
14
|
-
* Both methods accept an optional `tenantId`. When `
|
|
14
|
+
* Both methods accept an optional `tenantId`. When `INTEGRATION_MULTI_TENANT` is
|
|
15
15
|
* enabled (SYNC-6), the Drizzle backend MUST scope every read/write by
|
|
16
16
|
* `tenant_id`, and a `null`/missing value throws `MissingTenantIdError` at
|
|
17
17
|
* the module boundary. When the flag is off, `tenantId` is ignored.
|
|
@@ -26,23 +26,23 @@
|
|
|
26
26
|
* through input shapes, not through wrapper layers.
|
|
27
27
|
*/
|
|
28
28
|
/**
|
|
29
|
-
* Denormalized snapshot of one `
|
|
29
|
+
* Denormalized snapshot of one `integration_subscriptions` row for the OBS-5
|
|
30
30
|
* observability composer (epic #195). `cursor` is opaque (the port's
|
|
31
31
|
* contract); the rest is subscription metadata needed to label the snapshot
|
|
32
32
|
* in a dashboard/API surface.
|
|
33
33
|
*
|
|
34
|
-
* The Drizzle backend reads this directly from `
|
|
34
|
+
* The Drizzle backend reads this directly from `integration_subscriptions`. Memory
|
|
35
35
|
* backends derive it from the seedable `subscriptions` side-map — tests
|
|
36
36
|
* that want meaningful snapshots must seed first.
|
|
37
37
|
*/
|
|
38
38
|
interface CursorSnapshot {
|
|
39
39
|
readonly subscriptionId: string;
|
|
40
|
-
readonly
|
|
40
|
+
readonly connectionId: string;
|
|
41
41
|
readonly adapter: string;
|
|
42
42
|
readonly domain: string;
|
|
43
43
|
readonly externalRef: string | null;
|
|
44
44
|
readonly cursor: unknown | null;
|
|
45
|
-
readonly
|
|
45
|
+
readonly lastIntegrationAt: Date | null;
|
|
46
46
|
readonly updatedAt: Date;
|
|
47
47
|
readonly tenantId: string | null;
|
|
48
48
|
}
|
|
@@ -50,28 +50,28 @@ interface ICursorStore {
|
|
|
50
50
|
/**
|
|
51
51
|
* Return the last persisted cursor for `subscriptionId`, or `null`.
|
|
52
52
|
*
|
|
53
|
-
* @param tenantId required when `
|
|
53
|
+
* @param tenantId required when `INTEGRATION_MULTI_TENANT` is on (backend
|
|
54
54
|
* scopes the SELECT by tenant); ignored otherwise.
|
|
55
55
|
*/
|
|
56
56
|
get(subscriptionId: string, tenantId?: string | null): Promise<unknown | null>;
|
|
57
57
|
/**
|
|
58
58
|
* Persist `cursor` for `subscriptionId`. Overwrites.
|
|
59
59
|
*
|
|
60
|
-
* The Drizzle backend also stamps `
|
|
61
|
-
* same row so the scheduling index `(enabled,
|
|
60
|
+
* The Drizzle backend also stamps `last_integration_at` + `updated_at` on the
|
|
61
|
+
* same row so the scheduling index `(enabled, last_integration_at)` stays
|
|
62
62
|
* accurate without consumers wrapping the port. The memory backend
|
|
63
63
|
* ignores timestamps.
|
|
64
64
|
*
|
|
65
|
-
* @param tenantId required when `
|
|
65
|
+
* @param tenantId required when `INTEGRATION_MULTI_TENANT` is on (backend
|
|
66
66
|
* scopes the UPDATE by tenant); ignored otherwise.
|
|
67
67
|
*/
|
|
68
68
|
put(subscriptionId: string, cursor: unknown, tenantId?: string | null): Promise<void>;
|
|
69
69
|
/**
|
|
70
|
-
* Return one `CursorSnapshot` per `
|
|
70
|
+
* Return one `CursorSnapshot` per `integration_subscriptions` row, ordered by
|
|
71
71
|
* `updated_at DESC`. Consumed by the OBS-5 observability composer to
|
|
72
72
|
* surface current cursor state per subscription.
|
|
73
73
|
*
|
|
74
|
-
* @param tenantId required by Drizzle backend when `
|
|
74
|
+
* @param tenantId required by Drizzle backend when `INTEGRATION_MULTI_TENANT`
|
|
75
75
|
* is on (throws `MissingTenantIdError` otherwise); memory
|
|
76
76
|
* backend accepts but ignores.
|
|
77
77
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=integration-cursor-store.protocol.js.map
|
package/dist/runtime/subsystems/{sync/sync-errors.d.ts → integration/integration-errors.d.ts}
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Typed errors + shared boundary helpers for the
|
|
2
|
+
* Typed errors + shared boundary helpers for the integration subsystem.
|
|
3
3
|
*
|
|
4
4
|
* Classes (not bare Error) so consumers can `instanceof` them in catch
|
|
5
5
|
* blocks and exception filters can map them to HTTP codes.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
10
|
* Thrown by the Drizzle cursor-store / run-recorder backends AND by the
|
|
11
|
-
* orchestrator entry point when `
|
|
11
|
+
* orchestrator entry point when `INTEGRATION_MULTI_TENANT` is enabled but the
|
|
12
12
|
* caller did not supply a non-null `tenantId`. Strict enforcement at the
|
|
13
13
|
* boundary — explicit `null` still throws.
|
|
14
14
|
*
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
// runtime/subsystems/
|
|
1
|
+
// runtime/subsystems/integration/integration-errors.ts
|
|
2
2
|
var MissingTenantIdError = class extends Error {
|
|
3
3
|
name = "MissingTenantIdError";
|
|
4
4
|
constructor(operation) {
|
|
5
5
|
super(
|
|
6
|
-
`Missing tenantId for
|
|
6
|
+
`Missing tenantId for integration operation '${operation}'. IntegrationModule is configured with multiTenant: true \u2014 every call must include a non-null tenantId. Either pass the tenantId or disable multi-tenancy on the module.`
|
|
7
7
|
);
|
|
8
8
|
}
|
|
9
9
|
};
|
|
@@ -17,4 +17,4 @@ export {
|
|
|
17
17
|
MissingTenantIdError,
|
|
18
18
|
assertTenantId
|
|
19
19
|
};
|
|
20
|
-
//# sourceMappingURL=
|
|
20
|
+
//# sourceMappingURL=integration-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../runtime/subsystems/integration/integration-errors.ts"],"sourcesContent":["/**\n * Typed errors + shared boundary helpers for the integration subsystem.\n *\n * Classes (not bare Error) so consumers can `instanceof` them in catch\n * blocks and exception filters can map them to HTTP codes.\n *\n * Mirrors the shape of `events-errors.ts` and `jobs-errors.ts`.\n */\n\n/**\n * Thrown by the Drizzle cursor-store / run-recorder backends AND by the\n * orchestrator entry point when `INTEGRATION_MULTI_TENANT` is enabled but the\n * caller did not supply a non-null `tenantId`. Strict enforcement at the\n * boundary — explicit `null` still throws.\n *\n * Disable multi-tenancy on the module (`multiTenant: false`, the default)\n * to opt out of the requirement entirely.\n *\n * `operation` identifies the call site (e.g. `'cursor.put'`,\n * `'startRun'`, `'execute'`) so the stack-trace message points at the\n * specific boundary that rejected the input.\n */\nexport class MissingTenantIdError extends Error {\n override readonly name = 'MissingTenantIdError';\n constructor(operation: string) {\n super(\n `Missing tenantId for integration operation '${operation}'. IntegrationModule is ` +\n `configured with multiTenant: true — every call must include a ` +\n `non-null tenantId. Either pass the tenantId or disable multi-` +\n `tenancy on the module.`,\n );\n }\n}\n\n/**\n * Shared boundary guard — used at the orchestrator entry AND inside the\n * Drizzle backends. Keeping the check in one function guarantees every\n * `MissingTenantIdError` carries the same message shape regardless of the\n * site that raised it, which makes it easier for consumers to pattern-\n * match on the error in logs/metrics.\n *\n * When `multiTenant` is false, the function is a no-op — `tenantId` may\n * be anything (including `undefined`). When true, `undefined` or `null`\n * throws.\n */\nexport function assertTenantId(\n tenantId: string | null | undefined,\n options: { multiTenant: boolean; operation: string },\n): asserts tenantId is string {\n if (!options.multiTenant) return;\n if (tenantId === undefined || tenantId === null) {\n throw new MissingTenantIdError(options.operation);\n }\n}\n"],"mappings":";AAsBO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC5B,OAAO;AAAA,EACzB,YAAY,WAAmB;AAC7B;AAAA,MACE,+CAA+C,SAAS;AAAA,IAI1D;AAAA,EACF;AACF;AAaO,SAAS,eACd,UACA,SAC4B;AAC5B,MAAI,CAAC,QAAQ,YAAa;AAC1B,MAAI,aAAa,UAAa,aAAa,MAAM;AAC/C,UAAM,IAAI,qBAAqB,QAAQ,SAAS;AAAA,EAClD;AACF;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Integration subsystem — field-diff protocol (port)
|
|
5
5
|
*
|
|
6
6
|
* `IFieldDiffer<T>` is the pluggable differ seam. The default implementation
|
|
7
7
|
* (`DeepEqualDiffer`, ships in SYNC-5) walks every field except an ignore
|
|
@@ -14,7 +14,7 @@ import { z } from 'zod';
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* Structured per-field change. Enforced shape for `
|
|
17
|
+
* Structured per-field change. Enforced shape for `integration_run_items.changed_fields`.
|
|
18
18
|
*
|
|
19
19
|
* `created` items set `from: null, to: <value>` for every non-null field.
|
|
20
20
|
* `deleted` items set `from: <value>, to: null`.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// runtime/subsystems/
|
|
1
|
+
// runtime/subsystems/integration/integration-field-diff.protocol.ts
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
var FieldDiffValueSchema = z.object({
|
|
4
4
|
from: z.unknown(),
|
|
@@ -9,4 +9,4 @@ export {
|
|
|
9
9
|
FieldDiffSchema,
|
|
10
10
|
FieldDiffValueSchema
|
|
11
11
|
};
|
|
12
|
-
//# sourceMappingURL=
|
|
12
|
+
//# sourceMappingURL=integration-field-diff.protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../runtime/subsystems/integration/integration-field-diff.protocol.ts"],"sourcesContent":["/**\n * Integration subsystem — field-diff protocol (port)\n *\n * `IFieldDiffer<T>` is the pluggable differ seam. The default implementation\n * (`DeepEqualDiffer`, ships in SYNC-5) walks every field except an ignore\n * list; CDC-aware differs can skip comparison for fields the provider didn't\n * flag as changed.\n *\n * `FieldDiffSchema` is the structural enforcement of the `changed_fields`\n * column per ADR-0003 — enforced at write time by the recorder service so\n * consumers can rely on the shape in downstream queries.\n */\nimport { z } from 'zod';\n\n// ============================================================================\n// FieldDiff shape — the ADR-0003 contract\n// ============================================================================\n\n/**\n * Structured per-field change. Enforced shape for `integration_run_items.changed_fields`.\n *\n * `created` items set `from: null, to: <value>` for every non-null field.\n * `deleted` items set `from: <value>, to: null`.\n * `noop` items carry `{}`.\n */\nexport const FieldDiffValueSchema = z.object({\n from: z.unknown(),\n to: z.unknown(),\n});\n\nexport const FieldDiffSchema = z.record(z.string(), FieldDiffValueSchema);\n\nexport type FieldDiffValue = z.infer<typeof FieldDiffValueSchema>;\nexport type FieldDiff = z.infer<typeof FieldDiffSchema>;\n\n/** Result of comparing a new record against its existing local state. */\nexport type DiffResult = FieldDiff | 'noop';\n\n// ============================================================================\n// IFieldDiffer\n// ============================================================================\n\n/**\n * Pluggable differ. Default ships in SYNC-5 as `DeepEqualDiffer<T>` —\n * deep-equal over every field except an ignore list (`updated_at` and other\n * row metadata). CDC-aware differs restrict comparison to\n * `providerChangedFields` when supplied.\n */\nexport interface IFieldDiffer<T> {\n /**\n * @param existing — current local state, or `null` when the record is new\n * @param incoming — the canonical record coming from the adapter\n * @param providerChangedFields — optional hint from CDC-capable sources;\n * when present, differ may restrict the comparison to these fields\n */\n diff(\n existing: T | null,\n incoming: T,\n providerChangedFields?: string[],\n ): DiffResult;\n}\n"],"mappings":";AAYA,SAAS,SAAS;AAaX,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC3C,MAAM,EAAE,QAAQ;AAAA,EAChB,IAAI,EAAE,QAAQ;AAChB,CAAC;AAEM,IAAM,kBAAkB,EAAE,OAAO,EAAE,OAAO,GAAG,oBAAoB;","names":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Integration subsystem — loopback-fingerprint protocol (port)
|
|
3
3
|
*
|
|
4
4
|
* Optional port. When the local system writes to an upstream provider via an
|
|
5
5
|
* outbound path, the same change typically echoes back on the next inbound
|
|
6
|
-
* poll/CDC/webhook. A fingerprint store lets `
|
|
6
|
+
* poll/CDC/webhook. A fingerprint store lets `ExecuteIntegrationUseCase` skip
|
|
7
7
|
* records it already wrote, avoiding a diff-noop round trip and a spurious
|
|
8
8
|
* audit row.
|
|
9
9
|
*
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=integration-loopback.protocol.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IntegrationSubscriptionView, Change } from './integration-change-source.protocol.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Integration subsystem — change-source middleware protocol (#226-1)
|
|
5
5
|
*
|
|
6
6
|
* `ChangeMiddleware<T>` lets consumers compose cross-cutting concerns
|
|
7
7
|
* (loopback suppression, redaction, throttling) onto an `IChangeSource<T>`
|
|
@@ -13,7 +13,7 @@ import { SyncSubscriptionView, Change } from './sync-change-source.protocol.js';
|
|
|
13
13
|
*
|
|
14
14
|
* type ChangeMiddleware<T> =
|
|
15
15
|
* (next: ChangeIterator<T>) =>
|
|
16
|
-
* (subscription:
|
|
16
|
+
* (subscription: IntegrationSubscriptionView, cursor: unknown | null) =>
|
|
17
17
|
* AsyncIterable<Change<T>>;
|
|
18
18
|
*
|
|
19
19
|
* The middleware wraps the *next* iterator factory rather than the
|
|
@@ -28,7 +28,7 @@ import { SyncSubscriptionView, Change } from './sync-change-source.protocol.js';
|
|
|
28
28
|
* Loopback shipping as middleware (#226-5) is the canonical example —
|
|
29
29
|
* `createLoopbackMiddleware(store)` filters echoes of local writes
|
|
30
30
|
* before they reach the orchestrator's diff stage, replacing the prior
|
|
31
|
-
* `@Optional()
|
|
31
|
+
* `@Optional() INTEGRATION_LOOPBACK_FINGERPRINT_STORE` orchestrator branch.
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
34
|
/**
|
|
@@ -36,7 +36,7 @@ import { SyncSubscriptionView, Change } from './sync-change-source.protocol.js';
|
|
|
36
36
|
* `IChangeSource.listChanges` accepts `(subscription, cursor)` (#226-2), the
|
|
37
37
|
* `IChangeSource<T>` instance method binds 1:1 to this signature.
|
|
38
38
|
*/
|
|
39
|
-
type ChangeIterator<T> = (subscription:
|
|
39
|
+
type ChangeIterator<T> = (subscription: IntegrationSubscriptionView, cursor: unknown | null) => AsyncIterable<Change<T>>;
|
|
40
40
|
/**
|
|
41
41
|
* A composable wrapper around a `ChangeIterator<T>`. Middlewares may filter,
|
|
42
42
|
* transform, observe, or short-circuit the change stream; they may NOT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=integration-middleware.protocol.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { DrizzleClient } from '../../types/drizzle.js';
|
|
2
|
-
import {
|
|
2
|
+
import { IIntegrationRunRecorder, StartRunInput, RecordItemInput, IntegrationRunSummary, CompleteRunInput } from './integration-run-recorder.protocol.js';
|
|
3
3
|
import 'drizzle-orm/node-postgres';
|
|
4
|
-
import './
|
|
4
|
+
import './integration-field-diff.protocol.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
|
7
|
-
declare class
|
|
7
|
+
declare class DrizzleIntegrationRunRecorder implements IIntegrationRunRecorder {
|
|
8
8
|
private readonly db;
|
|
9
9
|
private readonly multiTenant;
|
|
10
10
|
constructor(db: DrizzleClient, multiTenant?: boolean);
|
|
@@ -12,8 +12,8 @@ declare class DrizzleSyncRunRecorder implements ISyncRunRecorder {
|
|
|
12
12
|
id: string;
|
|
13
13
|
}>;
|
|
14
14
|
recordItem(input: RecordItemInput): Promise<void>;
|
|
15
|
-
listRecent(limit: number, subscriptionId?: string, tenantId?: string | null): Promise<
|
|
15
|
+
listRecent(limit: number, subscriptionId?: string, tenantId?: string | null): Promise<IntegrationRunSummary[]>;
|
|
16
16
|
completeRun(runId: string, input: CompleteRunInput): Promise<void>;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export {
|
|
19
|
+
export { DrizzleIntegrationRunRecorder };
|
|
@@ -10,14 +10,14 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
10
10
|
};
|
|
11
11
|
var __decorateParam = (index2, decorator) => (target, key) => decorator(target, key, index2);
|
|
12
12
|
|
|
13
|
-
// runtime/subsystems/
|
|
13
|
+
// runtime/subsystems/integration/integration-run-recorder.drizzle-backend.ts
|
|
14
14
|
import { Inject, Injectable, Optional } from "@nestjs/common";
|
|
15
15
|
import { and, desc, eq } from "drizzle-orm";
|
|
16
16
|
|
|
17
17
|
// runtime/constants/tokens.ts
|
|
18
18
|
var DRIZZLE = "DRIZZLE";
|
|
19
19
|
|
|
20
|
-
// runtime/subsystems/
|
|
20
|
+
// runtime/subsystems/integration/integration-audit.schema.ts
|
|
21
21
|
import {
|
|
22
22
|
pgEnum,
|
|
23
23
|
pgTable,
|
|
@@ -30,39 +30,39 @@ import {
|
|
|
30
30
|
index,
|
|
31
31
|
uniqueIndex
|
|
32
32
|
} from "drizzle-orm/pg-core";
|
|
33
|
-
var
|
|
33
|
+
var integrationRunDirectionEnum = pgEnum("integration_run_direction", [
|
|
34
34
|
"inbound",
|
|
35
35
|
"outbound"
|
|
36
36
|
]);
|
|
37
|
-
var
|
|
37
|
+
var integrationRunActionEnum = pgEnum("integration_run_action", [
|
|
38
38
|
"poll",
|
|
39
39
|
"cdc",
|
|
40
40
|
"webhook",
|
|
41
41
|
"manual",
|
|
42
42
|
"writeback"
|
|
43
43
|
]);
|
|
44
|
-
var
|
|
44
|
+
var integrationRunStatusEnum = pgEnum("integration_run_status", [
|
|
45
45
|
"running",
|
|
46
46
|
"success",
|
|
47
47
|
"no_changes",
|
|
48
48
|
"failed"
|
|
49
49
|
]);
|
|
50
|
-
var
|
|
50
|
+
var integrationRunItemOperationEnum = pgEnum("integration_run_item_operation", [
|
|
51
51
|
"created",
|
|
52
52
|
"updated",
|
|
53
53
|
"deleted",
|
|
54
54
|
"noop"
|
|
55
55
|
]);
|
|
56
|
-
var
|
|
56
|
+
var integrationRunItemStatusEnum = pgEnum("integration_run_item_status", [
|
|
57
57
|
"success",
|
|
58
58
|
"failed",
|
|
59
59
|
"skipped"
|
|
60
60
|
]);
|
|
61
|
-
var
|
|
62
|
-
"
|
|
61
|
+
var integrationSubscriptions = pgTable(
|
|
62
|
+
"integration_subscriptions",
|
|
63
63
|
{
|
|
64
64
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
65
|
-
|
|
65
|
+
connectionId: text("connection_id").notNull(),
|
|
66
66
|
adapter: text("adapter").notNull(),
|
|
67
67
|
domain: text("domain").notNull(),
|
|
68
68
|
externalRef: text("external_ref"),
|
|
@@ -77,8 +77,8 @@ var syncSubscriptions = pgTable(
|
|
|
77
77
|
* successful run advances it.
|
|
78
78
|
*/
|
|
79
79
|
cursor: jsonb("cursor").$type(),
|
|
80
|
-
|
|
81
|
-
/** Runtime-enforced when `
|
|
80
|
+
lastIntegrationAt: timestamp("last_integration_at", { withTimezone: true }),
|
|
81
|
+
/** Runtime-enforced when `INTEGRATION_MULTI_TENANT` is true; see SYNC-6. */
|
|
82
82
|
tenantId: text("tenant_id"),
|
|
83
83
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
84
84
|
updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
|
|
@@ -87,31 +87,31 @@ var syncSubscriptions = pgTable(
|
|
|
87
87
|
/**
|
|
88
88
|
* Composite uniqueness per the epic shape. `external_ref` is nullable;
|
|
89
89
|
* Postgres treats NULLs as distinct in a UNIQUE constraint, which means
|
|
90
|
-
* two rows with the same `(
|
|
90
|
+
* two rows with the same `(connection_id, adapter, domain)` and NULL
|
|
91
91
|
* external_ref are allowed. That's intentional — a subscription with
|
|
92
92
|
* NULL external_ref covers the full domain, and duplicates there would
|
|
93
93
|
* be a consumer-layer modeling issue, not a schema concern.
|
|
94
94
|
*/
|
|
95
|
-
|
|
96
|
-
t.
|
|
95
|
+
uqIntegrationSubscriptionTuple: uniqueIndex("uq_integration_subscriptions_tuple").on(
|
|
96
|
+
t.connectionId,
|
|
97
97
|
t.adapter,
|
|
98
98
|
t.domain,
|
|
99
99
|
t.externalRef
|
|
100
100
|
),
|
|
101
101
|
/** Scheduling query: list enabled subscriptions ordered by staleness. */
|
|
102
|
-
|
|
103
|
-
"
|
|
104
|
-
).on(t.enabled, t.
|
|
102
|
+
idxIntegrationSubscriptionsEnabledLastIntegration: index(
|
|
103
|
+
"idx_integration_subscriptions_enabled_last_integration"
|
|
104
|
+
).on(t.enabled, t.lastIntegrationAt)
|
|
105
105
|
})
|
|
106
106
|
);
|
|
107
|
-
var
|
|
108
|
-
"
|
|
107
|
+
var integrationRuns = pgTable(
|
|
108
|
+
"integration_runs",
|
|
109
109
|
{
|
|
110
110
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
111
|
-
subscriptionId: uuid("subscription_id").notNull().references(() =>
|
|
112
|
-
direction:
|
|
113
|
-
action:
|
|
114
|
-
status:
|
|
111
|
+
subscriptionId: uuid("subscription_id").notNull().references(() => integrationSubscriptions.id, { onDelete: "cascade" }),
|
|
112
|
+
direction: integrationRunDirectionEnum("direction").notNull(),
|
|
113
|
+
action: integrationRunActionEnum("action").notNull(),
|
|
114
|
+
status: integrationRunStatusEnum("status").notNull().default("running"),
|
|
115
115
|
recordsFound: integer("records_found").notNull().default(0),
|
|
116
116
|
recordsProcessed: integer("records_processed").notNull().default(0),
|
|
117
117
|
cursorBefore: jsonb("cursor_before").$type(),
|
|
@@ -120,31 +120,31 @@ var syncRuns = pgTable(
|
|
|
120
120
|
error: text("error"),
|
|
121
121
|
startedAt: timestamp("started_at", { withTimezone: true }).notNull().defaultNow(),
|
|
122
122
|
completedAt: timestamp("completed_at", { withTimezone: true }),
|
|
123
|
-
/** Runtime-enforced when `
|
|
123
|
+
/** Runtime-enforced when `INTEGRATION_MULTI_TENANT` is true; see SYNC-6. */
|
|
124
124
|
tenantId: text("tenant_id")
|
|
125
125
|
},
|
|
126
126
|
(t) => ({
|
|
127
127
|
/** Timeline read: "most recent runs for this subscription". */
|
|
128
|
-
|
|
129
|
-
"
|
|
128
|
+
idxIntegrationRunsSubscriptionStartedAt: index(
|
|
129
|
+
"idx_integration_runs_subscription_started_at"
|
|
130
130
|
).on(t.subscriptionId, t.startedAt),
|
|
131
131
|
/** Stale-run sweeper: "runs that started > N minutes ago and are still running". */
|
|
132
|
-
|
|
132
|
+
idxIntegrationRunsStatusStartedAt: index("idx_integration_runs_status_started_at").on(
|
|
133
133
|
t.status,
|
|
134
134
|
t.startedAt
|
|
135
135
|
)
|
|
136
136
|
})
|
|
137
137
|
);
|
|
138
|
-
var
|
|
139
|
-
"
|
|
138
|
+
var integrationRunItems = pgTable(
|
|
139
|
+
"integration_run_items",
|
|
140
140
|
{
|
|
141
141
|
id: uuid("id").primaryKey().defaultRandom(),
|
|
142
|
-
|
|
142
|
+
integrationRunId: uuid("integration_run_id").notNull().references(() => integrationRuns.id, { onDelete: "cascade" }),
|
|
143
143
|
entityType: text("entity_type").notNull(),
|
|
144
144
|
externalId: text("external_id").notNull(),
|
|
145
145
|
localId: text("local_id"),
|
|
146
|
-
operation:
|
|
147
|
-
status:
|
|
146
|
+
operation: integrationRunItemOperationEnum("operation").notNull(),
|
|
147
|
+
status: integrationRunItemStatusEnum("status").notNull(),
|
|
148
148
|
/**
|
|
149
149
|
* Structured per-field diff — ADR-0003 shape enforced by
|
|
150
150
|
* `FieldDiffSchema.parse` at the recorder service layer.
|
|
@@ -158,23 +158,23 @@ var syncRunItems = pgTable(
|
|
|
158
158
|
title: text("title"),
|
|
159
159
|
error: text("error"),
|
|
160
160
|
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
161
|
-
/** Runtime-enforced when `
|
|
161
|
+
/** Runtime-enforced when `INTEGRATION_MULTI_TENANT` is true; see SYNC-6. */
|
|
162
162
|
tenantId: text("tenant_id")
|
|
163
163
|
},
|
|
164
164
|
(t) => ({
|
|
165
165
|
/** Ordered timeline within a run. */
|
|
166
|
-
|
|
167
|
-
t.
|
|
166
|
+
idxIntegrationRunItemsRunCreatedAt: index("idx_integration_run_items_run_created_at").on(
|
|
167
|
+
t.integrationRunId,
|
|
168
168
|
t.createdAt
|
|
169
169
|
),
|
|
170
|
-
/** Per-record history: "every
|
|
171
|
-
|
|
172
|
-
"
|
|
170
|
+
/** Per-record history: "every integration that touched opportunity/$extId". */
|
|
171
|
+
idxIntegrationRunItemsEntityExternal: index(
|
|
172
|
+
"idx_integration_run_items_entity_external"
|
|
173
173
|
).on(t.entityType, t.externalId)
|
|
174
174
|
})
|
|
175
175
|
);
|
|
176
176
|
|
|
177
|
-
// runtime/subsystems/
|
|
177
|
+
// runtime/subsystems/integration/integration-field-diff.protocol.ts
|
|
178
178
|
import { z } from "zod";
|
|
179
179
|
var FieldDiffValueSchema = z.object({
|
|
180
180
|
from: z.unknown(),
|
|
@@ -182,15 +182,15 @@ var FieldDiffValueSchema = z.object({
|
|
|
182
182
|
});
|
|
183
183
|
var FieldDiffSchema = z.record(z.string(), FieldDiffValueSchema);
|
|
184
184
|
|
|
185
|
-
// runtime/subsystems/
|
|
186
|
-
var
|
|
185
|
+
// runtime/subsystems/integration/integration.tokens.ts
|
|
186
|
+
var INTEGRATION_MULTI_TENANT = "INTEGRATION_MULTI_TENANT";
|
|
187
187
|
|
|
188
|
-
// runtime/subsystems/
|
|
188
|
+
// runtime/subsystems/integration/integration-errors.ts
|
|
189
189
|
var MissingTenantIdError = class extends Error {
|
|
190
190
|
name = "MissingTenantIdError";
|
|
191
191
|
constructor(operation) {
|
|
192
192
|
super(
|
|
193
|
-
`Missing tenantId for
|
|
193
|
+
`Missing tenantId for integration operation '${operation}'. IntegrationModule is configured with multiTenant: true \u2014 every call must include a non-null tenantId. Either pass the tenantId or disable multi-tenancy on the module.`
|
|
194
194
|
);
|
|
195
195
|
}
|
|
196
196
|
};
|
|
@@ -201,8 +201,8 @@ function assertTenantId(tenantId, options) {
|
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
// runtime/subsystems/
|
|
205
|
-
var
|
|
204
|
+
// runtime/subsystems/integration/integration-run-recorder.drizzle-backend.ts
|
|
205
|
+
var DrizzleIntegrationRunRecorder = class {
|
|
206
206
|
constructor(db, multiTenant) {
|
|
207
207
|
this.db = db;
|
|
208
208
|
this.multiTenant = multiTenant ?? false;
|
|
@@ -214,17 +214,17 @@ var DrizzleSyncRunRecorder = class {
|
|
|
214
214
|
multiTenant: this.multiTenant,
|
|
215
215
|
operation: "startRun"
|
|
216
216
|
});
|
|
217
|
-
const rows = await this.db.insert(
|
|
217
|
+
const rows = await this.db.insert(integrationRuns).values({
|
|
218
218
|
subscriptionId: input.subscriptionId,
|
|
219
219
|
direction: input.direction,
|
|
220
220
|
action: input.action,
|
|
221
221
|
status: "running",
|
|
222
222
|
cursorBefore: input.cursorBefore ?? null,
|
|
223
223
|
tenantId: input.tenantId ?? null
|
|
224
|
-
}).returning({ id:
|
|
224
|
+
}).returning({ id: integrationRuns.id });
|
|
225
225
|
const id = rows[0]?.id;
|
|
226
226
|
if (!id) {
|
|
227
|
-
throw new Error("
|
|
227
|
+
throw new Error("DrizzleIntegrationRunRecorder: INSERT RETURNING produced no id");
|
|
228
228
|
}
|
|
229
229
|
return { id };
|
|
230
230
|
}
|
|
@@ -234,8 +234,8 @@ var DrizzleSyncRunRecorder = class {
|
|
|
234
234
|
operation: "recordItem"
|
|
235
235
|
});
|
|
236
236
|
FieldDiffSchema.parse(input.changedFields);
|
|
237
|
-
await this.db.insert(
|
|
238
|
-
|
|
237
|
+
await this.db.insert(integrationRunItems).values({
|
|
238
|
+
integrationRunId: input.integrationRunId,
|
|
239
239
|
entityType: input.entityType,
|
|
240
240
|
externalId: input.externalId,
|
|
241
241
|
localId: input.localId ?? null,
|
|
@@ -254,29 +254,29 @@ var DrizzleSyncRunRecorder = class {
|
|
|
254
254
|
});
|
|
255
255
|
const conditions = [];
|
|
256
256
|
if (subscriptionId !== void 0) {
|
|
257
|
-
conditions.push(eq(
|
|
257
|
+
conditions.push(eq(integrationRuns.subscriptionId, subscriptionId));
|
|
258
258
|
}
|
|
259
259
|
if (this.multiTenant) {
|
|
260
|
-
conditions.push(eq(
|
|
260
|
+
conditions.push(eq(integrationRuns.tenantId, tenantId));
|
|
261
261
|
}
|
|
262
262
|
const where = conditions.length === 0 ? void 0 : conditions.length === 1 ? conditions[0] : and(...conditions);
|
|
263
263
|
const rows = await this.db.select({
|
|
264
|
-
id:
|
|
265
|
-
subscriptionId:
|
|
266
|
-
|
|
267
|
-
status:
|
|
268
|
-
startedAt:
|
|
269
|
-
completedAt:
|
|
270
|
-
recordsProcessed:
|
|
271
|
-
tenantId:
|
|
272
|
-
}).from(
|
|
273
|
-
|
|
274
|
-
eq(
|
|
275
|
-
).where(where).orderBy(desc(
|
|
264
|
+
id: integrationRuns.id,
|
|
265
|
+
subscriptionId: integrationRuns.subscriptionId,
|
|
266
|
+
connectionId: integrationSubscriptions.connectionId,
|
|
267
|
+
status: integrationRuns.status,
|
|
268
|
+
startedAt: integrationRuns.startedAt,
|
|
269
|
+
completedAt: integrationRuns.completedAt,
|
|
270
|
+
recordsProcessed: integrationRuns.recordsProcessed,
|
|
271
|
+
tenantId: integrationRuns.tenantId
|
|
272
|
+
}).from(integrationRuns).innerJoin(
|
|
273
|
+
integrationSubscriptions,
|
|
274
|
+
eq(integrationRuns.subscriptionId, integrationSubscriptions.id)
|
|
275
|
+
).where(where).orderBy(desc(integrationRuns.startedAt)).limit(limit);
|
|
276
276
|
return rows.map((row) => ({
|
|
277
277
|
id: row.id,
|
|
278
278
|
subscriptionId: row.subscriptionId,
|
|
279
|
-
|
|
279
|
+
connectionId: row.connectionId,
|
|
280
280
|
status: row.status,
|
|
281
281
|
startedAt: row.startedAt,
|
|
282
282
|
completedAt: row.completedAt,
|
|
@@ -285,7 +285,7 @@ var DrizzleSyncRunRecorder = class {
|
|
|
285
285
|
}));
|
|
286
286
|
}
|
|
287
287
|
async completeRun(runId, input) {
|
|
288
|
-
await this.db.update(
|
|
288
|
+
await this.db.update(integrationRuns).set({
|
|
289
289
|
status: input.status,
|
|
290
290
|
recordsFound: input.recordsFound,
|
|
291
291
|
recordsProcessed: input.recordsProcessed,
|
|
@@ -293,16 +293,16 @@ var DrizzleSyncRunRecorder = class {
|
|
|
293
293
|
durationMs: input.durationMs,
|
|
294
294
|
error: input.error ?? null,
|
|
295
295
|
completedAt: /* @__PURE__ */ new Date()
|
|
296
|
-
}).where(eq(
|
|
296
|
+
}).where(eq(integrationRuns.id, runId));
|
|
297
297
|
}
|
|
298
298
|
};
|
|
299
|
-
|
|
299
|
+
DrizzleIntegrationRunRecorder = __decorateClass([
|
|
300
300
|
Injectable(),
|
|
301
301
|
__decorateParam(0, Inject(DRIZZLE)),
|
|
302
302
|
__decorateParam(1, Optional()),
|
|
303
|
-
__decorateParam(1, Inject(
|
|
304
|
-
],
|
|
303
|
+
__decorateParam(1, Inject(INTEGRATION_MULTI_TENANT))
|
|
304
|
+
], DrizzleIntegrationRunRecorder);
|
|
305
305
|
export {
|
|
306
|
-
|
|
306
|
+
DrizzleIntegrationRunRecorder
|
|
307
307
|
};
|
|
308
|
-
//# sourceMappingURL=
|
|
308
|
+
//# sourceMappingURL=integration-run-recorder.drizzle-backend.js.map
|