@cosmicdrift/kumiko-framework 0.13.0 → 0.15.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/package.json +7 -7
- package/src/__tests__/{anonymous-access.integration.ts → anonymous-access.integration.test.ts} +12 -9
- package/src/__tests__/{error-contract.integration.ts → error-contract.integration.test.ts} +5 -4
- package/src/__tests__/{field-access.integration.ts → field-access.integration.test.ts} +3 -3
- package/src/__tests__/{full-stack.integration.ts → full-stack.integration.test.ts} +7 -16
- package/src/__tests__/{ownership.integration.ts → ownership.integration.test.ts} +3 -2
- package/src/__tests__/{raw-table.integration.ts → raw-table.integration.test.ts} +18 -30
- package/src/__tests__/{reference-data.integration.ts → reference-data.integration.test.ts} +24 -11
- package/src/__tests__/{transition-guard.integration.ts → transition-guard.integration.test.ts} +12 -10
- package/src/api/__tests__/api.test.ts +1 -1
- package/src/api/__tests__/auth-middleware-transport.test.ts +1 -1
- package/src/api/__tests__/auth-routes-cookie.test.ts +1 -1
- package/src/api/__tests__/{batch.integration.ts → batch.integration.test.ts} +30 -30
- package/src/api/__tests__/body-limit.test.ts +1 -1
- package/src/api/__tests__/csrf-middleware.test.ts +1 -1
- package/src/api/__tests__/{dispatcher-live.integration.ts → dispatcher-live.integration.test.ts} +10 -9
- package/src/api/__tests__/metrics-endpoint.test.ts +1 -1
- package/src/api/__tests__/{nested-write.integration.ts → nested-write.integration.test.ts} +13 -16
- package/src/api/__tests__/readiness.test.ts +1 -1
- package/src/api/__tests__/request-id-middleware.test.ts +1 -1
- package/src/api/__tests__/sse-broker.test.ts +12 -12
- package/src/api/__tests__/sse-route.test.ts +1 -1
- package/src/api/readiness.ts +2 -2
- package/src/auth/__tests__/roles.test.ts +2 -2
- package/src/bun-db/__tests__/PATTERN.md +73 -0
- package/src/bun-db/__tests__/_helpers.ts +103 -0
- package/src/bun-db/__tests__/batch-methods.integration.test.ts +143 -0
- package/src/bun-db/__tests__/batch-methods.test.ts +20 -0
- package/src/bun-db/__tests__/bun-test-db.ts +19 -0
- package/src/bun-db/__tests__/bun-test-stack.ts +6 -0
- package/src/bun-db/__tests__/column-types.integration.test.ts +132 -0
- package/src/bun-db/__tests__/compound-types.integration.test.ts +134 -0
- package/src/bun-db/__tests__/jsonb-edge-cases.integration.test.ts +235 -0
- package/src/bun-db/__tests__/smoke.integration.test.ts +43 -0
- package/src/bun-db/__tests__/sql-methods.integration.test.ts +231 -0
- package/src/bun-db/__tests__/where-patterns.integration.test.ts +185 -0
- package/src/bun-db/connection.ts +84 -0
- package/src/bun-db/index.ts +31 -0
- package/src/bun-db/query.ts +845 -0
- package/src/compliance/__tests__/duration-spec.test.ts +1 -1
- package/src/compliance/__tests__/profiles.test.ts +1 -1
- package/src/compliance/__tests__/sub-processors.test.ts +1 -1
- package/src/db/__tests__/{apply-entity-event-tenant.integration.ts → apply-entity-event-tenant.integration.test.ts} +13 -11
- package/src/db/__tests__/big-int-field.test.ts +15 -14
- package/src/db/__tests__/column-ddl.integration.test.ts +113 -0
- package/src/db/__tests__/compound-types.test.ts +1 -1
- package/src/db/__tests__/{config-seed.integration.ts → config-seed.integration.test.ts} +32 -27
- package/src/db/__tests__/connection-options.test.ts +1 -1
- package/src/db/__tests__/dialect-instant.test.ts +1 -1
- package/src/db/__tests__/encryption.test.ts +1 -1
- package/src/db/__tests__/{drizzle-table-types.test.ts → entity-table-types.test.ts} +16 -16
- package/src/db/__tests__/{event-store-executor-list.integration.ts → event-store-executor-list.integration.test.ts} +12 -7
- package/src/db/__tests__/{event-store-executor.integration.ts → event-store-executor.integration.test.ts} +19 -12
- package/src/db/__tests__/{implicit-projection-equivalence.integration.ts → implicit-projection-equivalence.integration.test.ts} +35 -29
- package/src/db/__tests__/located-timestamp.test.ts +1 -1
- package/src/db/__tests__/money.test.ts +1 -1
- package/src/db/__tests__/{multi-row-insert.integration.ts → multi-row-insert.integration.test.ts} +18 -11
- package/src/db/__tests__/parse-auto-verb.test.ts +1 -1
- package/src/db/__tests__/{required-not-null-migration-safety.integration.ts → required-not-null-migration-safety.integration.test.ts} +28 -24
- package/src/db/__tests__/{schema-migration.integration.ts → schema-migration.integration.test.ts} +32 -28
- package/src/db/__tests__/sql-inventory.test.ts +56 -0
- package/src/db/__tests__/table-builder-indexes.test.ts +30 -11
- package/src/db/__tests__/table-builder-required.test.ts +20 -22
- package/src/db/__tests__/{tenant-db.integration.ts → tenant-db.integration.test.ts} +106 -144
- package/src/db/__tests__/{unique-violation-mapping.integration.ts → unique-violation-mapping.integration.test.ts} +13 -8
- package/src/db/api.ts +46 -0
- package/src/db/apply-entity-event.ts +45 -36
- package/src/db/assert-exists-in.ts +5 -16
- package/src/db/bun-provider.ts +37 -0
- package/src/db/config-seed.ts +4 -4
- package/src/db/connection.ts +14 -57
- package/src/db/cursor.ts +5 -56
- package/src/db/dialect.ts +472 -99
- package/src/db/eagerload.ts +5 -12
- package/src/db/entity-table-meta.ts +390 -0
- package/src/db/event-store-executor.ts +158 -100
- package/src/db/index.ts +33 -5
- package/src/db/migrate-generator.ts +350 -0
- package/src/db/migrate-runner.ts +206 -0
- package/src/db/postgres-provider.ts +25 -0
- package/src/db/queries/entity-read.ts +15 -0
- package/src/db/queries/es-ops.ts +17 -0
- package/src/db/queries/event-consumer.ts +170 -0
- package/src/db/queries/event-store-admin.ts +127 -0
- package/src/db/queries/event-store.ts +155 -0
- package/src/db/queries/projection-rebuild.ts +59 -0
- package/src/db/queries/raw-sql.ts +15 -0
- package/src/db/queries/schema-drift.ts +35 -0
- package/src/db/queries/seed-context.ts +58 -0
- package/src/db/queries/table-ops.ts +11 -0
- package/src/db/queries/test-stack.ts +56 -0
- package/src/db/query-api.ts +22 -0
- package/src/db/query.ts +30 -0
- package/src/db/reference-data.ts +19 -22
- package/src/db/render-ddl.ts +57 -0
- package/src/db/row-helpers.ts +3 -52
- package/src/db/schema-inspection.ts +17 -4
- package/src/db/sql-inventory.ts +208 -0
- package/src/db/table-builder.ts +48 -40
- package/src/db/tenant-db.ts +105 -326
- package/src/engine/__tests__/auth-claims-registrar.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-api-exposure.test.ts +3 -3
- package/src/engine/__tests__/boot-validator-located-timestamps.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-pii-retention.test.ts +5 -5
- package/src/engine/__tests__/boot-validator-s0-integration.test.ts +3 -3
- package/src/engine/__tests__/boot-validator.test.ts +4 -3
- package/src/engine/__tests__/build-app-schema.test.ts +1 -1
- package/src/engine/__tests__/build-target.test.ts +1 -1
- package/src/engine/__tests__/claim-keys.test.ts +1 -1
- package/src/engine/__tests__/codemod-pipeline.test.ts +3 -3
- package/src/engine/__tests__/config-helpers.test.ts +1 -1
- package/src/engine/__tests__/effective-features.test.ts +1 -1
- package/src/engine/__tests__/engine.test.ts +1 -1
- package/src/engine/__tests__/entity-handlers.test.ts +3 -3
- package/src/engine/__tests__/event-helpers.test.ts +3 -3
- package/src/engine/__tests__/extends-registrar.test.ts +4 -4
- package/src/engine/__tests__/factories-long-text.test.ts +1 -1
- package/src/engine/__tests__/factories-time.test.ts +1 -1
- package/src/engine/__tests__/field-predicates.test.ts +1 -1
- package/src/engine/__tests__/hook-phases.test.ts +1 -1
- package/src/engine/__tests__/identifiers.test.ts +1 -1
- package/src/engine/__tests__/lifecycle-hooks.test.ts +1 -1
- package/src/engine/__tests__/nav.test.ts +1 -1
- package/src/engine/__tests__/ownership.test.ts +10 -11
- package/src/engine/__tests__/parse-ref-target.test.ts +1 -1
- package/src/engine/__tests__/pipeline-engine.test.ts +1 -1
- package/src/engine/__tests__/{pipeline-handler.integration.ts → pipeline-handler.integration.test.ts} +38 -52
- package/src/engine/__tests__/{pipeline-observability.integration.ts → pipeline-observability.integration.test.ts} +1 -1
- package/src/engine/__tests__/{pipeline-performance.integration.ts → pipeline-performance.integration.test.ts} +1 -1
- package/src/engine/__tests__/pipeline-sub-pipelines.test.ts +1 -1
- package/src/engine/__tests__/post-query-hook.test.ts +1 -1
- package/src/engine/__tests__/projection-helpers.test.ts +25 -17
- package/src/engine/__tests__/projection.test.ts +4 -4
- package/src/engine/__tests__/qualified-name.test.ts +1 -1
- package/src/engine/__tests__/raw-table.test.ts +9 -8
- package/src/engine/__tests__/resolve-config-or-param.test.ts +5 -5
- package/src/engine/__tests__/run-in.test.ts +1 -1
- package/src/engine/__tests__/schema-builder.test.ts +1 -1
- package/src/engine/__tests__/screen.test.ts +1 -1
- package/src/engine/__tests__/search-payload-extension.test.ts +3 -3
- package/src/engine/__tests__/state-machine.test.ts +1 -1
- package/src/engine/__tests__/steps-aggregate-append-event.test.ts +7 -7
- package/src/engine/__tests__/steps-aggregate-create.test.ts +4 -4
- package/src/engine/__tests__/steps-aggregate-update.test.ts +3 -3
- package/src/engine/__tests__/steps-call-feature.test.ts +5 -5
- package/src/engine/__tests__/steps-mail-send.test.ts +7 -7
- package/src/engine/__tests__/steps-read.test.ts +34 -40
- package/src/engine/__tests__/steps-resolver-utils.test.ts +6 -6
- package/src/engine/__tests__/steps-unsafe-projection-delete.test.ts +24 -19
- package/src/engine/__tests__/steps-unsafe-projection-upsert.test.ts +28 -17
- package/src/engine/__tests__/steps-webhook-send.test.ts +6 -6
- package/src/engine/__tests__/steps-workflow.test.ts +7 -7
- package/src/engine/__tests__/system-user.test.ts +1 -1
- package/src/engine/__tests__/validate-projection-allowlist.test.ts +4 -5
- package/src/engine/__tests__/validation-hooks.test.ts +1 -1
- package/src/engine/__tests__/visual-tree-patterns.test.ts +1 -1
- package/src/engine/boot-validator/entity-handler.ts +3 -3
- package/src/engine/boot-validator/ownership.ts +1 -1
- package/src/engine/define-feature.ts +1 -2
- package/src/engine/entity-handlers.ts +5 -5
- package/src/engine/factories.ts +1 -1
- package/src/engine/feature-ast/__tests__/canonical-form.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/parse-real-features.test.ts +2 -2
- package/src/engine/feature-ast/__tests__/parse.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/patch.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/patcher.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/visual-tree-parse.test.ts +1 -1
- package/src/engine/ownership.ts +113 -41
- package/src/engine/pattern-library/__tests__/library.test.ts +2 -2
- package/src/engine/projection-helpers.ts +2 -11
- package/src/engine/registry.ts +2 -2
- package/src/engine/steps/read-find-many.ts +13 -13
- package/src/engine/steps/read-find-one.ts +7 -9
- package/src/engine/steps/unsafe-projection-delete.ts +4 -5
- package/src/engine/steps/unsafe-projection-upsert.ts +63 -31
- package/src/engine/types/feature.ts +7 -2
- package/src/engine/types/fields.ts +4 -5
- package/src/engine/types/step.ts +10 -10
- package/src/engine/validate-projection-allowlist.ts +23 -3
- package/src/entrypoint/__tests__/{entrypoint-job-wiring.integration.ts → entrypoint-job-wiring.integration.test.ts} +4 -3
- package/src/entrypoint/__tests__/{split-deploy.integration.ts → split-deploy.integration.test.ts} +4 -3
- package/src/env/__tests__/compose-env-schema.test.ts +1 -1
- package/src/env/__tests__/dry-run.test.ts +1 -1
- package/src/errors/__tests__/classes.test.ts +1 -1
- package/src/errors/__tests__/write-failures.test.ts +1 -1
- package/src/es-ops/__tests__/{context.integration.ts → context.integration.test.ts} +43 -29
- package/src/es-ops/__tests__/{runner.integration.ts → runner.integration.test.ts} +25 -23
- package/src/es-ops/__tests__/runner.test.ts +29 -19
- package/src/es-ops/context.ts +9 -43
- package/src/es-ops/operations-schema.ts +2 -2
- package/src/es-ops/runner.ts +12 -26
- package/src/event-store/__tests__/{admin-api.integration.ts → admin-api.integration.test.ts} +71 -45
- package/src/event-store/__tests__/{event-store.integration.ts → event-store.integration.test.ts} +7 -5
- package/src/event-store/__tests__/{get-stream-version-perf.integration.ts → get-stream-version-perf.integration.test.ts} +5 -3
- package/src/event-store/__tests__/{perf.integration.ts → perf.integration.test.ts} +24 -16
- package/src/event-store/__tests__/{snapshot.integration.ts → snapshot.integration.test.ts} +34 -28
- package/src/event-store/__tests__/{upcaster-dead-letter.integration.ts → upcaster-dead-letter.integration.test.ts} +11 -12
- package/src/event-store/__tests__/{upcaster.integration.ts → upcaster.integration.test.ts} +19 -32
- package/src/event-store/admin-api.ts +55 -83
- package/src/event-store/archive.ts +15 -39
- package/src/event-store/event-store.ts +92 -86
- package/src/event-store/events-schema.ts +2 -1
- package/src/event-store/index.ts +1 -0
- package/src/event-store/snapshot.ts +26 -24
- package/src/event-store/upcaster-dead-letter.ts +19 -18
- package/src/files/__tests__/content-disposition.test.ts +1 -1
- package/src/files/__tests__/{file-field-pipeline.integration.ts → file-field-pipeline.integration.test.ts} +8 -5
- package/src/files/__tests__/file-handle.test.ts +1 -1
- package/src/files/__tests__/{files.integration.ts → files.integration.test.ts} +32 -17
- package/src/files/__tests__/read-stream.test.ts +1 -1
- package/src/files/__tests__/{storage-tracking.integration.ts → storage-tracking.integration.test.ts} +26 -30
- package/src/files/__tests__/write-stream.test.ts +1 -1
- package/src/files/__tests__/zip-stream.test.ts +1 -1
- package/src/files/file-ref-table.ts +2 -2
- package/src/files/file-routes.ts +7 -9
- package/src/files/storage-tracking.ts +9 -17
- package/src/i18n/__tests__/i18n.test.ts +1 -1
- package/src/jobs/__tests__/{job-event-trigger.integration.ts → job-event-trigger.integration.test.ts} +6 -3
- package/src/jobs/__tests__/{job-multi-trigger.integration.ts → job-multi-trigger.integration.test.ts} +6 -3
- package/src/jobs/__tests__/{jobs.integration.ts → jobs.integration.test.ts} +5 -7
- package/src/lifecycle/__tests__/{lifecycle-server.integration.ts → lifecycle-server.integration.test.ts} +1 -1
- package/src/lifecycle/__tests__/lifecycle.test.ts +6 -6
- package/src/lifecycle/__tests__/signal-handlers.test.ts +6 -6
- package/src/logging/__tests__/pino-trace-bridge.test.ts +1 -1
- package/src/migrations/__tests__/compare-snapshots.test.ts +1 -1
- package/src/migrations/__tests__/{detect-drift.integration.ts → detect-drift.integration.test.ts} +34 -26
- package/src/migrations/__tests__/{detect-projections-to-rebuild.integration.ts → detect-projections-to-rebuild.integration.test.ts} +1 -1
- package/src/migrations/__tests__/rebuild-marker.test.ts +1 -1
- package/src/migrations/projection-detection.ts +12 -1
- package/src/migrations/schema-drift.ts +7 -23
- package/src/observability/__tests__/console-provider.test.ts +1 -1
- package/src/observability/__tests__/metric-validator.test.ts +1 -1
- package/src/observability/__tests__/noop-provider.test.ts +1 -1
- package/src/observability/__tests__/{observability.integration.ts → observability.integration.test.ts} +5 -8
- package/src/observability/__tests__/prometheus-meter.test.ts +1 -1
- package/src/observability/__tests__/recording-meter.test.ts +1 -1
- package/src/observability/__tests__/recording-tracer.test.ts +1 -1
- package/src/observability/__tests__/sensitive-filter.test.ts +1 -1
- package/src/pipeline/__tests__/{archive-stream.integration.ts → archive-stream.integration.test.ts} +3 -3
- package/src/pipeline/__tests__/auth-claims-resolver.test.ts +9 -9
- package/src/pipeline/__tests__/{cascade-handler.integration.ts → cascade-handler.integration.test.ts} +18 -15
- package/src/pipeline/__tests__/cascade-handler.test.ts +1 -1
- package/src/pipeline/__tests__/{causation-chain.integration.ts → causation-chain.integration.test.ts} +12 -13
- package/src/pipeline/__tests__/{ctx-bridge.integration.ts → ctx-bridge.integration.test.ts} +12 -11
- package/src/pipeline/__tests__/dispatcher.test.ts +2 -2
- package/src/pipeline/__tests__/{distributed-lock.integration.ts → distributed-lock.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{domain-events-projections.integration.ts → domain-events-projections.integration.test.ts} +13 -15
- package/src/pipeline/__tests__/{event-dedup.integration.ts → event-dedup.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{event-define-event-strict.integration.ts → event-define-event-strict.integration.test.ts} +6 -16
- package/src/pipeline/__tests__/{event-dispatcher-lifecycle.integration.ts → event-dispatcher-lifecycle.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{event-dispatcher-multi-instance.integration.ts → event-dispatcher-multi-instance.integration.test.ts} +3 -2
- package/src/pipeline/__tests__/{event-dispatcher-pg-listen.integration.ts → event-dispatcher-pg-listen.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{event-dispatcher-recovery.integration.ts → event-dispatcher-recovery.integration.test.ts} +2 -2
- package/src/pipeline/__tests__/{event-dispatcher-second-audit.integration.ts → event-dispatcher-second-audit.integration.test.ts} +17 -16
- package/src/pipeline/__tests__/event-dispatcher-strict.test.ts +14 -12
- package/src/pipeline/__tests__/{event-dispatcher.integration.ts → event-dispatcher.integration.test.ts} +8 -15
- package/src/pipeline/__tests__/{event-retention.integration.ts → event-retention.integration.test.ts} +28 -25
- package/src/pipeline/__tests__/{fetch-for-writing.integration.ts → fetch-for-writing.integration.test.ts} +6 -6
- package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +4 -4
- package/src/pipeline/__tests__/{load-aggregate-query.integration.ts → load-aggregate-query.integration.test.ts} +9 -5
- package/src/pipeline/__tests__/{msp-error-mode.integration.ts → msp-error-mode.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{msp-multi-hop.integration.ts → msp-multi-hop.integration.test.ts} +9 -8
- package/src/pipeline/__tests__/{msp-rebuild.integration.ts → msp-rebuild.integration.test.ts} +47 -55
- package/src/pipeline/__tests__/{multi-stream-projection.integration.ts → multi-stream-projection.integration.test.ts} +19 -53
- package/src/pipeline/__tests__/{perf-rebuild.integration.ts → perf-rebuild.integration.test.ts} +36 -34
- package/src/pipeline/__tests__/{post-query-hook.integration.ts → post-query-hook.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{projection-rebuild.integration.ts → projection-rebuild.integration.test.ts} +21 -30
- package/src/pipeline/__tests__/{query-projection.integration.ts → query-projection.integration.test.ts} +6 -5
- package/src/pipeline/__tests__/{redis-pipeline.integration.ts → redis-pipeline.integration.test.ts} +3 -1
- package/src/pipeline/cascade-handler.ts +13 -21
- package/src/pipeline/dispatcher.ts +43 -48
- package/src/pipeline/event-consumer-state.ts +11 -2
- package/src/pipeline/event-dispatcher.ts +86 -146
- package/src/pipeline/event-retention.ts +14 -24
- package/src/pipeline/msp-rebuild.ts +54 -78
- package/src/pipeline/projection-rebuild.ts +65 -67
- package/src/pipeline/projection-state.ts +2 -2
- package/src/random/__tests__/generate.test.ts +13 -13
- package/src/rate-limit/__tests__/{dispatcher-l3.integration.ts → dispatcher-l3.integration.test.ts} +1 -1
- package/src/rate-limit/__tests__/{middleware.integration.ts → middleware.integration.test.ts} +1 -1
- package/src/rate-limit/__tests__/{resolver.integration.ts → resolver.integration.test.ts} +1 -1
- package/src/redis/__tests__/redis-options.test.ts +1 -1
- package/src/search/__tests__/{meilisearch-adapter.integration.ts → meilisearch-adapter.integration.test.ts} +1 -1
- package/src/search/__tests__/search-adapter.test.ts +1 -1
- package/src/secrets/__tests__/dek-cache.test.ts +1 -3
- package/src/secrets/__tests__/env-master-key-provider.test.ts +1 -1
- package/src/secrets/__tests__/envelope.test.ts +1 -1
- package/src/secrets/__tests__/leak-guard.test.ts +1 -1
- package/src/secrets/__tests__/rotation.test.ts +1 -1
- package/src/stack/db.ts +25 -48
- package/src/stack/push-entity-projection-tables.ts +2 -4
- package/src/stack/table-helpers.ts +98 -61
- package/src/stack/test-stack.ts +8 -7
- package/src/testing/__tests__/db-cleanup.test.ts +40 -0
- package/src/testing/__tests__/e2e-generator.test.ts +1 -1
- package/src/testing/__tests__/{ensure-entity-table.integration.ts → ensure-entity-table.integration.test.ts} +7 -14
- package/src/testing/db-cleanup.ts +44 -0
- package/src/testing/expect-error.ts +1 -1
- package/src/testing/index.ts +2 -0
- package/src/testing/multipart-helper.ts +94 -0
- package/src/testing/shared-entities.ts +5 -5
- package/src/time/__tests__/polyfill.test.ts +1 -1
- package/src/time/__tests__/tz-context.test.ts +1 -1
- package/src/utils/__tests__/assert.test.ts +1 -1
- package/src/utils/__tests__/env-parse.test.ts +1 -1
- package/CHANGELOG.md +0 -472
- package/src/db/__tests__/cursor.test.ts +0 -41
- package/src/db/__tests__/db-helpers.test.ts +0 -369
- package/src/db/__tests__/drizzle-helpers.integration.ts +0 -186
- package/src/db/__tests__/row-helpers.test.ts +0 -59
- package/src/engine/steps/_drizzle-boundary.ts +0 -19
- package/src/files/__tests__/file-field-column.integration.ts +0 -103
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
// - die throw-Policy bleibt unverändert (Regression-Guard)
|
|
7
7
|
// - listDeadLetters filtert per eventType
|
|
8
8
|
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { afterAll, afterEach, beforeAll, describe, expect, test } from "bun:test";
|
|
10
|
+
import { type BunTestDb, createTestDb } from "../../bun-db/__tests__/bun-test-db";
|
|
11
|
+
import { asRawClient, insertOne, selectMany } from "../../db/query";
|
|
12
|
+
import { ensureTemporalPolyfill } from "../../time/polyfill";
|
|
12
13
|
import type { StoredEvent } from "../event-store";
|
|
13
14
|
import { createEventsTable, eventsTable } from "../events-schema";
|
|
14
15
|
import { type EventUpcasters, makeUpcastCtx, upcastStoredEvents } from "../upcaster";
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
upcasterDeadLetterTable,
|
|
19
20
|
} from "../upcaster-dead-letter";
|
|
20
21
|
|
|
21
|
-
let testDb:
|
|
22
|
+
let testDb: BunTestDb;
|
|
22
23
|
|
|
23
24
|
const TENANT_ID = "00000000-0000-4000-8000-0000000000aa";
|
|
24
25
|
|
|
@@ -78,6 +79,7 @@ const passthroughUpcasters: EventUpcasters = new Map([
|
|
|
78
79
|
]);
|
|
79
80
|
|
|
80
81
|
beforeAll(async () => {
|
|
82
|
+
await ensureTemporalPolyfill();
|
|
81
83
|
testDb = await createTestDb();
|
|
82
84
|
await createEventsTable(testDb.db);
|
|
83
85
|
await createUpcasterDeadLetterTable(testDb.db);
|
|
@@ -88,8 +90,8 @@ afterAll(async () => {
|
|
|
88
90
|
});
|
|
89
91
|
|
|
90
92
|
afterEach(async () => {
|
|
91
|
-
await testDb.db.
|
|
92
|
-
await testDb.db.
|
|
93
|
+
await asRawClient(testDb.db).unsafe(`DELETE FROM "${upcasterDeadLetterTable.tableName}"`);
|
|
94
|
+
await asRawClient(testDb.db).unsafe(`DELETE FROM "${eventsTable.tableName}"`);
|
|
93
95
|
});
|
|
94
96
|
|
|
95
97
|
describe("upcaster error-policy: throw (default)", () => {
|
|
@@ -165,7 +167,7 @@ describe("upcaster error-policy: quarantine", () => {
|
|
|
165
167
|
);
|
|
166
168
|
|
|
167
169
|
// Drop one directly to add noise of a different type.
|
|
168
|
-
await testDb.db
|
|
170
|
+
await insertOne(testDb.db, upcasterDeadLetterTable, {
|
|
169
171
|
eventId: "99",
|
|
170
172
|
tenantId: TENANT_ID,
|
|
171
173
|
aggregateId: "other",
|
|
@@ -195,10 +197,7 @@ describe("upcaster error-policy: quarantine", () => {
|
|
|
195
197
|
errorPolicy: "quarantine",
|
|
196
198
|
});
|
|
197
199
|
|
|
198
|
-
const rows = await testDb.db
|
|
199
|
-
|
|
200
|
-
.from(upcasterDeadLetterTable)
|
|
201
|
-
.where(eq(upcasterDeadLetterTable.eventId, "30"));
|
|
202
|
-
expect(rows[0]?.c).toBe(2);
|
|
200
|
+
const rows = await selectMany(testDb.db, upcasterDeadLetterTable, { eventId: "30" });
|
|
201
|
+
expect(rows).toHaveLength(2);
|
|
203
202
|
});
|
|
204
203
|
});
|
|
@@ -8,12 +8,12 @@
|
|
|
8
8
|
// with only a 1→2 migration fails immediately, so a missing upcaster
|
|
9
9
|
// can never silently hand half-migrated data to consumers.
|
|
10
10
|
|
|
11
|
-
import {
|
|
12
|
-
import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
|
|
11
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
|
|
13
12
|
import { z } from "zod";
|
|
14
13
|
import { integer as pgInteger, table as pgTable, text as pgText } from "../../db/dialect";
|
|
15
14
|
import { createEventStoreExecutor } from "../../db/event-store-executor";
|
|
16
|
-
import {
|
|
15
|
+
import { asRawClient, insertOne, selectMany } from "../../db/query";
|
|
16
|
+
import { buildEntityTable } from "../../db/table-builder";
|
|
17
17
|
import { createTenantDb, type TenantDb } from "../../db/tenant-db";
|
|
18
18
|
import { createEntity, createRegistry, createTextField, defineFeature } from "../../engine";
|
|
19
19
|
import type { StoredEvent } from "../../event-store";
|
|
@@ -36,7 +36,7 @@ const orderEntity = createEntity({
|
|
|
36
36
|
customer: createTextField({ required: true }),
|
|
37
37
|
},
|
|
38
38
|
});
|
|
39
|
-
const orderTable =
|
|
39
|
+
const orderTable = buildEntityTable("upcast-order", orderEntity);
|
|
40
40
|
|
|
41
41
|
// Projection stores the UPCAST view: the v3 shape expects `totalCents` (int)
|
|
42
42
|
// even though the earliest writes might have stored `totalEuros` (string).
|
|
@@ -78,18 +78,10 @@ const orderFeature = defineFeature("upcastshop", (r) => {
|
|
|
78
78
|
apply: {
|
|
79
79
|
[orderPriced.name]: async (event, tx) => {
|
|
80
80
|
const p = event.payload as { totalCents: number; currency: string };
|
|
81
|
-
await tx
|
|
82
|
-
|
|
83
|
-
.
|
|
84
|
-
|
|
85
|
-
tenantId: event.tenantId,
|
|
86
|
-
totalCents: p.totalCents,
|
|
87
|
-
currency: p.currency,
|
|
88
|
-
})
|
|
89
|
-
.onConflictDoUpdate({
|
|
90
|
-
target: orderSummaryTable.orderId,
|
|
91
|
-
set: { totalCents: p.totalCents, currency: p.currency },
|
|
92
|
-
});
|
|
81
|
+
await asRawClient(tx).unsafe(
|
|
82
|
+
`INSERT INTO "read_upcast_order_summary" (order_id, tenant_id, total_cents, currency) VALUES ($1, $2, $3, $4) ON CONFLICT (order_id) DO UPDATE SET total_cents = $3, currency = $4`,
|
|
83
|
+
[event.aggregateId, event.tenantId, p.totalCents, p.currency],
|
|
84
|
+
);
|
|
93
85
|
},
|
|
94
86
|
},
|
|
95
87
|
});
|
|
@@ -121,8 +113,8 @@ afterAll(async () => {
|
|
|
121
113
|
});
|
|
122
114
|
|
|
123
115
|
beforeEach(async () => {
|
|
124
|
-
await testDb.db.
|
|
125
|
-
|
|
116
|
+
await asRawClient(testDb.db).unsafe(
|
|
117
|
+
`TRUNCATE kumiko_events, read_upcast_orders, read_upcast_order_summary, kumiko_projections RESTART IDENTITY CASCADE`,
|
|
126
118
|
);
|
|
127
119
|
});
|
|
128
120
|
|
|
@@ -280,10 +272,7 @@ describe("upcaster: projection rebuild walks the chain on replay", () => {
|
|
|
280
272
|
});
|
|
281
273
|
expect(result.eventsProcessed).toBe(3);
|
|
282
274
|
|
|
283
|
-
const rows = await testDb.db
|
|
284
|
-
.select()
|
|
285
|
-
.from(orderSummaryTable)
|
|
286
|
-
.orderBy(orderSummaryTable.orderId);
|
|
275
|
+
const rows = await selectMany(testDb.db, orderSummaryTable);
|
|
287
276
|
|
|
288
277
|
// Ordered by orderId → ord1 (10€ = 1000¢), ord2 ($25.50 = 2550¢), ord3 (9900¢)
|
|
289
278
|
expect(rows).toHaveLength(3);
|
|
@@ -305,9 +294,7 @@ describe("upcaster: async (Marten AsyncOnlyEventUpcaster — DB-Lookups)", () =>
|
|
|
305
294
|
segment: pgText("segment").notNull(),
|
|
306
295
|
});
|
|
307
296
|
await unsafePushTables(testDb.db, { upcastAsyncCustomerSegments: customerSegments });
|
|
308
|
-
await testDb.db
|
|
309
|
-
.insert(customerSegments)
|
|
310
|
-
.values({ customerId: "c-async-1", segment: "PREMIUM" });
|
|
297
|
+
await insertOne(testDb.db, customerSegments, { customerId: "c-async-1", segment: "PREMIUM" });
|
|
311
298
|
|
|
312
299
|
const asyncSummary = pgTable("upcast_async_summary", {
|
|
313
300
|
orderId: pgText("order_id").primaryKey(),
|
|
@@ -327,11 +314,11 @@ describe("upcaster: async (Marten AsyncOnlyEventUpcaster — DB-Lookups)", () =>
|
|
|
327
314
|
|
|
328
315
|
r.eventMigration("placed", 1, 2, async (payload, ctx) => {
|
|
329
316
|
const p = payload as { customerId: string };
|
|
330
|
-
const [row] = await ctx.db
|
|
331
|
-
|
|
332
|
-
.
|
|
333
|
-
|
|
334
|
-
|
|
317
|
+
const [row] = await selectMany(ctx.db, customerSegments, { customerId: p.customerId });
|
|
318
|
+
return {
|
|
319
|
+
customerId: p.customerId,
|
|
320
|
+
segment: (row as { segment?: string } | undefined)?.segment ?? "UNKNOWN",
|
|
321
|
+
};
|
|
335
322
|
});
|
|
336
323
|
|
|
337
324
|
r.projection({
|
|
@@ -341,7 +328,7 @@ describe("upcaster: async (Marten AsyncOnlyEventUpcaster — DB-Lookups)", () =>
|
|
|
341
328
|
apply: {
|
|
342
329
|
[placed.name]: async (event, tx) => {
|
|
343
330
|
const p = event.payload as { customerId: string; segment: string };
|
|
344
|
-
await tx
|
|
331
|
+
await insertOne(tx, asyncSummary, {
|
|
345
332
|
orderId: event.aggregateId,
|
|
346
333
|
customerId: p.customerId,
|
|
347
334
|
segment: p.segment,
|
|
@@ -384,7 +371,7 @@ describe("upcaster: async (Marten AsyncOnlyEventUpcaster — DB-Lookups)", () =>
|
|
|
384
371
|
});
|
|
385
372
|
expect(result.eventsProcessed).toBe(2);
|
|
386
373
|
|
|
387
|
-
const rows = await testDb.db
|
|
374
|
+
const rows = await selectMany(testDb.db, asyncSummary);
|
|
388
375
|
expect(rows).toHaveLength(2);
|
|
389
376
|
const byId = new Map(rows.map((r) => [r.orderId, r]));
|
|
390
377
|
// v1 → v2 via async DB lookup → segment from customer_segments.
|
|
@@ -7,13 +7,18 @@
|
|
|
7
7
|
// Allowlist: samples/*/migration/, scripts/migrations/, die Definition
|
|
8
8
|
// selbst, das Guard-Script selbst.
|
|
9
9
|
|
|
10
|
-
import { sql } from "drizzle-orm";
|
|
11
10
|
import type { DbRunner } from "../db";
|
|
12
11
|
import { isUniqueViolation } from "../db/pg-error";
|
|
12
|
+
import {
|
|
13
|
+
eventPredecessorExists,
|
|
14
|
+
findExistingEventVersion,
|
|
15
|
+
insertRawEventBatch,
|
|
16
|
+
insertRawFirstEvent,
|
|
17
|
+
insertRawSubsequentEvent,
|
|
18
|
+
} from "../db/queries/event-store-admin";
|
|
13
19
|
import type { TenantId } from "../engine/types";
|
|
14
20
|
import { VersionConflictError } from "./errors";
|
|
15
21
|
import type { EventMetadata } from "./event-store";
|
|
16
|
-
import { eventsTable } from "./events-schema";
|
|
17
22
|
|
|
18
23
|
export type RawEventToAppend = {
|
|
19
24
|
readonly aggregateId: string;
|
|
@@ -55,30 +60,28 @@ export async function appendRaw(runner: DbRunner, event: RawEventToAppend): Prom
|
|
|
55
60
|
}
|
|
56
61
|
}
|
|
57
62
|
|
|
63
|
+
function rawEventParams(event: RawEventToAppend, newVersion: number, eventVersion: number) {
|
|
64
|
+
return {
|
|
65
|
+
aggregateId: event.aggregateId,
|
|
66
|
+
aggregateType: event.aggregateType,
|
|
67
|
+
tenantId: event.tenantId,
|
|
68
|
+
newVersion,
|
|
69
|
+
type: event.type,
|
|
70
|
+
eventVersion,
|
|
71
|
+
payloadJson: JSON.stringify(event.payload),
|
|
72
|
+
metadataJson: JSON.stringify(event.metadata),
|
|
73
|
+
createdAt: event.createdAt.toString(),
|
|
74
|
+
createdBy: event.createdBy,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
58
78
|
async function insertRawFirst(
|
|
59
79
|
runner: DbRunner,
|
|
60
80
|
event: RawEventToAppend,
|
|
61
81
|
newVersion: number,
|
|
62
82
|
eventVersion: number,
|
|
63
83
|
): Promise<void> {
|
|
64
|
-
await runner
|
|
65
|
-
INSERT INTO ${eventsTable} (
|
|
66
|
-
aggregate_id, aggregate_type, tenant_id, version,
|
|
67
|
-
type, event_version, payload, metadata, created_at, created_by
|
|
68
|
-
)
|
|
69
|
-
VALUES (
|
|
70
|
-
${event.aggregateId}::uuid,
|
|
71
|
-
${event.aggregateType},
|
|
72
|
-
${event.tenantId}::uuid,
|
|
73
|
-
${newVersion},
|
|
74
|
-
${event.type},
|
|
75
|
-
${eventVersion},
|
|
76
|
-
${JSON.stringify(event.payload)}::jsonb,
|
|
77
|
-
${JSON.stringify(event.metadata)}::jsonb,
|
|
78
|
-
${event.createdAt.toString()}::timestamptz,
|
|
79
|
-
${event.createdBy}
|
|
80
|
-
)
|
|
81
|
-
`);
|
|
84
|
+
await insertRawFirstEvent(runner, rawEventParams(event, newVersion, eventVersion));
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
async function insertRawSubsequent(
|
|
@@ -87,30 +90,11 @@ async function insertRawSubsequent(
|
|
|
87
90
|
newVersion: number,
|
|
88
91
|
eventVersion: number,
|
|
89
92
|
): Promise<void> {
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
SELECT ${event.aggregateId}::uuid,
|
|
96
|
-
${event.aggregateType},
|
|
97
|
-
${event.tenantId}::uuid,
|
|
98
|
-
${newVersion},
|
|
99
|
-
${event.type},
|
|
100
|
-
${eventVersion},
|
|
101
|
-
${JSON.stringify(event.payload)}::jsonb,
|
|
102
|
-
${JSON.stringify(event.metadata)}::jsonb,
|
|
103
|
-
${event.createdAt.toString()}::timestamptz,
|
|
104
|
-
${event.createdBy}
|
|
105
|
-
WHERE EXISTS (
|
|
106
|
-
SELECT 1 FROM ${eventsTable}
|
|
107
|
-
WHERE aggregate_id = ${event.aggregateId}::uuid
|
|
108
|
-
AND version = ${event.expectedVersion}
|
|
109
|
-
AND tenant_id = ${event.tenantId}::uuid
|
|
110
|
-
)
|
|
111
|
-
RETURNING id
|
|
112
|
-
`);
|
|
113
|
-
if (rows.length === 0) {
|
|
93
|
+
const inserted = await insertRawSubsequentEvent(runner, {
|
|
94
|
+
...rawEventParams(event, newVersion, eventVersion),
|
|
95
|
+
expectedVersion: event.expectedVersion,
|
|
96
|
+
});
|
|
97
|
+
if (!inserted) {
|
|
114
98
|
throw new VersionConflictError(event.aggregateId, event.expectedVersion);
|
|
115
99
|
}
|
|
116
100
|
}
|
|
@@ -133,31 +117,28 @@ export async function appendRawBatch(
|
|
|
133
117
|
await verifyPredecessors(runner, events);
|
|
134
118
|
await verifyNoDuplicates(runner, events);
|
|
135
119
|
|
|
136
|
-
const
|
|
120
|
+
const params: unknown[] = [];
|
|
121
|
+
const valuesClauses = events.map((e) => {
|
|
137
122
|
const newVersion = e.expectedVersion + 1;
|
|
138
123
|
const eventVersion = e.eventVersion ?? 1;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
124
|
+
const baseIdx = params.length;
|
|
125
|
+
params.push(
|
|
126
|
+
e.aggregateId,
|
|
127
|
+
e.aggregateType,
|
|
128
|
+
e.tenantId,
|
|
129
|
+
newVersion,
|
|
130
|
+
e.type,
|
|
131
|
+
eventVersion,
|
|
132
|
+
JSON.stringify(e.payload),
|
|
133
|
+
JSON.stringify(e.metadata),
|
|
134
|
+
e.createdAt.toString(),
|
|
135
|
+
e.createdBy,
|
|
136
|
+
);
|
|
137
|
+
return `($${baseIdx + 1}::uuid, $${baseIdx + 2}, $${baseIdx + 3}::uuid, $${baseIdx + 4}, $${baseIdx + 5}, $${baseIdx + 6}, $${baseIdx + 7}::jsonb, $${baseIdx + 8}::jsonb, $${baseIdx + 9}::timestamptz, $${baseIdx + 10})`;
|
|
151
138
|
});
|
|
152
139
|
|
|
153
140
|
try {
|
|
154
|
-
await runner.
|
|
155
|
-
INSERT INTO ${eventsTable} (
|
|
156
|
-
aggregate_id, aggregate_type, tenant_id, version,
|
|
157
|
-
type, event_version, payload, metadata, created_at, created_by
|
|
158
|
-
)
|
|
159
|
-
VALUES ${sql.join(rows, sql`, `)}
|
|
160
|
-
`);
|
|
141
|
+
await insertRawEventBatch(runner, valuesClauses.join(", "), params);
|
|
161
142
|
} catch (e) {
|
|
162
143
|
if (isUniqueViolation(e)) {
|
|
163
144
|
// Pre-flight ran but lost a race against a concurrent writer. Rare for
|
|
@@ -221,15 +202,8 @@ async function verifyPredecessors(
|
|
|
221
202
|
|
|
222
203
|
for (const g of groups.values()) {
|
|
223
204
|
if (g.minExpected === 0) continue;
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
SELECT 1 FROM ${eventsTable}
|
|
227
|
-
WHERE aggregate_id = ${g.aggregateId}::uuid
|
|
228
|
-
AND tenant_id = ${g.tenantId}::uuid
|
|
229
|
-
AND version = ${g.minExpected}
|
|
230
|
-
) AS present
|
|
231
|
-
`);
|
|
232
|
-
if (!rows[0]?.present) {
|
|
205
|
+
const present = await eventPredecessorExists(runner, g.aggregateId, g.tenantId, g.minExpected);
|
|
206
|
+
if (!present) {
|
|
233
207
|
throw new VersionConflictError(g.aggregateId, g.minExpected);
|
|
234
208
|
}
|
|
235
209
|
}
|
|
@@ -242,16 +216,14 @@ async function verifyNoDuplicates(
|
|
|
242
216
|
runner: DbRunner,
|
|
243
217
|
events: readonly RawEventToAppend[],
|
|
244
218
|
): Promise<void> {
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
`);
|
|
253
|
-
const conflict = rows[0];
|
|
219
|
+
const params: unknown[] = [];
|
|
220
|
+
const tripleClauses = events.map((e) => {
|
|
221
|
+
const baseIdx = params.length;
|
|
222
|
+
params.push(e.tenantId, e.aggregateId, e.expectedVersion + 1);
|
|
223
|
+
return `($${baseIdx + 1}::uuid, $${baseIdx + 2}::uuid, $${baseIdx + 3})`;
|
|
224
|
+
});
|
|
225
|
+
const conflict = await findExistingEventVersion(runner, tripleClauses.join(", "), params);
|
|
254
226
|
if (conflict) {
|
|
255
|
-
throw new VersionConflictError(conflict.
|
|
227
|
+
throw new VersionConflictError(conflict.aggregateId, conflict.version - 1);
|
|
256
228
|
}
|
|
257
229
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// sql now comes from native dialect
|
|
2
|
+
|
|
2
3
|
import type { DbConnection, DbRunner } from "../db/connection";
|
|
3
|
-
import { instant, table as pgTable, text, uniqueIndex, uuid } from "../db/dialect";
|
|
4
|
+
import { instant, table as pgTable, sql, text, uniqueIndex, uuid } from "../db/dialect";
|
|
5
|
+
import { upsertArchivedStream } from "../db/queries/event-store";
|
|
6
|
+
import { deleteMany, fetchOne } from "../db/query";
|
|
4
7
|
import { tableExists } from "../db/schema-inspection";
|
|
5
8
|
import type { TenantId } from "../engine/types";
|
|
6
9
|
import { unsafePushTables } from "../stack";
|
|
@@ -46,24 +49,13 @@ export type ArchiveStreamArgs = {
|
|
|
46
49
|
// aggregate) updates archivedAt/archivedBy to the latest call instead of
|
|
47
50
|
// failing. That matches Marten's "archive is a state, not an event" model.
|
|
48
51
|
export async function archiveStream(db: DbRunner, args: ArchiveStreamArgs): Promise<void> {
|
|
49
|
-
await db
|
|
50
|
-
.
|
|
51
|
-
.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
reason: args.reason ?? null,
|
|
57
|
-
})
|
|
58
|
-
.onConflictDoUpdate({
|
|
59
|
-
target: [archivedStreamsTable.tenantId, archivedStreamsTable.aggregateId],
|
|
60
|
-
set: {
|
|
61
|
-
archivedAt: sql`now()`,
|
|
62
|
-
archivedBy: args.archivedBy,
|
|
63
|
-
aggregateType: args.aggregateType,
|
|
64
|
-
reason: args.reason ?? null,
|
|
65
|
-
},
|
|
66
|
-
});
|
|
52
|
+
await upsertArchivedStream(db, {
|
|
53
|
+
tenantId: args.tenantId,
|
|
54
|
+
aggregateId: args.aggregateId,
|
|
55
|
+
aggregateType: args.aggregateType,
|
|
56
|
+
archivedBy: args.archivedBy,
|
|
57
|
+
reason: args.reason ?? null,
|
|
58
|
+
});
|
|
67
59
|
}
|
|
68
60
|
|
|
69
61
|
// Cheap existence probe — issued in the hot read path, so keep the query to
|
|
@@ -73,17 +65,8 @@ export async function isStreamArchived(
|
|
|
73
65
|
tenantId: TenantId,
|
|
74
66
|
aggregateId: string,
|
|
75
67
|
): Promise<boolean> {
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
.from(archivedStreamsTable)
|
|
79
|
-
.where(
|
|
80
|
-
and(
|
|
81
|
-
eq(archivedStreamsTable.tenantId, tenantId),
|
|
82
|
-
eq(archivedStreamsTable.aggregateId, aggregateId),
|
|
83
|
-
),
|
|
84
|
-
)
|
|
85
|
-
.limit(1);
|
|
86
|
-
return rows.length > 0;
|
|
68
|
+
const row = await fetchOne(db, archivedStreamsTable, { tenantId, aggregateId });
|
|
69
|
+
return row !== undefined;
|
|
87
70
|
}
|
|
88
71
|
|
|
89
72
|
// Undo an archive — restores the stream to writable state. Ops tool. The
|
|
@@ -95,12 +78,5 @@ export async function restoreStream(
|
|
|
95
78
|
tenantId: TenantId,
|
|
96
79
|
aggregateId: string,
|
|
97
80
|
): Promise<void> {
|
|
98
|
-
await db
|
|
99
|
-
.delete(archivedStreamsTable)
|
|
100
|
-
.where(
|
|
101
|
-
and(
|
|
102
|
-
eq(archivedStreamsTable.tenantId, tenantId),
|
|
103
|
-
eq(archivedStreamsTable.aggregateId, aggregateId),
|
|
104
|
-
),
|
|
105
|
-
);
|
|
81
|
+
await deleteMany(db, archivedStreamsTable, { tenantId, aggregateId });
|
|
106
82
|
}
|