@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.
Files changed (314) hide show
  1. package/package.json +7 -7
  2. package/src/__tests__/{anonymous-access.integration.ts → anonymous-access.integration.test.ts} +12 -9
  3. package/src/__tests__/{error-contract.integration.ts → error-contract.integration.test.ts} +5 -4
  4. package/src/__tests__/{field-access.integration.ts → field-access.integration.test.ts} +3 -3
  5. package/src/__tests__/{full-stack.integration.ts → full-stack.integration.test.ts} +7 -16
  6. package/src/__tests__/{ownership.integration.ts → ownership.integration.test.ts} +3 -2
  7. package/src/__tests__/{raw-table.integration.ts → raw-table.integration.test.ts} +18 -30
  8. package/src/__tests__/{reference-data.integration.ts → reference-data.integration.test.ts} +24 -11
  9. package/src/__tests__/{transition-guard.integration.ts → transition-guard.integration.test.ts} +12 -10
  10. package/src/api/__tests__/api.test.ts +1 -1
  11. package/src/api/__tests__/auth-middleware-transport.test.ts +1 -1
  12. package/src/api/__tests__/auth-routes-cookie.test.ts +1 -1
  13. package/src/api/__tests__/{batch.integration.ts → batch.integration.test.ts} +30 -30
  14. package/src/api/__tests__/body-limit.test.ts +1 -1
  15. package/src/api/__tests__/csrf-middleware.test.ts +1 -1
  16. package/src/api/__tests__/{dispatcher-live.integration.ts → dispatcher-live.integration.test.ts} +10 -9
  17. package/src/api/__tests__/metrics-endpoint.test.ts +1 -1
  18. package/src/api/__tests__/{nested-write.integration.ts → nested-write.integration.test.ts} +13 -16
  19. package/src/api/__tests__/readiness.test.ts +1 -1
  20. package/src/api/__tests__/request-id-middleware.test.ts +1 -1
  21. package/src/api/__tests__/sse-broker.test.ts +12 -12
  22. package/src/api/__tests__/sse-route.test.ts +1 -1
  23. package/src/api/readiness.ts +2 -2
  24. package/src/auth/__tests__/roles.test.ts +2 -2
  25. package/src/bun-db/__tests__/PATTERN.md +73 -0
  26. package/src/bun-db/__tests__/_helpers.ts +103 -0
  27. package/src/bun-db/__tests__/batch-methods.integration.test.ts +143 -0
  28. package/src/bun-db/__tests__/batch-methods.test.ts +20 -0
  29. package/src/bun-db/__tests__/bun-test-db.ts +19 -0
  30. package/src/bun-db/__tests__/bun-test-stack.ts +6 -0
  31. package/src/bun-db/__tests__/column-types.integration.test.ts +132 -0
  32. package/src/bun-db/__tests__/compound-types.integration.test.ts +134 -0
  33. package/src/bun-db/__tests__/jsonb-edge-cases.integration.test.ts +235 -0
  34. package/src/bun-db/__tests__/smoke.integration.test.ts +43 -0
  35. package/src/bun-db/__tests__/sql-methods.integration.test.ts +231 -0
  36. package/src/bun-db/__tests__/where-patterns.integration.test.ts +185 -0
  37. package/src/bun-db/connection.ts +84 -0
  38. package/src/bun-db/index.ts +31 -0
  39. package/src/bun-db/query.ts +845 -0
  40. package/src/compliance/__tests__/duration-spec.test.ts +1 -1
  41. package/src/compliance/__tests__/profiles.test.ts +1 -1
  42. package/src/compliance/__tests__/sub-processors.test.ts +1 -1
  43. package/src/db/__tests__/{apply-entity-event-tenant.integration.ts → apply-entity-event-tenant.integration.test.ts} +13 -11
  44. package/src/db/__tests__/big-int-field.test.ts +15 -14
  45. package/src/db/__tests__/column-ddl.integration.test.ts +113 -0
  46. package/src/db/__tests__/compound-types.test.ts +1 -1
  47. package/src/db/__tests__/{config-seed.integration.ts → config-seed.integration.test.ts} +32 -27
  48. package/src/db/__tests__/connection-options.test.ts +1 -1
  49. package/src/db/__tests__/dialect-instant.test.ts +1 -1
  50. package/src/db/__tests__/encryption.test.ts +1 -1
  51. package/src/db/__tests__/{drizzle-table-types.test.ts → entity-table-types.test.ts} +16 -16
  52. package/src/db/__tests__/{event-store-executor-list.integration.ts → event-store-executor-list.integration.test.ts} +12 -7
  53. package/src/db/__tests__/{event-store-executor.integration.ts → event-store-executor.integration.test.ts} +19 -12
  54. package/src/db/__tests__/{implicit-projection-equivalence.integration.ts → implicit-projection-equivalence.integration.test.ts} +35 -29
  55. package/src/db/__tests__/located-timestamp.test.ts +1 -1
  56. package/src/db/__tests__/money.test.ts +1 -1
  57. package/src/db/__tests__/{multi-row-insert.integration.ts → multi-row-insert.integration.test.ts} +18 -11
  58. package/src/db/__tests__/parse-auto-verb.test.ts +1 -1
  59. package/src/db/__tests__/{required-not-null-migration-safety.integration.ts → required-not-null-migration-safety.integration.test.ts} +28 -24
  60. package/src/db/__tests__/{schema-migration.integration.ts → schema-migration.integration.test.ts} +32 -28
  61. package/src/db/__tests__/sql-inventory.test.ts +56 -0
  62. package/src/db/__tests__/table-builder-indexes.test.ts +30 -11
  63. package/src/db/__tests__/table-builder-required.test.ts +20 -22
  64. package/src/db/__tests__/{tenant-db.integration.ts → tenant-db.integration.test.ts} +106 -144
  65. package/src/db/__tests__/{unique-violation-mapping.integration.ts → unique-violation-mapping.integration.test.ts} +13 -8
  66. package/src/db/api.ts +46 -0
  67. package/src/db/apply-entity-event.ts +45 -36
  68. package/src/db/assert-exists-in.ts +5 -16
  69. package/src/db/bun-provider.ts +37 -0
  70. package/src/db/config-seed.ts +4 -4
  71. package/src/db/connection.ts +14 -57
  72. package/src/db/cursor.ts +5 -56
  73. package/src/db/dialect.ts +472 -99
  74. package/src/db/eagerload.ts +5 -12
  75. package/src/db/entity-table-meta.ts +390 -0
  76. package/src/db/event-store-executor.ts +158 -100
  77. package/src/db/index.ts +33 -5
  78. package/src/db/migrate-generator.ts +350 -0
  79. package/src/db/migrate-runner.ts +206 -0
  80. package/src/db/postgres-provider.ts +25 -0
  81. package/src/db/queries/entity-read.ts +15 -0
  82. package/src/db/queries/es-ops.ts +17 -0
  83. package/src/db/queries/event-consumer.ts +170 -0
  84. package/src/db/queries/event-store-admin.ts +127 -0
  85. package/src/db/queries/event-store.ts +155 -0
  86. package/src/db/queries/projection-rebuild.ts +59 -0
  87. package/src/db/queries/raw-sql.ts +15 -0
  88. package/src/db/queries/schema-drift.ts +35 -0
  89. package/src/db/queries/seed-context.ts +58 -0
  90. package/src/db/queries/table-ops.ts +11 -0
  91. package/src/db/queries/test-stack.ts +56 -0
  92. package/src/db/query-api.ts +22 -0
  93. package/src/db/query.ts +30 -0
  94. package/src/db/reference-data.ts +19 -22
  95. package/src/db/render-ddl.ts +57 -0
  96. package/src/db/row-helpers.ts +3 -52
  97. package/src/db/schema-inspection.ts +17 -4
  98. package/src/db/sql-inventory.ts +208 -0
  99. package/src/db/table-builder.ts +48 -40
  100. package/src/db/tenant-db.ts +105 -326
  101. package/src/engine/__tests__/auth-claims-registrar.test.ts +1 -1
  102. package/src/engine/__tests__/boot-validator-api-exposure.test.ts +3 -3
  103. package/src/engine/__tests__/boot-validator-located-timestamps.test.ts +1 -1
  104. package/src/engine/__tests__/boot-validator-pii-retention.test.ts +5 -5
  105. package/src/engine/__tests__/boot-validator-s0-integration.test.ts +3 -3
  106. package/src/engine/__tests__/boot-validator.test.ts +4 -3
  107. package/src/engine/__tests__/build-app-schema.test.ts +1 -1
  108. package/src/engine/__tests__/build-target.test.ts +1 -1
  109. package/src/engine/__tests__/claim-keys.test.ts +1 -1
  110. package/src/engine/__tests__/codemod-pipeline.test.ts +3 -3
  111. package/src/engine/__tests__/config-helpers.test.ts +1 -1
  112. package/src/engine/__tests__/effective-features.test.ts +1 -1
  113. package/src/engine/__tests__/engine.test.ts +1 -1
  114. package/src/engine/__tests__/entity-handlers.test.ts +3 -3
  115. package/src/engine/__tests__/event-helpers.test.ts +3 -3
  116. package/src/engine/__tests__/extends-registrar.test.ts +4 -4
  117. package/src/engine/__tests__/factories-long-text.test.ts +1 -1
  118. package/src/engine/__tests__/factories-time.test.ts +1 -1
  119. package/src/engine/__tests__/field-predicates.test.ts +1 -1
  120. package/src/engine/__tests__/hook-phases.test.ts +1 -1
  121. package/src/engine/__tests__/identifiers.test.ts +1 -1
  122. package/src/engine/__tests__/lifecycle-hooks.test.ts +1 -1
  123. package/src/engine/__tests__/nav.test.ts +1 -1
  124. package/src/engine/__tests__/ownership.test.ts +10 -11
  125. package/src/engine/__tests__/parse-ref-target.test.ts +1 -1
  126. package/src/engine/__tests__/pipeline-engine.test.ts +1 -1
  127. package/src/engine/__tests__/{pipeline-handler.integration.ts → pipeline-handler.integration.test.ts} +38 -52
  128. package/src/engine/__tests__/{pipeline-observability.integration.ts → pipeline-observability.integration.test.ts} +1 -1
  129. package/src/engine/__tests__/{pipeline-performance.integration.ts → pipeline-performance.integration.test.ts} +1 -1
  130. package/src/engine/__tests__/pipeline-sub-pipelines.test.ts +1 -1
  131. package/src/engine/__tests__/post-query-hook.test.ts +1 -1
  132. package/src/engine/__tests__/projection-helpers.test.ts +25 -17
  133. package/src/engine/__tests__/projection.test.ts +4 -4
  134. package/src/engine/__tests__/qualified-name.test.ts +1 -1
  135. package/src/engine/__tests__/raw-table.test.ts +9 -8
  136. package/src/engine/__tests__/resolve-config-or-param.test.ts +5 -5
  137. package/src/engine/__tests__/run-in.test.ts +1 -1
  138. package/src/engine/__tests__/schema-builder.test.ts +1 -1
  139. package/src/engine/__tests__/screen.test.ts +1 -1
  140. package/src/engine/__tests__/search-payload-extension.test.ts +3 -3
  141. package/src/engine/__tests__/state-machine.test.ts +1 -1
  142. package/src/engine/__tests__/steps-aggregate-append-event.test.ts +7 -7
  143. package/src/engine/__tests__/steps-aggregate-create.test.ts +4 -4
  144. package/src/engine/__tests__/steps-aggregate-update.test.ts +3 -3
  145. package/src/engine/__tests__/steps-call-feature.test.ts +5 -5
  146. package/src/engine/__tests__/steps-mail-send.test.ts +7 -7
  147. package/src/engine/__tests__/steps-read.test.ts +34 -40
  148. package/src/engine/__tests__/steps-resolver-utils.test.ts +6 -6
  149. package/src/engine/__tests__/steps-unsafe-projection-delete.test.ts +24 -19
  150. package/src/engine/__tests__/steps-unsafe-projection-upsert.test.ts +28 -17
  151. package/src/engine/__tests__/steps-webhook-send.test.ts +6 -6
  152. package/src/engine/__tests__/steps-workflow.test.ts +7 -7
  153. package/src/engine/__tests__/system-user.test.ts +1 -1
  154. package/src/engine/__tests__/validate-projection-allowlist.test.ts +4 -5
  155. package/src/engine/__tests__/validation-hooks.test.ts +1 -1
  156. package/src/engine/__tests__/visual-tree-patterns.test.ts +1 -1
  157. package/src/engine/boot-validator/entity-handler.ts +3 -3
  158. package/src/engine/boot-validator/ownership.ts +1 -1
  159. package/src/engine/define-feature.ts +1 -2
  160. package/src/engine/entity-handlers.ts +5 -5
  161. package/src/engine/factories.ts +1 -1
  162. package/src/engine/feature-ast/__tests__/canonical-form.test.ts +1 -1
  163. package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +1 -1
  164. package/src/engine/feature-ast/__tests__/parse-real-features.test.ts +2 -2
  165. package/src/engine/feature-ast/__tests__/parse.test.ts +1 -1
  166. package/src/engine/feature-ast/__tests__/patch.test.ts +1 -1
  167. package/src/engine/feature-ast/__tests__/patcher.test.ts +1 -1
  168. package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +1 -1
  169. package/src/engine/feature-ast/__tests__/visual-tree-parse.test.ts +1 -1
  170. package/src/engine/ownership.ts +113 -41
  171. package/src/engine/pattern-library/__tests__/library.test.ts +2 -2
  172. package/src/engine/projection-helpers.ts +2 -11
  173. package/src/engine/registry.ts +2 -2
  174. package/src/engine/steps/read-find-many.ts +13 -13
  175. package/src/engine/steps/read-find-one.ts +7 -9
  176. package/src/engine/steps/unsafe-projection-delete.ts +4 -5
  177. package/src/engine/steps/unsafe-projection-upsert.ts +63 -31
  178. package/src/engine/types/feature.ts +7 -2
  179. package/src/engine/types/fields.ts +4 -5
  180. package/src/engine/types/step.ts +10 -10
  181. package/src/engine/validate-projection-allowlist.ts +23 -3
  182. package/src/entrypoint/__tests__/{entrypoint-job-wiring.integration.ts → entrypoint-job-wiring.integration.test.ts} +4 -3
  183. package/src/entrypoint/__tests__/{split-deploy.integration.ts → split-deploy.integration.test.ts} +4 -3
  184. package/src/env/__tests__/compose-env-schema.test.ts +1 -1
  185. package/src/env/__tests__/dry-run.test.ts +1 -1
  186. package/src/errors/__tests__/classes.test.ts +1 -1
  187. package/src/errors/__tests__/write-failures.test.ts +1 -1
  188. package/src/es-ops/__tests__/{context.integration.ts → context.integration.test.ts} +43 -29
  189. package/src/es-ops/__tests__/{runner.integration.ts → runner.integration.test.ts} +25 -23
  190. package/src/es-ops/__tests__/runner.test.ts +29 -19
  191. package/src/es-ops/context.ts +9 -43
  192. package/src/es-ops/operations-schema.ts +2 -2
  193. package/src/es-ops/runner.ts +12 -26
  194. package/src/event-store/__tests__/{admin-api.integration.ts → admin-api.integration.test.ts} +71 -45
  195. package/src/event-store/__tests__/{event-store.integration.ts → event-store.integration.test.ts} +7 -5
  196. package/src/event-store/__tests__/{get-stream-version-perf.integration.ts → get-stream-version-perf.integration.test.ts} +5 -3
  197. package/src/event-store/__tests__/{perf.integration.ts → perf.integration.test.ts} +24 -16
  198. package/src/event-store/__tests__/{snapshot.integration.ts → snapshot.integration.test.ts} +34 -28
  199. package/src/event-store/__tests__/{upcaster-dead-letter.integration.ts → upcaster-dead-letter.integration.test.ts} +11 -12
  200. package/src/event-store/__tests__/{upcaster.integration.ts → upcaster.integration.test.ts} +19 -32
  201. package/src/event-store/admin-api.ts +55 -83
  202. package/src/event-store/archive.ts +15 -39
  203. package/src/event-store/event-store.ts +92 -86
  204. package/src/event-store/events-schema.ts +2 -1
  205. package/src/event-store/index.ts +1 -0
  206. package/src/event-store/snapshot.ts +26 -24
  207. package/src/event-store/upcaster-dead-letter.ts +19 -18
  208. package/src/files/__tests__/content-disposition.test.ts +1 -1
  209. package/src/files/__tests__/{file-field-pipeline.integration.ts → file-field-pipeline.integration.test.ts} +8 -5
  210. package/src/files/__tests__/file-handle.test.ts +1 -1
  211. package/src/files/__tests__/{files.integration.ts → files.integration.test.ts} +32 -17
  212. package/src/files/__tests__/read-stream.test.ts +1 -1
  213. package/src/files/__tests__/{storage-tracking.integration.ts → storage-tracking.integration.test.ts} +26 -30
  214. package/src/files/__tests__/write-stream.test.ts +1 -1
  215. package/src/files/__tests__/zip-stream.test.ts +1 -1
  216. package/src/files/file-ref-table.ts +2 -2
  217. package/src/files/file-routes.ts +7 -9
  218. package/src/files/storage-tracking.ts +9 -17
  219. package/src/i18n/__tests__/i18n.test.ts +1 -1
  220. package/src/jobs/__tests__/{job-event-trigger.integration.ts → job-event-trigger.integration.test.ts} +6 -3
  221. package/src/jobs/__tests__/{job-multi-trigger.integration.ts → job-multi-trigger.integration.test.ts} +6 -3
  222. package/src/jobs/__tests__/{jobs.integration.ts → jobs.integration.test.ts} +5 -7
  223. package/src/lifecycle/__tests__/{lifecycle-server.integration.ts → lifecycle-server.integration.test.ts} +1 -1
  224. package/src/lifecycle/__tests__/lifecycle.test.ts +6 -6
  225. package/src/lifecycle/__tests__/signal-handlers.test.ts +6 -6
  226. package/src/logging/__tests__/pino-trace-bridge.test.ts +1 -1
  227. package/src/migrations/__tests__/compare-snapshots.test.ts +1 -1
  228. package/src/migrations/__tests__/{detect-drift.integration.ts → detect-drift.integration.test.ts} +34 -26
  229. package/src/migrations/__tests__/{detect-projections-to-rebuild.integration.ts → detect-projections-to-rebuild.integration.test.ts} +1 -1
  230. package/src/migrations/__tests__/rebuild-marker.test.ts +1 -1
  231. package/src/migrations/projection-detection.ts +12 -1
  232. package/src/migrations/schema-drift.ts +7 -23
  233. package/src/observability/__tests__/console-provider.test.ts +1 -1
  234. package/src/observability/__tests__/metric-validator.test.ts +1 -1
  235. package/src/observability/__tests__/noop-provider.test.ts +1 -1
  236. package/src/observability/__tests__/{observability.integration.ts → observability.integration.test.ts} +5 -8
  237. package/src/observability/__tests__/prometheus-meter.test.ts +1 -1
  238. package/src/observability/__tests__/recording-meter.test.ts +1 -1
  239. package/src/observability/__tests__/recording-tracer.test.ts +1 -1
  240. package/src/observability/__tests__/sensitive-filter.test.ts +1 -1
  241. package/src/pipeline/__tests__/{archive-stream.integration.ts → archive-stream.integration.test.ts} +3 -3
  242. package/src/pipeline/__tests__/auth-claims-resolver.test.ts +9 -9
  243. package/src/pipeline/__tests__/{cascade-handler.integration.ts → cascade-handler.integration.test.ts} +18 -15
  244. package/src/pipeline/__tests__/cascade-handler.test.ts +1 -1
  245. package/src/pipeline/__tests__/{causation-chain.integration.ts → causation-chain.integration.test.ts} +12 -13
  246. package/src/pipeline/__tests__/{ctx-bridge.integration.ts → ctx-bridge.integration.test.ts} +12 -11
  247. package/src/pipeline/__tests__/dispatcher.test.ts +2 -2
  248. package/src/pipeline/__tests__/{distributed-lock.integration.ts → distributed-lock.integration.test.ts} +1 -1
  249. package/src/pipeline/__tests__/{domain-events-projections.integration.ts → domain-events-projections.integration.test.ts} +13 -15
  250. package/src/pipeline/__tests__/{event-dedup.integration.ts → event-dedup.integration.test.ts} +1 -1
  251. package/src/pipeline/__tests__/{event-define-event-strict.integration.ts → event-define-event-strict.integration.test.ts} +6 -16
  252. package/src/pipeline/__tests__/{event-dispatcher-lifecycle.integration.ts → event-dispatcher-lifecycle.integration.test.ts} +1 -1
  253. package/src/pipeline/__tests__/{event-dispatcher-multi-instance.integration.ts → event-dispatcher-multi-instance.integration.test.ts} +3 -2
  254. package/src/pipeline/__tests__/{event-dispatcher-pg-listen.integration.ts → event-dispatcher-pg-listen.integration.test.ts} +1 -1
  255. package/src/pipeline/__tests__/{event-dispatcher-recovery.integration.ts → event-dispatcher-recovery.integration.test.ts} +2 -2
  256. package/src/pipeline/__tests__/{event-dispatcher-second-audit.integration.ts → event-dispatcher-second-audit.integration.test.ts} +17 -16
  257. package/src/pipeline/__tests__/event-dispatcher-strict.test.ts +14 -12
  258. package/src/pipeline/__tests__/{event-dispatcher.integration.ts → event-dispatcher.integration.test.ts} +8 -15
  259. package/src/pipeline/__tests__/{event-retention.integration.ts → event-retention.integration.test.ts} +28 -25
  260. package/src/pipeline/__tests__/{fetch-for-writing.integration.ts → fetch-for-writing.integration.test.ts} +6 -6
  261. package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +4 -4
  262. package/src/pipeline/__tests__/{load-aggregate-query.integration.ts → load-aggregate-query.integration.test.ts} +9 -5
  263. package/src/pipeline/__tests__/{msp-error-mode.integration.ts → msp-error-mode.integration.test.ts} +1 -1
  264. package/src/pipeline/__tests__/{msp-multi-hop.integration.ts → msp-multi-hop.integration.test.ts} +9 -8
  265. package/src/pipeline/__tests__/{msp-rebuild.integration.ts → msp-rebuild.integration.test.ts} +47 -55
  266. package/src/pipeline/__tests__/{multi-stream-projection.integration.ts → multi-stream-projection.integration.test.ts} +19 -53
  267. package/src/pipeline/__tests__/{perf-rebuild.integration.ts → perf-rebuild.integration.test.ts} +36 -34
  268. package/src/pipeline/__tests__/{post-query-hook.integration.ts → post-query-hook.integration.test.ts} +1 -1
  269. package/src/pipeline/__tests__/{projection-rebuild.integration.ts → projection-rebuild.integration.test.ts} +21 -30
  270. package/src/pipeline/__tests__/{query-projection.integration.ts → query-projection.integration.test.ts} +6 -5
  271. package/src/pipeline/__tests__/{redis-pipeline.integration.ts → redis-pipeline.integration.test.ts} +3 -1
  272. package/src/pipeline/cascade-handler.ts +13 -21
  273. package/src/pipeline/dispatcher.ts +43 -48
  274. package/src/pipeline/event-consumer-state.ts +11 -2
  275. package/src/pipeline/event-dispatcher.ts +86 -146
  276. package/src/pipeline/event-retention.ts +14 -24
  277. package/src/pipeline/msp-rebuild.ts +54 -78
  278. package/src/pipeline/projection-rebuild.ts +65 -67
  279. package/src/pipeline/projection-state.ts +2 -2
  280. package/src/random/__tests__/generate.test.ts +13 -13
  281. package/src/rate-limit/__tests__/{dispatcher-l3.integration.ts → dispatcher-l3.integration.test.ts} +1 -1
  282. package/src/rate-limit/__tests__/{middleware.integration.ts → middleware.integration.test.ts} +1 -1
  283. package/src/rate-limit/__tests__/{resolver.integration.ts → resolver.integration.test.ts} +1 -1
  284. package/src/redis/__tests__/redis-options.test.ts +1 -1
  285. package/src/search/__tests__/{meilisearch-adapter.integration.ts → meilisearch-adapter.integration.test.ts} +1 -1
  286. package/src/search/__tests__/search-adapter.test.ts +1 -1
  287. package/src/secrets/__tests__/dek-cache.test.ts +1 -3
  288. package/src/secrets/__tests__/env-master-key-provider.test.ts +1 -1
  289. package/src/secrets/__tests__/envelope.test.ts +1 -1
  290. package/src/secrets/__tests__/leak-guard.test.ts +1 -1
  291. package/src/secrets/__tests__/rotation.test.ts +1 -1
  292. package/src/stack/db.ts +25 -48
  293. package/src/stack/push-entity-projection-tables.ts +2 -4
  294. package/src/stack/table-helpers.ts +98 -61
  295. package/src/stack/test-stack.ts +8 -7
  296. package/src/testing/__tests__/db-cleanup.test.ts +40 -0
  297. package/src/testing/__tests__/e2e-generator.test.ts +1 -1
  298. package/src/testing/__tests__/{ensure-entity-table.integration.ts → ensure-entity-table.integration.test.ts} +7 -14
  299. package/src/testing/db-cleanup.ts +44 -0
  300. package/src/testing/expect-error.ts +1 -1
  301. package/src/testing/index.ts +2 -0
  302. package/src/testing/multipart-helper.ts +94 -0
  303. package/src/testing/shared-entities.ts +5 -5
  304. package/src/time/__tests__/polyfill.test.ts +1 -1
  305. package/src/time/__tests__/tz-context.test.ts +1 -1
  306. package/src/utils/__tests__/assert.test.ts +1 -1
  307. package/src/utils/__tests__/env-parse.test.ts +1 -1
  308. package/CHANGELOG.md +0 -472
  309. package/src/db/__tests__/cursor.test.ts +0 -41
  310. package/src/db/__tests__/db-helpers.test.ts +0 -369
  311. package/src/db/__tests__/drizzle-helpers.integration.ts +0 -186
  312. package/src/db/__tests__/row-helpers.test.ts +0 -59
  313. package/src/engine/steps/_drizzle-boundary.ts +0 -19
  314. package/src/files/__tests__/file-field-column.integration.ts +0 -103
