@pattern-stack/codegen 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +135 -0
- package/README.md +5 -5
- package/consumer-skills/codegen/SKILL.md +2 -2
- package/consumer-skills/events/typed-bus-and-outbox.md +1 -1
- 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 +64 -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/bridge/bridge.module.d.ts +0 -1
- package/dist/runtime/subsystems/bridge/bridge.module.js +294 -710
- package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
- package/dist/runtime/subsystems/bridge/index.d.ts +0 -1
- package/dist/runtime/subsystems/bridge/index.js +248 -664
- package/dist/runtime/subsystems/bridge/index.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +18 -10
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/events.module.js +43 -244
- package/dist/runtime/subsystems/events/events.module.js.map +1 -1
- package/dist/runtime/subsystems/events/index.d.ts +0 -1
- package/dist/runtime/subsystems/events/index.js +39 -241
- package/dist/runtime/subsystems/events/index.js.map +1 -1
- package/dist/runtime/subsystems/index.d.ts +7 -7
- package/dist/runtime/subsystems/index.js +222 -839
- 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/{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 +28 -0
- package/dist/runtime/subsystems/{sync → integration}/index.js +171 -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 +47 -0
- package/dist/runtime/subsystems/integration/integration.tokens.js +18 -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/bullmq.config.d.ts +22 -3
- package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -1
- package/dist/runtime/subsystems/jobs/index.d.ts +1 -4
- package/dist/runtime/subsystems/jobs/index.js +87 -506
- package/dist/runtime/subsystems/jobs/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +3 -0
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +10 -3
- package/dist/runtime/subsystems/jobs/job-worker.module.js +248 -664
- package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.d.ts +0 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +89 -391
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +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 +412 -302
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/index.d.ts +22 -22
- package/dist/src/index.js +191 -191
- 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 +1 -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/events/event-bus.drizzle-backend.ts +32 -10
- package/runtime/subsystems/events/events.module.ts +38 -6
- package/runtime/subsystems/events/index.ts +7 -1
- package/runtime/subsystems/index.ts +11 -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/{sync/execute-sync.use-case.ts → integration/execute-integration.use-case.ts} +40 -40
- package/runtime/subsystems/{sync → integration}/index.ts +47 -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 +49 -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/jobs/bullmq.config.ts +23 -3
- package/runtime/subsystems/jobs/index.ts +13 -8
- package/runtime/subsystems/jobs/job-worker.bullmq-backend.ts +5 -2
- package/runtime/subsystems/jobs/job-worker.module.ts +27 -7
- package/runtime/subsystems/jobs/jobs-domain.module.ts +27 -2
- 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/backend/modules/core/{sync-source.providers.ejs.t → integration-source.providers.ejs.t} +2 -2
- package/templates/entity/new/clean-lite-ps/entity.ejs.t +1 -1
- package/templates/entity/new/clean-lite-ps/module.ejs.t +1 -1
- package/templates/entity/new/clean-lite-ps/prompt-extension.js +33 -33
- 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/events/domain-events.schema.ejs.t +43 -2
- 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/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,31 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* wiring the
|
|
2
|
+
* IntegrationModule — `DynamicModule.forRoot({ backend, multiTenant? })` factory
|
|
3
|
+
* wiring the integration subsystem's substrate (SYNC-6, ADR-008 subsystem pattern).
|
|
4
4
|
*
|
|
5
5
|
* ## What this module provides
|
|
6
6
|
*
|
|
7
|
-
* - `
|
|
8
|
-
* - `
|
|
9
|
-
* - `
|
|
10
|
-
* - `
|
|
11
|
-
* - `
|
|
7
|
+
* - `INTEGRATION_CURSOR_STORE` — Drizzle or Memory cursor store
|
|
8
|
+
* - `INTEGRATION_RUN_RECORDER` — Drizzle or Memory run recorder
|
|
9
|
+
* - `INTEGRATION_FIELD_DIFFER` — default `DeepEqualDiffer`
|
|
10
|
+
* - `INTEGRATION_MULTI_TENANT` — resolved boolean flag (defaults to false)
|
|
11
|
+
* - `INTEGRATION_MODULE_OPTIONS` — the options object itself, for backends
|
|
12
12
|
* that need to inspect config at construction time
|
|
13
13
|
*
|
|
14
14
|
* ## What this module does NOT provide
|
|
15
15
|
*
|
|
16
|
-
* - `
|
|
17
|
-
* their feature module (e.g. `
|
|
16
|
+
* - `INTEGRATION_CHANGE_SOURCE` — per-provider per-entity; consumer binds in
|
|
17
|
+
* their feature module (e.g. `OpportunityIntegrationModule` provides a
|
|
18
18
|
* `SalesforceOpportunityChangeSource`). Loopback suppression — when
|
|
19
19
|
* needed — is composed into the primitive's middleware chain via
|
|
20
20
|
* `createLoopbackMiddleware(store)` (#226-5 / ADR-033); the
|
|
21
21
|
* orchestrator no longer accepts a fingerprint store directly.
|
|
22
|
-
* - `
|
|
22
|
+
* - `INTEGRATION_SINK` — per canonical entity; consumer binds in their feature
|
|
23
23
|
* module.
|
|
24
|
-
* - `
|
|
24
|
+
* - `ExecuteIntegrationUseCase` — registered by the feature module alongside
|
|
25
25
|
* its source + sink bindings. Providing the orchestrator here would
|
|
26
|
-
* force Nest to resolve
|
|
26
|
+
* force Nest to resolve INTEGRATION_CHANGE_SOURCE + INTEGRATION_SINK at module
|
|
27
27
|
* compile time, which fails when the feature module hasn't been
|
|
28
|
-
* imported yet. Consumers register `
|
|
28
|
+
* imported yet. Consumers register `ExecuteIntegrationUseCase` in the same
|
|
29
29
|
* `providers` array as their source + sink so resolution is local
|
|
30
30
|
* to where all three are bound.
|
|
31
31
|
*
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
* ```ts
|
|
39
39
|
* // AppModule — single source of truth for backend + multi-tenancy.
|
|
40
40
|
* @Module({
|
|
41
|
-
* imports: [
|
|
41
|
+
* imports: [IntegrationModule.forRoot({ backend: 'drizzle' })],
|
|
42
42
|
* })
|
|
43
43
|
* export class AppModule {}
|
|
44
44
|
*
|
|
@@ -46,36 +46,36 @@
|
|
|
46
46
|
* // orchestrator for free.
|
|
47
47
|
* @Module({
|
|
48
48
|
* providers: [
|
|
49
|
-
* { provide:
|
|
50
|
-
* { provide:
|
|
51
|
-
*
|
|
49
|
+
* { provide: INTEGRATION_CHANGE_SOURCE, useClass: SalesforceOpportunitySource },
|
|
50
|
+
* { provide: INTEGRATION_SINK, useClass: OpportunityIntegrationSink },
|
|
51
|
+
* ExecuteIntegrationUseCase,
|
|
52
52
|
* ],
|
|
53
53
|
* })
|
|
54
|
-
* export class
|
|
54
|
+
* export class OpportunityIntegrationModule {
|
|
55
55
|
* constructor(
|
|
56
|
-
* private readonly execute:
|
|
56
|
+
* private readonly execute: ExecuteIntegrationUseCase<CanonicalOpportunity>,
|
|
57
57
|
* ) {}
|
|
58
58
|
* }
|
|
59
59
|
* ```
|
|
60
60
|
*
|
|
61
61
|
* `global: true` means feature modules do not need to re-import
|
|
62
|
-
* `
|
|
62
|
+
* `IntegrationModule` — the substrate tokens are available project-wide.
|
|
63
63
|
*/
|
|
64
64
|
import { Module, type DynamicModule, type Provider } from '@nestjs/common';
|
|
65
65
|
import {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
} from './
|
|
72
|
-
import { MemoryCursorStore } from './
|
|
73
|
-
import { MemoryRunRecorder } from './
|
|
74
|
-
import { PostgresCursorStore } from './
|
|
75
|
-
import {
|
|
66
|
+
INTEGRATION_CURSOR_STORE,
|
|
67
|
+
INTEGRATION_FIELD_DIFFER,
|
|
68
|
+
INTEGRATION_MODULE_OPTIONS,
|
|
69
|
+
INTEGRATION_MULTI_TENANT,
|
|
70
|
+
INTEGRATION_RUN_RECORDER,
|
|
71
|
+
} from './integration.tokens';
|
|
72
|
+
import { MemoryCursorStore } from './integration-cursor-store.memory-backend';
|
|
73
|
+
import { MemoryRunRecorder } from './integration-run-recorder.memory-backend';
|
|
74
|
+
import { PostgresCursorStore } from './integration-cursor-store.drizzle-backend';
|
|
75
|
+
import { DrizzleIntegrationRunRecorder } from './integration-run-recorder.drizzle-backend';
|
|
76
76
|
import { DeepEqualDiffer } from './deep-equal.differ';
|
|
77
77
|
|
|
78
|
-
export interface
|
|
78
|
+
export interface IntegrationModuleOptions {
|
|
79
79
|
/**
|
|
80
80
|
* Backend selection. `drizzle` wires the Postgres cursor store +
|
|
81
81
|
* run-log recorder; `memory` wires in-memory doubles suitable for
|
|
@@ -103,16 +103,16 @@ export interface SyncModuleOptions {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
@Module({})
|
|
106
|
-
export class
|
|
107
|
-
static forRoot(options:
|
|
106
|
+
export class IntegrationModule {
|
|
107
|
+
static forRoot(options: IntegrationModuleOptions): DynamicModule {
|
|
108
108
|
const multiTenant = options.multiTenant ?? false;
|
|
109
109
|
|
|
110
110
|
const sharedProviders: Provider[] = [
|
|
111
|
-
{ provide:
|
|
112
|
-
{ provide:
|
|
111
|
+
{ provide: INTEGRATION_MODULE_OPTIONS, useValue: options },
|
|
112
|
+
{ provide: INTEGRATION_MULTI_TENANT, useValue: multiTenant },
|
|
113
113
|
// Default differ — consumers can override by binding a different
|
|
114
|
-
// `IFieldDiffer<T>` to `
|
|
115
|
-
{ provide:
|
|
114
|
+
// `IFieldDiffer<T>` to `INTEGRATION_FIELD_DIFFER` in their feature module.
|
|
115
|
+
{ provide: INTEGRATION_FIELD_DIFFER, useValue: new DeepEqualDiffer() },
|
|
116
116
|
];
|
|
117
117
|
|
|
118
118
|
const backendProviders: Provider[] =
|
|
@@ -123,33 +123,33 @@ export class SyncModule {
|
|
|
123
123
|
// direct assertions. Matches JOB-4 / MemoryJobStore shape.
|
|
124
124
|
{ provide: MemoryCursorStore, useValue: new MemoryCursorStore() },
|
|
125
125
|
{
|
|
126
|
-
provide:
|
|
126
|
+
provide: INTEGRATION_CURSOR_STORE,
|
|
127
127
|
useExisting: MemoryCursorStore,
|
|
128
128
|
},
|
|
129
129
|
{ provide: MemoryRunRecorder, useValue: new MemoryRunRecorder() },
|
|
130
130
|
{
|
|
131
|
-
provide:
|
|
131
|
+
provide: INTEGRATION_RUN_RECORDER,
|
|
132
132
|
useExisting: MemoryRunRecorder,
|
|
133
133
|
},
|
|
134
134
|
]
|
|
135
135
|
: [
|
|
136
136
|
// Drizzle backends — injected with DRIZZLE (provided by the
|
|
137
|
-
// consumer's DrizzleModule) + the
|
|
137
|
+
// consumer's DrizzleModule) + the INTEGRATION_MULTI_TENANT flag
|
|
138
138
|
// we bound above.
|
|
139
|
-
{ provide:
|
|
140
|
-
{ provide:
|
|
139
|
+
{ provide: INTEGRATION_CURSOR_STORE, useClass: PostgresCursorStore },
|
|
140
|
+
{ provide: INTEGRATION_RUN_RECORDER, useClass: DrizzleIntegrationRunRecorder },
|
|
141
141
|
];
|
|
142
142
|
|
|
143
143
|
return {
|
|
144
|
-
module:
|
|
144
|
+
module: IntegrationModule,
|
|
145
145
|
global: true,
|
|
146
146
|
providers: [...sharedProviders, ...backendProviders],
|
|
147
147
|
exports: [
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
148
|
+
INTEGRATION_MODULE_OPTIONS,
|
|
149
|
+
INTEGRATION_MULTI_TENANT,
|
|
150
|
+
INTEGRATION_FIELD_DIFFER,
|
|
151
|
+
INTEGRATION_CURSOR_STORE,
|
|
152
|
+
INTEGRATION_RUN_RECORDER,
|
|
153
153
|
],
|
|
154
154
|
};
|
|
155
155
|
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration subsystem — DI tokens
|
|
3
|
+
*
|
|
4
|
+
* String constants (not Symbols) so they match by value across import
|
|
5
|
+
* boundaries — same convention as the events subsystem (`EVENT_BUS`). The
|
|
6
|
+
* jobs subsystem uses Symbols for its analogous tokens; events and integration
|
|
7
|
+
* stay internally consistent with strings.
|
|
8
|
+
*
|
|
9
|
+
* Usage in use cases:
|
|
10
|
+
* ```ts
|
|
11
|
+
* constructor(
|
|
12
|
+
* @Inject(INTEGRATION_CHANGE_SOURCE) private readonly source: IChangeSource<CanonicalOpportunity>,
|
|
13
|
+
* @Inject(INTEGRATION_CURSOR_STORE) private readonly cursors: ICursorStore,
|
|
14
|
+
* @Inject(INTEGRATION_FIELD_DIFFER) private readonly differ: IFieldDiffer<CanonicalOpportunity>,
|
|
15
|
+
* @Inject(INTEGRATION_SINK) private readonly sink: IIntegrationSink<CanonicalOpportunity>,
|
|
16
|
+
* @Inject(INTEGRATION_RUN_RECORDER) private readonly recorder: IIntegrationRunRecorder,
|
|
17
|
+
* ) {}
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* Concrete bindings are registered by `IntegrationModule.forRoot(...)` (SYNC-6).
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export const INTEGRATION_CHANGE_SOURCE = 'INTEGRATION_CHANGE_SOURCE' as const;
|
|
24
|
+
export const INTEGRATION_CURSOR_STORE = 'INTEGRATION_CURSOR_STORE' as const;
|
|
25
|
+
export const INTEGRATION_FIELD_DIFFER = 'INTEGRATION_FIELD_DIFFER' as const;
|
|
26
|
+
export const INTEGRATION_SINK = 'INTEGRATION_SINK' as const;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Run-recorder token (SYNC-5). Backed by `IIntegrationRunRecorder`. Drizzle impl
|
|
30
|
+
* lands in SYNC-4; tests provide inline fakes.
|
|
31
|
+
*/
|
|
32
|
+
export const INTEGRATION_RUN_RECORDER = 'INTEGRATION_RUN_RECORDER' as const;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Injection token for the resolved `IntegrationModuleOptions` object (SYNC-6).
|
|
36
|
+
*
|
|
37
|
+
* Backends that need to observe module configuration (e.g. `multiTenant`
|
|
38
|
+
* flag, pool filters) inject via this token. Provided automatically by
|
|
39
|
+
* `IntegrationModule.forRoot(...)` / `IntegrationModule.forRootAsync(...)`.
|
|
40
|
+
*/
|
|
41
|
+
export const INTEGRATION_MODULE_OPTIONS = 'INTEGRATION_MODULE_OPTIONS' as const;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Injection token for the resolved multi-tenancy flag (SYNC-6).
|
|
45
|
+
*
|
|
46
|
+
* Provided by `IntegrationModule.forRoot(...)` as `options.multiTenant ?? false`.
|
|
47
|
+
* Consumed by `ExecuteIntegrationUseCase` to enforce the tenantId-is-required rule.
|
|
48
|
+
*/
|
|
49
|
+
export const INTEGRATION_MULTI_TENANT = 'INTEGRATION_MULTI_TENANT' as const;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Integration subsystem — loopback `ChangeMiddleware` factory (#226-5, ADR-033).
|
|
3
3
|
*
|
|
4
|
-
* Replaces the prior orchestrator-side `@Optional()
|
|
4
|
+
* Replaces the prior orchestrator-side `@Optional() INTEGRATION_LOOPBACK_FINGERPRINT_STORE`
|
|
5
5
|
* branch. Consumers that need to suppress echoes of their own outbound
|
|
6
6
|
* writes compose `createLoopbackMiddleware(store)` into a primitive's
|
|
7
7
|
* middleware chain — typically alongside `PollChangeSource<T>` — instead
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
* their store or layer a counting middleware alongside this one.
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
|
-
import type { Change } from './
|
|
31
|
+
import type { Change } from './integration-change-source.protocol';
|
|
32
32
|
import type {
|
|
33
33
|
ChangeIterator,
|
|
34
34
|
ChangeMiddleware,
|
|
35
|
-
} from './
|
|
36
|
-
import type { ILoopbackFingerprintStore } from './
|
|
35
|
+
} from './integration-middleware.protocol';
|
|
36
|
+
import type { ILoopbackFingerprintStore } from './integration-loopback.protocol';
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* Build a `ChangeMiddleware<T>` that suppresses changes whose fingerprint
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Integration subsystem — `PollChangeSource<T>` primitive (#226-3, ADR-033).
|
|
3
3
|
*
|
|
4
4
|
* Generic poll-mode `IChangeSource<T>` implementation parameterized by a
|
|
5
5
|
* parsed `DetectionConfig` (poll mode) and a consumer-supplied
|
|
@@ -36,12 +36,12 @@ import type {
|
|
|
36
36
|
Change,
|
|
37
37
|
ChangeSource,
|
|
38
38
|
IChangeSource,
|
|
39
|
-
|
|
40
|
-
} from './
|
|
39
|
+
IntegrationSubscriptionView,
|
|
40
|
+
} from './integration-change-source.protocol';
|
|
41
41
|
import type {
|
|
42
42
|
ChangeIterator,
|
|
43
43
|
ChangeMiddleware,
|
|
44
|
-
} from './
|
|
44
|
+
} from './integration-middleware.protocol';
|
|
45
45
|
|
|
46
46
|
// ============================================================================
|
|
47
47
|
// Cursor + adapter callback shapes
|
|
@@ -60,7 +60,7 @@ export type PollCursor = unknown;
|
|
|
60
60
|
* NOT here on purpose.
|
|
61
61
|
*/
|
|
62
62
|
export interface PollFetchContext {
|
|
63
|
-
readonly subscription:
|
|
63
|
+
readonly subscription: IntegrationSubscriptionView;
|
|
64
64
|
readonly cursor: PollCursor | null;
|
|
65
65
|
readonly filters: readonly ResolvedFilter[];
|
|
66
66
|
}
|
|
@@ -174,14 +174,14 @@ export class PollChangeSource<T> implements IChangeSource<T> {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
listChanges(
|
|
177
|
-
subscription:
|
|
177
|
+
subscription: IntegrationSubscriptionView,
|
|
178
178
|
cursor: unknown | null,
|
|
179
179
|
): AsyncIterable<Change<T>> {
|
|
180
180
|
return this.composed(subscription, cursor);
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
private async *fetch(
|
|
184
|
-
subscription:
|
|
184
|
+
subscription: IntegrationSubscriptionView,
|
|
185
185
|
cursor: unknown | null,
|
|
186
186
|
): AsyncIterable<Change<T>> {
|
|
187
187
|
const ctx: PollFetchContext = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Integration subsystem — `WebhookChangeSource<T>` primitive (#226-4, ADR-033).
|
|
3
3
|
*
|
|
4
4
|
* Generic webhook-mode `IChangeSource<T>` implementation parameterized by a
|
|
5
5
|
* parsed `DetectionConfig` (webhook mode) and a consumer-supplied
|
|
@@ -40,12 +40,12 @@ import type { DetectionConfig } from './detection-config.schema';
|
|
|
40
40
|
import type {
|
|
41
41
|
Change,
|
|
42
42
|
IChangeSource,
|
|
43
|
-
|
|
44
|
-
} from './
|
|
43
|
+
IntegrationSubscriptionView,
|
|
44
|
+
} from './integration-change-source.protocol';
|
|
45
45
|
import type {
|
|
46
46
|
ChangeIterator,
|
|
47
47
|
ChangeMiddleware,
|
|
48
|
-
} from './
|
|
48
|
+
} from './integration-middleware.protocol';
|
|
49
49
|
|
|
50
50
|
// ============================================================================
|
|
51
51
|
// Cursor + queue callback shapes
|
|
@@ -65,7 +65,7 @@ export type WebhookCursor = unknown;
|
|
|
65
65
|
* `userId` / `tenantId`.
|
|
66
66
|
*/
|
|
67
67
|
export interface WebhookFetchContext {
|
|
68
|
-
readonly subscription:
|
|
68
|
+
readonly subscription: IntegrationSubscriptionView;
|
|
69
69
|
readonly cursor: WebhookCursor | null;
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -162,14 +162,14 @@ export class WebhookChangeSource<T> implements IChangeSource<T> {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
listChanges(
|
|
165
|
-
subscription:
|
|
165
|
+
subscription: IntegrationSubscriptionView,
|
|
166
166
|
cursor: unknown | null,
|
|
167
167
|
): AsyncIterable<Change<T>> {
|
|
168
168
|
return this.composed(subscription, cursor);
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
private async *fetch(
|
|
172
|
-
subscription:
|
|
172
|
+
subscription: IntegrationSubscriptionView,
|
|
173
173
|
cursor: unknown | null,
|
|
174
174
|
): AsyncIterable<Change<T>> {
|
|
175
175
|
const ctx: WebhookFetchContext = {
|
|
@@ -6,9 +6,29 @@
|
|
|
6
6
|
* `jobs.extensions.bullmq.*` config namespace (CLAUDE.md core/extension
|
|
7
7
|
* protocol). The Drizzle backend never reads any of it.
|
|
8
8
|
*/
|
|
9
|
-
import type { ConnectionOptions } from 'bullmq';
|
|
10
9
|
import { loadPoolConfig, type PoolConfig } from './pool-config.loader';
|
|
11
10
|
|
|
11
|
+
/**
|
|
12
|
+
* #6 — Structural mirror of BullMQ's `ConnectionOptions`. Declared locally
|
|
13
|
+
* so this config file (which ships into EVERY jobs install, drizzle or
|
|
14
|
+
* bullmq) does NOT need the `bullmq` peer dep resolved by the consumer's
|
|
15
|
+
* tsc. The bullmq backend internally casts to the real `ConnectionOptions`
|
|
16
|
+
* — that file is only vendored when `--backend bullmq` is selected
|
|
17
|
+
* (see `backendFileFilter`).
|
|
18
|
+
*
|
|
19
|
+
* Accepts the `{ url }` shape this resolver emits, plus the host/port/
|
|
20
|
+
* password/db form BullMQ also accepts, with an open index for any extra
|
|
21
|
+
* ioredis options consumers may flow through.
|
|
22
|
+
*/
|
|
23
|
+
export type BullMqConnectionOptions = {
|
|
24
|
+
url?: string;
|
|
25
|
+
host?: string;
|
|
26
|
+
port?: number;
|
|
27
|
+
password?: string;
|
|
28
|
+
db?: number;
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
};
|
|
31
|
+
|
|
12
32
|
/**
|
|
13
33
|
* Typed shape of `codegen.config.yaml: jobs.extensions.bullmq`. Snake_case
|
|
14
34
|
* because it mirrors the YAML the consumer authors.
|
|
@@ -53,7 +73,7 @@ export interface BullMqExtensionsConfig {
|
|
|
53
73
|
* orchestrator + worker actually consume.
|
|
54
74
|
*/
|
|
55
75
|
export interface BullMqResolvedConfig {
|
|
56
|
-
connection:
|
|
76
|
+
connection: BullMqConnectionOptions;
|
|
57
77
|
queuePrefix?: string;
|
|
58
78
|
bullBoard?: { enabled: boolean; mountPath: string };
|
|
59
79
|
}
|
|
@@ -85,7 +105,7 @@ export function resolveBullMqConfig(
|
|
|
85
105
|
ext?.redis_url ?? process.env.REDIS_URL ?? DEFAULT_REDIS_URL;
|
|
86
106
|
|
|
87
107
|
const resolved: BullMqResolvedConfig = {
|
|
88
|
-
connection: { url }
|
|
108
|
+
connection: { url },
|
|
89
109
|
queuePrefix: ext?.queue_prefix,
|
|
90
110
|
};
|
|
91
111
|
if (ext?.bull_board?.enabled) {
|
|
@@ -81,19 +81,24 @@ export { DrizzleJobRunService } from './job-run-service.drizzle-backend';
|
|
|
81
81
|
export { DrizzleJobStepService } from './job-step-service.drizzle-backend';
|
|
82
82
|
|
|
83
83
|
// ─── BULLMQ-1: BullMQ backend (additive; opt-in via jobs.backend: bullmq) ──
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
// #6 — backend-specific implementation classes are NOT re-exported from this
|
|
85
|
+
// public barrel. `BullMQJobOrchestrator` + `BullMQJobWorker` are only vendored
|
|
86
|
+
// when the consumer installs with `--backend bullmq`; surfacing them here
|
|
87
|
+
// would force every consumer's tsc to resolve those files even on a drizzle
|
|
88
|
+
// install (filtered out → TS2307). Consumers who select bullmq import them
|
|
89
|
+
// directly from their backend file; `JobsDomainModule.forRoot({ backend:
|
|
90
|
+
// 'bullmq' })` + `JobWorkerModule` lazy-load them internally.
|
|
91
|
+
//
|
|
92
|
+
// `bullmq.config.ts` (tokens + helpers) IS still re-exported — it always
|
|
93
|
+
// ships (its only type surface is a local `BullMqConnectionOptions`, no
|
|
94
|
+
// `bullmq` peer-dep resolution required). The module files static-import
|
|
95
|
+
// from it.
|
|
92
96
|
export {
|
|
93
97
|
BULLMQ_CONNECTION,
|
|
94
98
|
BULLMQ_RESOLVED_CONFIG,
|
|
95
99
|
resolveBullMqConfig,
|
|
96
100
|
resolvePoolQueueName,
|
|
101
|
+
type BullMqConnectionOptions,
|
|
97
102
|
type BullMqExtensionsConfig,
|
|
98
103
|
type BullMqResolvedConfig,
|
|
99
104
|
} from './bullmq.config';
|
|
@@ -94,13 +94,16 @@ export class BullMQJobWorker {
|
|
|
94
94
|
}
|
|
95
95
|
this.worker = new WorkerCtor(
|
|
96
96
|
this.options.queueName,
|
|
97
|
-
|
|
97
|
+
// #6 / noImplicitAny — explicit annotations so the file stays
|
|
98
|
+
// strict-clean even when consumers compile under a stricter tsconfig
|
|
99
|
+
// than the one used to type-check the runtime tree.
|
|
100
|
+
(job: Job<BullJobPayload>) => this.process(job),
|
|
98
101
|
{
|
|
99
102
|
connection: this.options.connection,
|
|
100
103
|
concurrency: this.options.concurrency,
|
|
101
104
|
},
|
|
102
105
|
);
|
|
103
|
-
this.worker.on('failed', (job, err) => {
|
|
106
|
+
this.worker.on('failed', (job: Job<BullJobPayload> | undefined, err: Error) => {
|
|
104
107
|
// BullMQ fires `failed` after EACH attempt; only mirror to job_run when
|
|
105
108
|
// attempts are exhausted (BullMQ will not retry further).
|
|
106
109
|
if (!job) return;
|
|
@@ -52,12 +52,17 @@ import {
|
|
|
52
52
|
type PoolConfig,
|
|
53
53
|
} from './pool-config.loader';
|
|
54
54
|
import { JobWorker, type JobWorkerOptions } from './job-worker';
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
// #6 — `BullMQJobWorker` is lazy-loaded only when `backend: 'bullmq'` is
|
|
56
|
+
// selected (`spawnBullMQWorker` below). The file is filtered out of drizzle/
|
|
57
|
+
// memory installs (see `backendFileFilter`). The `ConnectionOptions` type
|
|
58
|
+
// previously imported from `'bullmq'` is replaced by `BullMqConnectionOptions`
|
|
59
|
+
// from `./bullmq.config` (a self-contained structural mirror that does NOT
|
|
60
|
+
// require the `bullmq` peer dep to type-check).
|
|
57
61
|
import {
|
|
58
62
|
BULLMQ_CONNECTION,
|
|
59
63
|
BULLMQ_RESOLVED_CONFIG,
|
|
60
64
|
resolvePoolQueueName,
|
|
65
|
+
type BullMqConnectionOptions,
|
|
61
66
|
type BullMqResolvedConfig,
|
|
62
67
|
} from './bullmq.config';
|
|
63
68
|
import {
|
|
@@ -157,7 +162,7 @@ export class JobWorkerOrchestrator implements OnModuleInit, OnModuleDestroy {
|
|
|
157
162
|
*/
|
|
158
163
|
@Optional()
|
|
159
164
|
@Inject(BULLMQ_CONNECTION)
|
|
160
|
-
private readonly bullConnection:
|
|
165
|
+
private readonly bullConnection: BullMqConnectionOptions | null = null,
|
|
161
166
|
@Optional()
|
|
162
167
|
@Inject(BULLMQ_RESOLVED_CONFIG)
|
|
163
168
|
private readonly bullConfig: BullMqResolvedConfig | null = null,
|
|
@@ -233,7 +238,7 @@ export class JobWorkerOrchestrator implements OnModuleInit, OnModuleDestroy {
|
|
|
233
238
|
const worker = this.options.workerFactory
|
|
234
239
|
? this.options.workerFactory(workerOptions)
|
|
235
240
|
: backend === 'bullmq'
|
|
236
|
-
? this.spawnBullMQWorker(poolName, def.queue, def.concurrency, poolConfig)
|
|
241
|
+
? await this.spawnBullMQWorker(poolName, def.queue, def.concurrency, poolConfig)
|
|
237
242
|
: this.spawnWorker(workerOptions);
|
|
238
243
|
// `JobWorker` extends Nest's lifecycle hooks but the worker isn't
|
|
239
244
|
// a Nest provider here (we manage the array ourselves). Call
|
|
@@ -364,12 +369,20 @@ export class JobWorkerOrchestrator implements OnModuleInit, OnModuleDestroy {
|
|
|
364
369
|
* orchestrator's `dispatch` via `resolvePoolQueueName(pool, …)` so producer
|
|
365
370
|
* and consumer agree.
|
|
366
371
|
*/
|
|
367
|
-
|
|
372
|
+
/**
|
|
373
|
+
* #6 — async + dynamic-import. The `job-worker.bullmq-backend.ts` file is
|
|
374
|
+
* filtered out of the vendor set for drizzle/memory installs (no `bullmq`
|
|
375
|
+
* peer dep needed). The non-literal import specifier makes TS treat the
|
|
376
|
+
* module as `any` so the consumer's tsc never tries to resolve an absent
|
|
377
|
+
* file. This method is only entered when `backend === 'bullmq'` — at which
|
|
378
|
+
* point the file IS vendored.
|
|
379
|
+
*/
|
|
380
|
+
private async spawnBullMQWorker(
|
|
368
381
|
pool: string,
|
|
369
382
|
_queueAlias: string,
|
|
370
383
|
concurrency: number,
|
|
371
384
|
poolConfig: PoolConfig,
|
|
372
|
-
):
|
|
385
|
+
): Promise<Pick<JobWorker, 'onModuleInit' | 'onModuleDestroy'>> {
|
|
373
386
|
if (!this.db) {
|
|
374
387
|
throw new Error(
|
|
375
388
|
`JobWorkerModule: BullMQ worker spawning requires the Drizzle client ` +
|
|
@@ -390,7 +403,14 @@ export class JobWorkerOrchestrator implements OnModuleInit, OnModuleDestroy {
|
|
|
390
403
|
);
|
|
391
404
|
}
|
|
392
405
|
const queueName = resolvePoolQueueName(pool, this.bullConfig, poolConfig);
|
|
393
|
-
|
|
406
|
+
const specifier = './job-worker.bullmq-backend';
|
|
407
|
+
const mod = (await import(specifier)) as {
|
|
408
|
+
BullMQJobWorker: new (...args: unknown[]) => Pick<
|
|
409
|
+
JobWorker,
|
|
410
|
+
'onModuleInit' | 'onModuleDestroy'
|
|
411
|
+
>;
|
|
412
|
+
};
|
|
413
|
+
return new mod.BullMQJobWorker(
|
|
394
414
|
this.db,
|
|
395
415
|
this.orchestrator,
|
|
396
416
|
this.stepService,
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* and the type system reserves the slot.
|
|
16
16
|
*/
|
|
17
17
|
import { Module, type DynamicModule, type Provider } from '@nestjs/common';
|
|
18
|
+
import { DRIZZLE } from '../../constants/tokens';
|
|
18
19
|
import {
|
|
19
20
|
JOB_ORCHESTRATOR,
|
|
20
21
|
JOB_RUN_SERVICE,
|
|
@@ -24,7 +25,10 @@ import {
|
|
|
24
25
|
import { DrizzleJobOrchestrator } from './job-orchestrator.drizzle-backend';
|
|
25
26
|
import { DrizzleJobRunService } from './job-run-service.drizzle-backend';
|
|
26
27
|
import { DrizzleJobStepService } from './job-step-service.drizzle-backend';
|
|
27
|
-
|
|
28
|
+
// #6 — `BullMQJobOrchestrator` is lazy-loaded only when `backend: 'bullmq'`
|
|
29
|
+
// is selected. The backend file is filtered out of drizzle/memory installs
|
|
30
|
+
// (see `backendFileFilter`); a non-literal dynamic import below sidesteps
|
|
31
|
+
// consumer-side tsc resolution of an absent file.
|
|
28
32
|
import { MemoryJobOrchestrator } from './job-orchestrator.memory-backend';
|
|
29
33
|
import { MemoryJobRunService } from './job-run-service.memory-backend';
|
|
30
34
|
import { MemoryJobStepService } from './job-step-service.memory-backend';
|
|
@@ -102,10 +106,31 @@ export class JobsDomainModule {
|
|
|
102
106
|
// run/step services stay Drizzle (domain reads + `listForScope` are
|
|
103
107
|
// Postgres queries, unchanged per spec). Only the orchestrator's
|
|
104
108
|
// claim/dispatch half swaps to BullMQ.
|
|
109
|
+
//
|
|
110
|
+
// #6 — the bullmq backend module is filtered out of drizzle/memory
|
|
111
|
+
// installs (no `bullmq` peer dep, no consumer-side tsc compile of an
|
|
112
|
+
// unused file). The factory below dynamic-imports it via a non-literal
|
|
113
|
+
// specifier so TS treats the module type as `any` and never tries to
|
|
114
|
+
// resolve the absent file on a drizzle/memory consumer.
|
|
105
115
|
const resolved = resolveBullMqConfig(opts.extensions?.bullmq);
|
|
106
116
|
providers.push({ provide: BULLMQ_CONNECTION, useValue: resolved.connection });
|
|
107
117
|
providers.push({ provide: BULLMQ_RESOLVED_CONFIG, useValue: resolved });
|
|
108
|
-
providers.push({
|
|
118
|
+
providers.push({
|
|
119
|
+
provide: JOB_ORCHESTRATOR,
|
|
120
|
+
useFactory: async (...args: unknown[]): Promise<object> => {
|
|
121
|
+
const specifier = './job-orchestrator.bullmq-backend';
|
|
122
|
+
const mod = (await import(specifier)) as {
|
|
123
|
+
BullMQJobOrchestrator: new (...args: unknown[]) => object;
|
|
124
|
+
};
|
|
125
|
+
return new mod.BullMQJobOrchestrator(...args);
|
|
126
|
+
},
|
|
127
|
+
// The bullmq orchestrator constructor mirrors DrizzleJobOrchestrator's
|
|
128
|
+
// injection list: DRIZZLE + JOBS_MULTI_TENANT + the resolved BullMQ
|
|
129
|
+
// tokens. Importing token references would force a static dep on the
|
|
130
|
+
// tokens file in this module's import graph; using the existing
|
|
131
|
+
// symbols already in scope is sufficient.
|
|
132
|
+
inject: [DRIZZLE, JOBS_MULTI_TENANT, BULLMQ_CONNECTION, BULLMQ_RESOLVED_CONFIG],
|
|
133
|
+
});
|
|
109
134
|
providers.push({ provide: JOB_RUN_SERVICE, useClass: DrizzleJobRunService });
|
|
110
135
|
providers.push({ provide: JOB_STEP_SERVICE, useClass: DrizzleJobStepService });
|
|
111
136
|
} else {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ObservabilityModule — combiner subsystem (ADR-025, OBS-5, OBS-6).
|
|
3
3
|
*
|
|
4
|
-
* Composes the jobs, bridge, and
|
|
4
|
+
* Composes the jobs, bridge, and integration read ports into a single
|
|
5
5
|
* `IObservability` facade. Owned by no sibling subsystem; it consumes
|
|
6
6
|
* their tokens via DI, which the consumer app wires by registering the
|
|
7
7
|
* sibling modules in the right order (like BridgeModule — the named
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* EventsModule.forRoot({ backend: 'drizzle' }),
|
|
15
15
|
* JobsDomainModule.forRoot({ backend: 'drizzle' }),
|
|
16
16
|
* BridgeModule.forRoot({ backend: 'drizzle' }),
|
|
17
|
-
*
|
|
17
|
+
* IntegrationModule.forRoot({ backend: 'drizzle' }),
|
|
18
18
|
* ObservabilityModule.forRoot({
|
|
19
19
|
* reporters: {
|
|
20
20
|
* bridgeMetrics: {
|