@cosmicdrift/kumiko-bundled-features 0.14.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 (268) hide show
  1. package/package.json +2 -2
  2. package/src/__tests__/env-schemas.test.ts +1 -1
  3. package/src/__tests__/es-ops-e2e.integration.ts +10 -9
  4. package/src/audit/__tests__/audit.integration.ts +3 -3
  5. package/src/audit/handlers/list.query.ts +39 -51
  6. package/src/auth-email-password/__tests__/account-lockout-no-redis.integration.ts +4 -3
  7. package/src/auth-email-password/__tests__/account-lockout.integration.ts +4 -3
  8. package/src/auth-email-password/__tests__/auth-claims.integration.ts +5 -4
  9. package/src/auth-email-password/__tests__/auth.integration.ts +4 -3
  10. package/src/auth-email-password/__tests__/confirm-token-flow.test.ts +1 -1
  11. package/src/auth-email-password/__tests__/email-templates.test.ts +1 -1
  12. package/src/auth-email-password/__tests__/email-verification.integration.ts +7 -10
  13. package/src/auth-email-password/__tests__/identity-v3-hash.test.ts +1 -1
  14. package/src/auth-email-password/__tests__/identity-v3-login.integration.ts +4 -3
  15. package/src/auth-email-password/__tests__/invite-flow.integration.ts +16 -43
  16. package/src/auth-email-password/__tests__/multi-roles.integration.ts +6 -9
  17. package/src/auth-email-password/__tests__/password-reset.integration.ts +8 -7
  18. package/src/auth-email-password/__tests__/public-routes-rate-limit.integration.ts +4 -3
  19. package/src/auth-email-password/__tests__/seed-admin.integration.ts +19 -32
  20. package/src/auth-email-password/__tests__/session-callbacks.integration.ts +6 -5
  21. package/src/auth-email-password/__tests__/session-strict-mode.integration.ts +1 -1
  22. package/src/auth-email-password/__tests__/signed-token.test.ts +1 -1
  23. package/src/auth-email-password/__tests__/signup-flow.integration.ts +11 -15
  24. package/src/auth-email-password/handlers/invite-accept-with-login.write.ts +26 -26
  25. package/src/auth-email-password/handlers/invite-accept.write.ts +24 -21
  26. package/src/auth-email-password/handlers/invite-create.write.ts +3 -8
  27. package/src/auth-email-password/handlers/invite-signup-complete.write.ts +20 -17
  28. package/src/auth-email-password/handlers/signup-confirm.write.ts +3 -7
  29. package/src/auth-email-password/seeding.ts +1 -1
  30. package/src/auth-email-password/web/__tests__/auth-gate.test.tsx +1 -2
  31. package/src/auth-email-password/web/__tests__/forgot-password-screen.test.tsx +10 -19
  32. package/src/auth-email-password/web/__tests__/login-screen.test.tsx +12 -18
  33. package/src/auth-email-password/web/__tests__/reset-password-screen.test.tsx +12 -17
  34. package/src/auth-email-password/web/__tests__/session-roles.test.ts +1 -1
  35. package/src/auth-email-password/web/__tests__/tenant-switcher.test.tsx +1 -8
  36. package/src/auth-email-password/web/__tests__/test-utils.tsx +4 -8
  37. package/src/auth-email-password/web/__tests__/user-menu.test.tsx +2 -8
  38. package/src/auth-email-password/web/__tests__/verify-email-screen.test.tsx +10 -15
  39. package/src/billing-foundation/__tests__/billing-foundation.integration.ts +1 -1
  40. package/src/billing-foundation/__tests__/feature.test.ts +1 -1
  41. package/src/billing-foundation/__tests__/webhook-handler.test.ts +6 -5
  42. package/src/billing-foundation/db/queries/subscription-projection.ts +15 -0
  43. package/src/billing-foundation/get-subscription-for-tenant.ts +2 -6
  44. package/src/billing-foundation/handlers/create-portal-session.write.ts +2 -2
  45. package/src/billing-foundation/handlers/list-subscriptions.query.ts +4 -1
  46. package/src/billing-foundation/projection.ts +32 -13
  47. package/src/cap-counter/__tests__/cap-counter.integration.ts +1 -1
  48. package/src/cap-counter/__tests__/enforce-cap.test.ts +37 -32
  49. package/src/cap-counter/__tests__/with-cap-enforcement.integration.ts +1 -1
  50. package/src/cap-counter/enforce-cap.ts +14 -20
  51. package/src/cap-counter/handlers/get-counter.query.ts +7 -13
  52. package/src/cap-counter/handlers/increment.write.ts +2 -2
  53. package/src/cap-counter/handlers/mark-soft-warned.write.ts +2 -2
  54. package/src/channel-in-app/handlers/inbox.query.ts +7 -13
  55. package/src/channel-in-app/handlers/mark-all-read.write.ts +7 -9
  56. package/src/channel-in-app/handlers/mark-read.write.ts +8 -14
  57. package/src/channel-in-app/handlers/unread-count.query.ts +10 -9
  58. package/src/channel-in-app/in-app-channel.ts +10 -12
  59. package/src/channel-in-app/tables.ts +1 -1
  60. package/src/compliance-profiles/__tests__/compliance-profiles.integration.ts +1 -1
  61. package/src/compliance-profiles/__tests__/seeding.integration.ts +1 -1
  62. package/src/compliance-profiles/handlers/for-tenant.query.ts +4 -7
  63. package/src/compliance-profiles/handlers/needs-profile.query.ts +4 -7
  64. package/src/compliance-profiles/handlers/set-profile.write.ts +5 -7
  65. package/src/compliance-profiles/resolve-for-tenant.ts +5 -7
  66. package/src/compliance-profiles/schema/profile-selection.ts +2 -2
  67. package/src/compliance-profiles/seeding.ts +4 -7
  68. package/src/config/__tests__/app-overrides.test.ts +1 -1
  69. package/src/config/__tests__/cascade.integration.ts +1 -1
  70. package/src/config/__tests__/config.integration.ts +8 -27
  71. package/src/config/db/queries/resolver.ts +47 -0
  72. package/src/config/handlers/__tests__/prepare-config-write.test.ts +1 -1
  73. package/src/config/resolver.ts +14 -62
  74. package/src/config/table.ts +4 -4
  75. package/src/config/write-helpers.ts +7 -11
  76. package/src/custom-fields/__tests__/audit-integration.integration.ts +6 -6
  77. package/src/custom-fields/__tests__/custom-fields.integration.ts +7 -7
  78. package/src/custom-fields/__tests__/feature.test.ts +1 -1
  79. package/src/custom-fields/__tests__/field-access.integration.ts +6 -6
  80. package/src/custom-fields/__tests__/quota.integration.ts +6 -6
  81. package/src/custom-fields/__tests__/retention.integration.ts +12 -10
  82. package/src/custom-fields/__tests__/user-data-rights.integration.ts +27 -17
  83. package/src/custom-fields/__tests__/wire-for-entity.test.ts +5 -5
  84. package/src/custom-fields/db/queries/field-access.ts +16 -0
  85. package/src/custom-fields/db/queries/projection.ts +43 -0
  86. package/src/custom-fields/db/queries/quota.ts +14 -0
  87. package/src/custom-fields/db/queries/retention.ts +39 -0
  88. package/src/custom-fields/db/queries/user-data-rights.ts +54 -0
  89. package/src/custom-fields/lib/field-access.ts +2 -41
  90. package/src/custom-fields/lib/quota.ts +2 -25
  91. package/src/custom-fields/run-retention.ts +19 -21
  92. package/src/custom-fields/wire-for-entity.ts +30 -23
  93. package/src/custom-fields/wire-user-data-rights.ts +33 -85
  94. package/src/data-retention/__tests__/data-retention.integration.ts +1 -1
  95. package/src/data-retention/__tests__/keep-for.test.ts +1 -1
  96. package/src/data-retention/__tests__/override-schema.test.ts +1 -1
  97. package/src/data-retention/__tests__/policy-for.integration.ts +1 -1
  98. package/src/data-retention/__tests__/resolver.test.ts +1 -1
  99. package/src/data-retention/handlers/policy-for.query.ts +5 -8
  100. package/src/data-retention/resolve-for-tenant.ts +6 -8
  101. package/src/data-retention/schema/tenant-retention-override.ts +2 -2
  102. package/src/delivery/__tests__/delivery-events.integration.ts +8 -21
  103. package/src/delivery/__tests__/delivery.integration.ts +100 -190
  104. package/src/delivery/db/queries/preferences.ts +30 -0
  105. package/src/delivery/delivery-service.ts +8 -36
  106. package/src/delivery/feature.ts +2 -1
  107. package/src/delivery/handlers/log.query.ts +5 -7
  108. package/src/delivery/handlers/preferences.query.ts +2 -5
  109. package/src/delivery/tables.ts +26 -1
  110. package/src/delivery/upsert-preference.ts +8 -14
  111. package/src/feature-toggles/__tests__/feature-toggles.integration.ts +30 -30
  112. package/src/feature-toggles/__tests__/registered-system-tenant.test.ts +7 -6
  113. package/src/feature-toggles/db/queries/toggle-state.ts +25 -0
  114. package/src/feature-toggles/feature.ts +16 -2
  115. package/src/feature-toggles/global-feature-state-table.ts +1 -1
  116. package/src/feature-toggles/handlers/list.query.ts +9 -2
  117. package/src/feature-toggles/handlers/registered.query.ts +3 -7
  118. package/src/feature-toggles/handlers/set.write.ts +37 -25
  119. package/src/feature-toggles/toggle-runtime.ts +3 -6
  120. package/src/file-foundation/__tests__/feature.test.ts +1 -1
  121. package/src/file-foundation/__tests__/file-foundation.integration.ts +1 -1
  122. package/src/file-provider-inmemory/__tests__/feature.test.ts +1 -1
  123. package/src/file-provider-s3/__tests__/feature.test.ts +1 -1
  124. package/src/files/__tests__/files.integration.ts +18 -7
  125. package/src/files/schema/file-ref.ts +1 -1
  126. package/src/files-provider-s3/__tests__/env-helper.test.ts +1 -1
  127. package/src/files-provider-s3/__tests__/s3-provider.integration.ts +1 -1
  128. package/src/files-provider-s3/__tests__/s3-provider.test.ts +1 -1
  129. package/src/jobs/__tests__/job-system-user.integration.ts +1 -1
  130. package/src/jobs/__tests__/jobs-events.integration.ts +8 -21
  131. package/src/jobs/__tests__/jobs-feature.integration.ts +1 -1
  132. package/src/jobs/feature.ts +22 -14
  133. package/src/jobs/handlers/detail.query.ts +10 -8
  134. package/src/jobs/handlers/list.query.ts +9 -21
  135. package/src/jobs/handlers/retry.write.ts +2 -7
  136. package/src/jobs/job-run-logger.ts +3 -9
  137. package/src/jobs/job-run-table.ts +49 -17
  138. package/src/legal-pages/__tests__/legal-pages.integration.ts +1 -1
  139. package/src/mail-foundation/__tests__/feature.test.ts +1 -1
  140. package/src/mail-foundation/__tests__/mail-foundation.integration.ts +1 -1
  141. package/src/mail-transport-inmemory/__tests__/feature.test.ts +1 -1
  142. package/src/mail-transport-smtp/__tests__/feature.test.ts +1 -1
  143. package/src/rate-limiting/__tests__/rate-limiting.integration.ts +1 -1
  144. package/src/renderer-foundation/__tests__/api.test.ts +2 -2
  145. package/src/renderer-foundation/__tests__/collect-plugins.integration.ts +1 -1
  146. package/src/renderer-simple/__tests__/adapter.test.ts +2 -2
  147. package/src/renderer-simple/__tests__/simple-renderer.test.ts +1 -1
  148. package/src/secrets/__tests__/require-secrets-context.test.ts +6 -5
  149. package/src/secrets/__tests__/rotate.integration.ts +6 -9
  150. package/src/secrets/__tests__/secrets-events.integration.ts +6 -12
  151. package/src/secrets/__tests__/secrets.integration.ts +6 -11
  152. package/src/secrets/db/queries/read.ts +16 -0
  153. package/src/secrets/handlers/list.query.ts +16 -17
  154. package/src/secrets/handlers/rotate.job.ts +8 -12
  155. package/src/secrets/secrets-context.ts +9 -21
  156. package/src/secrets/table.ts +1 -1
  157. package/src/sessions/__tests__/cleanup.integration.ts +8 -6
  158. package/src/sessions/__tests__/password-auto-revoke.integration.ts +7 -6
  159. package/src/sessions/__tests__/sessions.integration.ts +23 -38
  160. package/src/sessions/__tests__/test-helpers.ts +1 -1
  161. package/src/sessions/db/queries/cleanup.ts +21 -0
  162. package/src/sessions/handlers/cleanup.job.ts +6 -29
  163. package/src/sessions/handlers/list.query.ts +24 -24
  164. package/src/sessions/handlers/mine.query.ts +24 -23
  165. package/src/sessions/handlers/revoke-all-for-user.write.ts +7 -11
  166. package/src/sessions/handlers/revoke-all-others.write.ts +7 -12
  167. package/src/sessions/handlers/revoke.write.ts +11 -18
  168. package/src/sessions/schema/user-session.ts +2 -2
  169. package/src/sessions/session-callbacks.ts +19 -21
  170. package/src/subscription-mollie/__tests__/feature.test.ts +1 -1
  171. package/src/subscription-mollie/__tests__/mollie-foundation.integration.ts +1 -1
  172. package/src/subscription-mollie/__tests__/verify-webhook.test.ts +8 -7
  173. package/src/subscription-stripe/__tests__/feature.test.ts +1 -1
  174. package/src/subscription-stripe/__tests__/plugin-methods.test.ts +14 -15
  175. package/src/subscription-stripe/__tests__/stripe-foundation.integration.ts +1 -1
  176. package/src/subscription-stripe/__tests__/verify-webhook.test.ts +14 -14
  177. package/src/subscription-stripe/verify-webhook.ts +1 -1
  178. package/src/template-resolver/__tests__/handlers.integration.ts +1 -1
  179. package/src/template-resolver/__tests__/template-resolver.integration.ts +3 -2
  180. package/src/template-resolver/api.ts +7 -13
  181. package/src/template-resolver/handlers/archive.write.ts +4 -7
  182. package/src/template-resolver/handlers/find-by-id.query.ts +4 -7
  183. package/src/template-resolver/handlers/list.query.ts +13 -21
  184. package/src/template-resolver/handlers/publish.write.ts +4 -7
  185. package/src/template-resolver/handlers/upsert-system.write.ts +7 -10
  186. package/src/template-resolver/handlers/upsert-tenant.write.ts +7 -10
  187. package/src/template-resolver/table.ts +2 -5
  188. package/src/tenant/__tests__/multi-tenant.integration.ts +1 -1
  189. package/src/tenant/__tests__/seed-testing.integration.ts +19 -45
  190. package/src/tenant/__tests__/tenant.integration.ts +1 -1
  191. package/src/tenant/handlers/active-tenant-ids.query.ts +3 -8
  192. package/src/tenant/handlers/add-member.write.ts +6 -8
  193. package/src/tenant/handlers/cancel-invitation.write.ts +5 -7
  194. package/src/tenant/handlers/invitations.query.ts +5 -10
  195. package/src/tenant/handlers/me.query.ts +2 -3
  196. package/src/tenant/handlers/members.query.ts +4 -5
  197. package/src/tenant/handlers/memberships.query.ts +2 -5
  198. package/src/tenant/handlers/remove-member.write.ts +6 -8
  199. package/src/tenant/handlers/resolve-user-ids.query.ts +6 -16
  200. package/src/tenant/handlers/update-member-roles.write.ts +6 -8
  201. package/src/tenant/invitation-table.ts +2 -5
  202. package/src/tenant/membership-table.ts +3 -6
  203. package/src/tenant/schema/tenant.ts +2 -2
  204. package/src/tenant/seeding.ts +12 -18
  205. package/src/text-content/README.md +1 -1
  206. package/src/text-content/__tests__/text-content.integration.ts +2 -2
  207. package/src/text-content/api.ts +2 -9
  208. package/src/text-content/handlers/by-slug.query.ts +6 -9
  209. package/src/text-content/handlers/by-tenant.query.ts +2 -2
  210. package/src/text-content/handlers/set.write.ts +7 -9
  211. package/src/text-content/seeding.ts +6 -9
  212. package/src/text-content/table.ts +2 -2
  213. package/src/text-content/web/__tests__/editor-read-only.test.tsx +31 -45
  214. package/src/text-content/web/__tests__/group-blocks.test.ts +1 -18
  215. package/src/text-content/web/client-plugin.tsx +11 -23
  216. package/src/tier-engine/__tests__/auto-default-tier.integration.ts +10 -16
  217. package/src/tier-engine/__tests__/compose-app.test.ts +1 -1
  218. package/src/tier-engine/__tests__/drift.test.ts +1 -1
  219. package/src/tier-engine/__tests__/resolver.integration.ts +6 -6
  220. package/src/tier-engine/__tests__/tier-engine.integration.ts +1 -1
  221. package/src/tier-engine/feature.ts +9 -16
  222. package/src/user/__tests__/seed-testing.integration.ts +10 -22
  223. package/src/user/__tests__/user-status.test.ts +1 -1
  224. package/src/user/__tests__/user.integration.ts +6 -5
  225. package/src/user/handlers/create.write.ts +5 -7
  226. package/src/user/handlers/find-for-auth.query.ts +5 -7
  227. package/src/user/schema/user.ts +2 -2
  228. package/src/user/seeding.ts +2 -3
  229. package/src/user-data-rights/__tests__/audit-log.integration.ts +24 -12
  230. package/src/user-data-rights/__tests__/cross-data-matrix.integration.ts +64 -37
  231. package/src/user-data-rights/__tests__/download.integration.ts +29 -46
  232. package/src/user-data-rights/__tests__/export-job-idempotency.integration.ts +35 -28
  233. package/src/user-data-rights/__tests__/export-job-schema.test.ts +2 -2
  234. package/src/user-data-rights/__tests__/policy-to-strategy.test.ts +1 -1
  235. package/src/user-data-rights/__tests__/request-cancel-deletion.integration.ts +11 -15
  236. package/src/user-data-rights/__tests__/request-deletion-callback.integration.ts +10 -12
  237. package/src/user-data-rights/__tests__/request-export.integration.ts +23 -16
  238. package/src/user-data-rights/__tests__/restriction-flow.integration.ts +24 -32
  239. package/src/user-data-rights/__tests__/run-export-jobs.integration.ts +142 -137
  240. package/src/user-data-rights/__tests__/run-forget-cleanup.integration.ts +46 -28
  241. package/src/user-data-rights/__tests__/run-user-export.integration.ts +20 -14
  242. package/src/user-data-rights/__tests__/token-helpers.test.ts +1 -1
  243. package/src/user-data-rights/__tests__/user-data-rights.integration.ts +1 -1
  244. package/src/user-data-rights/__tests__/zip-path.test.ts +1 -1
  245. package/src/user-data-rights/audit-download.ts +3 -3
  246. package/src/user-data-rights/db/queries/export-jobs.ts +23 -0
  247. package/src/user-data-rights/db/queries/forget-cleanup.ts +13 -0
  248. package/src/user-data-rights/handlers/cancel-deletion.write.ts +28 -22
  249. package/src/user-data-rights/handlers/download-by-job.query.ts +11 -21
  250. package/src/user-data-rights/handlers/download-by-token.query.ts +20 -35
  251. package/src/user-data-rights/handlers/export-status.query.ts +19 -33
  252. package/src/user-data-rights/handlers/lift-restriction.write.ts +7 -12
  253. package/src/user-data-rights/handlers/list-download-attempts.query.ts +14 -23
  254. package/src/user-data-rights/handlers/my-audit-log.query.ts +33 -23
  255. package/src/user-data-rights/handlers/request-deletion.write.ts +15 -15
  256. package/src/user-data-rights/handlers/request-export.write.ts +7 -11
  257. package/src/user-data-rights/handlers/restrict-account.write.ts +12 -12
  258. package/src/user-data-rights/run-export-jobs.ts +20 -60
  259. package/src/user-data-rights/run-forget-cleanup.ts +19 -33
  260. package/src/user-data-rights/run-user-export.ts +4 -6
  261. package/src/user-data-rights/schema/download-attempt.ts +2 -2
  262. package/src/user-data-rights/schema/download-token.ts +2 -2
  263. package/src/user-data-rights/schema/export-job.ts +2 -3
  264. package/src/user-data-rights-defaults/__tests__/user-data-rights-defaults.integration.ts +37 -30
  265. package/src/user-data-rights-defaults/db/queries/user-hook.ts +17 -0
  266. package/src/user-data-rights-defaults/hooks/file-ref.userdata-hook.ts +12 -27
  267. package/src/user-data-rights-defaults/hooks/user.userdata-hook.ts +16 -18
  268. package/CHANGELOG.md +0 -689