@@ -8,10 +8,10 @@
8
8
  // Sprint-G-Pieces nebeneinander leben aber sich nicht treffen — Marker
9
9
  // wäre leer, kein Rebuild würde ausgelöst.
10
10
 
11
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
11
12
  import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
12
13
  import { tmpdir } from "node:os";
13
14
  import { join } from "node:path";
14
- import { afterEach, beforeEach, describe, expect, test } from "vitest";
15
15
  import { createBooleanField, createEntity, createTextField, defineFeature } from "../../engine";
16
16
  import { createRegistry } from "../../engine/registry";
17
17
  import { detectProjectionsToRebuild } from "../projection-detection";
@@ -4,10 +4,10 @@
4
4
  // - schemaVersion-Mismatch wirft (verhindert dass alte Markers gegen
5
5
  // neue Lese-Logik fahren)
6
6
 
7
+ import { afterEach, beforeEach, describe, expect, test } from "bun:test";
7
8
  import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
8
9
  import { tmpdir } from "node:os";
9
10
  import { join } from "node:path";
10
- import { afterEach, beforeEach, describe, expect, test } from "vitest";
11
11
  import { readRebuildMarker, writeRebuildMarker } from "../rebuild-marker";
12
12
 
13
13
  let tmpDir: string;
@@ -11,7 +11,6 @@
11
11
  // Damit muss niemand Tabellen-Namen doppelt pflegen (Truth liegt in der
12
12
  // Projection-Definition).
13
13
 
14
- import { getTableName } from "drizzle-orm";
15
14
  import type { Registry } from "../engine/types/feature";
16
15
  import {
17
16
  type ColumnSpec,
@@ -90,6 +89,18 @@ function sameColumns(
90
89
  return true;
91
90
  }
92
91
 
92
+ const KUMIKO_NAME_SYMBOL = Symbol.for("kumiko:schema:Name");
93
+ function getTableName(table: unknown): string {
94
+ if (typeof table !== "object" || table === null) {
95
+ throw new Error("projection-detection: table is not a pgTable object");
96
+ }
97
+ const name = (table as Record<symbol, unknown>)[KUMIKO_NAME_SYMBOL];
98
+ if (typeof name !== "string") {
99
+ throw new Error("projection-detection: table missing drizzle name symbol");
100
+ }
101
+ return name;
102
+ }
103
+
93
104
  /** Index `tableName → projection-name` aus der Registry. Nur Projections
94
105
  * mit table-Definition (single-stream + multi-stream-with-table) zählen.
95
106
  * Side-effect-only MSPs (table omitted) haben keinen Rebuild-Sinn. */
@@ -9,7 +9,7 @@
9
9
  // 3. Column-Diff: information_schema-Vergleich gegen Snapshot —
10
10
  // missing-/extra-column, type-mismatch, nullability-mismatch. Fängt
11
11
  // manuelle ALTER TABLEs in Prod sowie doppelte pgTable-Definitionen
12
- // pro Tabelle (eine hand-written, eine via buildDrizzleTable), die
12
+ // pro Tabelle (eine hand-written, eine via buildEntityTable), die
13
13
  // stillschweigend gegen den Snapshot driften.
14
14
  //
15
15
  // Drizzle-kit's eigene Garantie: nach `migrate apply` ist der DB-Stand
@@ -19,8 +19,8 @@
19
19
 
20
20
  import { readFileSync } from "node:fs";
21
21
  import { resolve } from "node:path";
22
- import { sql } from "drizzle-orm";
23
22
  import type { DbConnection } from "../db/connection";
23
+ import { selectAppliedMigrations, selectPublicTableColumns } from "../db/queries/schema-drift";
24
24
  import { tableExists } from "../db/schema-inspection";
25
25
  import { parseJsonOrThrow } from "../utils/safe-json";
26
26
 
@@ -125,16 +125,10 @@ export async function loadAppliedMigrations(db: DbConnection): Promise<AppliedMi
125
125
  ? false
126
126
  : await tableExists(db, "public.__drizzle_migrations");
127
127
  if (!drizzleSchemaExists && !publicSchemaExists) return [];
128
- // sql.identifier mit qualifiziertem Namen: erstes Argument = Schema,
129
- // zweites = Tabellenname. Drizzle quotet beides defensiv.
130
- const tableRef = drizzleSchemaExists
131
- ? sql`drizzle.__drizzle_migrations`
132
- : sql`public.__drizzle_migrations`;
133
- const rows = await db.execute<{ hash: string; created_at: bigint | number | null }>(sql`
134
- SELECT hash, created_at
135
- FROM ${tableRef}
136
- ORDER BY id
137
- `);
128
+ const rows = await selectAppliedMigrations(
129
+ db,
130
+ drizzleSchemaExists ? "drizzle.__drizzle_migrations" : "public.__drizzle_migrations",
131
+ );
138
132
  return rows.map((r) => ({
139
133
  hash: r.hash,
140
134
  createdAt: typeof r.created_at === "bigint" ? Number(r.created_at) : (r.created_at ?? 0),
@@ -143,12 +137,6 @@ export async function loadAppliedMigrations(db: DbConnection): Promise<AppliedMi
143
137
 
144
138
  // --- Column-Diff (Welle 2 Boot-Gate Layer 3) ---
145
139
 
146
- type DbColumnRow = {
147
- readonly column_name: string;
148
- readonly data_type: string;
149
- readonly is_nullable: "YES" | "NO";
150
- };
151
-
152
140
  /** Liest information_schema.columns für eine Tabelle im public-Schema.
153
141
  * Map by column_name. Default-Werte werden bewusst ausgelassen — die
154
142
  * drift'en über drizzle-Versionen / PG-Reformulierungen hinweg ohne dass
@@ -158,11 +146,7 @@ async function loadDbColumns(
158
146
  db: DbConnection,
159
147
  tableName: string,
160
148
  ): Promise<ReadonlyMap<string, { type: string; notNull: boolean }>> {
161
- const rows = await db.execute<DbColumnRow>(sql`
162
- SELECT column_name, data_type, is_nullable
163
- FROM information_schema.columns
164
- WHERE table_schema = 'public' AND table_name = ${tableName}
165
- `);
149
+ const rows = await selectPublicTableColumns(db, tableName);
166
150
  const map = new Map<string, { type: string; notNull: boolean }>();
167
151
  for (const r of rows) {
168
152
  map.set(r.column_name, {
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { describe, expect, it } from "bun:test";
2
2
  import { createConsoleProvider } from "../console-provider";
3
3
 
4
4
  function makeProvider() {
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { describe, expect, it } from "bun:test";
2
2
  import { buildMetricName, validateLabelKey, validateMetricName } from "../metric-validator";
3
3
 
4
4
  describe("validateMetricName", () => {
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { describe, expect, it } from "bun:test";
2
2
  import { createNoopProvider } from "../noop-provider";
3
3
 
4
4
  describe("NoopProvider", () => {
@@ -1,6 +1,6 @@
1
- import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
1
+ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from "bun:test";
2
2
  import { z } from "zod";
3
- import { buildDrizzleTable } from "../../db/table-builder";
3
+ import { buildEntityTable } from "../../db/table-builder";
4
4
  import { createRegistry, defineFeature } from "../../engine";
5
5
  import type { AppContext, SaveContext } from "../../engine/types";
6
6
  import { createJobRunner } from "../../jobs";
@@ -65,18 +65,15 @@ const todoEntity = {
65
65
 
66
66
  let postSaveInvocations = 0;
67
67
  const todoFeature = defineFeature("todo", (r) => {
68
- const todoTable = buildDrizzleTable("todo", todoEntity);
68
+ const todoTable = buildEntityTable("todo", todoEntity);
69
69
  r.entity("todo", todoEntity);
70
70
 
71
71
  r.writeHandler(
72
72
  "create",
73
73
  z.object({ title: z.string() }),
74
74
  async (event, ctx) => {
75
- const rows = await ctx.db
76
- .insert(todoTable)
77
- .values({ title: event.payload.title })
78
- .returning();
79
- const row = rows[0] as { id: number; title: string };
75
+ const rows = await ctx.db.insertOne(todoTable, { title: event.payload.title });
76
+ const row = rows as { id: number; title: string };
80
77
  return {
81
78
  isSuccess: true,
82
79
  data: {
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "vitest";
1
+ import { describe, expect, test } from "bun:test";
2
2
  import { createPrometheusMeter, serializeOpenMetrics } from "../prometheus-meter";
3
3
 
4
4
  describe("PrometheusMeter — accumulation", () => {
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { describe, expect, it } from "bun:test";
2
2
  import { type MetricEvent, RecordingMeter } from "../recording-meter";
3
3
 
4
4
  function makeMeter() {
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { describe, expect, it } from "bun:test";
2
2
  import { type RecordedSpan, RecordingTracer } from "../recording-tracer";
3
3
  import { DEFAULT_SENSITIVE_CONFIG } from "../sensitive-filter";
4
4
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { describe, expect, it } from "bun:test";
2
2
  import {
3
3
  DEFAULT_SENSITIVE_CONFIG,
4
4
  mergeSensitiveConfig,
@@ -5,10 +5,10 @@
5
5
  // Kumiko carries this as a sparse kumiko_archived_streams table so active
6
6
  // streams never pay for extra metadata writes.
7
7
 
8
- import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
8
+ import { afterAll, afterEach, beforeAll, describe, expect, test } from "bun:test";
9
9
  import { z } from "zod";
10
10
  import { createEventStoreExecutor } from "../../db/event-store-executor";
11
- import { buildDrizzleTable } from "../../db/table-builder";
11
+ import { buildEntityTable } from "../../db/table-builder";
12
12
  import { createEntity, createTextField, defineFeature } from "../../engine";
13
13
  import {
14
14
  ArchivedStreamError,
@@ -27,7 +27,7 @@ const itemEntity = createEntity({
27
27
  table: "read_arch_items",
28
28
  fields: { label: createTextField({ required: true }) },
29
29
  });
30
- const itemTable = buildDrizzleTable("arch-item", itemEntity);
30
+ const itemTable = buildEntityTable("arch-item", itemEntity);
31
31
 
32
32
  const archFeature = defineFeature("archtest", (r) => {
33
33
  r.entity("arch-item", itemEntity);
@@ -1,18 +1,18 @@
1
- import { describe, expect, test, vi } from "vitest";
1
+ import { describe, expect, mock, test } from "bun:test";
2
2
  import type { AuthClaimsContext, AuthClaimsHookDef, SessionUser } from "../../engine/types";
3
3
  import type { Logger } from "../../logging/types";
4
4
  import { resolveAuthClaims } from "../auth-claims-resolver";
5
5
 
6
6
  type TestLogger = {
7
7
  readonly log: Logger;
8
- readonly warn: ReturnType<typeof vi.fn>;
8
+ readonly warn: ReturnType<typeof mock>;
9
9
  };
10
10
 
11
11
  function makeTestLogger(): TestLogger {
12
- const warn = vi.fn();
13
- const info = vi.fn();
14
- const error = vi.fn();
15
- const debug = vi.fn();
12
+ const warn = mock();
13
+ const info = mock();
14
+ const error = mock();
15
+ const debug = mock();
16
16
  const logger: Logger = {
17
17
  warn,
18
18
  info,
@@ -45,7 +45,7 @@ function hooks(...entries: AuthClaimsHookDef[]): readonly AuthClaimsHookDef[] {
45
45
 
46
46
  describe("resolveAuthClaims — empty", () => {
47
47
  test("zero hooks registered → empty record, contextFactory not called", async () => {
48
- const factory = vi.fn();
48
+ const factory = mock();
49
49
  const result = await resolveAuthClaims({
50
50
  user: testUser,
51
51
  hooks: [],
@@ -73,8 +73,8 @@ describe("resolveAuthClaims — single hook", () => {
73
73
  });
74
74
 
75
75
  test("receives the user and context handed in", async () => {
76
- const fn = vi.fn(async () => ({}));
77
- const factory = vi.fn(() => stubContext);
76
+ const fn = mock(async () => ({}));
77
+ const factory = mock(() => stubContext);
78
78
  await resolveAuthClaims({
79
79
  user: testUser,
80
80
  hooks: hooks({ featureName: "any", fn }),
@@ -1,7 +1,8 @@
1
- import { afterAll, beforeAll, describe, expect, test } from "vitest";
1
+ import { afterAll, beforeAll, describe, expect, test } from "bun:test";
2
+ import { type BunTestDb, createTestDb } from "../../bun-db/__tests__/bun-test-db";
2
3
  import type { TableColumns } from "../../db/dialect";
3
4
  import { createEventStoreExecutor, type EventStoreExecutor } from "../../db/event-store-executor";
4
- import { buildDrizzleTable } from "../../db/table-builder";
5
+ import { buildEntityTable } from "../../db/table-builder";
5
6
  import { createTenantDb, type TenantDb } from "../../db/tenant-db";
6
7
  import {
7
8
  createEntity,
@@ -11,13 +12,14 @@ import {
11
12
  type Registry,
12
13
  } from "../../engine";
13
14
  import { createEventsTable } from "../../event-store";
14
- import { createTestDb, type TestDb, TestUsers, unsafeCreateEntityTable } from "../../stack";
15
+ import { TestUsers, unsafeCreateEntityTable } from "../../stack";
16
+ import { ensureTemporalPolyfill } from "../../time/polyfill";
15
17
  import { createCascadeDeleteHook } from "../cascade-handler";
16
18
 
17
19
  // biome-ignore lint/suspicious/noExplicitAny: Drizzle dynamic tables
18
20
  type Table = TableColumns<any>;
19
21
 
20
- let testDb: TestDb;
22
+ let testDb: BunTestDb;
21
23
  let tdb: TenantDb;
22
24
  let registry: Registry;
23
25
  let departmentTable: Table;
@@ -77,6 +79,7 @@ const memberEntity = createEntity({
77
79
  });
78
80
 
79
81
  beforeAll(async () => {
82
+ await ensureTemporalPolyfill();
80
83
  testDb = await createTestDb();
81
84
  await createEventsTable(testDb.db);
82
85
  tdb = createTenantDb(testDb.db, admin.tenantId);
@@ -90,14 +93,14 @@ beforeAll(async () => {
90
93
  await unsafeCreateEntityTable(testDb.db, teamEntity);
91
94
  await unsafeCreateEntityTable(testDb.db, memberEntity);
92
95
 
93
- departmentTable = buildDrizzleTable("department", departmentEntity);
94
- userTable = buildDrizzleTable("user", userEntity);
95
- sessionTable = buildDrizzleTable("session", sessionEntity);
96
- groupTable = buildDrizzleTable("group", groupEntity);
97
- userGroupRestrictTable = buildDrizzleTable("user-group-restrict", userGroupRestrictEntity);
98
- userGroupCascadeTable = buildDrizzleTable("user-group-cascade", userGroupCascadeEntity);
99
- teamTable = buildDrizzleTable("team", teamEntity);
100
- memberTable = buildDrizzleTable("member", memberEntity);
96
+ departmentTable = buildEntityTable("department", departmentEntity);
97
+ userTable = buildEntityTable("user", userEntity);
98
+ sessionTable = buildEntityTable("session", sessionEntity);
99
+ groupTable = buildEntityTable("group", groupEntity);
100
+ userGroupRestrictTable = buildEntityTable("user-group-restrict", userGroupRestrictEntity);
101
+ userGroupCascadeTable = buildEntityTable("user-group-cascade", userGroupCascadeEntity);
102
+ teamTable = buildEntityTable("team", teamEntity);
103
+ memberTable = buildEntityTable("member", memberEntity);
101
104
 
102
105
  const feature = defineFeature("cascade", (r) => {
103
106
  r.entity("department", departmentEntity);
@@ -219,10 +222,10 @@ describe("cascade delete: cascade", () => {
219
222
  const user = await userExecutor.create({ name: "Cascade User" }, admin, tdb);
220
223
  if (!user.isSuccess) throw new Error("Setup failed");
221
224
 
222
- await sessionExecutor.create({ userId: user.data.id, token: "abc" }, admin, tdb);
223
- await sessionExecutor.create({ userId: user.data.id, token: "def" }, admin, tdb);
225
+ const s1 = await sessionExecutor.create({ userId: user.data.id, token: "abc" }, admin, tdb);
226
+ const s2 = await sessionExecutor.create({ userId: user.data.id, token: "def" }, admin, tdb);
227
+ if (!s1.isSuccess || !s2.isSuccess) throw new Error("Setup failed");
224
228
 
225
- // Verify sessions exist
226
229
  const before = await sessionExecutor.list({}, admin, tdb);
227
230
  const sessionsBefore = before.rows.filter((r) => r["userId"] === user.data.id);
228
231
  expect(sessionsBefore.length).toBe(2);
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "vitest";
1
+ import { describe, expect, test } from "bun:test";
2
2
  import { createEntity, createRegistry, createTextField, defineFeature } from "../../engine";
3
3
 
4
4
  describe("getIncomingRelations", () => {
@@ -15,11 +15,12 @@
15
15
  // The active propagation into cascaded writes is covered by
16
16
  // msp-multi-hop.integration.ts.
17
17
 
18
- import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
18
+ import { afterAll, afterEach, beforeAll, describe, expect, test } from "bun:test";
19
19
  import { z } from "zod";
20
20
  import { requestContext } from "../../api/request-context";
21
21
  import { createEventStoreExecutor } from "../../db/event-store-executor";
22
- import { buildDrizzleTable } from "../../db/table-builder";
22
+ import { selectMany } from "../../db/query";
23
+ import { buildEntityTable } from "../../db/table-builder";
23
24
  import { createEntity, createTextField, defineFeature } from "../../engine";
24
25
  import { eventsTable } from "../../event-store";
25
26
  import {
@@ -39,7 +40,7 @@ const orderEntity = createEntity({
39
40
  },
40
41
  });
41
42
 
42
- const orderTable = buildDrizzleTable("causation-order", orderEntity);
43
+ const orderTable = buildEntityTable("causation-order", orderEntity);
43
44
 
44
45
  // MSP-apply observation sink — every apply run pushes its reqCtx snapshot
45
46
  // here so the tests can assert what the event-dispatcher wrapped it with.
@@ -85,7 +86,7 @@ const causationFeature = defineFeature("causation", (r) => {
85
86
  [placed.name]: async (event) => {
86
87
  const ctx = requestContext.get();
87
88
  applyObservations.push({
88
- forEventId: String(event.id),
89
+ forEventId: String(event["id"]),
89
90
  correlationId: ctx?.correlationId,
90
91
  causationId: ctx?.causationId,
91
92
  });
@@ -118,11 +119,9 @@ afterEach(async () => {
118
119
 
119
120
  // --- Helpers ---
120
121
 
121
- type EventRow = typeof eventsTable.$inferSelect;
122
-
123
- async function eventsByType(type: string): Promise<EventRow[]> {
124
- const rows = await stack.db.select().from(eventsTable);
125
- return rows.filter((r) => r.type === type);
122
+ async function eventsByType(type: string) {
123
+ const rows = await selectMany(stack.db, eventsTable);
124
+ return rows.filter((r: Record<string, unknown>) => r["type"] === type);
126
125
  }
127
126
 
128
127
  // --- Tests ---
@@ -133,7 +132,7 @@ describe("Runde 2 — correlationId on root HTTP request", () => {
133
132
 
134
133
  const [placedEvent] = await eventsByType("causation:event:placed");
135
134
  expect(placedEvent).toBeDefined();
136
- const meta = placedEvent?.metadata as {
135
+ const meta = placedEvent?.["metadata"] as {
137
136
  requestId?: string;
138
137
  correlationId?: string;
139
138
  causationId?: string;
@@ -159,10 +158,10 @@ describe("Runde 2 — correlationId on root HTTP request", () => {
159
158
  const crudEvent = (await eventsByType("causation-order.created"))[0];
160
159
  const placedEvent = (await eventsByType("causation:event:placed"))[0];
161
160
 
162
- expect((crudEvent?.metadata as { correlationId?: string })?.correlationId).toBe(
161
+ expect((crudEvent?.["metadata"] as { correlationId?: string })?.correlationId).toBe(
163
162
  "test-chain-abc123",
164
163
  );
165
- expect((placedEvent?.metadata as { correlationId?: string })?.correlationId).toBe(
164
+ expect((placedEvent?.["metadata"] as { correlationId?: string })?.correlationId).toBe(
166
165
  "test-chain-abc123",
167
166
  );
168
167
  });
@@ -192,7 +191,7 @@ describe("Runde 2 — event-dispatcher propagates correlation + causation to MSP
192
191
  // should have seen as causationId.
193
192
  const [placedEvent] = await eventsByType("causation:event:placed");
194
193
  expect(placedEvent).toBeDefined();
195
- const placedId = String(placedEvent?.id);
194
+ const placedId = String(placedEvent?.["id"]);
196
195
 
197
196
  // Observation recorded inside the MSP apply.
198
197
  expect(applyObservations).toHaveLength(1);
@@ -1,7 +1,8 @@
1
- import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
2
2
  import { z } from "zod";
3
3
  import { createEventStoreExecutor } from "../../db/event-store-executor";
4
- import { buildDrizzleTable } from "../../db/table-builder";
4
+ import { asRawClient, selectMany } from "../../db/query";
5
+ import { buildEntityTable } from "../../db/table-builder";
5
6
  import {
6
7
  access,
7
8
  createEntity,
@@ -27,7 +28,7 @@ const bagEntity = createEntity({
27
28
  counter: createNumberField({ default: 0 }),
28
29
  },
29
30
  });
30
- const bagTable = buildDrizzleTable("bag", bagEntity);
31
+ const bagTable = buildEntityTable("bag", bagEntity);
31
32
 
32
33
  // secret has a system-only read field — proves queryAs(system) reads it,
33
34
  // plain query doesn't.
@@ -41,7 +42,7 @@ const secretEntity = createEntity({
41
42
  }),
42
43
  },
43
44
  });
44
- const secretTable = buildDrizzleTable("secret", secretEntity);
45
+ const secretTable = buildEntityTable("secret", secretEntity);
45
46
 
46
47
  let stack: TestStack;
47
48
  const admin = TestUsers.admin;
@@ -76,7 +77,7 @@ const bridgeFeature = defineFeature("ctxbridge", (r) => {
76
77
  "secret:by-owner",
77
78
  z.object({ owner: z.string() }),
78
79
  async (query, ctx) => {
79
- const rows = await ctx.db.select().from(secretTable);
80
+ const rows = await selectMany(ctx.db, secretTable);
80
81
  return (
81
82
  (rows as Array<Record<string, unknown>>).find((r) => r["owner"] === query.payload.owner) ??
82
83
  null
@@ -154,8 +155,8 @@ afterAll(async () => {
154
155
 
155
156
  beforeEach(async () => {
156
157
  afterCommitLog.length = 0;
157
- await stack.db.delete(bagTable);
158
- await stack.db.delete(secretTable);
158
+ await asRawClient(stack.db).unsafe(`DELETE FROM "${bagTable.tableName}"`);
159
+ await asRawClient(stack.db).unsafe(`DELETE FROM "${secretTable.tableName}"`);
159
160
  // Clear the event-dedup cache — tests re-use entity ids (Postgres sequences
160
161
  // reset, each test sees id=1). Without flushing Redis the second test hits
161
162
  // a dedup hit on the same handler:id:version:phase key and the hook is
@@ -195,8 +196,8 @@ describe("ctx.writeAs shares the outer transaction", () => {
195
196
  expect(body.isSuccess).toBe(false);
196
197
 
197
198
  // Both tables empty — outer bag + inner secret rolled back together
198
- const bags = await stack.db.select().from(bagTable);
199
- const secrets = await stack.db.select().from(secretTable);
199
+ const bags = await selectMany(stack.db, bagTable);
200
+ const secrets = await selectMany(stack.db, secretTable);
200
201
  expect(bags).toHaveLength(0);
201
202
  expect(secrets).toHaveLength(0);
202
203
  });
@@ -209,8 +210,8 @@ describe("ctx.writeAs shares the outer transaction", () => {
209
210
  );
210
211
  expect((await res.json()).isSuccess).toBe(true);
211
212
 
212
- const bags = await stack.db.select().from(bagTable);
213
- const secrets = await stack.db.select().from(secretTable);
213
+ const bags = await selectMany(stack.db, bagTable);
214
+ const secrets = await selectMany(stack.db, secretTable);
214
215
  expect(bags).toHaveLength(1);
215
216
  expect(secrets).toHaveLength(1);
216
217
 
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "vitest";
1
+ import { describe, expect, test } from "bun:test";
2
2
  import { z } from "zod";
3
3
  import { createEntity, createRegistry, createTextField, defineFeature } from "../../engine";
4
4
  import type { TenantId } from "../../engine/types/identifiers";
@@ -97,7 +97,7 @@ describe("dispatcher.write", () => {
97
97
  const res = await dispatcher.write("alias:write:item:create", { name: "x" }, user);
98
98
  expect(res.isSuccess).toBe(true);
99
99
  expect(captured.fromCtx).toBe(captured.fromEvent);
100
- expect((captured.fromCtx as { id: number }).id).toBe(user.id);
100
+ expect((captured.fromCtx as { id: unknown }).id).toBe(user.id);
101
101
  });
102
102
 
103
103
  test("runs validation hooks", async () => {
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeAll, describe, expect, test } from "vitest";
1
+ import { afterAll, beforeAll, describe, expect, test } from "bun:test";
2
2
  import { createTestRedis, type TestRedis } from "../../stack";
3
3
  import { createDistributedLock } from "../distributed-lock";
4
4
 
@@ -9,9 +9,7 @@
9
9
  // Without all three pieces wired together (registry opens defineEvent names,
10
10
  // projections-runner fires on appendEvent, dispatcher routes appendEvent to
11
11
  // the aggregate stream), any of the assertions below go red.
12
-
13
- import { eq } from "drizzle-orm";
14
- import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
12
+ import { afterAll, afterEach, beforeAll, describe, expect, test } from "bun:test";
15
13
  import { z } from "zod";
16
14
  import {
17
15
  integer as pgInteger,
@@ -20,7 +18,8 @@ import {
20
18
  uuid as pgUuid,
21
19
  } from "../../db/dialect";
22
20
  import { createEventStoreExecutor } from "../../db/event-store-executor";
23
- import { buildDrizzleTable } from "../../db/table-builder";
21
+ import { insertOne, selectMany, updateMany } from "../../db/query";
22
+ import { buildEntityTable } from "../../db/table-builder";
24
23
  import { createEntity, createTextField, defineFeature } from "../../engine";
25
24
  import { loadAggregate } from "../../event-store";
26
25
  import {
@@ -41,7 +40,7 @@ const shipmentEntity = createEntity({
41
40
  },
42
41
  });
43
42
 
44
- const shipmentTable = buildDrizzleTable("domain-shipment", shipmentEntity);
43
+ const shipmentTable = buildEntityTable("domain-shipment", shipmentEntity);
45
44
 
46
45
  // --- Read-model table (fed by the projection below) ---
47
46
 
@@ -69,7 +68,7 @@ const shippingFeature = defineFeature("shipping", (r) => {
69
68
  // Auto CRUD event — fires on shipment create.
70
69
  "domain-shipment.created": async (event, tx) => {
71
70
  const payload = event.payload as { cargo?: string };
72
- await tx.insert(billingTable).values({
71
+ await insertOne(tx, billingTable, {
73
72
  shipmentId: event.aggregateId,
74
73
  tenantId: event.tenantId,
75
74
  cargo: payload.cargo ?? "",
@@ -82,10 +81,12 @@ const shippingFeature = defineFeature("shipping", (r) => {
82
81
  // create-apply just inserted.
83
82
  [shipmentBilled.name]: async (event, tx) => {
84
83
  const payload = event.payload as { cost: number };
85
- await tx
86
- .update(billingTable)
87
- .set({ totalCost: payload.cost, billedMarker: "billed" })
88
- .where(eq(billingTable.shipmentId, event.aggregateId));
84
+ await updateMany(
85
+ tx,
86
+ billingTable,
87
+ { totalCost: payload.cost, billedMarker: "billed" },
88
+ { shipmentId: event.aggregateId },
89
+ );
89
90
  },
90
91
  },
91
92
  });
@@ -196,7 +197,7 @@ describe("Marten gold-standard: domain events → inline projections", () => {
196
197
  admin,
197
198
  );
198
199
 
199
- const rows = await stack.db.select().from(billingTable);
200
+ const rows = await selectMany(stack.db, billingTable);
200
201
  expect(rows).toHaveLength(1);
201
202
  expect(rows[0]?.shipmentId).toBe(data.id);
202
203
  expect(rows[0]?.billedMarker).toBe("pending");
@@ -212,10 +213,7 @@ describe("Marten gold-standard: domain events → inline projections", () => {
212
213
 
213
214
  await stack.http.writeOk("shipping:write:shipment:bill", { id: created.id, cost: 1500 }, admin);
214
215
 
215
- const [row] = await stack.db
216
- .select()
217
- .from(billingTable)
218
- .where(eq(billingTable.shipmentId, created.id));
216
+ const [row] = await selectMany(stack.db, billingTable, { shipmentId: created.id });
219
217
  expect(row).toBeDefined();
220
218
  expect(row?.billedMarker).toBe("billed");
221
219
  expect(row?.totalCost).toBe(1500);
@@ -1,4 +1,4 @@
1
- import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
1
+ import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
2
2
  import { z } from "zod";
3
3
  import { createEventStoreExecutor } from "../../db/event-store-executor";
4
4
  import { defineFeature, type SaveContext } from "../../engine";