@@ -1,9 +1,10 @@
1
1
  import { ROLES } from "@cosmicdrift/kumiko-framework/auth";
2
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
3
  import {
3
4
  complianceProfileOverrideSchema,
4
5
  SELECTABLE_PROFILE_KEYS,
5
6
  } from "@cosmicdrift/kumiko-framework/compliance";
6
- import { createEventStoreExecutor, fetchOne } from "@cosmicdrift/kumiko-framework/db";
7
+ import { createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
7
8
  import { defineWriteHandler, type TenantId } from "@cosmicdrift/kumiko-framework/engine";
8
9
  import {
9
10
  AccessDeniedError,
@@ -11,7 +12,6 @@ import {
11
12
  validationErrorFromZod,
12
13
  writeFailure,
13
14
  } from "@cosmicdrift/kumiko-framework/errors";
14
- import { eq } from "drizzle-orm";
15
15
  import { z } from "zod";
16
16
  import {
17
17
  tenantComplianceProfileEntity,
@@ -100,11 +100,9 @@ export const setProfileWrite = defineWriteHandler({
100
100
  }
101
101
 
102
102
  // Upsert: existierenden Eintrag suchen
103
- const existing = (await fetchOne(
104
- ctx.db,
105
- tenantComplianceProfileTable,
106
- eq(tenantComplianceProfileTable["tenantId"], tenantId),
107
- )) as { id: string; version: number } | null; // @cast-boundary db-runner
103
+ const existing = (await fetchOne(ctx.db, tenantComplianceProfileTable, {
104
+ tenantId: tenantId,
105
+ })) as { id: string; version: number } | null; // @cast-boundary db-runner
108
106
 
109
107
  if (existing) {
110
108
  const result = await crud.update(
@@ -8,15 +8,15 @@
8
8
  // Beide Pfade nutzen `resolveComplianceProfile` aus framework/compliance,
9
9
  // also kein Drift zwischen Query-API und Worker-Pfad.
10
10
 
11
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
11
12
  import {
12
13
  type ComplianceProfileKey,
13
14
  type ComplianceProfileOverride,
14
15
  type EffectiveComplianceProfile,
15
16
  resolveComplianceProfile,
16
17
  } from "@cosmicdrift/kumiko-framework/compliance";
17
- import { type DbRunner, fetchOne } from "@cosmicdrift/kumiko-framework/db";
18
+ import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
18
19
  import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
19
- import { eq } from "drizzle-orm";
20
20
  import { tenantComplianceProfileTable } from "./schema/profile-selection";
21
21
 
22
22
  export interface ResolveProfileForTenantArgs {
@@ -27,11 +27,9 @@ export interface ResolveProfileForTenantArgs {
27
27
  export async function resolveProfileForTenant(
28
28
  args: ResolveProfileForTenantArgs,
29
29
  ): Promise<EffectiveComplianceProfile> {
30
- const row = (await fetchOne(
31
- args.db,
32
- tenantComplianceProfileTable,
33
- eq(tenantComplianceProfileTable["tenantId"], args.tenantId),
34
- )) as { profileKey: string; override: string | null } | null; // @cast-boundary db-runner
30
+ const row = (await fetchOne(args.db, tenantComplianceProfileTable, {
31
+ tenantId: args.tenantId,
32
+ })) as { profileKey: string; override: string | null } | null; // @cast-boundary db-runner
35
33
 
36
34
  if (!row) {
37
35
  return resolveComplianceProfile({});
@@ -1,4 +1,4 @@
1
- import { buildDrizzleTable } from "@cosmicdrift/kumiko-framework/db";
1
+ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
2
2
  import {
3
3
  createEntity,
4
4
  createLongTextField,
@@ -46,7 +46,7 @@ export const tenantComplianceProfileEntity = createEntity({
46
46
  ],
47
47
  });
48
48
 
49
- export const tenantComplianceProfileTable = buildDrizzleTable(
49
+ export const tenantComplianceProfileTable = buildEntityTable(
50
50
  "tenantComplianceProfile",
51
51
  tenantComplianceProfileEntity,
52
52
  );
@@ -10,6 +10,7 @@
10
10
  //
11
11
  // Pattern matched seedTextBlock aus text-content.
12
12
 
13
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
13
14
  import type {
14
15
  ComplianceProfileKey,
15
16
  ComplianceProfileOverride,
@@ -18,11 +19,9 @@ import {
18
19
  createEventStoreExecutor,
19
20
  createTenantDb,
20
21
  type DbConnection,
21
- fetchOne,
22
22
  } from "@cosmicdrift/kumiko-framework/db";
23
23
  import type { SessionUser, TenantId } from "@cosmicdrift/kumiko-framework/engine";
24
24
  import { TestUsers } from "@cosmicdrift/kumiko-framework/stack";
25
- import { eq } from "drizzle-orm";
26
25
  import {
27
26
  tenantComplianceProfileEntity,
28
27
  tenantComplianceProfileTable,
@@ -52,11 +51,9 @@ export async function seedComplianceProfile(
52
51
  const tdb = createTenantDb(db, opts.tenantId, "system");
53
52
  const overrideJson = opts.override !== undefined ? JSON.stringify(opts.override) : null;
54
53
 
55
- const existing = (await fetchOne(
56
- db,
57
- tenantComplianceProfileTable,
58
- eq(tenantComplianceProfileTable["tenantId"], opts.tenantId),
59
- )) as { id: string; version: number } | null; // @cast-boundary db-runner
54
+ const existing = (await fetchOne(db, tenantComplianceProfileTable, {
55
+ tenantId: opts.tenantId,
56
+ })) as { id: string; version: number } | null; // @cast-boundary db-runner
60
57
 
61
58
  if (existing) {
62
59
  const result = await executor.update(
@@ -1,5 +1,5 @@
1
+ import { describe, expect, test } from "bun:test";
1
2
  import { createTenantConfig, createUserConfig } from "@cosmicdrift/kumiko-framework/engine";
2
- import { describe, expect, test } from "vitest";
3
3
  import { validateAppOverrides } from "../resolver";
4
4
 
5
5
  // Minimal registry stub — validateAppOverrides only reads getConfigKey.
@@ -1,3 +1,4 @@
1
+ import { afterAll, beforeAll, describe, expect, test } from "bun:test";
1
2
  import { seedConfigValues } from "@cosmicdrift/kumiko-framework/db";
2
3
  import type {
3
4
  ConfigCascade,
@@ -20,7 +21,6 @@ import {
20
21
  TestUsers,
21
22
  unsafePushTables,
22
23
  } from "@cosmicdrift/kumiko-framework/stack";
23
- import { afterAll, beforeAll, describe, expect, test } from "vitest";
24
24
  import { ConfigHandlers, ConfigQueries } from "../constants";
25
25
  import { createConfigAccessorFactory, createConfigFeature } from "../feature";
26
26
  import { type ConfigResolver, createConfigResolver } from "../resolver";
@@ -1,4 +1,6 @@
1
+ import { afterAll, beforeAll, describe, expect, test } from "bun:test";
1
2
  import { randomBytes } from "node:crypto";
3
+ import { selectMany } from "@cosmicdrift/kumiko-framework/bun-db";
2
4
  import {
3
5
  createEncryptionProvider,
4
6
  type DbConnection,
@@ -23,8 +25,6 @@ import {
23
25
  unsafePushTables,
24
26
  } from "@cosmicdrift/kumiko-framework/stack";
25
27
  import { expectErrorIncludes } from "@cosmicdrift/kumiko-framework/testing";
26
- import { eq } from "drizzle-orm";
27
- import { afterAll, beforeAll, describe, expect, test } from "vitest";
28
28
  import { z } from "zod";
29
29
  import { ConfigHandlers, ConfigQueries } from "../constants";
30
30
  import { createConfigAccessor, createConfigAccessorFactory, createConfigFeature } from "../feature";
@@ -756,11 +756,7 @@ describe("encrypted config", () => {
756
756
  expect(value).toBe("sk-super-secret-key-12345");
757
757
 
758
758
  // Verify raw DB value is NOT plaintext
759
- const { eq } = await import("drizzle-orm");
760
- const [raw] = await db
761
- .select({ value: configValuesTable.value })
762
- .from(configValuesTable)
763
- .where(eq(configValuesTable.key, "integration:config:api-secret"));
759
+ const [raw] = await selectMany(db, configValuesTable, { key: "integration:config:api-secret" });
764
760
  const rawValue = raw?.value as string;
765
761
  expect(rawValue).not.toBe("sk-super-secret-key-12345");
766
762
  expect(rawValue).not.toContain("sk-super-secret");
@@ -814,10 +810,7 @@ describe("configValue lifecycle events", () => {
814
810
  { key: "orders:config:max-order-count", value: 250 },
815
811
  tenantAdmin,
816
812
  );
817
- const events = await db
818
- .select()
819
- .from(eventsTable)
820
- .where(eq(eventsTable.aggregateType, "config-value"));
813
+ const events = await selectMany(db, eventsTable, { aggregateType: "config-value" });
821
814
  // The first set in the suite created the row; subsequent sets update it.
822
815
  // Look at the most recent update carrying our value to verify the
823
816
  // serialized JSON lands in the event payload (key stays on the row,
@@ -848,10 +841,7 @@ describe("configValue lifecycle events", () => {
848
841
  { key: "invoicing:config:mail-signature" },
849
842
  tenantAdmin,
850
843
  );
851
- const events = await db
852
- .select()
853
- .from(eventsTable)
854
- .where(eq(eventsTable.aggregateType, "config-value"));
844
+ const events = await selectMany(db, eventsTable, { aggregateType: "config-value" });
855
845
  const deletes = events.filter(
856
846
  (e) =>
857
847
  e.type === "config-value.deleted" &&
@@ -871,10 +861,7 @@ describe("configValue lifecycle events", () => {
871
861
  { key: "integration:config:lifecycle-probe", value: "alpha" },
872
862
  tenantAdmin,
873
863
  );
874
- const events = await db
875
- .select()
876
- .from(eventsTable)
877
- .where(eq(eventsTable.aggregateType, "config-value"));
864
+ const events = await selectMany(db, eventsTable, { aggregateType: "config-value" });
878
865
  const created = events.filter(
879
866
  (e) =>
880
867
  e.type === "config-value.created" &&
@@ -898,10 +885,7 @@ describe("configValue lifecycle events", () => {
898
885
  { key: "integration:config:lifecycle-probe", value: "beta" },
899
886
  tenantAdmin,
900
887
  );
901
- const events = await db
902
- .select()
903
- .from(eventsTable)
904
- .where(eq(eventsTable.aggregateType, "config-value"));
888
+ const events = await selectMany(db, eventsTable, { aggregateType: "config-value" });
905
889
  const updates = events.filter(
906
890
  (e) =>
907
891
  e.type === "config-value.updated" &&
@@ -925,10 +909,7 @@ describe("configValue lifecycle events", () => {
925
909
  { key: "integration:config:api-secret", value: "rotated-secret-987" },
926
910
  systemAdmin,
927
911
  );
928
- const events = await db
929
- .select()
930
- .from(eventsTable)
931
- .where(eq(eventsTable.aggregateType, "config-value"));
912
+ const events = await selectMany(db, eventsTable, { aggregateType: "config-value" });
932
913
  const created = events.filter(
933
914
  (e) =>
934
915
  e.type === "config-value.created" &&
@@ -0,0 +1,47 @@
1
+ import { asRawClient } from "@cosmicdrift/kumiko-framework/bun-db";
2
+ import type { DbRunner } from "@cosmicdrift/kumiko-framework/db";
3
+ import type { TenantId } from "@cosmicdrift/kumiko-framework/engine";
4
+
5
+ export type ConfigRow = {
6
+ readonly id: string;
7
+ readonly key: string;
8
+ readonly value: string | null;
9
+ readonly tenantId: TenantId;
10
+ readonly userId: string | null;
11
+ };
12
+
13
+ export async function selectConfigRowsForScope(
14
+ db: DbRunner,
15
+ systemTenantId: TenantId,
16
+ tenantId: TenantId,
17
+ userId: string,
18
+ ): Promise<readonly ConfigRow[]> {
19
+ return asRawClient(db).unsafe<ConfigRow>(
20
+ `SELECT id, key, value, tenant_id AS "tenantId", user_id AS "userId"
21
+ FROM read_config_values
22
+ WHERE (tenant_id = $1 AND user_id IS NULL)
23
+ OR (tenant_id = $2 AND user_id IS NULL)
24
+ OR (tenant_id = $2 AND user_id = $3)`,
25
+ [systemTenantId, tenantId, userId],
26
+ );
27
+ }
28
+
29
+ export async function selectConfigRowsForKeys(
30
+ db: DbRunner,
31
+ keys: readonly string[],
32
+ systemTenantId: TenantId,
33
+ tenantId: TenantId,
34
+ userId: string,
35
+ ): Promise<readonly ConfigRow[]> {
36
+ return asRawClient(db).unsafe<ConfigRow>(
37
+ `SELECT id, key, value, tenant_id AS "tenantId", user_id AS "userId"
38
+ FROM read_config_values
39
+ WHERE key = ANY($1)
40
+ AND (
41
+ (tenant_id = $2 AND user_id IS NULL)
42
+ OR (tenant_id = $3 AND user_id IS NULL)
43
+ OR (tenant_id = $3 AND user_id = $4)
44
+ )`,
45
+ [[...keys], systemTenantId, tenantId, userId],
46
+ );
47
+ }
@@ -1,3 +1,4 @@
1
+ import { describe, expect, test } from "bun:test";
1
2
  import {
2
3
  access,
3
4
  type ConfigKeyDefinition,
@@ -11,7 +12,6 @@ import {
11
12
  SYSTEM_TENANT_ID,
12
13
  type TenantId,
13
14
  } from "@cosmicdrift/kumiko-framework/engine";
14
- import { describe, expect, test } from "vitest";
15
15
  import { prepareConfigWrite, validateBounds } from "../../write-helpers";
16
16
 
17
17
  // Minimal Registry stub — only getConfigKey is exercised by prepareConfigWrite.
@@ -1,9 +1,5 @@
1
- import {
2
- type DbConnection,
3
- type EncryptionProvider,
4
- fetchOne,
5
- type TenantDb,
6
- } from "@cosmicdrift/kumiko-framework/db";
1
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
2
+ import type { DbConnection, EncryptionProvider, TenantDb } from "@cosmicdrift/kumiko-framework/db";
7
3
  import type {
8
4
  ConfigCascade,
9
5
  ConfigCascadeLevel,
@@ -15,7 +11,7 @@ import type {
15
11
  } from "@cosmicdrift/kumiko-framework/engine";
16
12
  import { SYSTEM_TENANT_ID } from "@cosmicdrift/kumiko-framework/engine";
17
13
  import { assertUnreachable, parseJsonOrThrow } from "@cosmicdrift/kumiko-framework/utils";
18
- import { and, eq, inArray, isNull, or } from "drizzle-orm";
14
+ import { selectConfigRowsForKeys, selectConfigRowsForScope } from "./db/queries/resolver";
19
15
  import { configValuesTable } from "./table";
20
16
 
21
17
  type ConfigRow = {
@@ -219,16 +215,11 @@ export function createConfigResolver(options: ConfigResolverOptions = {}): Confi
219
215
  userId: string | null,
220
216
  db: DbConnection | TenantDb,
221
217
  ): Promise<ConfigRow | null> {
222
- const userCond =
223
- userId !== null ? eq(configValuesTable.userId, userId) : isNull(configValuesTable.userId);
224
-
225
- const row = await fetchOne<ConfigRow>(
226
- db,
227
- configValuesTable,
228
- eq(configValuesTable.key, key),
229
- eq(configValuesTable.tenantId, tenantId),
230
- userCond,
231
- );
218
+ const row = await fetchOne<ConfigRow>(db, configValuesTable, {
219
+ key,
220
+ tenantId,
221
+ userId,
222
+ });
232
223
 
233
224
  return row ?? null;
234
225
  }
@@ -308,23 +299,10 @@ export function createConfigResolver(options: ConfigResolverOptions = {}): Confi
308
299
 
309
300
  async getAll(tenantId, userId, db) {
310
301
  // Only load rows relevant to this user/tenant (system + tenant + user scope)
311
- const rows = await db
312
- .select()
313
- .from(configValuesTable)
314
- .where(
315
- or(
316
- // System-level values
317
- and(eq(configValuesTable.tenantId, SYSTEM_TENANT_ID), isNull(configValuesTable.userId)),
318
- // Tenant-level values
319
- and(eq(configValuesTable.tenantId, tenantId), isNull(configValuesTable.userId)),
320
- // User-level values
321
- and(eq(configValuesTable.tenantId, tenantId), eq(configValuesTable.userId, userId)),
322
- ),
323
- );
302
+ const rows = await selectConfigRowsForScope(db, SYSTEM_TENANT_ID, tenantId, userId);
324
303
 
325
304
  const result = new Map<string, ConfigRow>();
326
- for (const row of rows) {
327
- const r = row as ConfigRow; // @cast-boundary db-row
305
+ for (const r of rows) {
328
306
  // Higher specificity wins: user > tenant > system. Under the ES
329
307
  // schema system rows carry SYSTEM_TENANT_ID instead of NULL, so the
330
308
  // "tenant set" check compares against the sentinel rather than null.
@@ -341,23 +319,13 @@ export function createConfigResolver(options: ConfigResolverOptions = {}): Confi
341
319
 
342
320
  async getAllWithSource(tenantId, userId, db) {
343
321
  // Load ALL potentially relevant rows (user + tenant + system)
344
- const rows = await db
345
- .select()
346
- .from(configValuesTable)
347
- .where(
348
- or(
349
- and(eq(configValuesTable.tenantId, SYSTEM_TENANT_ID), isNull(configValuesTable.userId)),
350
- and(eq(configValuesTable.tenantId, tenantId), isNull(configValuesTable.userId)),
351
- and(eq(configValuesTable.tenantId, tenantId), eq(configValuesTable.userId, userId)),
352
- ),
353
- );
322
+ const rows = await selectConfigRowsForScope(db, SYSTEM_TENANT_ID, tenantId, userId);
354
323
 
355
324
  const result = new Map<string, ConfigStoredRowWithSource>();
356
325
 
357
326
  // Group rows by key so we can determine the winner and its source
358
327
  const groups = new Map<string, ConfigRow[]>();
359
- for (const row of rows) {
360
- const r = row as ConfigRow; // @cast-boundary db-row
328
+ for (const r of rows) {
361
329
  const g = groups.get(r.key) ?? [];
362
330
  g.push(r);
363
331
  groups.set(r.key, g);
@@ -418,26 +386,10 @@ export function createConfigResolver(options: ConfigResolverOptions = {}): Confi
418
386
  // One SQL query for all keys + every scope (user-row,
419
387
  // tenant-row, system-row). The cascade-builder then matches
420
388
  // per-key from this preloaded set instead of querying again.
421
- const rows = await db
422
- .select()
423
- .from(configValuesTable)
424
- .where(
425
- and(
426
- inArray(configValuesTable.key, [...keys]),
427
- or(
428
- and(
429
- eq(configValuesTable.tenantId, SYSTEM_TENANT_ID),
430
- isNull(configValuesTable.userId),
431
- ),
432
- and(eq(configValuesTable.tenantId, tenantId), isNull(configValuesTable.userId)),
433
- and(eq(configValuesTable.tenantId, tenantId), eq(configValuesTable.userId, userId)),
434
- ),
435
- ),
436
- );
389
+ const rows = await selectConfigRowsForKeys(db, keys, SYSTEM_TENANT_ID, tenantId, userId);
437
390
 
438
391
  const grouped = new Map<string, ConfigRow[]>();
439
- for (const row of rows) {
440
- const r = row as ConfigRow; // @cast-boundary db-row
392
+ for (const r of rows) {
441
393
  const g = grouped.get(r.key) ?? [];
442
394
  g.push(r);
443
395
  grouped.set(r.key, g);
@@ -1,4 +1,4 @@
1
- import { buildDrizzleTable } from "@cosmicdrift/kumiko-framework/db";
1
+ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
2
2
  import { createEntity, createTextField } from "@cosmicdrift/kumiko-framework/engine";
3
3
 
4
4
  // Config values are event-sourced. Each (key, scope) is its own aggregate
@@ -7,13 +7,13 @@ import { createEntity, createTextField } from "@cosmicdrift/kumiko-framework/eng
7
7
  // projection in one TX. Reads stay O(1) against the projection.
8
8
  //
9
9
  // System-scope rows use SYSTEM_TENANT_ID (not null) — buildBaseColumns
10
- // (via buildDrizzleTable) forces tenant_id NOT NULL, so die pre-ES "NULL
10
+ // (via buildEntityTable) forces tenant_id NOT NULL, so die pre-ES "NULL
11
11
  // means system" convention is replaced with a fixed sentinel. Der unique
12
12
  // index über (key, tenant_id, user_id) prevent duplicate writes at the DB
13
13
  // level — deklariert via entity.indexes.
14
14
  //
15
15
  // Single-Source-of-Truth: `configValueEntity`. Die DB-Tabelle wird über
16
- // buildDrizzleTable aus der EntityDefinition abgeleitet, der unique-Index
16
+ // buildEntityTable aus der EntityDefinition abgeleitet, der unique-Index
17
17
  // ist via entity.indexes deklariert. Plural-Re-Export `configValuesTable`
18
18
  // dient handlers (`reset.write.ts` etc.) als typisierte Drizzle-Table-Ref.
19
19
  export const configValueEntity = createEntity({
@@ -32,4 +32,4 @@ export const configValueEntity = createEntity({
32
32
  ],
33
33
  });
34
34
 
35
- export const configValuesTable = buildDrizzleTable("config-value", configValueEntity);
35
+ export const configValuesTable = buildEntityTable("config-value", configValueEntity);
@@ -2,7 +2,8 @@
2
2
  // Extracted from set.write.ts so reset.write.ts + values.query.ts don't
3
3
  // have to cross-import from another handler file.
4
4
 
5
- import { type DbConnection, fetchOne, type TenantDb } from "@cosmicdrift/kumiko-framework/db";
5
+ import { fetchOne } from "@cosmicdrift/kumiko-framework/bun-db";
6
+ import type { DbConnection, TenantDb } from "@cosmicdrift/kumiko-framework/db";
6
7
  import {
7
8
  type ConfigKeyDefinition,
8
9
  type ConfigScope,
@@ -23,7 +24,6 @@ import {
23
24
  writeFailure,
24
25
  } from "@cosmicdrift/kumiko-framework/errors";
25
26
  import { assertUnreachable } from "@cosmicdrift/kumiko-framework/utils";
26
- import { eq, isNull } from "drizzle-orm";
27
27
  import { ConfigErrors } from "./constants";
28
28
  import { configValuesTable } from "./table";
29
29
 
@@ -44,15 +44,11 @@ export async function findConfigRow(
44
44
  tenantId: TenantId,
45
45
  userId: string | null,
46
46
  ): Promise<ConfigRowLookup | null> {
47
- const userCond =
48
- userId !== null ? eq(configValuesTable.userId, userId) : isNull(configValuesTable.userId);
49
- const row = await fetchOne<ConfigRowLookup>(
50
- db,
51
- configValuesTable,
52
- eq(configValuesTable.key, key),
53
- eq(configValuesTable.tenantId, tenantId),
54
- userCond,
55
- );
47
+ const row = await fetchOne<ConfigRowLookup>(db, configValuesTable, {
48
+ key,
49
+ tenantId,
50
+ userId,
51
+ });
56
52
  if (!row) return null;
57
53
  return {
58
54
  id: row.id,
@@ -10,7 +10,9 @@
10
10
  // directly) picks them up automatically. This suite is the evidence that
11
11
  // the promise holds end-to-end.
12
12
 
13
- import { buildDrizzleTable } from "@cosmicdrift/kumiko-framework/db";
13
+ import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
14
+ import { asRawClient } from "@cosmicdrift/kumiko-framework/bun-db";
15
+ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
14
16
  import {
15
17
  createEntity,
16
18
  createEntityExecutor,
@@ -26,8 +28,6 @@ import {
26
28
  TestUsers,
27
29
  unsafeCreateEntityTable,
28
30
  } from "@cosmicdrift/kumiko-framework/stack";
29
- import { sql } from "drizzle-orm";
30
- import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
31
31
  import { z } from "zod";
32
32
  import { AuditQueries } from "../../audit/constants";
33
33
  import { createAuditFeature } from "../../audit/feature";
@@ -42,7 +42,7 @@ const propertyEntity = createEntity({
42
42
  customFields: customFieldsField(),
43
43
  },
44
44
  });
45
- const propertyTable = buildDrizzleTable("property", propertyEntity);
45
+ const propertyTable = buildEntityTable("property", propertyEntity);
46
46
 
47
47
  const propertyFeature = defineFeature("property-t15a", (r) => {
48
48
  r.entity("property", propertyEntity);
@@ -92,8 +92,8 @@ afterAll(async () => {
92
92
 
93
93
  beforeEach(async () => {
94
94
  await resetEventStore(stack);
95
- await stack.db.execute(sql`DELETE FROM read_t15a_properties`);
96
- await stack.db.execute(sql`DELETE FROM read_custom_field_definitions`);
95
+ await asRawClient(stack.db).unsafe(`DELETE FROM read_t15a_properties`);
96
+ await asRawClient(stack.db).unsafe(`DELETE FROM read_custom_field_definitions`);
97
97
  });
98
98
 
99
99
  type AuditRow = {
@@ -10,7 +10,9 @@
10
10
  // Pattern follows cap-counter.integration.ts: probe-feature mit own entity,
11
11
  // wired via wireCustomFieldsFor.
12
12
 
13
- import { buildDrizzleTable } from "@cosmicdrift/kumiko-framework/db";
13
+ import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
14
+ import { asRawClient } from "@cosmicdrift/kumiko-framework/bun-db";
15
+ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
14
16
  import {
15
17
  createEntity,
16
18
  createEntityExecutor,
@@ -25,8 +27,6 @@ import {
25
27
  type TestStack,
26
28
  unsafeCreateEntityTable,
27
29
  } from "@cosmicdrift/kumiko-framework/stack";
28
- import { sql } from "drizzle-orm";
29
- import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
30
30
  import { z } from "zod";
31
31
  import { fieldDefinitionEntity } from "../entity";
32
32
  import { createCustomFieldsFeature } from "../feature";
@@ -41,7 +41,7 @@ const propertyEntity = createEntity({
41
41
  customFields: customFieldsField(),
42
42
  },
43
43
  });
44
- const propertyTable = buildDrizzleTable("property", propertyEntity);
44
+ const propertyTable = buildEntityTable("property", propertyEntity);
45
45
 
46
46
  const propertyFeature = defineFeature("property-test", (r) => {
47
47
  r.entity("property", propertyEntity);
@@ -91,9 +91,9 @@ afterAll(async () => {
91
91
 
92
92
  beforeEach(async () => {
93
93
  // Clean slate per test — event-log + entity-rows.
94
- await stack.db.execute(sql`DELETE FROM kumiko_events`);
95
- await stack.db.execute(sql`DELETE FROM read_t1_properties`);
96
- await stack.db.execute(sql`DELETE FROM read_custom_field_definitions`);
94
+ await asRawClient(stack.db).unsafe(`DELETE FROM kumiko_events`);
95
+ await asRawClient(stack.db).unsafe(`DELETE FROM read_t1_properties`);
96
+ await asRawClient(stack.db).unsafe(`DELETE FROM read_custom_field_definitions`);
97
97
  });
98
98
 
99
99
  // --- Helpers ---
@@ -1,4 +1,4 @@
1
- import { describe, expect, test } from "vitest";
1
+ import { describe, expect, test } from "bun:test";
2
2
  import { fieldDefinitionAggregateId } from "../aggregate-id";
3
3
  import { SUPPORTED_FIELD_TYPES } from "../constants";
4
4
  import { createCustomFieldsFeature } from "../feature";
@@ -9,7 +9,9 @@
9
9
  // exactly as in B2 (no extra gate) — the existing roundtrip-test suite
10
10
  // stays green, and we add an explicit covers-the-no-op-path test here too.
11
11
 
12
- import { buildDrizzleTable } from "@cosmicdrift/kumiko-framework/db";
12
+ import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
13
+ import { asRawClient } from "@cosmicdrift/kumiko-framework/bun-db";
14
+ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
13
15
  import {
14
16
  createEntity,
15
17
  createEntityExecutor,
@@ -24,8 +26,6 @@ import {
24
26
  type TestStack,
25
27
  unsafeCreateEntityTable,
26
28
  } from "@cosmicdrift/kumiko-framework/stack";
27
- import { sql } from "drizzle-orm";
28
- import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
29
29
  import { z } from "zod";
30
30
  import { fieldDefinitionEntity } from "../entity";
31
31
  import { createCustomFieldsFeature } from "../feature";
@@ -38,7 +38,7 @@ const propertyEntity = createEntity({
38
38
  customFields: customFieldsField(),
39
39
  },
40
40
  });
41
- const propertyTable = buildDrizzleTable("property", propertyEntity);
41
+ const propertyTable = buildEntityTable("property", propertyEntity);
42
42
 
43
43
  const propertyFeature = defineFeature("property-t15b", (r) => {
44
44
  r.entity("property", propertyEntity);
@@ -84,8 +84,8 @@ afterAll(async () => {
84
84
 
85
85
  beforeEach(async () => {
86
86
  await resetEventStore(stack);
87
- await stack.db.execute(sql`DELETE FROM read_t15b_properties`);
88
- await stack.db.execute(sql`DELETE FROM read_custom_field_definitions`);
87
+ await asRawClient(stack.db).unsafe(`DELETE FROM read_t15b_properties`);
88
+ await asRawClient(stack.db).unsafe(`DELETE FROM read_custom_field_definitions`);
89
89
  });
90
90
 
91
91
  async function defineField(fieldKey: string, serializedField: Record<string, unknown>) {
@@ -5,7 +5,9 @@
5
5
  // rejects with `unprocessable` + reason `cap_exceeded` when the
6
6
  // tenant already has >= N definitions.
7
7
 
8
- import { buildDrizzleTable } from "@cosmicdrift/kumiko-framework/db";
8
+ import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
9
+ import { asRawClient } from "@cosmicdrift/kumiko-framework/bun-db";
10
+ import { buildEntityTable } from "@cosmicdrift/kumiko-framework/db";
9
11
  import {
10
12
  createEntity,
11
13
  createEntityExecutor,
@@ -20,8 +22,6 @@ import {
20
22
  type TestStack,
21
23
  unsafeCreateEntityTable,
22
24
  } from "@cosmicdrift/kumiko-framework/stack";
23
- import { sql } from "drizzle-orm";
24
- import { afterAll, beforeAll, beforeEach, describe, expect, test } from "vitest";
25
25
  import { z } from "zod";
26
26
  import { fieldDefinitionEntity } from "../entity";
27
27
  import { createCustomFieldsFeature } from "../feature";
@@ -34,7 +34,7 @@ const propertyEntity = createEntity({
34
34
  customFields: customFieldsField(),
35
35
  },
36
36
  });
37
- const propertyTable = buildDrizzleTable("property", propertyEntity);
37
+ const propertyTable = buildEntityTable("property", propertyEntity);
38
38
 
39
39
  const propertyFeature = defineFeature("property-t15e", (r) => {
40
40
  r.entity("property", propertyEntity);
@@ -74,8 +74,8 @@ afterAll(async () => {
74
74
 
75
75
  beforeEach(async () => {
76
76
  await resetEventStore(stack);
77
- await stack.db.execute(sql`DELETE FROM read_t15e_properties`);
78
- await stack.db.execute(sql`DELETE FROM read_custom_field_definitions`);
77
+ await asRawClient(stack.db).unsafe(`DELETE FROM read_t15e_properties`);
78
+ await asRawClient(stack.db).unsafe(`DELETE FROM read_custom_field_definitions`);
79
79
  });
80
80
 
81
81
  async function defineField(fieldKey: string) {