@burdenoff/be-sdk 2026.1015.1 → 2026.1015.2

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.
@@ -2,6 +2,80 @@ import { logger } from './chunk-RU266375.js';
2
2
  import { __name } from './chunk-XE4OXN2W.js';
3
3
  import { AsyncLocalStorage } from 'async_hooks';
4
4
 
5
+ var contextFields = [
6
+ "workspaceId",
7
+ "tenantId",
8
+ "actorId",
9
+ "actorType",
10
+ "organizationId",
11
+ "projectId",
12
+ "appId",
13
+ "onBehalfOf"
14
+ ];
15
+ function sameContext(a, b) {
16
+ return contextFields.every((field) => a[field] === b[field]);
17
+ }
18
+ __name(sameContext, "sameContext");
19
+ function bindTransactionContext(client, scope, getWorkspaceContext2) {
20
+ const delegates = /* @__PURE__ */ new WeakMap();
21
+ function bindOperation(value) {
22
+ if (!value || typeof value !== "object" || Reflect.get(value, Symbol.toStringTag) !== "PrismaPromise") return value;
23
+ const sourceContext = getWorkspaceContext2();
24
+ const captured = sourceContext ? {
25
+ ...sourceContext
26
+ } : void 0;
27
+ const restore = AsyncLocalStorage.snapshot();
28
+ return new Proxy(value, {
29
+ get(target, property, receiver) {
30
+ const original = Reflect.get(target, property, receiver);
31
+ if (typeof original !== "function" || property === "constructor") return original;
32
+ return (...args) => {
33
+ if (!scope.active) throw new Error("[WorkspaceExtension] Lazy operation belongs to a completed interactive transaction.");
34
+ if (sourceContext && captured && !sameContext(sourceContext, captured)) {
35
+ throw new Error("[WorkspaceExtension] Captured workspace/actor context changed before lazy execution.");
36
+ }
37
+ const current = getWorkspaceContext2();
38
+ if (captured && current && !sameContext(captured, current)) {
39
+ throw new Error("[WorkspaceExtension] Lazy operation cannot cross workspace/actor context.");
40
+ }
41
+ if (property === "requestTransaction") throw new Error("[WorkspaceExtension] Interactive operation cannot be rebound to another transaction.");
42
+ return restore(() => {
43
+ const result = Reflect.apply(original, target, args);
44
+ return [
45
+ "then",
46
+ "catch",
47
+ "finally"
48
+ ].includes(String(property)) ? result : bindOperation(result);
49
+ });
50
+ };
51
+ }
52
+ });
53
+ }
54
+ __name(bindOperation, "bindOperation");
55
+ function facade(target, model) {
56
+ const existing = delegates.get(target);
57
+ if (existing) return existing;
58
+ const proxy = new Proxy(target, {
59
+ get(object, property, receiver) {
60
+ const value = Reflect.get(object, property, receiver);
61
+ if (typeof value === "function" && (model || typeof property === "string" && !property.startsWith("_") && property !== "constructor")) {
62
+ return (...args) => bindOperation(Reflect.apply(value, object, args));
63
+ }
64
+ if (!model && typeof property === "string" && !property.startsWith("_") && !property.startsWith("$") && value && typeof value === "object" && typeof Reflect.get(value, "findMany") === "function") {
65
+ return facade(value, true);
66
+ }
67
+ return value;
68
+ }
69
+ });
70
+ delegates.set(target, proxy);
71
+ return proxy;
72
+ }
73
+ __name(facade, "facade");
74
+ return facade(client, false);
75
+ }
76
+ __name(bindTransactionContext, "bindTransactionContext");
77
+
78
+ // src/prisma/workspace-extension.ts
5
79
  var workspaceContextStore = new AsyncLocalStorage();
6
80
  var fallbackContext;
7
81
  function setWorkspaceContext(context) {
@@ -787,7 +861,6 @@ function addWorkspaceExtension(baseClient, config) {
787
861
  }
788
862
  }
789
863
  });
790
- if (!tagsTransactions) return withQueryHooks;
791
864
  const wrapped = withQueryHooks;
792
865
  return wrapped.$extends({
793
866
  client: {
@@ -798,7 +871,7 @@ function addWorkspaceExtension(baseClient, config) {
798
871
  }
799
872
  if (Array.isArray(input)) {
800
873
  const wsCtx = getWorkspaceContext();
801
- const statement = wsCtx?.workspaceId ? buildTransactionContextStatement(wsCtx, fullConfig) : void 0;
874
+ const statement = tagsTransactions && wsCtx?.workspaceId ? buildTransactionContextStatement(wsCtx, fullConfig) : void 0;
802
875
  if (statement) {
803
876
  const setContext = rawPrismaForCallerTransactions.$executeRawUnsafe(statement.sql, ...statement.params);
804
877
  return parent.$transaction([
@@ -807,6 +880,19 @@ function addWorkspaceExtension(baseClient, config) {
807
880
  ], options).then((results) => Array.isArray(results) ? results.slice(1) : results);
808
881
  }
809
882
  }
883
+ if (typeof input === "function") {
884
+ const callback = input;
885
+ return transactionDelegate.call(this, async (tx) => {
886
+ const scope = {
887
+ active: true
888
+ };
889
+ try {
890
+ return await callback(bindTransactionContext(tx, scope, getWorkspaceContext));
891
+ } finally {
892
+ scope.active = false;
893
+ }
894
+ }, options);
895
+ }
810
896
  return transactionDelegate.call(this, input, options);
811
897
  }
812
898
  }
@@ -815,5 +901,5 @@ function addWorkspaceExtension(baseClient, config) {
815
901
  __name(addWorkspaceExtension, "addWorkspaceExtension");
816
902
 
817
903
  export { addWorkspaceExtension, buildTransactionContextStatement, defaultWorkspaceExtensionConfig, getCallerTransaction, getWorkspaceContext, injectCreateFields, injectWhereWorkspaceId, maybeSetRlsGuc, maybeTagConnection, resetCallerTransactionStateForTests, runOperationInCallerTransaction, runOperationWithRlsGuc, setWorkspaceContext, withWorkspaceContext, withWorkspaceContextSync };
818
- //# sourceMappingURL=chunk-HMVQOZHM.js.map
819
- //# sourceMappingURL=chunk-HMVQOZHM.js.map
904
+ //# sourceMappingURL=chunk-3Z2VRCT6.js.map
905
+ //# sourceMappingURL=chunk-3Z2VRCT6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/prisma/transaction-context.ts","../src/prisma/workspace-extension.ts"],"names":["contextFields","sameContext","a","b","every","field","bindTransactionContext","client","scope","getWorkspaceContext","delegates","WeakMap","bindOperation","value","Reflect","get","Symbol","toStringTag","sourceContext","captured","undefined","restore","AsyncLocalStorage","snapshot","Proxy","target","property","receiver","original","args","active","Error","current","result","apply","includes","String","facade","model","existing","proxy","object","startsWith","set","workspaceContextStore","fallbackContext","setWorkspaceContext","context","enterWith","getStore","withWorkspaceContext","fn","run","withWorkspaceContextSync","defaultWorkspaceExtensionConfig","enabled","enableReadIsolation","enableDeleteIsolation","enableUpdateWhereIsolation","populateContextJson","populateCreatedBy","populateUpdatedBy","populateTenantId","populateOnBehalfOf","excludeModels","excludeModelsFromReadIsolation","strictMode","allowedUnguardedOperations","debug","enableApplicationNameTagging","enableRlsGucTagging","hasField","data","injectCreateFields","wsCtx","config","injected","workspaceId","tenantId","actorId","onBehalfOf","contextJson","buildContextJsonFromWorkspaceContext","injectUpdateFields","injectWhereClause","where","organizationId","projectId","appId","Object","keys","length","injectWhereWorkspaceId","ctx","stripSkipFlag","cleaned","isExcludedFromReadIsolation","enforceStrictMode","operation","opKey","taggedContexts","WeakSet","maybeTagConnection","rawPrisma","has","add","safeSvc","process","env","replace","safeWs","tag","$executeRawUnsafe","delete","rlsTaggedContexts","maybeSetRlsGuc","modelToClientProperty","charAt","toLowerCase","slice","runOperationWithRlsGuc","rootClient","clientProperty","$transaction","tx","delegate","method","runQueryWithRlsGuc","query","pendingQuery","pendingContext","sanitizeWorkspaceId","requestTransaction","getCallerTransaction","internalParams","transaction","kind","id","descriptor","buildApplicationNameTag","buildTransactionContextStatement","settings","params","push","sql","join","key","MAX_TRACKED_CALLER_TRANSACTIONS","callerTransactionStates","Map","rememberCallerTransaction","state","size","oldest","next","applyCallerTransactionContext","statement","pending","runOperationInCallerTransaction","inflight","ready","catch","resetCallerTransactionStateForTests","clear","addWorkspaceExtension","baseClient","fullConfig","logger","info","rawPrismaForContinuations","transactionDelegate","rawPrismaForCallerTransactions","tagsTransactions","dispatch","_operation","finalArgs","callerTransaction","__internalParams","rawOperation","prismaClient","rawOperationHooks","$queryRaw","$executeRaw","$queryRawUnsafe","$queryRawTyped","withQueryHooks","$extends","$allModels","create","_skipWorkspaceInjection","injectedData","injectedKeys","filter","k","createMany","dataArray","Array","isArray","map","item","createManyAndReturn","update","injectedWhere","injectedDataKeys","whereChanged","updateMany","upsert","injectedCreate","injectedUpdate","findMany","findFirst","findFirstOrThrow","findUnique","findUniqueOrThrow","count","aggregate","groupBy","deleteMany","wrapped","input","options","parent","$parent","setContext","then","results","callback","call"],"mappings":"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","file":"chunk-3Z2VRCT6.js","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { WorkspaceContext } from './workspace-extension.js';\n\ninterface TransactionScope {\n active: boolean;\n}\nconst contextFields = [\n 'workspaceId',\n 'tenantId',\n 'actorId',\n 'actorType',\n 'organizationId',\n 'projectId',\n 'appId',\n 'onBehalfOf',\n] as const;\n\nfunction sameContext(a: WorkspaceContext, b: WorkspaceContext): boolean {\n return contextFields.every((field) => a[field] === b[field]);\n}\n\n/**\n * Bun can assimilate a returned lazy thenable outside its async callback's ALS\n * scope. Bind only consumption of native PrismaPromises, never their creation:\n * the query stays cold and retains Prisma's brand/spec/continuation machinery.\n * This facade belongs to exactly one interactive callback, not the root client.\n */\nexport function bindTransactionContext<T extends object>(\n client: T,\n scope: TransactionScope,\n getWorkspaceContext: () => WorkspaceContext | undefined\n): T {\n const delegates = new WeakMap<object, object>();\n function bindOperation(value: unknown): unknown {\n if (!value || typeof value !== 'object' || Reflect.get(value, Symbol.toStringTag) !== 'PrismaPromise') return value;\n const sourceContext = getWorkspaceContext();\n const captured = sourceContext ? { ...sourceContext } : undefined;\n const restore = AsyncLocalStorage.snapshot();\n return new Proxy(value, {\n get(target, property, receiver) {\n const original = Reflect.get(target, property, receiver);\n if (typeof original !== 'function' || property === 'constructor') return original;\n return (...args: unknown[]) => {\n if (!scope.active)\n throw new Error('[WorkspaceExtension] Lazy operation belongs to a completed interactive transaction.');\n // snapshot() keeps ALS store references. Retain identity values too,\n // so mutating the original request object cannot retarget cold work.\n if (sourceContext && captured && !sameContext(sourceContext, captured)) {\n throw new Error('[WorkspaceExtension] Captured workspace/actor context changed before lazy execution.');\n }\n const current = getWorkspaceContext();\n if (captured && current && !sameContext(captured, current)) {\n throw new Error('[WorkspaceExtension] Lazy operation cannot cross workspace/actor context.');\n }\n // Interactive operations already belong to their native transaction.\n // Root batch promises are untouched; moving an itx promise into a new\n // batch must not replace that transaction or restore an old identity.\n if (property === 'requestTransaction')\n throw new Error('[WorkspaceExtension] Interactive operation cannot be rebound to another transaction.');\n return restore(() => {\n const result: unknown = Reflect.apply(original, target, args);\n // Fluent relation accessors return another cold PrismaPromise.\n // Capture that continuation too, without starting either query.\n return ['then', 'catch', 'finally'].includes(String(property)) ? result : bindOperation(result);\n });\n };\n },\n });\n }\n function facade(target: object, model: boolean): object {\n const existing = delegates.get(target);\n if (existing) return existing;\n const proxy = new Proxy(target, {\n get(object, property, receiver) {\n const value: unknown = Reflect.get(object, property, receiver);\n if (\n typeof value === 'function' &&\n (model || (typeof property === 'string' && !property.startsWith('_') && property !== 'constructor'))\n ) {\n return (...args: unknown[]) => bindOperation(Reflect.apply(value, object, args));\n }\n // Public custom client/model methods keep their native receiver; only\n // returned PrismaPromises are bound. Prisma model delegates are objects. Internal\n // metadata, symbols, fields, and the non-thenable client stay untouched.\n if (\n !model &&\n typeof property === 'string' &&\n !property.startsWith('_') &&\n !property.startsWith('$') &&\n value &&\n typeof value === 'object' &&\n typeof Reflect.get(value, 'findMany') === 'function'\n ) {\n return facade(value, true);\n }\n return value;\n },\n });\n delegates.set(target, proxy);\n return proxy;\n }\n return facade(client, false) as T;\n}\n","/**\n * Prisma Workspace Extension\n *\n * Automatically injects workspaceId into ALL Prisma operations using\n * request-scoped context from AsyncLocalStorage:\n *\n * **Write operations** (create, createMany, update, upsert):\n * - Auto-populates `workspaceId`, `tenantId`, `createdBy`, `updatedBy`, `context` JSON\n *\n * **Read operations** (findMany, findFirst, findUnique, count, aggregate, groupBy):\n * - Auto-injects `workspaceId` into the `where` clause for workspace isolation\n *\n * **Delete operations** (delete, deleteMany):\n * - Auto-injects `workspaceId` into the `where` clause to prevent cross-workspace deletion\n *\n * **Update where clause** (update, updateMany):\n * - Auto-injects `workspaceId` into the `where` clause to prevent cross-workspace updates\n *\n * **How it works:**\n * 1. The GraphQL server's buildContext extracts workspaceId from x-workspace-id header\n * 2. The workspace context store (AsyncLocalStorage) holds the current request's workspace info\n * 3. This Prisma extension intercepts ALL operations and auto-injects workspaceId\n *\n * **What gets auto-populated on writes:**\n * - `workspaceId` field (String or String?) - set from context if not explicitly provided\n * - `context` field (Json) - merged with workspace/actor info if not explicitly provided\n * - `tenantId` field (String or String?) - set from context if not explicitly provided\n * - `createdBy` / `updatedBy` fields - set from actor context if not explicitly provided\n *\n * **What gets auto-injected on reads/updates/deletes:**\n * - `workspaceId` in the `where` clause - ensures queries only access data within the workspace\n *\n * **Opt-out:**\n * - Explicitly providing `workspaceId` in the where/data will override auto-injection\n * - Pass `_skipWorkspaceInjection: true` in the query args to skip entirely\n * - Set `enableReadIsolation: false` in config to disable read-side injection only\n * - Add model names to `excludeModels` to skip specific models\n *\n * @module prisma/workspace-extension\n * @category Database\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { logger } from '../logger/index.js';\nimport type { InputJsonValue } from './context.js';\nimport { bindTransactionContext } from './transaction-context.js';\n\n// ============================================================================\n// Workspace Context Store (AsyncLocalStorage)\n// ============================================================================\n\n/**\n * Workspace context for the current request scope\n */\nexport interface WorkspaceContext {\n /** Workspace ID (from x-workspace-id header) */\n workspaceId?: string;\n /** Tenant ID (from x-tenant-id header or derived from workspace) */\n tenantId?: string;\n /** Actor ID (user/service/app performing the operation) */\n actorId?: string;\n /** Actor type (user, app, service, super_admin) */\n actorType?: string;\n /** Organization ID */\n organizationId?: string;\n /** Project ID */\n projectId?: string;\n /** App ID */\n appId?: string;\n /** On behalf of actor ID (for consent-based delegation) */\n onBehalfOf?: string;\n}\n\n/**\n * AsyncLocalStorage for workspace context\n * This is separate from the SDK's general ContextManager to allow\n * fine-grained control over workspace-specific context propagation.\n */\nconst workspaceContextStore = new AsyncLocalStorage<WorkspaceContext>();\n\n/**\n * Fallback context for environments where AsyncLocalStorage.enterWith()\n * doesn't propagate across async boundaries (e.g., Bun + GraphQL Yoga).\n *\n * IMPORTANT: This is NOT request-isolated — it's a module-level singleton.\n * It works for single-request-at-a-time scenarios but could race under\n * concurrent requests. The ALS is the primary mechanism; this is a fallback.\n */\nlet fallbackContext: WorkspaceContext | undefined;\n\n/**\n * Set workspace context for the current async scope.\n * Call this in your GraphQL context builder or middleware.\n *\n * Uses AsyncLocalStorage.enterWith() as the primary mechanism,\n * with a module-level fallback for runtimes where enterWith()\n * doesn't propagate through all async chains (e.g., Bun).\n *\n * @param context - The workspace context for this request\n *\n * @example\n * ```typescript\n * // In your server's buildContext:\n * import { setWorkspaceContext } from '@burdenoff/be-sdk/prisma';\n *\n * buildContext: async (defaultContext) => {\n * setWorkspaceContext({\n * workspaceId: defaultContext.workspace?.id,\n * tenantId: defaultContext.tenant?.id,\n * actorId: defaultContext.actor?.id,\n * actorType: defaultContext.actor?.type,\n * organizationId: defaultContext.organization?.id,\n * });\n * return defaultContext;\n * }\n * ```\n */\nexport function setWorkspaceContext(context: WorkspaceContext): void {\n workspaceContextStore.enterWith(context);\n fallbackContext = context;\n}\n\n/**\n * Get the current workspace context from AsyncLocalStorage.\n * Falls back to module-level context if ALS returns undefined\n * (can happen in Bun where enterWith() doesn't propagate through\n * some async chains like GraphQL Yoga's execution pipeline).\n *\n * @returns The current workspace context, or undefined if not set\n */\nexport function getWorkspaceContext(): WorkspaceContext | undefined {\n return workspaceContextStore.getStore() ?? fallbackContext;\n}\n\n/**\n * Run a function with a specific workspace context.\n * The context is isolated to this execution and its children.\n *\n * @param context - The workspace context\n * @param fn - The function to run\n * @returns The result of the function\n *\n * @example\n * ```typescript\n * const result = await withWorkspaceContext(\n * { workspaceId: 'ws-123', actorId: 'user-456' },\n * async () => {\n * // All Prisma operations in here will auto-inject workspaceId\n * return await prisma.tag.create({ data: { name: 'test' } });\n * }\n * );\n * ```\n */\nexport async function withWorkspaceContext<T>(context: WorkspaceContext, fn: () => Promise<T>): Promise<T> {\n return workspaceContextStore.run(context, fn);\n}\n\n/**\n * Run a synchronous function with a specific workspace context.\n */\nexport function withWorkspaceContextSync<T>(context: WorkspaceContext, fn: () => T): T {\n return workspaceContextStore.run(context, fn);\n}\n\n// ============================================================================\n// Extension Configuration\n// ============================================================================\n\n/**\n * Configuration for the workspace extension\n */\nexport interface WorkspaceExtensionConfig {\n /**\n * Enable automatic workspaceId injection on create/update\n * @default true\n */\n enabled?: boolean;\n\n /**\n * Enable automatic workspaceId injection on read operations\n * (findMany, findFirst, findUnique, findFirstOrThrow, findUniqueOrThrow,\n * count, aggregate, groupBy)\n *\n * When enabled, every read query automatically includes `workspaceId`\n * in the `where` clause, preventing cross-workspace data leakage.\n *\n * @default true\n */\n enableReadIsolation?: boolean;\n\n /**\n * Enable automatic workspaceId injection on delete operations\n * (delete, deleteMany)\n *\n * When enabled, every delete operation automatically includes `workspaceId`\n * in the `where` clause, preventing cross-workspace deletion.\n *\n * @default true\n */\n enableDeleteIsolation?: boolean;\n\n /**\n * Enable automatic workspaceId injection into update/updateMany `where` clauses.\n *\n * When enabled, update operations automatically include `workspaceId`\n * in the `where` clause in addition to the `data` injection,\n * preventing cross-workspace updates.\n *\n * @default true\n */\n enableUpdateWhereIsolation?: boolean;\n\n /**\n * Automatically populate the `context` JSON field with workspace/actor info\n * @default true\n */\n populateContextJson?: boolean;\n\n /**\n * Automatically populate `createdBy` field on create operations\n * @default true\n */\n populateCreatedBy?: boolean;\n\n /**\n * Automatically populate `updatedBy` field on update operations\n * @default true\n */\n populateUpdatedBy?: boolean;\n\n /**\n * Automatically populate `tenantId` field from context\n * @default false (tenantId is typically derived from workspaceId at the DB level)\n */\n populateTenantId?: boolean;\n\n /**\n * Automatically populate the `onBehalfOf` field on create operations\n * (consent-based delegation tracking — defaults to the acting actor when no\n * delegation is present).\n *\n * Unlike `populateContextJson`/`populateCreatedBy`/`populateUpdatedBy`, this\n * has no per-model opt-out other than `excludeModels` (which also disables\n * RLS GUC tagging and isolation for that model). Set to `false` for services\n * whose Prisma models don't carry an `onBehalfOf` column — otherwise every\n * create on those models throws `Unknown argument onBehalfOf` from Prisma's\n * client-side validation.\n *\n * @default true\n */\n populateOnBehalfOf?: boolean;\n\n /**\n * Models to exclude from auto-injection (both reads and writes).\n * Use this for models that intentionally don't have workspaceId.\n *\n * Common exclusions: system tables, infra tables, global reference data.\n *\n * @default []\n */\n excludeModels?: string[];\n\n /**\n * Models to exclude from read isolation only.\n * These models will still get write-side injection (workspaceId on create)\n * but reads will NOT have workspaceId auto-injected into `where`.\n *\n * Use this for child/join tables where workspace scoping is inherited\n * through parent relations, or for models queried by ID that don't\n * have a workspaceId column.\n *\n * @default []\n */\n excludeModelsFromReadIsolation?: string[];\n\n /**\n * When true, throws an error if workspaceId is missing from context\n * for any non-excluded model operation. This prevents silent\n * workspace-unscoped queries that could leak data across workspaces.\n *\n * When false, operations without workspace context proceed without\n * workspaceId injection (legacy behavior).\n *\n * @default true\n */\n strictMode?: boolean;\n\n /**\n * Operations that are allowed without workspace context even in strict mode.\n * Use `Model.operation` format (e.g., `['Workspace.create', 'RevokedToken.findMany']`).\n *\n * Valid operation names: create, createMany, createManyAndReturn, update, updateMany,\n * upsert, findMany, findFirst, findFirstOrThrow, findUnique, findUniqueOrThrow,\n * count, aggregate, groupBy, delete, deleteMany.\n *\n * @default []\n */\n allowedUnguardedOperations?: string[];\n\n /**\n * Log injection events (useful for debugging)\n * @default false\n */\n debug?: boolean;\n\n /**\n * Tag the PostgreSQL connection with workspace attribution for pg_stat_activity visibility.\n *\n * When enabled, the first DB operation per workspace context sets:\n * `application_name = 'svc=<SERVICE_NAME>;ws=<workspaceId>'`\n *\n * This makes workspace-level query attribution visible in pg_stat_activity,\n * pg_locks, auto_explain, and monitoring tools without any schema changes.\n * Subsequent operations in the same request are deduplicated via WeakSet,\n * costing ~0 overhead after the first round-trip per request context.\n *\n * NOTE: This is a session-level SET so attribution may drift across ops\n * that reuse the same pooled connection from different requests. Use for\n * aggregate observability, not per-query forensics.\n *\n * @default false\n */\n enableApplicationNameTagging?: boolean;\n\n /**\n * Set the `app.workspace_id` GUC for Row Level Security enforcement.\n *\n * When enabled, every workspace-scoped operation runs with\n * `SET LOCAL app.workspace_id = '<workspaceId>'`\n * in effect (see \"Transactions\" below for how that is scoped).\n *\n * RLS policies using `current_setting('app.workspace_id', true)` then filter\n * rows by workspace, providing a defense-in-depth backstop to the application-\n * layer workspaceId injection in the WHERE clause.\n *\n * Pair with migrations that run per table:\n * `ALTER TABLE t ENABLE ROW LEVEL SECURITY;`\n * `CREATE POLICY ws_isolation ON t\n * USING (workspace_id = current_setting('app.workspace_id', true))\n * WITH CHECK (workspace_id = current_setting('app.workspace_id', true));`\n *\n * Fail-closed semantics: if the GUC is unset (NULL from missing_ok=true),\n * `workspace_id = NULL` is always false, so RLS returns no rows — leaking\n * nothing rather than everything.\n *\n * Transactions: a standalone operation runs in its own short transaction\n * (`SET LOCAL` + the operation). An operation on the `tx` client inside a\n * caller's `$transaction(async (tx) => …)`, including raw SQL, runs in the\n * caller's transaction, after one `set_config(..., true)` per transaction and\n * workspace, so it is atomic with the rest of that transaction and its row\n * locks are held until commit. `$transaction([...])` batches get the same\n * statement prepended (BOFF-8874).\n *\n * @default false\n */\n enableRlsGucTagging?: boolean;\n}\n\n/**\n * Default configuration. Exported so consumers/tests can spread over the\n * real defaults (`{ ...defaultWorkspaceExtensionConfig, populateOnBehalfOf: false }`)\n * instead of re-declaring every field.\n */\nexport const defaultWorkspaceExtensionConfig: Required<WorkspaceExtensionConfig> = {\n enabled: true,\n enableReadIsolation: true,\n enableDeleteIsolation: true,\n enableUpdateWhereIsolation: true,\n populateContextJson: true,\n populateCreatedBy: true,\n populateUpdatedBy: true,\n populateTenantId: false,\n populateOnBehalfOf: true,\n excludeModels: [],\n excludeModelsFromReadIsolation: [],\n strictMode: true,\n allowedUnguardedOperations: [],\n debug: false,\n enableApplicationNameTagging: false,\n enableRlsGucTagging: false,\n};\n\n// ============================================================================\n// Data Injection Helpers\n// ============================================================================\n\n/**\n * Check if a field exists in the data object (including being set to null/undefined explicitly)\n */\nfunction hasField(data: Record<string, unknown>, field: string): boolean {\n return field in data;\n}\n\n/**\n * Inject workspace-related fields into create data.\n *\n * Exported (alongside `injectWhereWorkspaceId`) so consumers can unit-test\n * exactly what a given `WorkspaceExtensionConfig` injects for their own\n * Prisma schema — in particular, to verify `populateOnBehalfOf: false` /\n * `populateContextJson: false` actually suppress `onBehalfOf`/`context`\n * before wiring the extension against models that don't have those columns.\n */\nexport function injectCreateFields(\n data: Record<string, unknown>,\n wsCtx: WorkspaceContext,\n config: Required<WorkspaceExtensionConfig>\n): Record<string, unknown> {\n const injected = { ...data };\n\n // Inject workspaceId if not already provided\n if (wsCtx.workspaceId && !hasField(injected, 'workspaceId')) {\n injected['workspaceId'] = wsCtx.workspaceId;\n }\n\n // Inject tenantId if configured and not already provided\n if (config.populateTenantId && wsCtx.tenantId && !hasField(injected, 'tenantId')) {\n injected['tenantId'] = wsCtx.tenantId;\n }\n\n // Inject createdBy if configured and not already provided\n if (config.populateCreatedBy && wsCtx.actorId && !hasField(injected, 'createdBy')) {\n injected['createdBy'] = wsCtx.actorId;\n }\n\n // Inject updatedBy on create as well (initial value)\n if (config.populateUpdatedBy && wsCtx.actorId && !hasField(injected, 'updatedBy')) {\n injected['updatedBy'] = wsCtx.actorId;\n }\n\n // Inject onBehalfOf (for consent-based delegation tracking)\n // If onBehalfOf is in context (from consent), use it; otherwise defaults to actorId (self-action)\n if (config.populateOnBehalfOf && wsCtx.onBehalfOf && !hasField(injected, 'onBehalfOf')) {\n injected['onBehalfOf'] = wsCtx.onBehalfOf;\n } else if (config.populateOnBehalfOf && wsCtx.actorId && !hasField(injected, 'onBehalfOf')) {\n // Default to actorId if no delegation (self-action)\n injected['onBehalfOf'] = wsCtx.actorId;\n }\n\n // Populate context JSON field\n if (config.populateContextJson && !hasField(injected, 'context')) {\n const contextJson = buildContextJsonFromWorkspaceContext(wsCtx);\n if (contextJson) {\n injected['context'] = contextJson;\n }\n }\n\n return injected;\n}\n\n/**\n * Inject workspace-related fields into update data\n */\nfunction injectUpdateFields(\n data: Record<string, unknown>,\n wsCtx: WorkspaceContext,\n config: Required<WorkspaceExtensionConfig>\n): Record<string, unknown> {\n const injected = { ...data };\n\n // Inject updatedBy if configured and not already provided\n if (config.populateUpdatedBy && wsCtx.actorId && !hasField(injected, 'updatedBy')) {\n injected['updatedBy'] = wsCtx.actorId;\n }\n\n // Note: We intentionally do NOT auto-inject workspaceId on updates\n // because updates target existing records (workspaceId is immutable after creation)\n // and changing it would be a data integrity issue.\n\n return injected;\n}\n\n/**\n * Inject workspaceId into a where clause.\n * Only injects if workspaceId is available in context and not already present in where.\n *\n * For operations that may not have a where clause (e.g., findMany without filters),\n * creates a new where object with just workspaceId.\n */\nfunction injectWhereClause(\n where: Record<string, unknown> | undefined,\n wsCtx: WorkspaceContext\n): Record<string, unknown> | undefined {\n if (!wsCtx.workspaceId) return where;\n\n if (!where) {\n // No where clause exists, create one with just workspaceId\n return { workspaceId: wsCtx.workspaceId };\n }\n\n // Only inject if not already present\n if (!hasField(where, 'workspaceId')) {\n return { ...where, workspaceId: wsCtx.workspaceId };\n }\n\n return where;\n}\n\n/**\n * Build context JSON from workspace context\n */\nfunction buildContextJsonFromWorkspaceContext(wsCtx: WorkspaceContext): InputJsonValue | undefined {\n const context: Record<string, string> = {};\n\n if (wsCtx.workspaceId) context['workspaceId'] = wsCtx.workspaceId;\n if (wsCtx.actorId) context['userId'] = wsCtx.actorId;\n if (wsCtx.organizationId) context['organizationId'] = wsCtx.organizationId;\n if (wsCtx.projectId) context['projectId'] = wsCtx.projectId;\n if (wsCtx.appId) context['appId'] = wsCtx.appId;\n\n return Object.keys(context).length > 0 ? context : undefined;\n}\n\n/**\n * Inject workspaceId into where clause for read/update/delete operations.\n * This is a utility function exported for services that want to manually\n * add workspace scoping to their queries.\n *\n * @param where - The existing where clause\n * @param wsCtx - The workspace context (or auto-detected from AsyncLocalStorage)\n * @returns The where clause with workspaceId injected if not already present\n *\n * @example\n * ```typescript\n * import { injectWhereWorkspaceId, getWorkspaceContext } from '@burdenoff/be-sdk/prisma';\n *\n * const wsCtx = getWorkspaceContext();\n * const where = injectWhereWorkspaceId({ status: 'ACTIVE' }, wsCtx);\n * // Result: { status: 'ACTIVE', workspaceId: 'ws-123' }\n * ```\n */\nexport function injectWhereWorkspaceId(\n where: Record<string, unknown> | undefined,\n wsCtx?: WorkspaceContext\n): Record<string, unknown> | undefined {\n const ctx = wsCtx ?? getWorkspaceContext();\n if (!where || !ctx?.workspaceId) return where;\n\n // Only inject if not already present\n if (!hasField(where, 'workspaceId')) {\n return { ...where, workspaceId: ctx.workspaceId };\n }\n\n return where;\n}\n\n/**\n * Remove the _skipWorkspaceInjection flag from args before passing to Prisma.\n * Using a dedicated function avoids ESLint unused-variable warnings from destructuring.\n */\nfunction stripSkipFlag<T extends Record<string, unknown>>(args: T): Omit<T, '_skipWorkspaceInjection'> {\n const cleaned = { ...args };\n delete (cleaned as Record<string, unknown>)['_skipWorkspaceInjection'];\n return cleaned;\n}\n\n/**\n * Check if a model should be excluded from read isolation.\n * A model is excluded if it's in excludeModels OR excludeModelsFromReadIsolation.\n */\nfunction isExcludedFromReadIsolation(model: string, config: Required<WorkspaceExtensionConfig>): boolean {\n return config.excludeModels.includes(model) || config.excludeModelsFromReadIsolation.includes(model);\n}\n\n// ============================================================================\n// Strict Mode Enforcement\n// ============================================================================\n\n/**\n * Enforce strict mode: throw if workspace context is missing and the operation\n * is not explicitly allowed to run without it.\n *\n * @returns true if the operation should proceed without workspace injection (non-strict or allowed)\n * @throws Error if strict mode is enabled and the operation is not allowed\n */\nfunction enforceStrictMode(\n model: string,\n operation: string,\n wsCtx: WorkspaceContext | undefined,\n config: Required<WorkspaceExtensionConfig>\n): void {\n // If workspace context has a workspaceId, nothing to enforce\n if (wsCtx?.workspaceId) return;\n\n // If strict mode is off, allow silently\n if (!config.strictMode) return;\n\n // Check if this specific operation is allowed without workspace context\n const opKey = `${model}.${operation}`;\n if (config.allowedUnguardedOperations.includes(opKey)) return;\n\n // Strict mode violation — throw\n throw new Error(\n `[WorkspaceExtension] Workspace context required for ${model}.${operation}. ` +\n `No workspaceId found in request context. To bypass, either: ` +\n `(1) add \"${model}\" to excludeModels, ` +\n `(2) add \"${opKey}\" to allowedUnguardedOperations, or ` +\n `(3) pass _skipWorkspaceInjection: true in the query args.`\n );\n}\n\n// ============================================================================\n// Prisma Extension\n// ============================================================================\n\n/**\n * Standard args shape for operations with a `where` clause\n */\ninterface WhereArgs {\n where?: Record<string, unknown>;\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n}\n\n/**\n * Standard handler params from Prisma $extends\n */\ninterface ExtensionHandlerParams<TArgs> {\n model: string;\n args: TArgs;\n query: (args: unknown) => Promise<unknown>;\n /** Prisma-internal request params; `transaction` identifies a caller transaction. */\n __internalParams?: PrismaQueryInternalParams;\n}\n\n/** Handler params for top-level raw operations (`$queryRaw`, `$executeRaw`, …). */\ninterface RawOperationHandlerParams {\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n __internalParams?: PrismaQueryInternalParams;\n}\n\n/** Client surface the `$transaction` wrapper delegates to (the client one layer down). */\ntype TransactionDelegate = {\n $transaction: (input: unknown, options?: unknown) => Promise<unknown>;\n};\n\n/**\n * Add workspace extension to a Prisma client.\n *\n * This extension provides comprehensive workspace isolation by automatically\n * injecting workspaceId into ALL Prisma operations:\n *\n * **Writes**: Auto-populates workspaceId, tenantId, createdBy, updatedBy, context JSON\n * **Reads**: Auto-injects workspaceId into where clause (findMany, findFirst, etc.)\n * **Updates**: Auto-injects workspaceId into where clause + updatedBy into data\n * **Deletes**: Auto-injects workspaceId into where clause\n *\n * **Chain order matters**: Apply this extension AFTER the graph extension\n * (handled automatically by createDatabaseClient).\n *\n * @param baseClient - The Prisma client to extend\n * @param config - Extension configuration\n * @returns Extended Prisma client with workspace auto-injection\n *\n * @example\n * ```typescript\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { addWorkspaceExtension } from '@burdenoff/be-sdk/prisma';\n *\n * const baseClient = new PrismaClient({ adapter });\n * const client = addWorkspaceExtension(baseClient, {\n * populateContextJson: true,\n * populateCreatedBy: true,\n * enableReadIsolation: true,\n * debug: process.env.NODE_ENV === 'development',\n * excludeModels: ['CircuitBreakerState', 'SchedulerState'],\n * excludeModelsFromReadIsolation: ['Permission', 'RbacResourceType'],\n * });\n * ```\n */\n// ============================================================================\n// Connection Tagging (Phase 0.2)\n// ============================================================================\n\n/** Minimal Prisma raw-exec surface needed for SET application_name */\ntype RawPrismaForTagging = {\n $executeRawUnsafe: (query: string, ...values: unknown[]) => Promise<number>;\n};\n\n/**\n * WeakSet of contexts that have already had the connection tagged this request.\n * WorkspaceContext objects live only for the duration of a request, so entries\n * are automatically GC'd when the context goes out of scope — no manual cleanup.\n */\nconst taggedContexts = new WeakSet<WorkspaceContext>();\n\n/**\n * Tag the current Postgres connection with workspace attribution (once per context).\n * Sets `application_name = 'svc=<name>;ws=<workspaceId>'` at the session level.\n * Non-fatal: tagging failures are swallowed so the main operation still proceeds.\n *\n * @internal Exported for unit testing only — do not call from product code.\n */\nexport async function maybeTagConnection(rawPrisma: RawPrismaForTagging, wsCtx: WorkspaceContext): Promise<void> {\n if (taggedContexts.has(wsCtx)) return;\n taggedContexts.add(wsCtx);\n // Strip non-safe chars; workspace IDs are UUIDs/CUIDs, service names are kebab-case\n const safeSvc = (process.env['SERVICE_NAME'] ?? 'svc').replace(/[^a-zA-Z0-9\\-_]/g, '');\n const safeWs = (wsCtx.workspaceId ?? '').replace(/[^a-zA-Z0-9\\-_]/g, '');\n const tag = `svc=${safeSvc};ws=${safeWs}`;\n try {\n await rawPrisma.$executeRawUnsafe(`SET application_name = '${tag}'`);\n } catch {\n // Retry on the next operation if this one failed\n taggedContexts.delete(wsCtx);\n }\n}\n\n// ============================================================================\n// RLS GUC Tagging (Phase 3)\n// ============================================================================\n\n/**\n * WeakSet of contexts that have already had the RLS GUC set this request.\n */\nconst rlsTaggedContexts = new WeakSet<WorkspaceContext>();\n\n/**\n * Set `app.workspace_id` GUC for RLS enforcement (once per context, session-level).\n *\n * When set, RLS policies using `current_setting('app.workspace_id', true)` filter\n * rows to the current workspace. Non-fatal: failures are swallowed and retried on\n * the next operation via WeakSet entry removal.\n *\n * NOT used by the extension's operation handlers below (see\n * `runOperationWithRlsGuc`) — session-level `SET` is unsafe once traffic is routed\n * through PgBouncer in transaction-pooling mode (see that function's doc comment\n * for the full incident writeup, BOFF-5488). Kept as a standalone export, still\n * unit tested, for any caller that genuinely runs on an unpooled/session-pooled\n * connection where session-level `SET` is sufficient.\n *\n * @internal Exported for unit testing only — do not call from product code.\n */\nexport async function maybeSetRlsGuc(rawPrisma: RawPrismaForTagging, wsCtx: WorkspaceContext): Promise<void> {\n if (rlsTaggedContexts.has(wsCtx)) return;\n rlsTaggedContexts.add(wsCtx);\n // Allow alphanumeric, hyphens, underscores — CUID/UUID safe, prevents SQL injection\n const safeWs = (wsCtx.workspaceId ?? '').replace(/[^a-zA-Z0-9\\-_]/g, '');\n try {\n await rawPrisma.$executeRawUnsafe(`SET app.workspace_id = '${safeWs}'`);\n } catch {\n // Retry on the next operation if this one failed\n rlsTaggedContexts.delete(wsCtx);\n }\n}\n\n/**\n * A Prisma interactive-transaction client (`tx` inside `$transaction(async (tx) =>\n * …)`), typed with just enough surface for `runOperationWithRlsGuc`: raw SQL\n * execution, plus one delegate per model keyed by its Prisma Client property name\n * (e.g. `customer`, `driver`). The index signature is `unknown` (not a concrete\n * delegate shape) because this helper is generic across every model in the schema\n * — callers narrow and verify the specific delegate/method they need at runtime.\n */\ntype PrismaTxForRlsGuc = {\n $executeRawUnsafe: (query: string, ...values: unknown[]) => Promise<number>;\n [modelClientProperty: string]: unknown;\n};\n\n/** Minimal Prisma client surface needed to open an interactive transaction. */\ntype RawPrismaForRlsTransaction = {\n $transaction: <TResult>(fn: (tx: PrismaTxForRlsGuc) => Promise<TResult>) => Promise<TResult>;\n};\n\n/**\n * Prisma DMMF model name (e.g. `Customer`) -> Prisma Client delegate property\n * (e.g. `customer`). Matches Prisma's own client-generation rule: lower-case the\n * first character, leave the rest untouched.\n */\nfunction modelToClientProperty(model: string): string {\n return model.length > 0 ? model.charAt(0).toLowerCase() + model.slice(1) : model;\n}\n\n/**\n * Run a single Prisma operation with `app.workspace_id` set as a\n * **transaction-scoped** (`SET LOCAL`) GUC immediately ahead of it, so Postgres\n * RLS policies using `current_setting('app.workspace_id', true)` see the right\n * value for both the `USING` (read) and `WITH CHECK` (write) clauses.\n *\n * Session-level `SET` (`maybeSetRlsGuc` above, the original Phase 3\n * implementation) is NOT safe once traffic goes through PgBouncer in\n * **transaction pooling mode** — the mode configured on all four\n * `boff-pg-{global,wspace}-{alpha,prod}-cin` servers' built-in PgBouncer (see\n * infra-specs/current-architecture/02-database-postgres-age.md). PgBouncer hands\n * the physical backend connection back to the pool after every standalone\n * statement/implicit transaction, so a `SET` executed by one statement is not\n * guaranteed visible to the very next one, even over what looks like the same\n * logical client connection.\n *\n * This was exactly BOFF-5488: `wspace-movethewheels-svc`'s RLS Phase 3b (FORCE\n * ROW LEVEL SECURITY + a non-owner runtime role, `wspace_movethewheels_app`,\n * pointed at the pooled `:6432` connection) made the `ws_isolation` policy bind\n * for real, but the session-level `SET` from `maybeSetRlsGuc` was landing on a\n * different pooled backend connection than the write that followed it — so every\n * write failed `WITH CHECK` (`new row violates row-level security policy`) and\n * every read matched zero rows.\n *\n * A Prisma **interactive transaction** (`$transaction(async (tx) => …)`) pins one\n * physical connection for the callback's full duration — PgBouncer sees a single\n * unbroken `BEGIN … COMMIT` and cannot reassign the backend mid-transaction — so\n * `SET LOCAL` inside it is guaranteed visible to the operation issued right after\n * it in the same callback. Safe under transaction-mode pooling, session-mode\n * pooling, and with no pooler in front of Postgres at all. The extra round trip\n * (one interactive transaction instead of one direct call) only applies to\n * services that opt into `enableRlsGucTagging` — off by default.\n *\n * @internal Legacy exported helper retained for compatibility and its historical\n * tests. It reissues a model call and cannot preserve surrounding query hooks;\n * addWorkspaceExtension uses the continuation-based route below instead. Do not\n * call this helper from product code.\n */\nexport async function runOperationWithRlsGuc<TResult>(\n rootClient: RawPrismaForRlsTransaction,\n wsCtx: WorkspaceContext,\n model: string,\n operation: string,\n args: unknown\n): Promise<TResult> {\n const safeWs = (wsCtx.workspaceId ?? '').replace(/[^a-zA-Z0-9\\-_]/g, '');\n const clientProperty = modelToClientProperty(model);\n return rootClient.$transaction(async (tx) => {\n await tx.$executeRawUnsafe(`SET LOCAL app.workspace_id = '${safeWs}'`);\n // `tx[clientProperty]` is typed `unknown` (see PrismaTxForRlsGuc) because this\n // helper is generic across every model; narrow to the minimal callable shape\n // needed and verify at runtime before invoking rather than trusting a cast.\n const delegate = tx[clientProperty] as Record<string, (opArgs: unknown) => Promise<TResult>> | undefined;\n const method = delegate?.[operation];\n if (typeof method !== 'function') {\n throw new Error(\n `[WorkspaceExtension] Unable to resolve ${model}.${operation} (client property \"${clientProperty}\") ` +\n 'on the interactive-transaction client for RLS GUC tagging.'\n );\n }\n return method(args);\n });\n}\n\n/** Minimal batch surface; both operations must stay lazy until Prisma binds them. */\ntype RawPrismaForRlsContinuation = {\n $executeRawUnsafe: (sql: string, ...values: unknown[]) => PendingRawStatement;\n $transaction: <TResult>(input: [PendingRawStatement, Promise<TResult>]) => Promise<[unknown, TResult]>;\n};\n\n/**\n * Keep the original query continuation, including later query extensions, inside\n * the GUC-tagged transaction. Reissuing a model call on the root client would\n * skip later hooks, or execute an earlier hook twice (BOFF-8874).\n */\nasync function runQueryWithRlsGuc<TResult>(\n rootClient: RawPrismaForRlsContinuation,\n wsCtx: WorkspaceContext,\n query: () => Promise<TResult>\n): Promise<TResult> {\n // Prisma types this as Promise, but its extension callback returns a lazy\n // PrismaPromise. Require the binding capability instead of falling back to an\n // independent model call or executing the query outside the transaction.\n const pendingQuery = query() as Promise<TResult> & { requestTransaction?: unknown };\n const pendingContext = rootClient.$executeRawUnsafe(\n \"SELECT set_config('app.workspace_id', $1, true), \" +\n \"set_config('statement_timeout', CASE \" +\n \"WHEN current_setting('statement_timeout')::interval > interval '0' \" +\n \"AND current_setting('statement_timeout')::interval < interval '5 seconds' \" +\n \"THEN current_setting('statement_timeout') ELSE '5000ms' END, true)\",\n sanitizeWorkspaceId(wsCtx.workspaceId)\n );\n if (\n typeof pendingQuery.requestTransaction !== 'function' ||\n typeof pendingContext.requestTransaction !== 'function'\n ) {\n throw new Error(\n '[WorkspaceExtension] RLS query continuation requires transaction-bindable PrismaPromises; ' +\n 'refusing the unsupported Prisma integration (BOFF-8874).'\n );\n }\n const [, result] = await rootClient.$transaction([pendingContext, pendingQuery]);\n return result;\n}\n\n// ============================================================================\n// Caller transactions (BOFF-8874)\n// ============================================================================\n//\n// `runOperationWithRlsGuc` above opens its OWN interactive transaction per\n// operation. That is right for a standalone call, but wrong when the operation is\n// issued on the `tx` client inside a caller's `prisma.$transaction(...)`: the\n// operation would commit on another connection, so the caller's transaction\n// would not be atomic and its `SELECT … FOR UPDATE` fences would run without the\n// GUC (matching no rows under FORCE RLS, so locking nothing).\n//\n// Inside a caller transaction the extension now runs the context statement\n// (`set_config(..., is_local => true)`, identical to `SET LOCAL`) on the caller's\n// transaction itself, once per transaction and workspace, and then executes the\n// operation in place. Batch transactions (`$transaction([...])`) get the same\n// statement prepended to the batch by the client-level `$transaction` wrapper in\n// `addWorkspaceExtension`. Outside any transaction nothing changes.\n\n/**\n * Prisma passes the transaction an operation belongs to on the query-extension\n * callback's `__internalParams.transaction`: `{ kind: 'itx', id, payload }` for an\n * interactive transaction, `{ kind: 'batch', … }` for `$transaction([...])`, and\n * nothing for a standalone call. The `live-pg` contract test pins this down\n * against the installed Prisma version.\n */\nexport interface PrismaQueryInternalParams {\n transaction?: unknown;\n}\n\n/** The caller transaction an operation runs in, if any. */\nexport type CallerTransaction = { kind: 'itx'; id: string; descriptor: object } | { kind: 'batch' };\n\n/**\n * Classify the transaction an extension callback is running in.\n *\n * Throws on a transaction descriptor this version does not understand rather\n * than guessing: running such an operation down the standalone path would\n * silently break the caller's atomicity again.\n *\n * @internal Exported for unit testing only — do not call from product code.\n */\nexport function getCallerTransaction(\n internalParams: PrismaQueryInternalParams | undefined\n): CallerTransaction | undefined {\n const transaction = internalParams?.transaction;\n if (transaction === undefined || transaction === null) return undefined;\n if (typeof transaction === 'object') {\n const { kind, id } = transaction as { kind?: unknown; id?: unknown };\n if (kind === 'itx' && typeof id === 'string' && id.length > 0) {\n return { kind: 'itx', id, descriptor: transaction };\n }\n if (kind === 'batch') return { kind: 'batch' };\n }\n throw new Error(\n '[WorkspaceExtension] Unrecognised Prisma transaction descriptor on __internalParams.transaction; ' +\n 'refusing to run the operation outside the caller transaction. This Prisma version is not supported ' +\n 'by the be-sdk RLS transaction integration (BOFF-8874).'\n );\n}\n\n/** Same sanitisation as the standalone path: CUID/UUID-safe, prevents SQL injection. */\nfunction sanitizeWorkspaceId(workspaceId: string | undefined): string {\n return (workspaceId ?? '').replace(/[^a-zA-Z0-9\\-_]/g, '');\n}\n\n/** Same tag `maybeTagConnection` sets: `svc=<SERVICE_NAME>;ws=<workspaceId>`. */\nfunction buildApplicationNameTag(wsCtx: WorkspaceContext): string {\n const safeSvc = (process.env['SERVICE_NAME'] ?? 'svc').replace(/[^a-zA-Z0-9\\-_]/g, '');\n return `svc=${safeSvc};ws=${sanitizeWorkspaceId(wsCtx.workspaceId)}`;\n}\n\n/** A single parameterised statement that sets the transaction-local context. */\nexport interface TransactionContextStatement {\n sql: string;\n params: string[];\n /** Identifies the values set, so a transaction only re-runs it when they change. */\n key: string;\n}\n\n/**\n * Build the transaction-local context statement for the enabled tagging modes,\n * or `undefined` when neither RLS GUC nor application_name tagging is on.\n * `set_config(name, value, true)` is exactly `SET LOCAL name = value`.\n *\n * @internal Exported for unit testing only — do not call from product code.\n */\nexport function buildTransactionContextStatement(\n wsCtx: WorkspaceContext,\n config: Pick<Required<WorkspaceExtensionConfig>, 'enableRlsGucTagging' | 'enableApplicationNameTagging'>\n): TransactionContextStatement | undefined {\n const settings: string[] = [];\n const params: string[] = [];\n if (config.enableRlsGucTagging) {\n params.push(sanitizeWorkspaceId(wsCtx.workspaceId));\n settings.push(`set_config('app.workspace_id', $${params.length}, true)`);\n }\n if (config.enableApplicationNameTagging) {\n params.push(buildApplicationNameTag(wsCtx));\n settings.push(`set_config('application_name', $${params.length}, true)`);\n }\n if (settings.length === 0) return undefined;\n return { sql: `SELECT ${settings.join(', ')}`, params, key: params.join('\\u0000') };\n}\n\n/**\n * A raw Prisma statement before it runs. Prisma's lazy `PrismaPromise` exposes\n * `requestTransaction(descriptor)`, which is how `$transaction` binds statements to\n * a transaction; the extension uses it to run the context statement on the\n * caller's transaction instead of a pooled connection of its own.\n */\ntype PendingRawStatement = PromiseLike<number> & {\n requestTransaction?: (transaction: object) => PromiseLike<unknown>;\n};\n\n/** Unextended client surface for issuing the context statement. */\nexport type RawPrismaForCallerTransaction = {\n $executeRawUnsafe: (query: string, ...values: unknown[]) => PendingRawStatement;\n};\n\ninterface CallerTransactionState {\n /** Descriptor of the (possibly nested) transaction level the context was set on. */\n descriptor: object;\n key: string;\n ready: Promise<void>;\n inflight: number;\n}\n\n/**\n * Context already applied per caller transaction id. Bounded: an evicted entry\n * only costs one repeated context statement, never correctness.\n */\nconst MAX_TRACKED_CALLER_TRANSACTIONS = 4096;\nconst callerTransactionStates = new Map<string, CallerTransactionState>();\n\nfunction rememberCallerTransaction(id: string, state: CallerTransactionState): void {\n callerTransactionStates.delete(id);\n callerTransactionStates.set(id, state);\n if (callerTransactionStates.size > MAX_TRACKED_CALLER_TRANSACTIONS) {\n const oldest = callerTransactionStates.keys().next().value;\n if (oldest !== undefined) callerTransactionStates.delete(oldest);\n }\n}\n\nasync function applyCallerTransactionContext(\n rawPrisma: RawPrismaForCallerTransaction,\n descriptor: object,\n statement: TransactionContextStatement\n): Promise<void> {\n const pending = rawPrisma.$executeRawUnsafe(statement.sql, ...statement.params);\n if (typeof pending.requestTransaction !== 'function') {\n throw new Error(\n '[WorkspaceExtension] Cannot bind the RLS context statement to the caller transaction ' +\n '(PrismaPromise.requestTransaction is unavailable); refusing to run it on another connection (BOFF-8874).'\n );\n }\n await pending.requestTransaction(descriptor);\n}\n\n/**\n * Run `run` (the operation, already bound to the caller's interactive\n * transaction by Prisma) after making sure that transaction carries the\n * workspace context. The context statement runs on the caller's transaction,\n * once per transaction level and workspace: a later operation for the same\n * workspace costs no extra round trip, a workspace switch re-runs it, and so does\n * the first operation after entering or leaving a nested transaction (a\n * savepoint rollback reverts `SET LOCAL`, a release keeps it).\n *\n * Concurrent operations for *different* workspaces on one transaction cannot be\n * isolated from each other, so that case throws instead of risking one running\n * under the other's GUC.\n *\n * @internal Exported for unit testing only — do not call from product code.\n */\nexport async function runOperationInCallerTransaction<TResult>(\n rawPrisma: RawPrismaForCallerTransaction,\n transaction: { id: string; descriptor: object },\n wsCtx: WorkspaceContext,\n config: Pick<Required<WorkspaceExtensionConfig>, 'enableRlsGucTagging' | 'enableApplicationNameTagging'>,\n run: () => Promise<TResult>\n): Promise<TResult> {\n const statement = buildTransactionContextStatement(wsCtx, config);\n if (!statement) return run();\n\n let state = callerTransactionStates.get(transaction.id);\n if (!state || state.descriptor !== transaction.descriptor || state.key !== statement.key) {\n if (state && state.inflight > 0 && state.key !== statement.key) {\n throw new Error(\n '[WorkspaceExtension] Concurrent operations for different workspaces inside one transaction are not ' +\n 'supported: the RLS context is per transaction. Await the other workspace’s operations first.'\n );\n }\n const next: CallerTransactionState = {\n descriptor: transaction.descriptor,\n key: statement.key,\n ready: applyCallerTransactionContext(rawPrisma, transaction.descriptor, statement),\n inflight: 0,\n };\n next.ready.catch(() => {\n if (callerTransactionStates.get(transaction.id) === next) callerTransactionStates.delete(transaction.id);\n });\n rememberCallerTransaction(transaction.id, next);\n state = next;\n }\n\n state.inflight += 1;\n try {\n await state.ready;\n return await run();\n } finally {\n state.inflight -= 1;\n }\n}\n\n/** @internal Test hook: forget all tracked caller transactions. */\nexport function resetCallerTransactionStateForTests(): void {\n callerTransactionStates.clear();\n}\n\nexport function addWorkspaceExtension<T>(baseClient: T, config?: WorkspaceExtensionConfig): T {\n const fullConfig: Required<WorkspaceExtensionConfig> = {\n ...defaultWorkspaceExtensionConfig,\n ...config,\n };\n\n if (!fullConfig.enabled) {\n logger.info('[WorkspaceExtension] Extension disabled by configuration');\n return baseClient;\n }\n\n // Capture the unwrapped client for connection tagging (pre-extension, avoids recursion)\n const rawPrisma = baseClient as unknown as RawPrismaForTagging;\n // Same unwrapped client, typed for a lazy query-continuation batch; no new pool.\n const rawPrismaForContinuations = baseClient as unknown as RawPrismaForRlsContinuation;\n // Capture the pre-wrapper transaction method, but preserve its final receiver\n // when invoked. Selecting $parent would discard query extensions added later.\n const transactionDelegate = (baseClient as unknown as TransactionDelegate).$transaction;\n // Same unwrapped client again, typed for binding the context statement to a\n // caller's transaction (see runOperationInCallerTransaction).\n const rawPrismaForCallerTransactions = baseClient as unknown as RawPrismaForCallerTransaction;\n const tagsTransactions = fullConfig.enableRlsGucTagging || fullConfig.enableApplicationNameTagging;\n\n /**\n * Execute an operation whose args have already been workspace-injected.\n *\n * - Inside a caller's interactive transaction: set the context on that\n * transaction (once) and run the operation in place, so it is atomic with\n * the rest of the caller's transaction and its locks last until commit.\n * - Inside a batch `$transaction([...])`: run in place; the `$transaction`\n * wrapper below prepended the context statement to the batch.\n * - Standalone: unchanged — session application_name tag, then the\n * operation in its own `SET LOCAL` transaction when RLS tagging is on.\n */\n const dispatch = async (\n params: { model: string; query: (args: unknown) => Promise<unknown>; __internalParams?: PrismaQueryInternalParams },\n wsCtx: WorkspaceContext,\n _operation: string,\n finalArgs: unknown\n ): Promise<unknown> => {\n // No tagging: nothing is set per operation, so every call runs in place\n // exactly as before (inside a caller transaction or not).\n if (!tagsTransactions) return params.query(finalArgs);\n const callerTransaction = getCallerTransaction(params.__internalParams);\n if (callerTransaction?.kind === 'itx') {\n return runOperationInCallerTransaction(rawPrismaForCallerTransactions, callerTransaction, wsCtx, fullConfig, () =>\n params.query(finalArgs)\n );\n }\n if (callerTransaction?.kind === 'batch') {\n return params.query(finalArgs);\n }\n if (fullConfig.enableApplicationNameTagging) {\n await maybeTagConnection(rawPrisma, wsCtx);\n }\n if (fullConfig.enableRlsGucTagging) {\n return runQueryWithRlsGuc(rawPrismaForContinuations, wsCtx, () => params.query(finalArgs));\n }\n return params.query(finalArgs);\n };\n\n /**\n * Raw SQL inside a caller's interactive transaction gets the same context, so\n * `SELECT … FOR UPDATE` fences and raw reads/writes see the caller's workspace\n * under FORCE RLS. Standalone raw SQL is unchanged (no context statement).\n */\n const rawOperation = async ({ args, query, __internalParams }: RawOperationHandlerParams): Promise<unknown> => {\n if (!tagsTransactions) return query(args);\n const callerTransaction = getCallerTransaction(__internalParams);\n if (callerTransaction?.kind !== 'itx') return query(args);\n const wsCtx = getWorkspaceContext();\n if (!wsCtx?.workspaceId) return query(args);\n return runOperationInCallerTransaction(rawPrismaForCallerTransactions, callerTransaction, wsCtx, fullConfig, () =>\n query(args)\n );\n };\n\n // Type assertion for Prisma client $extends\n const prismaClient = baseClient as { $extends: (args: unknown) => T };\n\n logger.info('[WorkspaceExtension] Workspace extension enabled', {\n populateContextJson: fullConfig.populateContextJson,\n populateCreatedBy: fullConfig.populateCreatedBy,\n populateUpdatedBy: fullConfig.populateUpdatedBy,\n populateTenantId: fullConfig.populateTenantId,\n enableReadIsolation: fullConfig.enableReadIsolation,\n enableDeleteIsolation: fullConfig.enableDeleteIsolation,\n enableUpdateWhereIsolation: fullConfig.enableUpdateWhereIsolation,\n strictMode: fullConfig.strictMode,\n excludeModels: fullConfig.excludeModels,\n excludeModelsFromReadIsolation: fullConfig.excludeModelsFromReadIsolation,\n allowedUnguardedOperations: fullConfig.allowedUnguardedOperations,\n enableApplicationNameTagging: fullConfig.enableApplicationNameTagging,\n enableRlsGucTagging: fullConfig.enableRlsGucTagging,\n });\n\n // Raw SQL hooks only matter when a context statement exists to apply.\n const rawOperationHooks = tagsTransactions\n ? {\n $queryRaw: rawOperation,\n $executeRaw: rawOperation,\n $queryRawUnsafe: rawOperation,\n $executeRawUnsafe: rawOperation,\n $queryRawTyped: rawOperation,\n }\n : {};\n\n const withQueryHooks = prismaClient.$extends({\n query: {\n ...rawOperationHooks,\n $allModels: {\n // ================================================================\n // WRITE OPERATIONS - inject workspaceId into data\n // ================================================================\n\n async create({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n data: Record<string, unknown>;\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n // Skip if model is excluded or injection is explicitly skipped\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'create', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n // Inject fields into data\n const injectedData = injectCreateFields(args.data, wsCtx, fullConfig);\n\n if (fullConfig.debug) {\n const injectedKeys = Object.keys(injectedData).filter((k) => !(k in args.data));\n if (injectedKeys.length > 0) {\n logger.debug(`[WorkspaceExtension] ${model}.create - injected: ${injectedKeys.join(', ')}`, {\n workspaceId: wsCtx.workspaceId,\n actorId: wsCtx.actorId,\n });\n }\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n data: injectedData,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'create', finalArgs);\n },\n\n async createMany({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n data: Record<string, unknown> | Record<string, unknown>[];\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'createMany', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n // Handle both single object and array\n const dataArray = Array.isArray(args.data) ? args.data : [args.data];\n const injectedData = dataArray.map((item) => injectCreateFields(item, wsCtx, fullConfig));\n\n const finalArgs = {\n ...stripSkipFlag(args),\n data: Array.isArray(args.data) ? injectedData : injectedData[0],\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'createMany', finalArgs);\n },\n\n async createManyAndReturn({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n data: Record<string, unknown> | Record<string, unknown>[];\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'createManyAndReturn', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const dataArray = Array.isArray(args.data) ? args.data : [args.data];\n const injectedData = dataArray.map((item) => injectCreateFields(item, wsCtx, fullConfig));\n\n const finalArgs = {\n ...stripSkipFlag(args),\n data: Array.isArray(args.data) ? injectedData : injectedData[0],\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'createManyAndReturn', finalArgs);\n },\n\n // ================================================================\n // UPDATE OPERATIONS - inject updatedBy into data + workspaceId into where\n // ================================================================\n\n async update({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n data: Record<string, unknown>;\n where?: Record<string, unknown>;\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'update', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedData = injectUpdateFields(args.data, wsCtx, fullConfig);\n\n // Inject workspaceId into where clause for update isolation\n let injectedWhere = args.where;\n if (fullConfig.enableUpdateWhereIsolation && !isExcludedFromReadIsolation(model, fullConfig)) {\n injectedWhere = injectWhereClause(args.where, wsCtx);\n }\n\n if (fullConfig.debug) {\n const injectedDataKeys = Object.keys(injectedData).filter((k) => !(k in args.data));\n const whereChanged = injectedWhere !== args.where;\n if (injectedDataKeys.length > 0 || whereChanged) {\n logger.debug(\n `[WorkspaceExtension] ${model}.update - injected data: ${injectedDataKeys.join(', ')}${whereChanged ? ', where: workspaceId' : ''}`\n );\n }\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n data: injectedData,\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'update', finalArgs);\n },\n\n async updateMany({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n data: Record<string, unknown>;\n where?: Record<string, unknown>;\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'updateMany', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedData = injectUpdateFields(args.data, wsCtx, fullConfig);\n\n // Inject workspaceId into where clause for update isolation\n let injectedWhere = args.where;\n if (fullConfig.enableUpdateWhereIsolation && !isExcludedFromReadIsolation(model, fullConfig)) {\n injectedWhere = injectWhereClause(args.where, wsCtx);\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n data: injectedData,\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'updateMany', finalArgs);\n },\n\n async upsert({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n create: Record<string, unknown>;\n update: Record<string, unknown>;\n where?: Record<string, unknown>;\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'upsert', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedCreate = injectCreateFields(args.create, wsCtx, fullConfig);\n const injectedUpdate = injectUpdateFields(args.update, wsCtx, fullConfig);\n\n // Inject workspaceId into where clause for upsert isolation\n let injectedWhere = args.where;\n if (fullConfig.enableUpdateWhereIsolation && !isExcludedFromReadIsolation(model, fullConfig)) {\n injectedWhere = injectWhereClause(args.where, wsCtx);\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n create: injectedCreate,\n update: injectedUpdate,\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'upsert', finalArgs);\n },\n\n // ================================================================\n // READ OPERATIONS - inject workspaceId into where clause\n // ================================================================\n\n async findMany({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'findMany', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.findMany - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'findMany', finalArgs);\n },\n\n async findFirst({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'findFirst', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.findFirst - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'findFirst', finalArgs);\n },\n\n async findFirstOrThrow({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'findFirstOrThrow', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.findFirstOrThrow - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'findFirstOrThrow', finalArgs);\n },\n\n async findUnique({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'findUnique', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n // For findUnique, the where clause uses unique fields.\n // We inject workspaceId only if the where clause is a plain object\n // (compound unique keys with workspaceId are common and already include it).\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.findUnique - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'findUnique', finalArgs);\n },\n\n async findUniqueOrThrow({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'findUniqueOrThrow', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.findUniqueOrThrow - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'findUniqueOrThrow', finalArgs);\n },\n\n async count({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'count', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.count - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'count', finalArgs);\n },\n\n async aggregate({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'aggregate', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.aggregate - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'aggregate', finalArgs);\n },\n\n async groupBy({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'groupBy', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.groupBy - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'groupBy', finalArgs);\n },\n\n // ================================================================\n // DELETE OPERATIONS - inject workspaceId into where clause\n // ================================================================\n\n async delete({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableDeleteIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'delete', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.delete - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'delete', finalArgs);\n },\n\n async deleteMany({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableDeleteIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'deleteMany', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.deleteMany - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'deleteMany', finalArgs);\n },\n },\n },\n });\n\n // Batch transactions: Prisma runs `$transaction([...])` members in one database\n // transaction, but an operation hook cannot add a statement to the batch. So\n // wrap `$transaction` itself and prepend the context statement; its result is\n // dropped so callers get exactly their own members' results. The function form\n // binds lazy consumption inside its callback; query hooks still apply RLS GUCs.\n // `$parent` is the client one extension layer down (the query-hooked client\n // above), so members and nested transactions keep every hook.\n const wrapped = withQueryHooks as unknown as { $extends: (args: unknown) => T };\n return wrapped.$extends({\n client: {\n $transaction(this: { $parent?: TransactionDelegate }, input: unknown, options?: unknown): Promise<unknown> {\n const parent = this.$parent;\n if (!parent) {\n throw new Error('[WorkspaceExtension] $transaction wrapper could not resolve its parent client.');\n }\n if (Array.isArray(input)) {\n const wsCtx = getWorkspaceContext();\n const statement =\n tagsTransactions && wsCtx?.workspaceId ? buildTransactionContextStatement(wsCtx, fullConfig) : undefined;\n if (statement) {\n const setContext = rawPrismaForCallerTransactions.$executeRawUnsafe(statement.sql, ...statement.params);\n return parent\n .$transaction([setContext, ...input], options)\n .then((results) => (Array.isArray(results) ? results.slice(1) : results));\n }\n }\n // The native delegate reads the final client's extension chain. Calling\n // it on $parent would silently omit later graph/audit query hooks.\n if (typeof input === 'function') {\n // Keep lazy returned operations in their originating callback context,\n // including Bun thenable assimilation after an awaited earlier query.\n const callback = input as (tx: object) => Promise<unknown>;\n return transactionDelegate.call(\n this,\n async (tx: object) => {\n const scope = { active: true };\n try {\n return await callback(bindTransactionContext(tx, scope, getWorkspaceContext));\n } finally {\n scope.active = false;\n }\n },\n options\n );\n }\n return transactionDelegate.call(this, input, options);\n },\n },\n });\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { productSlugVariants, isSameProductSlug } from './chunk-OBBCR6WY.js';
2
- import { withWorkspaceContextSync, withWorkspaceContext, setWorkspaceContext, runOperationWithRlsGuc, runOperationInCallerTransaction, resetCallerTransactionStateForTests, maybeTagConnection, maybeSetRlsGuc, injectWhereWorkspaceId, injectCreateFields, getWorkspaceContext, getCallerTransaction, defaultWorkspaceExtensionConfig, buildTransactionContextStatement, addWorkspaceExtension } from './chunk-HMVQOZHM.js';
2
+ import { withWorkspaceContextSync, withWorkspaceContext, setWorkspaceContext, runOperationWithRlsGuc, runOperationInCallerTransaction, resetCallerTransactionStateForTests, maybeTagConnection, maybeSetRlsGuc, injectWhereWorkspaceId, injectCreateFields, getWorkspaceContext, getCallerTransaction, defaultWorkspaceExtensionConfig, buildTransactionContextStatement, addWorkspaceExtension } from './chunk-3Z2VRCT6.js';
3
3
  import { isTransientAcquireError, installAcquireRetry, ensureServiceApplicationName, createPrismaClient, createPrismaAdapter, createConnectionPool, configurePrismaLogging, PrismaClientWrapper, addGraphExtension } from './chunk-6VK53YR3.js';
4
4
  import { getGraphEventEmitter } from './chunk-XTIOBNT7.js';
5
5
  import { logger } from './chunk-RU266375.js';
@@ -685,5 +685,5 @@ function createContextFromSDK(sdkContext) {
685
685
  __name(createContextFromSDK, "createContextFromSDK");
686
686
 
687
687
  export { buildContextWhereClause, buildContextWhereConditions, checkDatabaseHealth, contextMatches, createContextFromSDK, createDatabaseClient, createDatabaseClientFromEnv, extractFieldsFromModel, getAllModelNames, getDatabaseManager, getDatabaseProductName, getDatabaseStats, getDatabaseVersion, getDb, getModelFields, hasModel, initializeDatabase, initializeDatabaseWithConfig, isDatabaseInitialized, loadGeneratedFields, mergeContext, parseContext, prisma_exports, resetDatabaseManager, resolvePoolTuningFromEnv, testConnection, toContextJson };
688
- //# sourceMappingURL=chunk-PKKVCYJH.js.map
689
- //# sourceMappingURL=chunk-PKKVCYJH.js.map
688
+ //# sourceMappingURL=chunk-E5HKS7KD.js.map
689
+ //# sourceMappingURL=chunk-E5HKS7KD.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/prisma/index.ts","../src/prisma/factory.ts","../src/prisma/manager.ts","../src/prisma/health.ts","../src/prisma/fields.ts","../src/prisma/context.ts"],"names":["resolveWorkspaceExtensionDefault","productName","explicit","process","env","layer","toLowerCase","name","startsWith","createDatabaseClient","PrismaClientConstructor","config","enableGraphExtension","graphEventEmitter","enableWorkspaceExtension","workspaceExtensionConfig","registerShutdownHandlers","prismaConfig","prismaConfigWithDefaults","applicationName","ensureServiceApplicationName","wrapper","createPrismaClient","baseClient","getClient","extendedClient","eventEmitter","getGraphEventEmitter","graphConfig","enabled","addGraphExtension","logger","info","addWorkspaceExtension","db","debug","connect","retries","delay","disconnect","parsePositiveIntEnv","raw","trim","undefined","parsed","Number","parseInt","isFinite","resolvePoolTuningFromEnv","tuning","queryTimeout","queryTimeoutMillis","statementTimeout","statementTimeoutMillis","idleInTransactionTimeout","idleInTransactionTimeoutMillis","lockTimeout","lockTimeoutMillis","createDatabaseClientFromEnv","overrides","databaseUrl","Error","isDevelopment","maxConnections","idleTimeoutMillis","connectionTimeoutMillis","enableQueryLogging","slowQueryThreshold","acquireRetriesRaw","acquireRetries","acquireRetryDelay","acquireRetryDelayMillis","state","initialized","client","initializeDatabase","initializeDatabaseWithConfig","getDb","getDatabaseManager","isDatabaseInitialized","getDatabaseProductName","resetDatabaseManager","error","warn","checkDatabaseHealth","start","Date","now","$queryRaw","latency","healthy","errorMessage","message","String","testConnection","getDatabaseVersion","result","version","getDatabaseStats","health","Promise","all","timestamp","requireFn","createRequire","url","loadGeneratedFields","generatedFieldsPath","generated","default","path","extractFieldsFromModel","modelName","modelFieldsMap","options","modelFields","Object","keys","join","excludeFields","includeRelations","customFilter","fields","relations","excluded","length","filter","field","includes","push","fieldName","isRelation","shouldInclude","type","metadata","totalFields","excludedCount","excludedFields","relationFields","getModelFields","hasModel","getAllModelNames","buildContextWhereClause","contextFilter","conditions","workspaceId","equals","userId","projectId","appId","productId","organizationId","buildContextWhereConditions","context","slugs","productSlugVariants","OR","map","slug","toContextJson","contextInput","custom","filterNullValues","obj","filtered","key","value","entries","mergeContextField","merged","fieldValue","mergeContext","existingContext","newContext","Array","isArray","parseContext","contextJson","ctx","contextMatches","isSameProductSlug","createContextFromSDK","sdkContext"],"mappings":"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","file":"chunk-PKKVCYJH.js","sourcesContent":["/**\n * Prisma Module for Burdenoff Backend SDK\n *\n * Provides Prisma 7 utilities including:\n * - Singleton database manager for microservices\n * - Unified database client factory with graph extension\n * - Prisma client configuration with PostgreSQL adapter\n * - Connection pooling and management\n * - Health checks and monitoring\n * - Graceful shutdown handling\n * - Field extraction utilities for graph sync\n * - Context filtering utilities for multi-tenant queries\n * - Workspace extension for automatic workspaceId injection\n *\n * @module prisma\n * @category Database\n */\n\nexport * from './manager.js';\nexport * from './factory.js';\nexport * from './client.js';\nexport type * from './types.js';\nexport * from './health.js';\nexport * from './fields.js';\nexport * from './context.js';\nexport * from './workspace-extension.js';\n","/**\n * Database Client Factory\n *\n * Provides a unified factory for creating fully-configured database clients\n * with Prisma 7, PostgreSQL adapter, graph extension, and graceful shutdown.\n *\n * This module consolidates all database setup into a single call, reducing\n * boilerplate across all backend services.\n *\n * @module prisma/factory\n * @category Database\n */\n\nimport { logger } from '../logger/index.js';\nimport {\n createPrismaClient,\n ensureServiceApplicationName,\n type PrismaClientBase,\n type PrismaClientWrapper,\n type PrismaClientConstructorOptions,\n} from './client.js';\nimport type { PrismaClientConfig } from './types.js';\nimport { addGraphExtension, type GraphMiddlewareConfig, type GraphEventEmitter } from '../graph/middleware/index.js';\nimport { getGraphEventEmitter } from '../event-queue/graph-emitter.js';\nimport { addWorkspaceExtension, type WorkspaceExtensionConfig } from './workspace-extension.js';\n\n/**\n * Configuration for creating a database client\n */\nexport interface DatabaseClientConfig extends PrismaClientConfig {\n /**\n * Product name for graph events (e.g., 'module-tags', 'workspaces')\n */\n productName: string;\n\n /**\n * Enable graph extension for entity sync\n * @default true (reads from GRAPH_MIDDLEWARE_ENABLED env var)\n */\n enableGraphExtension?: boolean;\n\n /**\n * Custom graph event emitter (defaults to NATS-based emitter)\n */\n graphEventEmitter?: GraphEventEmitter;\n\n /**\n * Enable workspace extension for automatic workspaceId injection.\n *\n * Default is layer-aware:\n * - Global-layer services (`productName` starting with `global-` or `global_`,\n * or `WORKSPACE_LAYER=global`) default to `false`. Global-layer tables\n * (Tenant, Organization, Workspace, PlatformProduct, etc.) are intentionally\n * not workspace-scoped — enforcing workspaceId on them would block legitimate\n * queries like `myOrganizations`, `myWorkspaces`, `myAccessibleProducts`.\n * - All other services (wspace layer, product backends) default to `true`.\n *\n * `WORKSPACE_EXTENSION_ENABLED` env var always wins when explicitly set\n * (`true` or `false`). Pass the field on `config` for code-level override.\n */\n enableWorkspaceExtension?: boolean;\n\n /**\n * Configuration for the workspace extension\n */\n workspaceExtensionConfig?: WorkspaceExtensionConfig;\n\n /**\n * Register process shutdown handlers for graceful shutdown\n * @default true\n */\n registerShutdownHandlers?: boolean;\n}\n\n/**\n * Result of creating a database client\n */\nexport interface DatabaseClient<T extends PrismaClientBase> {\n /**\n * The extended Prisma client for database operations\n * Use this for all queries: db.model.operation()\n */\n db: T & { client: T };\n\n /**\n * The Prisma client wrapper with connection management utilities\n */\n wrapper: PrismaClientWrapper<T>;\n\n /**\n * Connect to the database with retry logic\n */\n connect: (retries?: number, delay?: number) => Promise<void>;\n\n /**\n * Disconnect from the database\n */\n disconnect: () => Promise<void>;\n}\n\n/**\n * Layer-aware default for the workspace extension.\n *\n * Global-layer services (productName starting with `global-`/`global_`, or\n * `WORKSPACE_LAYER=global`) opt out by default because their tables don't carry\n * a workspaceId column — enforcement would break queries like `myOrganizations`,\n * `myAccessibleProducts`, `contentPages`.\n *\n * `WORKSPACE_EXTENSION_ENABLED` is respected as an explicit override.\n */\nfunction resolveWorkspaceExtensionDefault(productName: string): boolean {\n const explicit = process.env['WORKSPACE_EXTENSION_ENABLED'];\n if (explicit === 'true') return true;\n if (explicit === 'false') return false;\n\n const layer = process.env['WORKSPACE_LAYER']?.toLowerCase();\n if (layer === 'global') return false;\n if (layer === 'wspace') return true;\n\n const name = productName.toLowerCase();\n if (name.startsWith('global-') || name.startsWith('global_')) return false;\n return true;\n}\n\n/**\n * Create a fully-configured database client with graph extension\n *\n * This is the recommended way to create a database connection in all backend services.\n * It handles:\n * - Prisma client creation with PostgreSQL adapter\n * - Connection pooling configuration\n * - Query logging (in development)\n * - Graph extension for entity sync (via NATS or in-memory)\n * - Graceful shutdown handlers\n *\n * @example\n * ```typescript\n * // In your service's db.ts\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { createDatabaseClient } from '@burdenoff/be-sdk/prisma';\n *\n * const { db, wrapper, connect, disconnect } = createDatabaseClient(PrismaClient, {\n * productName: 'my-service',\n * databaseUrl: process.env.DATABASE_URL!,\n * });\n *\n * export { db, wrapper, connect, disconnect };\n * export type ExtendedPrismaClient = typeof db;\n * ```\n *\n * @example\n * ```typescript\n * // With custom configuration\n * const { db } = createDatabaseClient(PrismaClient, {\n * productName: 'workspaces',\n * databaseUrl: process.env.DATABASE_URL!,\n * maxConnections: 50,\n * enableQueryLogging: true,\n * slowQueryThreshold: 200,\n * enableGraphExtension: true,\n * registerShutdownHandlers: true,\n * });\n * ```\n */\nexport function createDatabaseClient<T extends PrismaClientBase>(\n PrismaClientConstructor: new (options: PrismaClientConstructorOptions) => T,\n config: DatabaseClientConfig\n): DatabaseClient<T> {\n const {\n productName,\n enableGraphExtension = process.env['GRAPH_MIDDLEWARE_ENABLED'] !== 'false',\n graphEventEmitter,\n enableWorkspaceExtension = resolveWorkspaceExtensionDefault(productName),\n workspaceExtensionConfig,\n registerShutdownHandlers = true,\n ...prismaConfig\n } = config;\n\n // Tag every service's pool with `svc=<productName>` by default so its\n // connections are attributable in pg_stat_activity / pg_stat_statements\n // (the on-ramp to per-workspace observability and shard routing). This is\n // pure diagnostic metadata with no effect on behavior; explicit\n // `applicationName` on the config always wins.\n const prismaConfigWithDefaults: PrismaClientConfig = {\n ...prismaConfig,\n applicationName: prismaConfig.applicationName ?? `svc=${productName}`,\n };\n\n // Belt-and-suspenders: also set the PGAPPNAME env fallback so any additional\n // pools this service opens outside be-sdk still carry the per-service tag.\n ensureServiceApplicationName(productName);\n\n // Create Prisma client wrapper\n const wrapper = createPrismaClient(PrismaClientConstructor, prismaConfigWithDefaults);\n\n // Get the base client\n const baseClient = wrapper.getClient();\n\n // Extension chaining order:\n // 1. Graph extension (event emission on CRUD) - runs first\n // 2. Workspace extension (auto-inject workspaceId) - runs second\n //\n // The workspace extension should run BEFORE graph extension in the\n // interception chain so that graph events include the injected workspaceId.\n // In Prisma $extends, the LAST extension added runs FIRST (outermost wrapper).\n // So we add graph first, then workspace on top.\n\n let extendedClient: T;\n\n // Step 1: Add graph extension\n if (enableGraphExtension) {\n const eventEmitter = graphEventEmitter ?? getGraphEventEmitter();\n\n const graphConfig: GraphMiddlewareConfig = {\n enabled: true,\n productName,\n eventEmitter,\n };\n\n extendedClient = addGraphExtension(baseClient, graphConfig);\n\n logger.info('[Database] Graph extension enabled', { productName });\n } else {\n extendedClient = baseClient;\n logger.info('[Database] Graph extension disabled');\n }\n\n // Step 2: Add workspace extension (wraps on top of graph)\n if (enableWorkspaceExtension) {\n extendedClient = addWorkspaceExtension(extendedClient, workspaceExtensionConfig);\n\n logger.info('[Database] Workspace extension enabled', { productName });\n } else {\n logger.info('[Database] Workspace extension disabled');\n }\n\n // Add backwards compatibility alias\n const db = extendedClient as T & { client: T };\n (db as unknown as Record<string, unknown>)['client'] = db;\n\n // Register shutdown handlers if requested\n if (registerShutdownHandlers) {\n wrapper.registerShutdownHandlers();\n logger.debug('[Database] Shutdown handlers registered');\n }\n\n return {\n db,\n wrapper,\n connect: (retries?: number, delay?: number) => wrapper.connect(retries, delay),\n disconnect: () => wrapper.disconnect(),\n };\n}\n\n/**\n * Pool-tuning options resolved from environment variables.\n */\nexport interface PoolTuningEnv {\n /** Postgres application_name (defaults to `svc=<productName>`). */\n applicationName: string;\n /** Client-side node-postgres query_timeout in ms, if opted in (pooler-safe). */\n queryTimeoutMillis?: number;\n /** Server-side statement_timeout in ms, if opted in. */\n statementTimeoutMillis?: number;\n /** Server-side idle_in_transaction_session_timeout in ms, if opted in. */\n idleInTransactionTimeoutMillis?: number;\n /** Server-side lock_timeout in ms, if opted in. */\n lockTimeoutMillis?: number;\n}\n\n/**\n * Parse a strictly-positive integer environment variable.\n *\n * Returns `undefined` for unset, empty, non-numeric, zero, or negative values —\n * so a misconfigured or absent env var can never silently enable an aggressive\n * (or nonsensical) timeout. This is what keeps the DB-enforced timeouts OFF by\n * default and therefore behavior-preserving.\n */\nfunction parsePositiveIntEnv(name: string): number | undefined {\n const raw = process.env[name];\n if (raw == null || raw.trim() === '') {\n return undefined;\n }\n const parsed = Number.parseInt(raw.trim(), 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\n/**\n * Resolve pool tuning (application_name + opt-in DB timeouts) from env vars:\n * - DATABASE_APPLICATION_NAME: overrides the default `svc=<productName>` tag\n * - DATABASE_QUERY_TIMEOUT: client-side node-postgres query_timeout in ms (opt-in, pooler-safe)\n * - DATABASE_STATEMENT_TIMEOUT: server-side statement_timeout in ms (opt-in; DIRECT :5432 only — see note)\n * - DATABASE_IDLE_IN_TRANSACTION_TIMEOUT: idle_in_transaction_session_timeout in ms (opt-in)\n * - DATABASE_LOCK_TIMEOUT: lock_timeout in ms (opt-in)\n *\n * Timeouts are omitted entirely unless explicitly set to a positive integer, so\n * the default is exactly today's behavior (no timeouts).\n *\n * NOTE: prefer `DATABASE_QUERY_TIMEOUT` for services whose `DATABASE_URL` points\n * at the built-in PgBouncer (`:6432`). `DATABASE_STATEMENT_TIMEOUT` and friends\n * are Postgres startup parameters that Azure PgBouncer does not pass through, so\n * they silently have no effect (or fail the connection) on the pooled path.\n */\nexport function resolvePoolTuningFromEnv(productName: string): PoolTuningEnv {\n const tuning: PoolTuningEnv = {\n applicationName: process.env['DATABASE_APPLICATION_NAME']?.trim() || `svc=${productName}`,\n };\n\n const queryTimeout = parsePositiveIntEnv('DATABASE_QUERY_TIMEOUT');\n if (queryTimeout !== undefined) {\n tuning.queryTimeoutMillis = queryTimeout;\n }\n\n const statementTimeout = parsePositiveIntEnv('DATABASE_STATEMENT_TIMEOUT');\n if (statementTimeout !== undefined) {\n tuning.statementTimeoutMillis = statementTimeout;\n }\n\n const idleInTransactionTimeout = parsePositiveIntEnv('DATABASE_IDLE_IN_TRANSACTION_TIMEOUT');\n if (idleInTransactionTimeout !== undefined) {\n tuning.idleInTransactionTimeoutMillis = idleInTransactionTimeout;\n }\n\n const lockTimeout = parsePositiveIntEnv('DATABASE_LOCK_TIMEOUT');\n if (lockTimeout !== undefined) {\n tuning.lockTimeoutMillis = lockTimeout;\n }\n\n return tuning;\n}\n\n/**\n * Create a database client from environment variables\n *\n * Convenience function that reads configuration from standard environment variables:\n * - DATABASE_URL: Connection string (required)\n * - DATABASE_MAX_CONNECTIONS: Max pool connections (default: 20)\n * - DATABASE_APPLICATION_NAME: Postgres application_name (default: `svc=<productName>`)\n * - DATABASE_QUERY_TIMEOUT: opt-in client-side query timeout in ms — the\n * PgBouncer-safe query bound (default: OFF, preserving current behavior)\n * - DATABASE_STATEMENT_TIMEOUT / DATABASE_IDLE_IN_TRANSACTION_TIMEOUT / DATABASE_LOCK_TIMEOUT:\n * opt-in server-side timeouts in ms (default: OFF; DIRECT :5432 only — not\n * honored through the built-in PgBouncer :6432 runtime path)\n * - NODE_ENV: Environment for logging settings\n * - GRAPH_MIDDLEWARE_ENABLED: Enable graph sync (default: true)\n *\n * @example\n * ```typescript\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { createDatabaseClientFromEnv } from '@burdenoff/be-sdk/prisma';\n *\n * const { db } = createDatabaseClientFromEnv(PrismaClient, 'module-tags');\n * export { db };\n * ```\n */\nexport function createDatabaseClientFromEnv<T extends PrismaClientBase>(\n PrismaClientConstructor: new (options: PrismaClientConstructorOptions) => T,\n productName: string,\n overrides?: Partial<DatabaseClientConfig>\n): DatabaseClient<T> {\n const databaseUrl = process.env['DATABASE_URL'];\n if (!databaseUrl) {\n throw new Error('DATABASE_URL environment variable is required');\n }\n\n const isDevelopment = process.env['NODE_ENV'] === 'development';\n\n const config: DatabaseClientConfig = {\n productName,\n databaseUrl,\n maxConnections: parseInt(process.env['DATABASE_MAX_CONNECTIONS'] || '20', 10),\n idleTimeoutMillis: parseInt(process.env['DATABASE_IDLE_TIMEOUT'] || '30000', 10),\n connectionTimeoutMillis: parseInt(process.env['DATABASE_CONNECTION_TIMEOUT'] || '10000', 10),\n ...resolvePoolTuningFromEnv(productName),\n enableQueryLogging: isDevelopment,\n slowQueryThreshold: isDevelopment ? 100 : 500,\n ...overrides,\n };\n\n // Transient acquire retry — env-tunable, and unlike the fields above zero is\n // meaningful (DATABASE_ACQUIRE_RETRIES=0 disables the retry entirely).\n const acquireRetriesRaw = process.env['DATABASE_ACQUIRE_RETRIES']?.trim();\n if (acquireRetriesRaw !== undefined && acquireRetriesRaw !== '' && config.acquireRetries === undefined) {\n const parsed = Number.parseInt(acquireRetriesRaw, 10);\n if (Number.isFinite(parsed) && parsed >= 0) {\n config.acquireRetries = parsed;\n }\n }\n const acquireRetryDelay = parsePositiveIntEnv('DATABASE_ACQUIRE_RETRY_DELAY');\n if (acquireRetryDelay !== undefined && config.acquireRetryDelayMillis === undefined) {\n config.acquireRetryDelayMillis = acquireRetryDelay;\n }\n\n return createDatabaseClient(PrismaClientConstructor, config);\n}\n","/**\n * Database Singleton Manager\n *\n * Provides a singleton pattern for database connections across microservices.\n * Services initialize once at startup and access the db instance globally.\n *\n * This eliminates the need for individual db.ts files in each microservice.\n *\n * @module prisma/manager\n * @category Database\n *\n * @example\n * ```typescript\n * // In your service's index.ts (startup)\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { initializeDatabase } from '@burdenoff/be-sdk/prisma';\n *\n * // Initialize once at startup\n * const { db, connect } = initializeDatabase(PrismaClient, 'module-tags');\n * await connect();\n *\n * // In any other file\n * import { getDb } from '@burdenoff/be-sdk/prisma';\n * const db = getDb();\n * await db.client.user.findMany();\n * ```\n */\n\nimport { logger } from '../logger/index.js';\nimport {\n createDatabaseClient,\n createDatabaseClientFromEnv,\n type DatabaseClient,\n type DatabaseClientConfig,\n} from './factory.js';\nimport type { PrismaClientBase, PrismaClientConstructorOptions, DatabaseReturnType } from './client.js';\n\n/**\n * Global database manager state\n */\ninterface DatabaseManagerState {\n initialized: boolean;\n productName: string | null;\n client: DatabaseClient<PrismaClientBase> | null;\n}\n\n/**\n * Singleton state for the database manager\n */\nconst state: DatabaseManagerState = {\n initialized: false,\n productName: null,\n client: null,\n};\n\n/**\n * Initialize the database singleton\n *\n * Call this once at application startup with your service's PrismaClient.\n * After initialization, use `getDb()` to access the database anywhere.\n *\n * @param PrismaClientConstructor - The generated PrismaClient class from your service\n * @param productName - Product name for graph events (e.g., 'module-tags', 'workspaces')\n * @param config - Optional configuration overrides\n * @returns The database client with db, wrapper, connect, disconnect\n *\n * @throws Error if already initialized with a different product\n *\n * @example\n * ```typescript\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { initializeDatabase } from '@burdenoff/be-sdk/prisma';\n *\n * const { db, connect, disconnect } = initializeDatabase(PrismaClient, 'module-tags');\n * await connect();\n * ```\n */\nexport function initializeDatabase<T extends PrismaClientBase>(\n PrismaClientConstructor: new (options: PrismaClientConstructorOptions) => T,\n productName: string,\n config?: Partial<DatabaseClientConfig>\n): DatabaseClient<T> {\n // Check if already initialized\n if (state.initialized) {\n if (state.productName !== productName) {\n throw new Error(\n `Database already initialized for product \"${state.productName}\". ` +\n `Cannot reinitialize for \"${productName}\".`\n );\n }\n logger.debug('[DatabaseManager] Already initialized, returning existing client', { productName });\n return state.client as DatabaseClient<T>;\n }\n\n // Create the database client using env-based factory\n const client = createDatabaseClientFromEnv(PrismaClientConstructor, productName, config);\n\n // Store in singleton state\n state.initialized = true;\n state.productName = productName;\n state.client = client;\n\n logger.info('[DatabaseManager] Database initialized', { productName });\n\n return client;\n}\n\n/**\n * Initialize the database with explicit configuration\n *\n * Use this when you need full control over database configuration\n * rather than reading from environment variables.\n *\n * @param PrismaClientConstructor - The generated PrismaClient class\n * @param config - Full database configuration\n * @returns The database client\n *\n * @example\n * ```typescript\n * const { db } = initializeDatabaseWithConfig(PrismaClient, {\n * productName: 'module-tags',\n * databaseUrl: 'postgresql://...',\n * maxConnections: 50,\n * enableGraphExtension: false,\n * });\n * ```\n */\nexport function initializeDatabaseWithConfig<T extends PrismaClientBase>(\n PrismaClientConstructor: new (options: PrismaClientConstructorOptions) => T,\n config: DatabaseClientConfig\n): DatabaseClient<T> {\n const { productName } = config;\n\n // Check if already initialized\n if (state.initialized) {\n if (state.productName !== productName) {\n throw new Error(\n `Database already initialized for product \"${state.productName}\". ` +\n `Cannot reinitialize for \"${productName}\".`\n );\n }\n logger.debug('[DatabaseManager] Already initialized, returning existing client', { productName });\n return state.client as DatabaseClient<T>;\n }\n\n // Create the database client\n const client = createDatabaseClient(PrismaClientConstructor, config);\n\n // Store in singleton state\n state.initialized = true;\n state.productName = productName;\n state.client = client;\n\n logger.info('[DatabaseManager] Database initialized with custom config', { productName });\n\n return client;\n}\n\n/**\n * Get the initialized database client\n *\n * Use this anywhere in your application to access the database.\n * Must call `initializeDatabase()` first at application startup.\n *\n * The returned client provides dynamic model access - you can access any\n * model property (e.g., `db.client.user`, `db.client.universalTag`) and\n * TypeScript will allow common Prisma operations (findMany, create, etc.).\n *\n * @returns The extended Prisma client (db) with dynamic model access\n * @throws Error if database not initialized\n *\n * @example\n * ```typescript\n * import { getDb } from '@burdenoff/be-sdk/prisma';\n *\n * const db = getDb();\n * // Dynamic model access works without importing service-specific types\n * const tags = await db.client.universalTag.findMany();\n * const users = await db.client.user.findMany({ where: { active: true } });\n * ```\n */\nexport function getDb<T extends PrismaClientBase = PrismaClientBase>(): DatabaseReturnType<T> {\n if (!state.initialized || !state.client) {\n throw new Error('Database not initialized. Call initializeDatabase() at application startup before using getDb().');\n }\n return state.client.db as unknown as DatabaseReturnType<T>;\n}\n\n/**\n * Get the full database manager\n *\n * Returns the complete database client including wrapper, connect, and disconnect functions.\n * Useful when you need access to connection management utilities.\n *\n * @returns The full database client\n * @throws Error if database not initialized\n *\n * @example\n * ```typescript\n * import { getDatabaseManager } from '@burdenoff/be-sdk/prisma';\n *\n * const { db, wrapper, connect, disconnect } = getDatabaseManager();\n * await connect();\n * ```\n */\nexport function getDatabaseManager<T extends PrismaClientBase = PrismaClientBase>(): DatabaseClient<T> {\n if (!state.initialized || !state.client) {\n throw new Error(\n 'Database not initialized. Call initializeDatabase() at application startup before using getDatabaseManager().'\n );\n }\n return state.client as DatabaseClient<T>;\n}\n\n/**\n * Check if database is initialized\n *\n * @returns True if database has been initialized\n *\n * @example\n * ```typescript\n * if (!isDatabaseInitialized()) {\n * await initializeDatabase(PrismaClient, 'my-service');\n * }\n * ```\n */\nexport function isDatabaseInitialized(): boolean {\n return state.initialized;\n}\n\n/**\n * Get the product name of the initialized database\n *\n * @returns The product name or null if not initialized\n */\nexport function getDatabaseProductName(): string | null {\n return state.productName;\n}\n\n/**\n * Reset the database manager (for testing purposes only)\n *\n * WARNING: This disconnects and resets the database manager.\n * Only use this in test environments for cleanup between tests.\n *\n * @internal\n */\nexport async function resetDatabaseManager(): Promise<void> {\n if (state.client) {\n try {\n await state.client.disconnect();\n } catch (error) {\n logger.warn('[DatabaseManager] Error during disconnect on reset', { error });\n }\n }\n\n state.initialized = false;\n state.productName = null;\n state.client = null;\n\n logger.debug('[DatabaseManager] Database manager reset');\n}\n","/**\n * Prisma Health Check Utilities\n */\n\nimport { logger } from '../logger/index.js';\nimport type { DatabaseHealth } from './types.js';\nimport type { PrismaClientBase } from './client.js';\n\n/**\n * Check database health\n */\nexport async function checkDatabaseHealth<T extends PrismaClientBase>(client: T): Promise<DatabaseHealth> {\n try {\n const start = Date.now();\n await client.$queryRaw`SELECT 1`;\n const latency = Date.now() - start;\n\n return { healthy: true, latency };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error('[Prisma] Health check failed', { error: errorMessage });\n\n return {\n healthy: false,\n error: errorMessage,\n };\n }\n}\n\n/**\n * Test database connection\n */\nexport async function testConnection<T extends PrismaClientBase>(client: T): Promise<boolean> {\n try {\n await client.$queryRaw`SELECT 1`;\n return true;\n } catch (error) {\n logger.error('[Prisma] Connection test failed', {\n error: error instanceof Error ? error.message : String(error),\n });\n return false;\n }\n}\n\n/**\n * Get database version\n */\nexport async function getDatabaseVersion<T extends PrismaClientBase>(client: T): Promise<string | null> {\n try {\n const result = await client.$queryRaw<Array<{ version?: string }>>`SELECT version()`;\n return result[0]?.version ?? null;\n } catch (error) {\n logger.error('[Prisma] Failed to get database version', {\n error: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n}\n\n/**\n * Get database stats\n */\nexport async function getDatabaseStats<T extends PrismaClientBase>(\n client: T\n): Promise<{\n health: DatabaseHealth;\n version: string | null;\n timestamp: Date;\n}> {\n const [health, version] = await Promise.all([checkDatabaseHealth(client), getDatabaseVersion(client)]);\n\n return {\n health,\n version,\n timestamp: new Date(),\n };\n}\n","/**\n * Prisma Field Extraction Utilities\n *\n * Provides utilities for extracting model fields from Prisma schema.\n * In Prisma 7, DMMF is not available at runtime, so this module provides\n * build-time field extraction through a generator.\n *\n * @module prisma/fields\n */\n\nimport { createRequire } from 'node:module';\nimport { logger } from '../logger/index.js';\n\nconst requireFn = createRequire(import.meta.url);\n\n/**\n * Field extraction options\n */\nexport interface FieldExtractionOptions {\n /** Fields to exclude from extraction */\n excludeFields?: string[];\n /** Whether to include relation fields */\n includeRelations?: boolean;\n /** Custom filter function */\n customFilter?: (field: { name: string; type: string; isRelation: boolean }) => boolean;\n}\n\n/**\n * Field extraction result\n */\nexport interface FieldExtractionResult {\n /** Extracted field names */\n fields: string[];\n /** Metadata about the extraction */\n metadata: {\n /** Total number of fields found */\n totalFields: number;\n /** Number of fields excluded */\n excludedCount: number;\n /** Names of excluded fields */\n excludedFields: string[];\n /** Number of relation fields */\n relationFields: number;\n };\n}\n\n/**\n * Model fields mapping\n * This will be generated at build time by the Prisma generator\n */\nexport type ModelFieldsMap = Record<\n string,\n {\n fields: string[];\n relations: string[];\n }\n>;\n\n/**\n * Import generated fields from the consuming package\n * This function should be used by backends to load their generated fields\n */\nexport function loadGeneratedFields(generatedFieldsPath: string): ModelFieldsMap {\n try {\n // Dynamic import of generated fields using createRequire\n const generated = requireFn(generatedFieldsPath) as { default: ModelFieldsMap };\n return generated.default || generated;\n } catch (error) {\n logger.error('[Prisma] Failed to load generated fields', {\n error: error instanceof Error ? error.message : String(error),\n path: generatedFieldsPath,\n });\n throw new Error(`Failed to load generated fields from ${generatedFieldsPath}`);\n }\n}\n\n/**\n * Extract fields from generated model fields with options\n */\nexport function extractFieldsFromModel(\n modelName: string,\n modelFieldsMap: ModelFieldsMap,\n options: FieldExtractionOptions = {}\n): FieldExtractionResult {\n const modelFields = modelFieldsMap[modelName];\n\n if (!modelFields) {\n throw new Error(\n `Model \"${modelName}\" not found in generated fields. ` +\n `Available models: ${Object.keys(modelFieldsMap).join(', ')}`\n );\n }\n\n const { excludeFields = [], includeRelations = false, customFilter } = options;\n\n // Start with scalar fields\n let fields = [...modelFields.fields];\n\n // Add relations if requested\n if (includeRelations) {\n fields = [...fields, ...modelFields.relations];\n }\n\n // Track excluded fields\n const excluded: string[] = [];\n\n // Apply exclusions\n if (excludeFields.length > 0) {\n fields = fields.filter((field) => {\n if (excludeFields.includes(field)) {\n excluded.push(field);\n return false;\n }\n return true;\n });\n }\n\n // Apply custom filter\n if (customFilter) {\n fields = fields.filter((fieldName) => {\n const isRelation = modelFields.relations.includes(fieldName);\n const shouldInclude = customFilter({\n name: fieldName,\n type: 'unknown', // Type information not available without full DMMF\n isRelation,\n });\n\n if (!shouldInclude) {\n excluded.push(fieldName);\n }\n\n return shouldInclude;\n });\n }\n\n return {\n fields,\n metadata: {\n totalFields: modelFields.fields.length + modelFields.relations.length,\n excludedCount: excluded.length,\n excludedFields: excluded,\n relationFields: modelFields.relations.length,\n },\n };\n}\n\n/**\n * Get all field names for a model (without options)\n */\nexport function getModelFields(modelName: string, modelFieldsMap: ModelFieldsMap, includeRelations = false): string[] {\n const result = extractFieldsFromModel(modelName, modelFieldsMap, { includeRelations });\n return result.fields;\n}\n\n/**\n * Check if a model exists in the generated fields\n */\nexport function hasModel(modelName: string, modelFieldsMap: ModelFieldsMap): boolean {\n return modelName in modelFieldsMap;\n}\n\n/**\n * Get all available model names\n */\nexport function getAllModelNames(modelFieldsMap: ModelFieldsMap): string[] {\n return Object.keys(modelFieldsMap);\n}\n","/**\n * Prisma Context Filtering Utilities\n *\n * Utilities for handling operation context in queries, mutations, and filtering.\n * Context JSON enables multi-dimensional data isolation across workspaces, users, projects, etc.\n *\n * @module prisma/context\n * @category Database\n */\n\nimport { isSameProductSlug, productSlugVariants } from '../product-alias/index.js';\n\n/**\n * Context filter input for querying entities by context\n */\nexport interface ContextFilterInput {\n workspaceId?: string | null;\n userId?: string | null;\n projectId?: string | null;\n appId?: string | null;\n /** Product identifier (e.g. \"vibecontrols\", \"workspaces\"). Stamped on cross-product\n * records so admin filters can scope by originating product. */\n productId?: string | null;\n /** Organization identifier within the tenant. */\n organizationId?: string | null;\n}\n\n/**\n * Operation context for create/update operations\n */\nexport interface OperationContext extends ContextFilterInput {\n custom?: Record<string, unknown> | null;\n}\n\n/**\n * Prisma JSON filter type (simplified for context filtering)\n * This type is designed to be compatible with Prisma's JsonNullableFilter\n * Uses Record<string, unknown> for maximum compatibility with various Prisma versions\n */\nexport type PrismaJsonFilter = Record<string, unknown>;\n\n/**\n * One entry of {@link buildContextWhereConditions}: a JSON-path predicate on `context`,\n * or an `OR` of them (used for a renamed product's slug twins).\n */\nexport type ContextWhereCondition = { context: PrismaJsonFilter } | { OR: Array<{ context: PrismaJsonFilter }> };\n\n/**\n * JSON value type for Prisma (includes null for reading from DB)\n */\nexport type JsonValue = string | number | boolean | null | { [key: string]: JsonValue } | JsonValue[];\n\n/**\n * Input JSON value type for Prisma (excludes null for writing to DB)\n * Compatible with Prisma's InputJsonValue type\n */\nexport type InputJsonValue = string | number | boolean | { [key: string]: InputJsonValue } | InputJsonValue[];\n\n/**\n * Build Prisma where condition for context filtering.\n * Uses PostgreSQL JSONB containment operators for efficient queries.\n *\n * @param contextFilter - The context filter input\n * @returns Prisma where clause for context field, or undefined if no filter provided\n *\n * @example\n * ```typescript\n * const contextWhere = buildContextWhereClause({\n * workspaceId: '123',\n * projectId: '456'\n * });\n * // Returns: { path: ['workspaceId'], equals: '123' }\n * ```\n */\nexport function buildContextWhereClause(\n contextFilter: ContextFilterInput | null | undefined\n): PrismaJsonFilter | undefined {\n if (!contextFilter) {\n return undefined;\n }\n\n // Build array of path conditions for each non-null field\n const conditions: PrismaJsonFilter[] = [];\n\n if (contextFilter.workspaceId != null) {\n conditions.push({\n path: ['workspaceId'],\n equals: contextFilter.workspaceId,\n });\n }\n\n if (contextFilter.userId != null) {\n conditions.push({\n path: ['userId'],\n equals: contextFilter.userId,\n });\n }\n\n if (contextFilter.projectId != null) {\n conditions.push({\n path: ['projectId'],\n equals: contextFilter.projectId,\n });\n }\n\n if (contextFilter.appId != null) {\n conditions.push({\n path: ['appId'],\n equals: contextFilter.appId,\n });\n }\n\n if (contextFilter.productId != null) {\n conditions.push({\n path: ['productId'],\n equals: contextFilter.productId,\n });\n }\n\n if (contextFilter.organizationId != null) {\n conditions.push({\n path: ['organizationId'],\n equals: contextFilter.organizationId,\n });\n }\n\n // If no conditions, return undefined\n if (conditions.length === 0) {\n return undefined;\n }\n\n // If single condition, return it directly\n if (conditions.length === 1) {\n return conditions[0];\n }\n\n // For multiple conditions, return the first one\n // Caller should use buildContextWhereConditions for multiple AND conditions\n return conditions[0];\n}\n\n/**\n * Build context where conditions as an array for use in AND clause.\n * This is useful when you need to filter by multiple context fields.\n *\n * @param contextFilter - The context filter input\n * @returns Array of Prisma where conditions, each targeting the context field\n *\n * @example\n * ```typescript\n * const conditions = buildContextWhereConditions({\n * workspaceId: '123',\n * projectId: '456'\n * });\n * // Use in Prisma query:\n * prisma.entity.findMany({\n * where: { AND: conditions }\n * });\n * ```\n */\nexport function buildContextWhereConditions(\n contextFilter: ContextFilterInput | null | undefined\n): ContextWhereCondition[] {\n if (!contextFilter) {\n return [];\n }\n\n const conditions: ContextWhereCondition[] = [];\n\n if (contextFilter.workspaceId != null) {\n conditions.push({\n context: {\n path: ['workspaceId'],\n equals: contextFilter.workspaceId,\n },\n });\n }\n\n if (contextFilter.userId != null) {\n conditions.push({\n context: {\n path: ['userId'],\n equals: contextFilter.userId,\n },\n });\n }\n\n if (contextFilter.projectId != null) {\n conditions.push({\n context: {\n path: ['projectId'],\n equals: contextFilter.projectId,\n },\n });\n }\n\n if (contextFilter.appId != null) {\n conditions.push({\n context: {\n path: ['appId'],\n equals: contextFilter.appId,\n },\n });\n }\n\n if (contextFilter.productId != null) {\n // A renamed product (botlit → botmanor) matches rows stored under either slug while\n // they are migrated; every other product keeps the exact single-slug predicate.\n const slugs = productSlugVariants(contextFilter.productId);\n if (slugs.length > 1) {\n conditions.push({\n OR: slugs.map((slug) => ({ context: { path: ['productId'], equals: slug } })),\n });\n } else {\n conditions.push({\n context: {\n path: ['productId'],\n equals: contextFilter.productId,\n },\n });\n }\n }\n\n if (contextFilter.organizationId != null) {\n conditions.push({\n context: {\n path: ['organizationId'],\n equals: contextFilter.organizationId,\n },\n });\n }\n\n return conditions;\n}\n\n/**\n * Convert context input to Prisma JSON format for create/update operations.\n *\n * @param contextInput - The context input\n * @returns JSON value for the context field, or undefined if empty\n *\n * @example\n * ```typescript\n * const contextJson = toContextJson({\n * workspaceId: '123',\n * userId: '456'\n * });\n * // Use in Prisma create:\n * prisma.entity.create({\n * data: { context: contextJson }\n * });\n * ```\n */\nexport function toContextJson(contextInput: OperationContext | null | undefined): InputJsonValue | undefined {\n if (!contextInput) {\n return undefined;\n }\n\n // Remove null values and build clean context object\n const context: Record<string, InputJsonValue> = {};\n\n if (contextInput.workspaceId != null) {\n context['workspaceId'] = contextInput.workspaceId;\n }\n if (contextInput.userId != null) {\n context['userId'] = contextInput.userId;\n }\n if (contextInput.projectId != null) {\n context['projectId'] = contextInput.projectId;\n }\n if (contextInput.appId != null) {\n context['appId'] = contextInput.appId;\n }\n if (contextInput.productId != null) {\n context['productId'] = contextInput.productId;\n }\n if (contextInput.organizationId != null) {\n context['organizationId'] = contextInput.organizationId;\n }\n if (contextInput.custom != null) {\n context['custom'] = contextInput.custom as InputJsonValue;\n }\n\n // Return undefined if no fields set\n if (Object.keys(context).length === 0) {\n return undefined;\n }\n\n return context;\n}\n\n/**\n * Filter out null values from an object for Prisma compatibility\n */\nfunction filterNullValues(obj: Record<string, unknown>): Record<string, InputJsonValue> {\n const filtered: Record<string, InputJsonValue> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value !== null) {\n filtered[key] = value as InputJsonValue;\n }\n }\n return filtered;\n}\n\n/**\n * Merge a single field into the merged context object\n */\nfunction mergeContextField(\n merged: Record<string, InputJsonValue>,\n fieldName: string,\n fieldValue: string | Record<string, unknown> | null | undefined\n): void {\n if (fieldValue === undefined) {\n return; // Don't touch this field\n }\n\n if (fieldValue === null) {\n delete merged[fieldName]; // Explicitly remove\n } else {\n merged[fieldName] = fieldValue as InputJsonValue; // Set new value\n }\n}\n\n/**\n * Merge existing context with new context input.\n * New values override existing ones, but undefined values are preserved from existing.\n *\n * @param existingContext - The existing context JSON from database\n * @param newContext - The new context input\n * @returns Merged context as InputJsonValue (suitable for Prisma writes)\n *\n * @example\n * ```typescript\n * const merged = mergeContext(\n * { workspaceId: '123', userId: 'old' },\n * { userId: 'new', projectId: '456' }\n * );\n * // Result: { workspaceId: '123', userId: 'new', projectId: '456' }\n * ```\n */\nexport function mergeContext(\n existingContext: JsonValue | null | undefined,\n newContext: OperationContext | null | undefined\n): InputJsonValue | undefined {\n // If no new context, return existing (excluding null values)\n if (!newContext) {\n if (!existingContext) {\n return undefined;\n }\n // Filter out null values from existing context for Prisma compatibility\n if (typeof existingContext === 'object' && !Array.isArray(existingContext)) {\n const filtered = filterNullValues(existingContext);\n return Object.keys(filtered).length > 0 ? filtered : undefined;\n }\n return existingContext as InputJsonValue;\n }\n\n // If no existing context, convert new to JSON\n if (!existingContext || typeof existingContext !== 'object' || Array.isArray(existingContext)) {\n return toContextJson(newContext);\n }\n\n // Merge existing with new\n const merged = filterNullValues(existingContext);\n\n // Merge each field from new context\n mergeContextField(merged, 'workspaceId', newContext.workspaceId);\n mergeContextField(merged, 'userId', newContext.userId);\n mergeContextField(merged, 'projectId', newContext.projectId);\n mergeContextField(merged, 'appId', newContext.appId);\n mergeContextField(merged, 'productId', newContext.productId);\n mergeContextField(merged, 'organizationId', newContext.organizationId);\n mergeContextField(merged, 'custom', newContext.custom);\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\n/**\n * Parse context JSON from database to OperationContext interface.\n *\n * @param contextJson - The context JSON from database\n * @returns Parsed OperationContext or null\n *\n * @example\n * ```typescript\n * const context = parseContext(entity.context);\n * if (context?.workspaceId) {\n * // Use workspace-specific logic\n * }\n * ```\n */\nexport function parseContext(contextJson: JsonValue | null | undefined): OperationContext | null {\n if (!contextJson || typeof contextJson !== 'object' || Array.isArray(contextJson)) {\n return null;\n }\n\n const ctx = contextJson as Record<string, unknown>;\n\n return {\n workspaceId: typeof ctx['workspaceId'] === 'string' ? ctx['workspaceId'] : null,\n userId: typeof ctx['userId'] === 'string' ? ctx['userId'] : null,\n projectId: typeof ctx['projectId'] === 'string' ? ctx['projectId'] : null,\n appId: typeof ctx['appId'] === 'string' ? ctx['appId'] : null,\n productId: typeof ctx['productId'] === 'string' ? ctx['productId'] : null,\n organizationId: typeof ctx['organizationId'] === 'string' ? ctx['organizationId'] : null,\n custom: typeof ctx['custom'] === 'object' ? (ctx['custom'] as Record<string, unknown>) : null,\n };\n}\n\n/**\n * Check if context matches filter criteria\n *\n * @param context - The context to check\n * @param filter - The filter criteria\n * @returns True if context matches all filter criteria\n */\nexport function contextMatches(context: OperationContext | null | undefined, filter: ContextFilterInput): boolean {\n if (!context) {\n return false;\n }\n\n if (filter.workspaceId != null && context.workspaceId !== filter.workspaceId) {\n return false;\n }\n if (filter.userId != null && context.userId !== filter.userId) {\n return false;\n }\n if (filter.projectId != null && context.projectId !== filter.projectId) {\n return false;\n }\n if (filter.appId != null && context.appId !== filter.appId) {\n return false;\n }\n // Renamed products (botlit → botmanor) match under either slug while rows are migrated.\n if (filter.productId != null && !isSameProductSlug(context.productId, filter.productId)) {\n return false;\n }\n if (filter.organizationId != null && context.organizationId !== filter.organizationId) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Create a default context from SDK context\n *\n * @param sdkContext - The SDK context (from AsyncLocalStorage)\n * @returns Operation context with workspace and user info\n */\nexport function createContextFromSDK(sdkContext: {\n workspaceId?: string;\n userId?: string;\n projectId?: string;\n appId?: string;\n productId?: string;\n organizationId?: string;\n}): OperationContext {\n return {\n workspaceId: sdkContext.workspaceId ?? null,\n userId: sdkContext.userId ?? null,\n projectId: sdkContext.projectId ?? null,\n appId: sdkContext.appId ?? null,\n productId: sdkContext.productId ?? null,\n organizationId: sdkContext.organizationId ?? null,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/prisma/index.ts","../src/prisma/factory.ts","../src/prisma/manager.ts","../src/prisma/health.ts","../src/prisma/fields.ts","../src/prisma/context.ts"],"names":["resolveWorkspaceExtensionDefault","productName","explicit","process","env","layer","toLowerCase","name","startsWith","createDatabaseClient","PrismaClientConstructor","config","enableGraphExtension","graphEventEmitter","enableWorkspaceExtension","workspaceExtensionConfig","registerShutdownHandlers","prismaConfig","prismaConfigWithDefaults","applicationName","ensureServiceApplicationName","wrapper","createPrismaClient","baseClient","getClient","extendedClient","eventEmitter","getGraphEventEmitter","graphConfig","enabled","addGraphExtension","logger","info","addWorkspaceExtension","db","debug","connect","retries","delay","disconnect","parsePositiveIntEnv","raw","trim","undefined","parsed","Number","parseInt","isFinite","resolvePoolTuningFromEnv","tuning","queryTimeout","queryTimeoutMillis","statementTimeout","statementTimeoutMillis","idleInTransactionTimeout","idleInTransactionTimeoutMillis","lockTimeout","lockTimeoutMillis","createDatabaseClientFromEnv","overrides","databaseUrl","Error","isDevelopment","maxConnections","idleTimeoutMillis","connectionTimeoutMillis","enableQueryLogging","slowQueryThreshold","acquireRetriesRaw","acquireRetries","acquireRetryDelay","acquireRetryDelayMillis","state","initialized","client","initializeDatabase","initializeDatabaseWithConfig","getDb","getDatabaseManager","isDatabaseInitialized","getDatabaseProductName","resetDatabaseManager","error","warn","checkDatabaseHealth","start","Date","now","$queryRaw","latency","healthy","errorMessage","message","String","testConnection","getDatabaseVersion","result","version","getDatabaseStats","health","Promise","all","timestamp","requireFn","createRequire","url","loadGeneratedFields","generatedFieldsPath","generated","default","path","extractFieldsFromModel","modelName","modelFieldsMap","options","modelFields","Object","keys","join","excludeFields","includeRelations","customFilter","fields","relations","excluded","length","filter","field","includes","push","fieldName","isRelation","shouldInclude","type","metadata","totalFields","excludedCount","excludedFields","relationFields","getModelFields","hasModel","getAllModelNames","buildContextWhereClause","contextFilter","conditions","workspaceId","equals","userId","projectId","appId","productId","organizationId","buildContextWhereConditions","context","slugs","productSlugVariants","OR","map","slug","toContextJson","contextInput","custom","filterNullValues","obj","filtered","key","value","entries","mergeContextField","merged","fieldValue","mergeContext","existingContext","newContext","Array","isArray","parseContext","contextJson","ctx","contextMatches","isSameProductSlug","createContextFromSDK","sdkContext"],"mappings":"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","file":"chunk-E5HKS7KD.js","sourcesContent":["/**\n * Prisma Module for Burdenoff Backend SDK\n *\n * Provides Prisma 7 utilities including:\n * - Singleton database manager for microservices\n * - Unified database client factory with graph extension\n * - Prisma client configuration with PostgreSQL adapter\n * - Connection pooling and management\n * - Health checks and monitoring\n * - Graceful shutdown handling\n * - Field extraction utilities for graph sync\n * - Context filtering utilities for multi-tenant queries\n * - Workspace extension for automatic workspaceId injection\n *\n * @module prisma\n * @category Database\n */\n\nexport * from './manager.js';\nexport * from './factory.js';\nexport * from './client.js';\nexport type * from './types.js';\nexport * from './health.js';\nexport * from './fields.js';\nexport * from './context.js';\nexport * from './workspace-extension.js';\n","/**\n * Database Client Factory\n *\n * Provides a unified factory for creating fully-configured database clients\n * with Prisma 7, PostgreSQL adapter, graph extension, and graceful shutdown.\n *\n * This module consolidates all database setup into a single call, reducing\n * boilerplate across all backend services.\n *\n * @module prisma/factory\n * @category Database\n */\n\nimport { logger } from '../logger/index.js';\nimport {\n createPrismaClient,\n ensureServiceApplicationName,\n type PrismaClientBase,\n type PrismaClientWrapper,\n type PrismaClientConstructorOptions,\n} from './client.js';\nimport type { PrismaClientConfig } from './types.js';\nimport { addGraphExtension, type GraphMiddlewareConfig, type GraphEventEmitter } from '../graph/middleware/index.js';\nimport { getGraphEventEmitter } from '../event-queue/graph-emitter.js';\nimport { addWorkspaceExtension, type WorkspaceExtensionConfig } from './workspace-extension.js';\n\n/**\n * Configuration for creating a database client\n */\nexport interface DatabaseClientConfig extends PrismaClientConfig {\n /**\n * Product name for graph events (e.g., 'module-tags', 'workspaces')\n */\n productName: string;\n\n /**\n * Enable graph extension for entity sync\n * @default true (reads from GRAPH_MIDDLEWARE_ENABLED env var)\n */\n enableGraphExtension?: boolean;\n\n /**\n * Custom graph event emitter (defaults to NATS-based emitter)\n */\n graphEventEmitter?: GraphEventEmitter;\n\n /**\n * Enable workspace extension for automatic workspaceId injection.\n *\n * Default is layer-aware:\n * - Global-layer services (`productName` starting with `global-` or `global_`,\n * or `WORKSPACE_LAYER=global`) default to `false`. Global-layer tables\n * (Tenant, Organization, Workspace, PlatformProduct, etc.) are intentionally\n * not workspace-scoped — enforcing workspaceId on them would block legitimate\n * queries like `myOrganizations`, `myWorkspaces`, `myAccessibleProducts`.\n * - All other services (wspace layer, product backends) default to `true`.\n *\n * `WORKSPACE_EXTENSION_ENABLED` env var always wins when explicitly set\n * (`true` or `false`). Pass the field on `config` for code-level override.\n */\n enableWorkspaceExtension?: boolean;\n\n /**\n * Configuration for the workspace extension\n */\n workspaceExtensionConfig?: WorkspaceExtensionConfig;\n\n /**\n * Register process shutdown handlers for graceful shutdown\n * @default true\n */\n registerShutdownHandlers?: boolean;\n}\n\n/**\n * Result of creating a database client\n */\nexport interface DatabaseClient<T extends PrismaClientBase> {\n /**\n * The extended Prisma client for database operations\n * Use this for all queries: db.model.operation()\n */\n db: T & { client: T };\n\n /**\n * The Prisma client wrapper with connection management utilities\n */\n wrapper: PrismaClientWrapper<T>;\n\n /**\n * Connect to the database with retry logic\n */\n connect: (retries?: number, delay?: number) => Promise<void>;\n\n /**\n * Disconnect from the database\n */\n disconnect: () => Promise<void>;\n}\n\n/**\n * Layer-aware default for the workspace extension.\n *\n * Global-layer services (productName starting with `global-`/`global_`, or\n * `WORKSPACE_LAYER=global`) opt out by default because their tables don't carry\n * a workspaceId column — enforcement would break queries like `myOrganizations`,\n * `myAccessibleProducts`, `contentPages`.\n *\n * `WORKSPACE_EXTENSION_ENABLED` is respected as an explicit override.\n */\nfunction resolveWorkspaceExtensionDefault(productName: string): boolean {\n const explicit = process.env['WORKSPACE_EXTENSION_ENABLED'];\n if (explicit === 'true') return true;\n if (explicit === 'false') return false;\n\n const layer = process.env['WORKSPACE_LAYER']?.toLowerCase();\n if (layer === 'global') return false;\n if (layer === 'wspace') return true;\n\n const name = productName.toLowerCase();\n if (name.startsWith('global-') || name.startsWith('global_')) return false;\n return true;\n}\n\n/**\n * Create a fully-configured database client with graph extension\n *\n * This is the recommended way to create a database connection in all backend services.\n * It handles:\n * - Prisma client creation with PostgreSQL adapter\n * - Connection pooling configuration\n * - Query logging (in development)\n * - Graph extension for entity sync (via NATS or in-memory)\n * - Graceful shutdown handlers\n *\n * @example\n * ```typescript\n * // In your service's db.ts\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { createDatabaseClient } from '@burdenoff/be-sdk/prisma';\n *\n * const { db, wrapper, connect, disconnect } = createDatabaseClient(PrismaClient, {\n * productName: 'my-service',\n * databaseUrl: process.env.DATABASE_URL!,\n * });\n *\n * export { db, wrapper, connect, disconnect };\n * export type ExtendedPrismaClient = typeof db;\n * ```\n *\n * @example\n * ```typescript\n * // With custom configuration\n * const { db } = createDatabaseClient(PrismaClient, {\n * productName: 'workspaces',\n * databaseUrl: process.env.DATABASE_URL!,\n * maxConnections: 50,\n * enableQueryLogging: true,\n * slowQueryThreshold: 200,\n * enableGraphExtension: true,\n * registerShutdownHandlers: true,\n * });\n * ```\n */\nexport function createDatabaseClient<T extends PrismaClientBase>(\n PrismaClientConstructor: new (options: PrismaClientConstructorOptions) => T,\n config: DatabaseClientConfig\n): DatabaseClient<T> {\n const {\n productName,\n enableGraphExtension = process.env['GRAPH_MIDDLEWARE_ENABLED'] !== 'false',\n graphEventEmitter,\n enableWorkspaceExtension = resolveWorkspaceExtensionDefault(productName),\n workspaceExtensionConfig,\n registerShutdownHandlers = true,\n ...prismaConfig\n } = config;\n\n // Tag every service's pool with `svc=<productName>` by default so its\n // connections are attributable in pg_stat_activity / pg_stat_statements\n // (the on-ramp to per-workspace observability and shard routing). This is\n // pure diagnostic metadata with no effect on behavior; explicit\n // `applicationName` on the config always wins.\n const prismaConfigWithDefaults: PrismaClientConfig = {\n ...prismaConfig,\n applicationName: prismaConfig.applicationName ?? `svc=${productName}`,\n };\n\n // Belt-and-suspenders: also set the PGAPPNAME env fallback so any additional\n // pools this service opens outside be-sdk still carry the per-service tag.\n ensureServiceApplicationName(productName);\n\n // Create Prisma client wrapper\n const wrapper = createPrismaClient(PrismaClientConstructor, prismaConfigWithDefaults);\n\n // Get the base client\n const baseClient = wrapper.getClient();\n\n // Extension chaining order:\n // 1. Graph extension (event emission on CRUD) - runs first\n // 2. Workspace extension (auto-inject workspaceId) - runs second\n //\n // The workspace extension should run BEFORE graph extension in the\n // interception chain so that graph events include the injected workspaceId.\n // In Prisma $extends, the LAST extension added runs FIRST (outermost wrapper).\n // So we add graph first, then workspace on top.\n\n let extendedClient: T;\n\n // Step 1: Add graph extension\n if (enableGraphExtension) {\n const eventEmitter = graphEventEmitter ?? getGraphEventEmitter();\n\n const graphConfig: GraphMiddlewareConfig = {\n enabled: true,\n productName,\n eventEmitter,\n };\n\n extendedClient = addGraphExtension(baseClient, graphConfig);\n\n logger.info('[Database] Graph extension enabled', { productName });\n } else {\n extendedClient = baseClient;\n logger.info('[Database] Graph extension disabled');\n }\n\n // Step 2: Add workspace extension (wraps on top of graph)\n if (enableWorkspaceExtension) {\n extendedClient = addWorkspaceExtension(extendedClient, workspaceExtensionConfig);\n\n logger.info('[Database] Workspace extension enabled', { productName });\n } else {\n logger.info('[Database] Workspace extension disabled');\n }\n\n // Add backwards compatibility alias\n const db = extendedClient as T & { client: T };\n (db as unknown as Record<string, unknown>)['client'] = db;\n\n // Register shutdown handlers if requested\n if (registerShutdownHandlers) {\n wrapper.registerShutdownHandlers();\n logger.debug('[Database] Shutdown handlers registered');\n }\n\n return {\n db,\n wrapper,\n connect: (retries?: number, delay?: number) => wrapper.connect(retries, delay),\n disconnect: () => wrapper.disconnect(),\n };\n}\n\n/**\n * Pool-tuning options resolved from environment variables.\n */\nexport interface PoolTuningEnv {\n /** Postgres application_name (defaults to `svc=<productName>`). */\n applicationName: string;\n /** Client-side node-postgres query_timeout in ms, if opted in (pooler-safe). */\n queryTimeoutMillis?: number;\n /** Server-side statement_timeout in ms, if opted in. */\n statementTimeoutMillis?: number;\n /** Server-side idle_in_transaction_session_timeout in ms, if opted in. */\n idleInTransactionTimeoutMillis?: number;\n /** Server-side lock_timeout in ms, if opted in. */\n lockTimeoutMillis?: number;\n}\n\n/**\n * Parse a strictly-positive integer environment variable.\n *\n * Returns `undefined` for unset, empty, non-numeric, zero, or negative values —\n * so a misconfigured or absent env var can never silently enable an aggressive\n * (or nonsensical) timeout. This is what keeps the DB-enforced timeouts OFF by\n * default and therefore behavior-preserving.\n */\nfunction parsePositiveIntEnv(name: string): number | undefined {\n const raw = process.env[name];\n if (raw == null || raw.trim() === '') {\n return undefined;\n }\n const parsed = Number.parseInt(raw.trim(), 10);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;\n}\n\n/**\n * Resolve pool tuning (application_name + opt-in DB timeouts) from env vars:\n * - DATABASE_APPLICATION_NAME: overrides the default `svc=<productName>` tag\n * - DATABASE_QUERY_TIMEOUT: client-side node-postgres query_timeout in ms (opt-in, pooler-safe)\n * - DATABASE_STATEMENT_TIMEOUT: server-side statement_timeout in ms (opt-in; DIRECT :5432 only — see note)\n * - DATABASE_IDLE_IN_TRANSACTION_TIMEOUT: idle_in_transaction_session_timeout in ms (opt-in)\n * - DATABASE_LOCK_TIMEOUT: lock_timeout in ms (opt-in)\n *\n * Timeouts are omitted entirely unless explicitly set to a positive integer, so\n * the default is exactly today's behavior (no timeouts).\n *\n * NOTE: prefer `DATABASE_QUERY_TIMEOUT` for services whose `DATABASE_URL` points\n * at the built-in PgBouncer (`:6432`). `DATABASE_STATEMENT_TIMEOUT` and friends\n * are Postgres startup parameters that Azure PgBouncer does not pass through, so\n * they silently have no effect (or fail the connection) on the pooled path.\n */\nexport function resolvePoolTuningFromEnv(productName: string): PoolTuningEnv {\n const tuning: PoolTuningEnv = {\n applicationName: process.env['DATABASE_APPLICATION_NAME']?.trim() || `svc=${productName}`,\n };\n\n const queryTimeout = parsePositiveIntEnv('DATABASE_QUERY_TIMEOUT');\n if (queryTimeout !== undefined) {\n tuning.queryTimeoutMillis = queryTimeout;\n }\n\n const statementTimeout = parsePositiveIntEnv('DATABASE_STATEMENT_TIMEOUT');\n if (statementTimeout !== undefined) {\n tuning.statementTimeoutMillis = statementTimeout;\n }\n\n const idleInTransactionTimeout = parsePositiveIntEnv('DATABASE_IDLE_IN_TRANSACTION_TIMEOUT');\n if (idleInTransactionTimeout !== undefined) {\n tuning.idleInTransactionTimeoutMillis = idleInTransactionTimeout;\n }\n\n const lockTimeout = parsePositiveIntEnv('DATABASE_LOCK_TIMEOUT');\n if (lockTimeout !== undefined) {\n tuning.lockTimeoutMillis = lockTimeout;\n }\n\n return tuning;\n}\n\n/**\n * Create a database client from environment variables\n *\n * Convenience function that reads configuration from standard environment variables:\n * - DATABASE_URL: Connection string (required)\n * - DATABASE_MAX_CONNECTIONS: Max pool connections (default: 20)\n * - DATABASE_APPLICATION_NAME: Postgres application_name (default: `svc=<productName>`)\n * - DATABASE_QUERY_TIMEOUT: opt-in client-side query timeout in ms — the\n * PgBouncer-safe query bound (default: OFF, preserving current behavior)\n * - DATABASE_STATEMENT_TIMEOUT / DATABASE_IDLE_IN_TRANSACTION_TIMEOUT / DATABASE_LOCK_TIMEOUT:\n * opt-in server-side timeouts in ms (default: OFF; DIRECT :5432 only — not\n * honored through the built-in PgBouncer :6432 runtime path)\n * - NODE_ENV: Environment for logging settings\n * - GRAPH_MIDDLEWARE_ENABLED: Enable graph sync (default: true)\n *\n * @example\n * ```typescript\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { createDatabaseClientFromEnv } from '@burdenoff/be-sdk/prisma';\n *\n * const { db } = createDatabaseClientFromEnv(PrismaClient, 'module-tags');\n * export { db };\n * ```\n */\nexport function createDatabaseClientFromEnv<T extends PrismaClientBase>(\n PrismaClientConstructor: new (options: PrismaClientConstructorOptions) => T,\n productName: string,\n overrides?: Partial<DatabaseClientConfig>\n): DatabaseClient<T> {\n const databaseUrl = process.env['DATABASE_URL'];\n if (!databaseUrl) {\n throw new Error('DATABASE_URL environment variable is required');\n }\n\n const isDevelopment = process.env['NODE_ENV'] === 'development';\n\n const config: DatabaseClientConfig = {\n productName,\n databaseUrl,\n maxConnections: parseInt(process.env['DATABASE_MAX_CONNECTIONS'] || '20', 10),\n idleTimeoutMillis: parseInt(process.env['DATABASE_IDLE_TIMEOUT'] || '30000', 10),\n connectionTimeoutMillis: parseInt(process.env['DATABASE_CONNECTION_TIMEOUT'] || '10000', 10),\n ...resolvePoolTuningFromEnv(productName),\n enableQueryLogging: isDevelopment,\n slowQueryThreshold: isDevelopment ? 100 : 500,\n ...overrides,\n };\n\n // Transient acquire retry — env-tunable, and unlike the fields above zero is\n // meaningful (DATABASE_ACQUIRE_RETRIES=0 disables the retry entirely).\n const acquireRetriesRaw = process.env['DATABASE_ACQUIRE_RETRIES']?.trim();\n if (acquireRetriesRaw !== undefined && acquireRetriesRaw !== '' && config.acquireRetries === undefined) {\n const parsed = Number.parseInt(acquireRetriesRaw, 10);\n if (Number.isFinite(parsed) && parsed >= 0) {\n config.acquireRetries = parsed;\n }\n }\n const acquireRetryDelay = parsePositiveIntEnv('DATABASE_ACQUIRE_RETRY_DELAY');\n if (acquireRetryDelay !== undefined && config.acquireRetryDelayMillis === undefined) {\n config.acquireRetryDelayMillis = acquireRetryDelay;\n }\n\n return createDatabaseClient(PrismaClientConstructor, config);\n}\n","/**\n * Database Singleton Manager\n *\n * Provides a singleton pattern for database connections across microservices.\n * Services initialize once at startup and access the db instance globally.\n *\n * This eliminates the need for individual db.ts files in each microservice.\n *\n * @module prisma/manager\n * @category Database\n *\n * @example\n * ```typescript\n * // In your service's index.ts (startup)\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { initializeDatabase } from '@burdenoff/be-sdk/prisma';\n *\n * // Initialize once at startup\n * const { db, connect } = initializeDatabase(PrismaClient, 'module-tags');\n * await connect();\n *\n * // In any other file\n * import { getDb } from '@burdenoff/be-sdk/prisma';\n * const db = getDb();\n * await db.client.user.findMany();\n * ```\n */\n\nimport { logger } from '../logger/index.js';\nimport {\n createDatabaseClient,\n createDatabaseClientFromEnv,\n type DatabaseClient,\n type DatabaseClientConfig,\n} from './factory.js';\nimport type { PrismaClientBase, PrismaClientConstructorOptions, DatabaseReturnType } from './client.js';\n\n/**\n * Global database manager state\n */\ninterface DatabaseManagerState {\n initialized: boolean;\n productName: string | null;\n client: DatabaseClient<PrismaClientBase> | null;\n}\n\n/**\n * Singleton state for the database manager\n */\nconst state: DatabaseManagerState = {\n initialized: false,\n productName: null,\n client: null,\n};\n\n/**\n * Initialize the database singleton\n *\n * Call this once at application startup with your service's PrismaClient.\n * After initialization, use `getDb()` to access the database anywhere.\n *\n * @param PrismaClientConstructor - The generated PrismaClient class from your service\n * @param productName - Product name for graph events (e.g., 'module-tags', 'workspaces')\n * @param config - Optional configuration overrides\n * @returns The database client with db, wrapper, connect, disconnect\n *\n * @throws Error if already initialized with a different product\n *\n * @example\n * ```typescript\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { initializeDatabase } from '@burdenoff/be-sdk/prisma';\n *\n * const { db, connect, disconnect } = initializeDatabase(PrismaClient, 'module-tags');\n * await connect();\n * ```\n */\nexport function initializeDatabase<T extends PrismaClientBase>(\n PrismaClientConstructor: new (options: PrismaClientConstructorOptions) => T,\n productName: string,\n config?: Partial<DatabaseClientConfig>\n): DatabaseClient<T> {\n // Check if already initialized\n if (state.initialized) {\n if (state.productName !== productName) {\n throw new Error(\n `Database already initialized for product \"${state.productName}\". ` +\n `Cannot reinitialize for \"${productName}\".`\n );\n }\n logger.debug('[DatabaseManager] Already initialized, returning existing client', { productName });\n return state.client as DatabaseClient<T>;\n }\n\n // Create the database client using env-based factory\n const client = createDatabaseClientFromEnv(PrismaClientConstructor, productName, config);\n\n // Store in singleton state\n state.initialized = true;\n state.productName = productName;\n state.client = client;\n\n logger.info('[DatabaseManager] Database initialized', { productName });\n\n return client;\n}\n\n/**\n * Initialize the database with explicit configuration\n *\n * Use this when you need full control over database configuration\n * rather than reading from environment variables.\n *\n * @param PrismaClientConstructor - The generated PrismaClient class\n * @param config - Full database configuration\n * @returns The database client\n *\n * @example\n * ```typescript\n * const { db } = initializeDatabaseWithConfig(PrismaClient, {\n * productName: 'module-tags',\n * databaseUrl: 'postgresql://...',\n * maxConnections: 50,\n * enableGraphExtension: false,\n * });\n * ```\n */\nexport function initializeDatabaseWithConfig<T extends PrismaClientBase>(\n PrismaClientConstructor: new (options: PrismaClientConstructorOptions) => T,\n config: DatabaseClientConfig\n): DatabaseClient<T> {\n const { productName } = config;\n\n // Check if already initialized\n if (state.initialized) {\n if (state.productName !== productName) {\n throw new Error(\n `Database already initialized for product \"${state.productName}\". ` +\n `Cannot reinitialize for \"${productName}\".`\n );\n }\n logger.debug('[DatabaseManager] Already initialized, returning existing client', { productName });\n return state.client as DatabaseClient<T>;\n }\n\n // Create the database client\n const client = createDatabaseClient(PrismaClientConstructor, config);\n\n // Store in singleton state\n state.initialized = true;\n state.productName = productName;\n state.client = client;\n\n logger.info('[DatabaseManager] Database initialized with custom config', { productName });\n\n return client;\n}\n\n/**\n * Get the initialized database client\n *\n * Use this anywhere in your application to access the database.\n * Must call `initializeDatabase()` first at application startup.\n *\n * The returned client provides dynamic model access - you can access any\n * model property (e.g., `db.client.user`, `db.client.universalTag`) and\n * TypeScript will allow common Prisma operations (findMany, create, etc.).\n *\n * @returns The extended Prisma client (db) with dynamic model access\n * @throws Error if database not initialized\n *\n * @example\n * ```typescript\n * import { getDb } from '@burdenoff/be-sdk/prisma';\n *\n * const db = getDb();\n * // Dynamic model access works without importing service-specific types\n * const tags = await db.client.universalTag.findMany();\n * const users = await db.client.user.findMany({ where: { active: true } });\n * ```\n */\nexport function getDb<T extends PrismaClientBase = PrismaClientBase>(): DatabaseReturnType<T> {\n if (!state.initialized || !state.client) {\n throw new Error('Database not initialized. Call initializeDatabase() at application startup before using getDb().');\n }\n return state.client.db as unknown as DatabaseReturnType<T>;\n}\n\n/**\n * Get the full database manager\n *\n * Returns the complete database client including wrapper, connect, and disconnect functions.\n * Useful when you need access to connection management utilities.\n *\n * @returns The full database client\n * @throws Error if database not initialized\n *\n * @example\n * ```typescript\n * import { getDatabaseManager } from '@burdenoff/be-sdk/prisma';\n *\n * const { db, wrapper, connect, disconnect } = getDatabaseManager();\n * await connect();\n * ```\n */\nexport function getDatabaseManager<T extends PrismaClientBase = PrismaClientBase>(): DatabaseClient<T> {\n if (!state.initialized || !state.client) {\n throw new Error(\n 'Database not initialized. Call initializeDatabase() at application startup before using getDatabaseManager().'\n );\n }\n return state.client as DatabaseClient<T>;\n}\n\n/**\n * Check if database is initialized\n *\n * @returns True if database has been initialized\n *\n * @example\n * ```typescript\n * if (!isDatabaseInitialized()) {\n * await initializeDatabase(PrismaClient, 'my-service');\n * }\n * ```\n */\nexport function isDatabaseInitialized(): boolean {\n return state.initialized;\n}\n\n/**\n * Get the product name of the initialized database\n *\n * @returns The product name or null if not initialized\n */\nexport function getDatabaseProductName(): string | null {\n return state.productName;\n}\n\n/**\n * Reset the database manager (for testing purposes only)\n *\n * WARNING: This disconnects and resets the database manager.\n * Only use this in test environments for cleanup between tests.\n *\n * @internal\n */\nexport async function resetDatabaseManager(): Promise<void> {\n if (state.client) {\n try {\n await state.client.disconnect();\n } catch (error) {\n logger.warn('[DatabaseManager] Error during disconnect on reset', { error });\n }\n }\n\n state.initialized = false;\n state.productName = null;\n state.client = null;\n\n logger.debug('[DatabaseManager] Database manager reset');\n}\n","/**\n * Prisma Health Check Utilities\n */\n\nimport { logger } from '../logger/index.js';\nimport type { DatabaseHealth } from './types.js';\nimport type { PrismaClientBase } from './client.js';\n\n/**\n * Check database health\n */\nexport async function checkDatabaseHealth<T extends PrismaClientBase>(client: T): Promise<DatabaseHealth> {\n try {\n const start = Date.now();\n await client.$queryRaw`SELECT 1`;\n const latency = Date.now() - start;\n\n return { healthy: true, latency };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error('[Prisma] Health check failed', { error: errorMessage });\n\n return {\n healthy: false,\n error: errorMessage,\n };\n }\n}\n\n/**\n * Test database connection\n */\nexport async function testConnection<T extends PrismaClientBase>(client: T): Promise<boolean> {\n try {\n await client.$queryRaw`SELECT 1`;\n return true;\n } catch (error) {\n logger.error('[Prisma] Connection test failed', {\n error: error instanceof Error ? error.message : String(error),\n });\n return false;\n }\n}\n\n/**\n * Get database version\n */\nexport async function getDatabaseVersion<T extends PrismaClientBase>(client: T): Promise<string | null> {\n try {\n const result = await client.$queryRaw<Array<{ version?: string }>>`SELECT version()`;\n return result[0]?.version ?? null;\n } catch (error) {\n logger.error('[Prisma] Failed to get database version', {\n error: error instanceof Error ? error.message : String(error),\n });\n return null;\n }\n}\n\n/**\n * Get database stats\n */\nexport async function getDatabaseStats<T extends PrismaClientBase>(\n client: T\n): Promise<{\n health: DatabaseHealth;\n version: string | null;\n timestamp: Date;\n}> {\n const [health, version] = await Promise.all([checkDatabaseHealth(client), getDatabaseVersion(client)]);\n\n return {\n health,\n version,\n timestamp: new Date(),\n };\n}\n","/**\n * Prisma Field Extraction Utilities\n *\n * Provides utilities for extracting model fields from Prisma schema.\n * In Prisma 7, DMMF is not available at runtime, so this module provides\n * build-time field extraction through a generator.\n *\n * @module prisma/fields\n */\n\nimport { createRequire } from 'node:module';\nimport { logger } from '../logger/index.js';\n\nconst requireFn = createRequire(import.meta.url);\n\n/**\n * Field extraction options\n */\nexport interface FieldExtractionOptions {\n /** Fields to exclude from extraction */\n excludeFields?: string[];\n /** Whether to include relation fields */\n includeRelations?: boolean;\n /** Custom filter function */\n customFilter?: (field: { name: string; type: string; isRelation: boolean }) => boolean;\n}\n\n/**\n * Field extraction result\n */\nexport interface FieldExtractionResult {\n /** Extracted field names */\n fields: string[];\n /** Metadata about the extraction */\n metadata: {\n /** Total number of fields found */\n totalFields: number;\n /** Number of fields excluded */\n excludedCount: number;\n /** Names of excluded fields */\n excludedFields: string[];\n /** Number of relation fields */\n relationFields: number;\n };\n}\n\n/**\n * Model fields mapping\n * This will be generated at build time by the Prisma generator\n */\nexport type ModelFieldsMap = Record<\n string,\n {\n fields: string[];\n relations: string[];\n }\n>;\n\n/**\n * Import generated fields from the consuming package\n * This function should be used by backends to load their generated fields\n */\nexport function loadGeneratedFields(generatedFieldsPath: string): ModelFieldsMap {\n try {\n // Dynamic import of generated fields using createRequire\n const generated = requireFn(generatedFieldsPath) as { default: ModelFieldsMap };\n return generated.default || generated;\n } catch (error) {\n logger.error('[Prisma] Failed to load generated fields', {\n error: error instanceof Error ? error.message : String(error),\n path: generatedFieldsPath,\n });\n throw new Error(`Failed to load generated fields from ${generatedFieldsPath}`);\n }\n}\n\n/**\n * Extract fields from generated model fields with options\n */\nexport function extractFieldsFromModel(\n modelName: string,\n modelFieldsMap: ModelFieldsMap,\n options: FieldExtractionOptions = {}\n): FieldExtractionResult {\n const modelFields = modelFieldsMap[modelName];\n\n if (!modelFields) {\n throw new Error(\n `Model \"${modelName}\" not found in generated fields. ` +\n `Available models: ${Object.keys(modelFieldsMap).join(', ')}`\n );\n }\n\n const { excludeFields = [], includeRelations = false, customFilter } = options;\n\n // Start with scalar fields\n let fields = [...modelFields.fields];\n\n // Add relations if requested\n if (includeRelations) {\n fields = [...fields, ...modelFields.relations];\n }\n\n // Track excluded fields\n const excluded: string[] = [];\n\n // Apply exclusions\n if (excludeFields.length > 0) {\n fields = fields.filter((field) => {\n if (excludeFields.includes(field)) {\n excluded.push(field);\n return false;\n }\n return true;\n });\n }\n\n // Apply custom filter\n if (customFilter) {\n fields = fields.filter((fieldName) => {\n const isRelation = modelFields.relations.includes(fieldName);\n const shouldInclude = customFilter({\n name: fieldName,\n type: 'unknown', // Type information not available without full DMMF\n isRelation,\n });\n\n if (!shouldInclude) {\n excluded.push(fieldName);\n }\n\n return shouldInclude;\n });\n }\n\n return {\n fields,\n metadata: {\n totalFields: modelFields.fields.length + modelFields.relations.length,\n excludedCount: excluded.length,\n excludedFields: excluded,\n relationFields: modelFields.relations.length,\n },\n };\n}\n\n/**\n * Get all field names for a model (without options)\n */\nexport function getModelFields(modelName: string, modelFieldsMap: ModelFieldsMap, includeRelations = false): string[] {\n const result = extractFieldsFromModel(modelName, modelFieldsMap, { includeRelations });\n return result.fields;\n}\n\n/**\n * Check if a model exists in the generated fields\n */\nexport function hasModel(modelName: string, modelFieldsMap: ModelFieldsMap): boolean {\n return modelName in modelFieldsMap;\n}\n\n/**\n * Get all available model names\n */\nexport function getAllModelNames(modelFieldsMap: ModelFieldsMap): string[] {\n return Object.keys(modelFieldsMap);\n}\n","/**\n * Prisma Context Filtering Utilities\n *\n * Utilities for handling operation context in queries, mutations, and filtering.\n * Context JSON enables multi-dimensional data isolation across workspaces, users, projects, etc.\n *\n * @module prisma/context\n * @category Database\n */\n\nimport { isSameProductSlug, productSlugVariants } from '../product-alias/index.js';\n\n/**\n * Context filter input for querying entities by context\n */\nexport interface ContextFilterInput {\n workspaceId?: string | null;\n userId?: string | null;\n projectId?: string | null;\n appId?: string | null;\n /** Product identifier (e.g. \"vibecontrols\", \"workspaces\"). Stamped on cross-product\n * records so admin filters can scope by originating product. */\n productId?: string | null;\n /** Organization identifier within the tenant. */\n organizationId?: string | null;\n}\n\n/**\n * Operation context for create/update operations\n */\nexport interface OperationContext extends ContextFilterInput {\n custom?: Record<string, unknown> | null;\n}\n\n/**\n * Prisma JSON filter type (simplified for context filtering)\n * This type is designed to be compatible with Prisma's JsonNullableFilter\n * Uses Record<string, unknown> for maximum compatibility with various Prisma versions\n */\nexport type PrismaJsonFilter = Record<string, unknown>;\n\n/**\n * One entry of {@link buildContextWhereConditions}: a JSON-path predicate on `context`,\n * or an `OR` of them (used for a renamed product's slug twins).\n */\nexport type ContextWhereCondition = { context: PrismaJsonFilter } | { OR: Array<{ context: PrismaJsonFilter }> };\n\n/**\n * JSON value type for Prisma (includes null for reading from DB)\n */\nexport type JsonValue = string | number | boolean | null | { [key: string]: JsonValue } | JsonValue[];\n\n/**\n * Input JSON value type for Prisma (excludes null for writing to DB)\n * Compatible with Prisma's InputJsonValue type\n */\nexport type InputJsonValue = string | number | boolean | { [key: string]: InputJsonValue } | InputJsonValue[];\n\n/**\n * Build Prisma where condition for context filtering.\n * Uses PostgreSQL JSONB containment operators for efficient queries.\n *\n * @param contextFilter - The context filter input\n * @returns Prisma where clause for context field, or undefined if no filter provided\n *\n * @example\n * ```typescript\n * const contextWhere = buildContextWhereClause({\n * workspaceId: '123',\n * projectId: '456'\n * });\n * // Returns: { path: ['workspaceId'], equals: '123' }\n * ```\n */\nexport function buildContextWhereClause(\n contextFilter: ContextFilterInput | null | undefined\n): PrismaJsonFilter | undefined {\n if (!contextFilter) {\n return undefined;\n }\n\n // Build array of path conditions for each non-null field\n const conditions: PrismaJsonFilter[] = [];\n\n if (contextFilter.workspaceId != null) {\n conditions.push({\n path: ['workspaceId'],\n equals: contextFilter.workspaceId,\n });\n }\n\n if (contextFilter.userId != null) {\n conditions.push({\n path: ['userId'],\n equals: contextFilter.userId,\n });\n }\n\n if (contextFilter.projectId != null) {\n conditions.push({\n path: ['projectId'],\n equals: contextFilter.projectId,\n });\n }\n\n if (contextFilter.appId != null) {\n conditions.push({\n path: ['appId'],\n equals: contextFilter.appId,\n });\n }\n\n if (contextFilter.productId != null) {\n conditions.push({\n path: ['productId'],\n equals: contextFilter.productId,\n });\n }\n\n if (contextFilter.organizationId != null) {\n conditions.push({\n path: ['organizationId'],\n equals: contextFilter.organizationId,\n });\n }\n\n // If no conditions, return undefined\n if (conditions.length === 0) {\n return undefined;\n }\n\n // If single condition, return it directly\n if (conditions.length === 1) {\n return conditions[0];\n }\n\n // For multiple conditions, return the first one\n // Caller should use buildContextWhereConditions for multiple AND conditions\n return conditions[0];\n}\n\n/**\n * Build context where conditions as an array for use in AND clause.\n * This is useful when you need to filter by multiple context fields.\n *\n * @param contextFilter - The context filter input\n * @returns Array of Prisma where conditions, each targeting the context field\n *\n * @example\n * ```typescript\n * const conditions = buildContextWhereConditions({\n * workspaceId: '123',\n * projectId: '456'\n * });\n * // Use in Prisma query:\n * prisma.entity.findMany({\n * where: { AND: conditions }\n * });\n * ```\n */\nexport function buildContextWhereConditions(\n contextFilter: ContextFilterInput | null | undefined\n): ContextWhereCondition[] {\n if (!contextFilter) {\n return [];\n }\n\n const conditions: ContextWhereCondition[] = [];\n\n if (contextFilter.workspaceId != null) {\n conditions.push({\n context: {\n path: ['workspaceId'],\n equals: contextFilter.workspaceId,\n },\n });\n }\n\n if (contextFilter.userId != null) {\n conditions.push({\n context: {\n path: ['userId'],\n equals: contextFilter.userId,\n },\n });\n }\n\n if (contextFilter.projectId != null) {\n conditions.push({\n context: {\n path: ['projectId'],\n equals: contextFilter.projectId,\n },\n });\n }\n\n if (contextFilter.appId != null) {\n conditions.push({\n context: {\n path: ['appId'],\n equals: contextFilter.appId,\n },\n });\n }\n\n if (contextFilter.productId != null) {\n // A renamed product (botlit → botmanor) matches rows stored under either slug while\n // they are migrated; every other product keeps the exact single-slug predicate.\n const slugs = productSlugVariants(contextFilter.productId);\n if (slugs.length > 1) {\n conditions.push({\n OR: slugs.map((slug) => ({ context: { path: ['productId'], equals: slug } })),\n });\n } else {\n conditions.push({\n context: {\n path: ['productId'],\n equals: contextFilter.productId,\n },\n });\n }\n }\n\n if (contextFilter.organizationId != null) {\n conditions.push({\n context: {\n path: ['organizationId'],\n equals: contextFilter.organizationId,\n },\n });\n }\n\n return conditions;\n}\n\n/**\n * Convert context input to Prisma JSON format for create/update operations.\n *\n * @param contextInput - The context input\n * @returns JSON value for the context field, or undefined if empty\n *\n * @example\n * ```typescript\n * const contextJson = toContextJson({\n * workspaceId: '123',\n * userId: '456'\n * });\n * // Use in Prisma create:\n * prisma.entity.create({\n * data: { context: contextJson }\n * });\n * ```\n */\nexport function toContextJson(contextInput: OperationContext | null | undefined): InputJsonValue | undefined {\n if (!contextInput) {\n return undefined;\n }\n\n // Remove null values and build clean context object\n const context: Record<string, InputJsonValue> = {};\n\n if (contextInput.workspaceId != null) {\n context['workspaceId'] = contextInput.workspaceId;\n }\n if (contextInput.userId != null) {\n context['userId'] = contextInput.userId;\n }\n if (contextInput.projectId != null) {\n context['projectId'] = contextInput.projectId;\n }\n if (contextInput.appId != null) {\n context['appId'] = contextInput.appId;\n }\n if (contextInput.productId != null) {\n context['productId'] = contextInput.productId;\n }\n if (contextInput.organizationId != null) {\n context['organizationId'] = contextInput.organizationId;\n }\n if (contextInput.custom != null) {\n context['custom'] = contextInput.custom as InputJsonValue;\n }\n\n // Return undefined if no fields set\n if (Object.keys(context).length === 0) {\n return undefined;\n }\n\n return context;\n}\n\n/**\n * Filter out null values from an object for Prisma compatibility\n */\nfunction filterNullValues(obj: Record<string, unknown>): Record<string, InputJsonValue> {\n const filtered: Record<string, InputJsonValue> = {};\n for (const [key, value] of Object.entries(obj)) {\n if (value !== null) {\n filtered[key] = value as InputJsonValue;\n }\n }\n return filtered;\n}\n\n/**\n * Merge a single field into the merged context object\n */\nfunction mergeContextField(\n merged: Record<string, InputJsonValue>,\n fieldName: string,\n fieldValue: string | Record<string, unknown> | null | undefined\n): void {\n if (fieldValue === undefined) {\n return; // Don't touch this field\n }\n\n if (fieldValue === null) {\n delete merged[fieldName]; // Explicitly remove\n } else {\n merged[fieldName] = fieldValue as InputJsonValue; // Set new value\n }\n}\n\n/**\n * Merge existing context with new context input.\n * New values override existing ones, but undefined values are preserved from existing.\n *\n * @param existingContext - The existing context JSON from database\n * @param newContext - The new context input\n * @returns Merged context as InputJsonValue (suitable for Prisma writes)\n *\n * @example\n * ```typescript\n * const merged = mergeContext(\n * { workspaceId: '123', userId: 'old' },\n * { userId: 'new', projectId: '456' }\n * );\n * // Result: { workspaceId: '123', userId: 'new', projectId: '456' }\n * ```\n */\nexport function mergeContext(\n existingContext: JsonValue | null | undefined,\n newContext: OperationContext | null | undefined\n): InputJsonValue | undefined {\n // If no new context, return existing (excluding null values)\n if (!newContext) {\n if (!existingContext) {\n return undefined;\n }\n // Filter out null values from existing context for Prisma compatibility\n if (typeof existingContext === 'object' && !Array.isArray(existingContext)) {\n const filtered = filterNullValues(existingContext);\n return Object.keys(filtered).length > 0 ? filtered : undefined;\n }\n return existingContext as InputJsonValue;\n }\n\n // If no existing context, convert new to JSON\n if (!existingContext || typeof existingContext !== 'object' || Array.isArray(existingContext)) {\n return toContextJson(newContext);\n }\n\n // Merge existing with new\n const merged = filterNullValues(existingContext);\n\n // Merge each field from new context\n mergeContextField(merged, 'workspaceId', newContext.workspaceId);\n mergeContextField(merged, 'userId', newContext.userId);\n mergeContextField(merged, 'projectId', newContext.projectId);\n mergeContextField(merged, 'appId', newContext.appId);\n mergeContextField(merged, 'productId', newContext.productId);\n mergeContextField(merged, 'organizationId', newContext.organizationId);\n mergeContextField(merged, 'custom', newContext.custom);\n\n return Object.keys(merged).length > 0 ? merged : undefined;\n}\n\n/**\n * Parse context JSON from database to OperationContext interface.\n *\n * @param contextJson - The context JSON from database\n * @returns Parsed OperationContext or null\n *\n * @example\n * ```typescript\n * const context = parseContext(entity.context);\n * if (context?.workspaceId) {\n * // Use workspace-specific logic\n * }\n * ```\n */\nexport function parseContext(contextJson: JsonValue | null | undefined): OperationContext | null {\n if (!contextJson || typeof contextJson !== 'object' || Array.isArray(contextJson)) {\n return null;\n }\n\n const ctx = contextJson as Record<string, unknown>;\n\n return {\n workspaceId: typeof ctx['workspaceId'] === 'string' ? ctx['workspaceId'] : null,\n userId: typeof ctx['userId'] === 'string' ? ctx['userId'] : null,\n projectId: typeof ctx['projectId'] === 'string' ? ctx['projectId'] : null,\n appId: typeof ctx['appId'] === 'string' ? ctx['appId'] : null,\n productId: typeof ctx['productId'] === 'string' ? ctx['productId'] : null,\n organizationId: typeof ctx['organizationId'] === 'string' ? ctx['organizationId'] : null,\n custom: typeof ctx['custom'] === 'object' ? (ctx['custom'] as Record<string, unknown>) : null,\n };\n}\n\n/**\n * Check if context matches filter criteria\n *\n * @param context - The context to check\n * @param filter - The filter criteria\n * @returns True if context matches all filter criteria\n */\nexport function contextMatches(context: OperationContext | null | undefined, filter: ContextFilterInput): boolean {\n if (!context) {\n return false;\n }\n\n if (filter.workspaceId != null && context.workspaceId !== filter.workspaceId) {\n return false;\n }\n if (filter.userId != null && context.userId !== filter.userId) {\n return false;\n }\n if (filter.projectId != null && context.projectId !== filter.projectId) {\n return false;\n }\n if (filter.appId != null && context.appId !== filter.appId) {\n return false;\n }\n // Renamed products (botlit → botmanor) match under either slug while rows are migrated.\n if (filter.productId != null && !isSameProductSlug(context.productId, filter.productId)) {\n return false;\n }\n if (filter.organizationId != null && context.organizationId !== filter.organizationId) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Create a default context from SDK context\n *\n * @param sdkContext - The SDK context (from AsyncLocalStorage)\n * @returns Operation context with workspace and user info\n */\nexport function createContextFromSDK(sdkContext: {\n workspaceId?: string;\n userId?: string;\n projectId?: string;\n appId?: string;\n productId?: string;\n organizationId?: string;\n}): OperationContext {\n return {\n workspaceId: sdkContext.workspaceId ?? null,\n userId: sdkContext.userId ?? null,\n projectId: sdkContext.projectId ?? null,\n appId: sdkContext.appId ?? null,\n productId: sdkContext.productId ?? null,\n organizationId: sdkContext.organizationId ?? null,\n };\n}\n"]}
package/dist/index.js CHANGED
@@ -5,11 +5,11 @@ export { ActivityModule, TrackerModule, UsageModule } from './chunk-NCC5UN3L.js'
5
5
  export { NAME_MAX_LENGTH, NAME_MIN_LENGTH, USERNAME_MAX_LENGTH, USERNAME_MIN_LENGTH, validation_exports as Validation, lengthInCodePoints, validateName, validateUserFields, validateUsername } from './chunk-AHEXIONU.js';
6
6
  export { observability_exports as Observability } from './chunk-VAT66FJA.js';
7
7
  export { platform_exports as Platform } from './chunk-Z5BURBFZ.js';
8
- export { prisma_exports as Prisma } from './chunk-PKKVCYJH.js';
8
+ export { prisma_exports as Prisma } from './chunk-E5HKS7KD.js';
9
9
  export { PRODUCT_RENAMES, PRODUCT_RENAME_EMIT, PRODUCT_SLUG_ALIASES, product_alias_exports as ProductAlias, RENAME_CONCERNS, billingIdVariants, emitBillingId, emitName, emitProductSlug, emitQuotaKey, emitRbacResource, emitTemplateKey, isLegacyName, isSameBillingId, isSameGraphQLName, isSameName, isSameProductSlug, isSameQuotaKey, isSameRbacResource, isSameTemplateKey, nameVariants, normalizeBillingId, normalizeGraphQLName, normalizeProductSlug, normalizeQuotaKey, normalizeRbacResource, normalizeTemplateKey, productSlugVariants, quotaKeyVariants, rbacResourceVariants, readRenamedEnv, templateKeyVariants, toCurrentName, toLegacyName } from './chunk-OBBCR6WY.js';
10
10
  import { RBACModule } from './chunk-5JNHVKHG.js';
11
11
  export { RBACModule, createRBACDirective, createRBACDirectiveForLayer, createRBACDirectiveFromEnv } from './chunk-5JNHVKHG.js';
12
- import './chunk-HMVQOZHM.js';
12
+ import './chunk-3Z2VRCT6.js';
13
13
  export { instrumentation_exports as Instrumentation } from './chunk-E5DTAGCA.js';
14
14
  export { middleware_exports as Middleware } from './chunk-ELU7VL3E.js';
15
15
  import { TenantNotificationsModule, NotificationsModule } from './chunk-INAZ3PKF.js';
@@ -1,6 +1,6 @@
1
- export { buildContextWhereClause, buildContextWhereConditions, checkDatabaseHealth, contextMatches, createContextFromSDK, createDatabaseClient, createDatabaseClientFromEnv, extractFieldsFromModel, getAllModelNames, getDatabaseManager, getDatabaseProductName, getDatabaseStats, getDatabaseVersion, getDb, getModelFields, hasModel, initializeDatabase, initializeDatabaseWithConfig, isDatabaseInitialized, loadGeneratedFields, mergeContext, parseContext, resetDatabaseManager, resolvePoolTuningFromEnv, testConnection, toContextJson } from '../chunk-PKKVCYJH.js';
1
+ export { buildContextWhereClause, buildContextWhereConditions, checkDatabaseHealth, contextMatches, createContextFromSDK, createDatabaseClient, createDatabaseClientFromEnv, extractFieldsFromModel, getAllModelNames, getDatabaseManager, getDatabaseProductName, getDatabaseStats, getDatabaseVersion, getDb, getModelFields, hasModel, initializeDatabase, initializeDatabaseWithConfig, isDatabaseInitialized, loadGeneratedFields, mergeContext, parseContext, resetDatabaseManager, resolvePoolTuningFromEnv, testConnection, toContextJson } from '../chunk-E5HKS7KD.js';
2
2
  import '../chunk-OBBCR6WY.js';
3
- export { addWorkspaceExtension, buildTransactionContextStatement, defaultWorkspaceExtensionConfig, getCallerTransaction, getWorkspaceContext, injectCreateFields, injectWhereWorkspaceId, maybeSetRlsGuc, maybeTagConnection, resetCallerTransactionStateForTests, runOperationInCallerTransaction, runOperationWithRlsGuc, setWorkspaceContext, withWorkspaceContext, withWorkspaceContextSync } from '../chunk-HMVQOZHM.js';
3
+ export { addWorkspaceExtension, buildTransactionContextStatement, defaultWorkspaceExtensionConfig, getCallerTransaction, getWorkspaceContext, injectCreateFields, injectWhereWorkspaceId, maybeSetRlsGuc, maybeTagConnection, resetCallerTransactionStateForTests, runOperationInCallerTransaction, runOperationWithRlsGuc, setWorkspaceContext, withWorkspaceContext, withWorkspaceContextSync } from '../chunk-3Z2VRCT6.js';
4
4
  export { PrismaClientWrapper, configurePrismaLogging, createConnectionPool, createPrismaAdapter, createPrismaClient, ensureServiceApplicationName, installAcquireRetry, isTransientAcquireError } from '../chunk-6VK53YR3.js';
5
5
  import '../chunk-XTIOBNT7.js';
6
6
  import '../chunk-P67HNJGL.js';
@@ -1,7 +1,7 @@
1
1
  import { createHumanReadableErrorPlugin, formatHttpError, normalizeGraphQLResponse, createHttpErrorResponse } from '../chunk-6GL4SLU7.js';
2
2
  export { UserFacingGraphQLError, createHttpErrorResponse, createHumanReadableErrorPlugin, createWorkspaceGuardPlugin, formatHttpError, normalizeError, normalizeExecutionResultErrors, normalizeGraphQLResponse, normalizeGraphQLResponsePayload, toUserFacingGraphQLError } from '../chunk-6GL4SLU7.js';
3
3
  import { getWorkspaceQuotaRegistry } from '../chunk-WTEHAVBX.js';
4
- import { setWorkspaceContext, withWorkspaceContext } from '../chunk-HMVQOZHM.js';
4
+ import { setWorkspaceContext, withWorkspaceContext } from '../chunk-3Z2VRCT6.js';
5
5
  import { I18n } from '../chunk-EBDHIL7V.js';
6
6
  import { getMetricsRegistry } from '../chunk-AWPNRV3L.js';
7
7
  import { ContextManager } from '../chunk-RZOFS2BQ.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/be-sdk",
3
- "version": "2026.1015.1",
3
+ "version": "2026.1015.2",
4
4
  "description": "Backend SDK for Burdenoff products providing unified access to notifications, RBAC, activity tracking, usage monitoring, and more",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/prisma/workspace-extension.ts"],"names":["workspaceContextStore","AsyncLocalStorage","fallbackContext","setWorkspaceContext","context","enterWith","getWorkspaceContext","getStore","withWorkspaceContext","fn","run","withWorkspaceContextSync","defaultWorkspaceExtensionConfig","enabled","enableReadIsolation","enableDeleteIsolation","enableUpdateWhereIsolation","populateContextJson","populateCreatedBy","populateUpdatedBy","populateTenantId","populateOnBehalfOf","excludeModels","excludeModelsFromReadIsolation","strictMode","allowedUnguardedOperations","debug","enableApplicationNameTagging","enableRlsGucTagging","hasField","data","field","injectCreateFields","wsCtx","config","injected","workspaceId","tenantId","actorId","onBehalfOf","contextJson","buildContextJsonFromWorkspaceContext","injectUpdateFields","injectWhereClause","where","organizationId","projectId","appId","Object","keys","length","undefined","injectWhereWorkspaceId","ctx","stripSkipFlag","args","cleaned","isExcludedFromReadIsolation","model","includes","enforceStrictMode","operation","opKey","Error","taggedContexts","WeakSet","maybeTagConnection","rawPrisma","has","add","safeSvc","process","env","replace","safeWs","tag","$executeRawUnsafe","delete","rlsTaggedContexts","maybeSetRlsGuc","modelToClientProperty","charAt","toLowerCase","slice","runOperationWithRlsGuc","rootClient","clientProperty","$transaction","tx","delegate","method","runQueryWithRlsGuc","query","pendingQuery","pendingContext","sanitizeWorkspaceId","requestTransaction","result","getCallerTransaction","internalParams","transaction","kind","id","descriptor","buildApplicationNameTag","buildTransactionContextStatement","settings","params","push","sql","join","key","MAX_TRACKED_CALLER_TRANSACTIONS","callerTransactionStates","Map","rememberCallerTransaction","state","set","size","oldest","next","value","applyCallerTransactionContext","statement","pending","runOperationInCallerTransaction","get","inflight","ready","catch","resetCallerTransactionStateForTests","clear","addWorkspaceExtension","baseClient","fullConfig","logger","info","rawPrismaForContinuations","transactionDelegate","rawPrismaForCallerTransactions","tagsTransactions","dispatch","_operation","finalArgs","callerTransaction","__internalParams","rawOperation","prismaClient","rawOperationHooks","$queryRaw","$executeRaw","$queryRawUnsafe","$queryRawTyped","withQueryHooks","$extends","$allModels","create","_skipWorkspaceInjection","injectedData","injectedKeys","filter","k","createMany","dataArray","Array","isArray","map","item","createManyAndReturn","update","injectedWhere","injectedDataKeys","whereChanged","updateMany","upsert","injectedCreate","injectedUpdate","findMany","findFirst","findFirstOrThrow","findUnique","findUniqueOrThrow","count","aggregate","groupBy","deleteMany","wrapped","client","input","options","parent","$parent","setContext","then","results","call"],"mappings":"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","file":"chunk-HMVQOZHM.js","sourcesContent":["/**\n * Prisma Workspace Extension\n *\n * Automatically injects workspaceId into ALL Prisma operations using\n * request-scoped context from AsyncLocalStorage:\n *\n * **Write operations** (create, createMany, update, upsert):\n * - Auto-populates `workspaceId`, `tenantId`, `createdBy`, `updatedBy`, `context` JSON\n *\n * **Read operations** (findMany, findFirst, findUnique, count, aggregate, groupBy):\n * - Auto-injects `workspaceId` into the `where` clause for workspace isolation\n *\n * **Delete operations** (delete, deleteMany):\n * - Auto-injects `workspaceId` into the `where` clause to prevent cross-workspace deletion\n *\n * **Update where clause** (update, updateMany):\n * - Auto-injects `workspaceId` into the `where` clause to prevent cross-workspace updates\n *\n * **How it works:**\n * 1. The GraphQL server's buildContext extracts workspaceId from x-workspace-id header\n * 2. The workspace context store (AsyncLocalStorage) holds the current request's workspace info\n * 3. This Prisma extension intercepts ALL operations and auto-injects workspaceId\n *\n * **What gets auto-populated on writes:**\n * - `workspaceId` field (String or String?) - set from context if not explicitly provided\n * - `context` field (Json) - merged with workspace/actor info if not explicitly provided\n * - `tenantId` field (String or String?) - set from context if not explicitly provided\n * - `createdBy` / `updatedBy` fields - set from actor context if not explicitly provided\n *\n * **What gets auto-injected on reads/updates/deletes:**\n * - `workspaceId` in the `where` clause - ensures queries only access data within the workspace\n *\n * **Opt-out:**\n * - Explicitly providing `workspaceId` in the where/data will override auto-injection\n * - Pass `_skipWorkspaceInjection: true` in the query args to skip entirely\n * - Set `enableReadIsolation: false` in config to disable read-side injection only\n * - Add model names to `excludeModels` to skip specific models\n *\n * @module prisma/workspace-extension\n * @category Database\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { logger } from '../logger/index.js';\nimport type { InputJsonValue } from './context.js';\n\n// ============================================================================\n// Workspace Context Store (AsyncLocalStorage)\n// ============================================================================\n\n/**\n * Workspace context for the current request scope\n */\nexport interface WorkspaceContext {\n /** Workspace ID (from x-workspace-id header) */\n workspaceId?: string;\n /** Tenant ID (from x-tenant-id header or derived from workspace) */\n tenantId?: string;\n /** Actor ID (user/service/app performing the operation) */\n actorId?: string;\n /** Actor type (user, app, service, super_admin) */\n actorType?: string;\n /** Organization ID */\n organizationId?: string;\n /** Project ID */\n projectId?: string;\n /** App ID */\n appId?: string;\n /** On behalf of actor ID (for consent-based delegation) */\n onBehalfOf?: string;\n}\n\n/**\n * AsyncLocalStorage for workspace context\n * This is separate from the SDK's general ContextManager to allow\n * fine-grained control over workspace-specific context propagation.\n */\nconst workspaceContextStore = new AsyncLocalStorage<WorkspaceContext>();\n\n/**\n * Fallback context for environments where AsyncLocalStorage.enterWith()\n * doesn't propagate across async boundaries (e.g., Bun + GraphQL Yoga).\n *\n * IMPORTANT: This is NOT request-isolated — it's a module-level singleton.\n * It works for single-request-at-a-time scenarios but could race under\n * concurrent requests. The ALS is the primary mechanism; this is a fallback.\n */\nlet fallbackContext: WorkspaceContext | undefined;\n\n/**\n * Set workspace context for the current async scope.\n * Call this in your GraphQL context builder or middleware.\n *\n * Uses AsyncLocalStorage.enterWith() as the primary mechanism,\n * with a module-level fallback for runtimes where enterWith()\n * doesn't propagate through all async chains (e.g., Bun).\n *\n * @param context - The workspace context for this request\n *\n * @example\n * ```typescript\n * // In your server's buildContext:\n * import { setWorkspaceContext } from '@burdenoff/be-sdk/prisma';\n *\n * buildContext: async (defaultContext) => {\n * setWorkspaceContext({\n * workspaceId: defaultContext.workspace?.id,\n * tenantId: defaultContext.tenant?.id,\n * actorId: defaultContext.actor?.id,\n * actorType: defaultContext.actor?.type,\n * organizationId: defaultContext.organization?.id,\n * });\n * return defaultContext;\n * }\n * ```\n */\nexport function setWorkspaceContext(context: WorkspaceContext): void {\n workspaceContextStore.enterWith(context);\n fallbackContext = context;\n}\n\n/**\n * Get the current workspace context from AsyncLocalStorage.\n * Falls back to module-level context if ALS returns undefined\n * (can happen in Bun where enterWith() doesn't propagate through\n * some async chains like GraphQL Yoga's execution pipeline).\n *\n * @returns The current workspace context, or undefined if not set\n */\nexport function getWorkspaceContext(): WorkspaceContext | undefined {\n return workspaceContextStore.getStore() ?? fallbackContext;\n}\n\n/**\n * Run a function with a specific workspace context.\n * The context is isolated to this execution and its children.\n *\n * @param context - The workspace context\n * @param fn - The function to run\n * @returns The result of the function\n *\n * @example\n * ```typescript\n * const result = await withWorkspaceContext(\n * { workspaceId: 'ws-123', actorId: 'user-456' },\n * async () => {\n * // All Prisma operations in here will auto-inject workspaceId\n * return await prisma.tag.create({ data: { name: 'test' } });\n * }\n * );\n * ```\n */\nexport async function withWorkspaceContext<T>(context: WorkspaceContext, fn: () => Promise<T>): Promise<T> {\n return workspaceContextStore.run(context, fn);\n}\n\n/**\n * Run a synchronous function with a specific workspace context.\n */\nexport function withWorkspaceContextSync<T>(context: WorkspaceContext, fn: () => T): T {\n return workspaceContextStore.run(context, fn);\n}\n\n// ============================================================================\n// Extension Configuration\n// ============================================================================\n\n/**\n * Configuration for the workspace extension\n */\nexport interface WorkspaceExtensionConfig {\n /**\n * Enable automatic workspaceId injection on create/update\n * @default true\n */\n enabled?: boolean;\n\n /**\n * Enable automatic workspaceId injection on read operations\n * (findMany, findFirst, findUnique, findFirstOrThrow, findUniqueOrThrow,\n * count, aggregate, groupBy)\n *\n * When enabled, every read query automatically includes `workspaceId`\n * in the `where` clause, preventing cross-workspace data leakage.\n *\n * @default true\n */\n enableReadIsolation?: boolean;\n\n /**\n * Enable automatic workspaceId injection on delete operations\n * (delete, deleteMany)\n *\n * When enabled, every delete operation automatically includes `workspaceId`\n * in the `where` clause, preventing cross-workspace deletion.\n *\n * @default true\n */\n enableDeleteIsolation?: boolean;\n\n /**\n * Enable automatic workspaceId injection into update/updateMany `where` clauses.\n *\n * When enabled, update operations automatically include `workspaceId`\n * in the `where` clause in addition to the `data` injection,\n * preventing cross-workspace updates.\n *\n * @default true\n */\n enableUpdateWhereIsolation?: boolean;\n\n /**\n * Automatically populate the `context` JSON field with workspace/actor info\n * @default true\n */\n populateContextJson?: boolean;\n\n /**\n * Automatically populate `createdBy` field on create operations\n * @default true\n */\n populateCreatedBy?: boolean;\n\n /**\n * Automatically populate `updatedBy` field on update operations\n * @default true\n */\n populateUpdatedBy?: boolean;\n\n /**\n * Automatically populate `tenantId` field from context\n * @default false (tenantId is typically derived from workspaceId at the DB level)\n */\n populateTenantId?: boolean;\n\n /**\n * Automatically populate the `onBehalfOf` field on create operations\n * (consent-based delegation tracking — defaults to the acting actor when no\n * delegation is present).\n *\n * Unlike `populateContextJson`/`populateCreatedBy`/`populateUpdatedBy`, this\n * has no per-model opt-out other than `excludeModels` (which also disables\n * RLS GUC tagging and isolation for that model). Set to `false` for services\n * whose Prisma models don't carry an `onBehalfOf` column — otherwise every\n * create on those models throws `Unknown argument onBehalfOf` from Prisma's\n * client-side validation.\n *\n * @default true\n */\n populateOnBehalfOf?: boolean;\n\n /**\n * Models to exclude from auto-injection (both reads and writes).\n * Use this for models that intentionally don't have workspaceId.\n *\n * Common exclusions: system tables, infra tables, global reference data.\n *\n * @default []\n */\n excludeModels?: string[];\n\n /**\n * Models to exclude from read isolation only.\n * These models will still get write-side injection (workspaceId on create)\n * but reads will NOT have workspaceId auto-injected into `where`.\n *\n * Use this for child/join tables where workspace scoping is inherited\n * through parent relations, or for models queried by ID that don't\n * have a workspaceId column.\n *\n * @default []\n */\n excludeModelsFromReadIsolation?: string[];\n\n /**\n * When true, throws an error if workspaceId is missing from context\n * for any non-excluded model operation. This prevents silent\n * workspace-unscoped queries that could leak data across workspaces.\n *\n * When false, operations without workspace context proceed without\n * workspaceId injection (legacy behavior).\n *\n * @default true\n */\n strictMode?: boolean;\n\n /**\n * Operations that are allowed without workspace context even in strict mode.\n * Use `Model.operation` format (e.g., `['Workspace.create', 'RevokedToken.findMany']`).\n *\n * Valid operation names: create, createMany, createManyAndReturn, update, updateMany,\n * upsert, findMany, findFirst, findFirstOrThrow, findUnique, findUniqueOrThrow,\n * count, aggregate, groupBy, delete, deleteMany.\n *\n * @default []\n */\n allowedUnguardedOperations?: string[];\n\n /**\n * Log injection events (useful for debugging)\n * @default false\n */\n debug?: boolean;\n\n /**\n * Tag the PostgreSQL connection with workspace attribution for pg_stat_activity visibility.\n *\n * When enabled, the first DB operation per workspace context sets:\n * `application_name = 'svc=<SERVICE_NAME>;ws=<workspaceId>'`\n *\n * This makes workspace-level query attribution visible in pg_stat_activity,\n * pg_locks, auto_explain, and monitoring tools without any schema changes.\n * Subsequent operations in the same request are deduplicated via WeakSet,\n * costing ~0 overhead after the first round-trip per request context.\n *\n * NOTE: This is a session-level SET so attribution may drift across ops\n * that reuse the same pooled connection from different requests. Use for\n * aggregate observability, not per-query forensics.\n *\n * @default false\n */\n enableApplicationNameTagging?: boolean;\n\n /**\n * Set the `app.workspace_id` GUC for Row Level Security enforcement.\n *\n * When enabled, every workspace-scoped operation runs with\n * `SET LOCAL app.workspace_id = '<workspaceId>'`\n * in effect (see \"Transactions\" below for how that is scoped).\n *\n * RLS policies using `current_setting('app.workspace_id', true)` then filter\n * rows by workspace, providing a defense-in-depth backstop to the application-\n * layer workspaceId injection in the WHERE clause.\n *\n * Pair with migrations that run per table:\n * `ALTER TABLE t ENABLE ROW LEVEL SECURITY;`\n * `CREATE POLICY ws_isolation ON t\n * USING (workspace_id = current_setting('app.workspace_id', true))\n * WITH CHECK (workspace_id = current_setting('app.workspace_id', true));`\n *\n * Fail-closed semantics: if the GUC is unset (NULL from missing_ok=true),\n * `workspace_id = NULL` is always false, so RLS returns no rows — leaking\n * nothing rather than everything.\n *\n * Transactions: a standalone operation runs in its own short transaction\n * (`SET LOCAL` + the operation). An operation on the `tx` client inside a\n * caller's `$transaction(async (tx) => …)`, including raw SQL, runs in the\n * caller's transaction, after one `set_config(..., true)` per transaction and\n * workspace, so it is atomic with the rest of that transaction and its row\n * locks are held until commit. `$transaction([...])` batches get the same\n * statement prepended (BOFF-8874).\n *\n * @default false\n */\n enableRlsGucTagging?: boolean;\n}\n\n/**\n * Default configuration. Exported so consumers/tests can spread over the\n * real defaults (`{ ...defaultWorkspaceExtensionConfig, populateOnBehalfOf: false }`)\n * instead of re-declaring every field.\n */\nexport const defaultWorkspaceExtensionConfig: Required<WorkspaceExtensionConfig> = {\n enabled: true,\n enableReadIsolation: true,\n enableDeleteIsolation: true,\n enableUpdateWhereIsolation: true,\n populateContextJson: true,\n populateCreatedBy: true,\n populateUpdatedBy: true,\n populateTenantId: false,\n populateOnBehalfOf: true,\n excludeModels: [],\n excludeModelsFromReadIsolation: [],\n strictMode: true,\n allowedUnguardedOperations: [],\n debug: false,\n enableApplicationNameTagging: false,\n enableRlsGucTagging: false,\n};\n\n// ============================================================================\n// Data Injection Helpers\n// ============================================================================\n\n/**\n * Check if a field exists in the data object (including being set to null/undefined explicitly)\n */\nfunction hasField(data: Record<string, unknown>, field: string): boolean {\n return field in data;\n}\n\n/**\n * Inject workspace-related fields into create data.\n *\n * Exported (alongside `injectWhereWorkspaceId`) so consumers can unit-test\n * exactly what a given `WorkspaceExtensionConfig` injects for their own\n * Prisma schema — in particular, to verify `populateOnBehalfOf: false` /\n * `populateContextJson: false` actually suppress `onBehalfOf`/`context`\n * before wiring the extension against models that don't have those columns.\n */\nexport function injectCreateFields(\n data: Record<string, unknown>,\n wsCtx: WorkspaceContext,\n config: Required<WorkspaceExtensionConfig>\n): Record<string, unknown> {\n const injected = { ...data };\n\n // Inject workspaceId if not already provided\n if (wsCtx.workspaceId && !hasField(injected, 'workspaceId')) {\n injected['workspaceId'] = wsCtx.workspaceId;\n }\n\n // Inject tenantId if configured and not already provided\n if (config.populateTenantId && wsCtx.tenantId && !hasField(injected, 'tenantId')) {\n injected['tenantId'] = wsCtx.tenantId;\n }\n\n // Inject createdBy if configured and not already provided\n if (config.populateCreatedBy && wsCtx.actorId && !hasField(injected, 'createdBy')) {\n injected['createdBy'] = wsCtx.actorId;\n }\n\n // Inject updatedBy on create as well (initial value)\n if (config.populateUpdatedBy && wsCtx.actorId && !hasField(injected, 'updatedBy')) {\n injected['updatedBy'] = wsCtx.actorId;\n }\n\n // Inject onBehalfOf (for consent-based delegation tracking)\n // If onBehalfOf is in context (from consent), use it; otherwise defaults to actorId (self-action)\n if (config.populateOnBehalfOf && wsCtx.onBehalfOf && !hasField(injected, 'onBehalfOf')) {\n injected['onBehalfOf'] = wsCtx.onBehalfOf;\n } else if (config.populateOnBehalfOf && wsCtx.actorId && !hasField(injected, 'onBehalfOf')) {\n // Default to actorId if no delegation (self-action)\n injected['onBehalfOf'] = wsCtx.actorId;\n }\n\n // Populate context JSON field\n if (config.populateContextJson && !hasField(injected, 'context')) {\n const contextJson = buildContextJsonFromWorkspaceContext(wsCtx);\n if (contextJson) {\n injected['context'] = contextJson;\n }\n }\n\n return injected;\n}\n\n/**\n * Inject workspace-related fields into update data\n */\nfunction injectUpdateFields(\n data: Record<string, unknown>,\n wsCtx: WorkspaceContext,\n config: Required<WorkspaceExtensionConfig>\n): Record<string, unknown> {\n const injected = { ...data };\n\n // Inject updatedBy if configured and not already provided\n if (config.populateUpdatedBy && wsCtx.actorId && !hasField(injected, 'updatedBy')) {\n injected['updatedBy'] = wsCtx.actorId;\n }\n\n // Note: We intentionally do NOT auto-inject workspaceId on updates\n // because updates target existing records (workspaceId is immutable after creation)\n // and changing it would be a data integrity issue.\n\n return injected;\n}\n\n/**\n * Inject workspaceId into a where clause.\n * Only injects if workspaceId is available in context and not already present in where.\n *\n * For operations that may not have a where clause (e.g., findMany without filters),\n * creates a new where object with just workspaceId.\n */\nfunction injectWhereClause(\n where: Record<string, unknown> | undefined,\n wsCtx: WorkspaceContext\n): Record<string, unknown> | undefined {\n if (!wsCtx.workspaceId) return where;\n\n if (!where) {\n // No where clause exists, create one with just workspaceId\n return { workspaceId: wsCtx.workspaceId };\n }\n\n // Only inject if not already present\n if (!hasField(where, 'workspaceId')) {\n return { ...where, workspaceId: wsCtx.workspaceId };\n }\n\n return where;\n}\n\n/**\n * Build context JSON from workspace context\n */\nfunction buildContextJsonFromWorkspaceContext(wsCtx: WorkspaceContext): InputJsonValue | undefined {\n const context: Record<string, string> = {};\n\n if (wsCtx.workspaceId) context['workspaceId'] = wsCtx.workspaceId;\n if (wsCtx.actorId) context['userId'] = wsCtx.actorId;\n if (wsCtx.organizationId) context['organizationId'] = wsCtx.organizationId;\n if (wsCtx.projectId) context['projectId'] = wsCtx.projectId;\n if (wsCtx.appId) context['appId'] = wsCtx.appId;\n\n return Object.keys(context).length > 0 ? context : undefined;\n}\n\n/**\n * Inject workspaceId into where clause for read/update/delete operations.\n * This is a utility function exported for services that want to manually\n * add workspace scoping to their queries.\n *\n * @param where - The existing where clause\n * @param wsCtx - The workspace context (or auto-detected from AsyncLocalStorage)\n * @returns The where clause with workspaceId injected if not already present\n *\n * @example\n * ```typescript\n * import { injectWhereWorkspaceId, getWorkspaceContext } from '@burdenoff/be-sdk/prisma';\n *\n * const wsCtx = getWorkspaceContext();\n * const where = injectWhereWorkspaceId({ status: 'ACTIVE' }, wsCtx);\n * // Result: { status: 'ACTIVE', workspaceId: 'ws-123' }\n * ```\n */\nexport function injectWhereWorkspaceId(\n where: Record<string, unknown> | undefined,\n wsCtx?: WorkspaceContext\n): Record<string, unknown> | undefined {\n const ctx = wsCtx ?? getWorkspaceContext();\n if (!where || !ctx?.workspaceId) return where;\n\n // Only inject if not already present\n if (!hasField(where, 'workspaceId')) {\n return { ...where, workspaceId: ctx.workspaceId };\n }\n\n return where;\n}\n\n/**\n * Remove the _skipWorkspaceInjection flag from args before passing to Prisma.\n * Using a dedicated function avoids ESLint unused-variable warnings from destructuring.\n */\nfunction stripSkipFlag<T extends Record<string, unknown>>(args: T): Omit<T, '_skipWorkspaceInjection'> {\n const cleaned = { ...args };\n delete (cleaned as Record<string, unknown>)['_skipWorkspaceInjection'];\n return cleaned;\n}\n\n/**\n * Check if a model should be excluded from read isolation.\n * A model is excluded if it's in excludeModels OR excludeModelsFromReadIsolation.\n */\nfunction isExcludedFromReadIsolation(model: string, config: Required<WorkspaceExtensionConfig>): boolean {\n return config.excludeModels.includes(model) || config.excludeModelsFromReadIsolation.includes(model);\n}\n\n// ============================================================================\n// Strict Mode Enforcement\n// ============================================================================\n\n/**\n * Enforce strict mode: throw if workspace context is missing and the operation\n * is not explicitly allowed to run without it.\n *\n * @returns true if the operation should proceed without workspace injection (non-strict or allowed)\n * @throws Error if strict mode is enabled and the operation is not allowed\n */\nfunction enforceStrictMode(\n model: string,\n operation: string,\n wsCtx: WorkspaceContext | undefined,\n config: Required<WorkspaceExtensionConfig>\n): void {\n // If workspace context has a workspaceId, nothing to enforce\n if (wsCtx?.workspaceId) return;\n\n // If strict mode is off, allow silently\n if (!config.strictMode) return;\n\n // Check if this specific operation is allowed without workspace context\n const opKey = `${model}.${operation}`;\n if (config.allowedUnguardedOperations.includes(opKey)) return;\n\n // Strict mode violation — throw\n throw new Error(\n `[WorkspaceExtension] Workspace context required for ${model}.${operation}. ` +\n `No workspaceId found in request context. To bypass, either: ` +\n `(1) add \"${model}\" to excludeModels, ` +\n `(2) add \"${opKey}\" to allowedUnguardedOperations, or ` +\n `(3) pass _skipWorkspaceInjection: true in the query args.`\n );\n}\n\n// ============================================================================\n// Prisma Extension\n// ============================================================================\n\n/**\n * Standard args shape for operations with a `where` clause\n */\ninterface WhereArgs {\n where?: Record<string, unknown>;\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n}\n\n/**\n * Standard handler params from Prisma $extends\n */\ninterface ExtensionHandlerParams<TArgs> {\n model: string;\n args: TArgs;\n query: (args: unknown) => Promise<unknown>;\n /** Prisma-internal request params; `transaction` identifies a caller transaction. */\n __internalParams?: PrismaQueryInternalParams;\n}\n\n/** Handler params for top-level raw operations (`$queryRaw`, `$executeRaw`, …). */\ninterface RawOperationHandlerParams {\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n __internalParams?: PrismaQueryInternalParams;\n}\n\n/** Client surface the `$transaction` wrapper delegates to (the client one layer down). */\ntype TransactionDelegate = {\n $transaction: (input: unknown, options?: unknown) => Promise<unknown>;\n};\n\n/**\n * Add workspace extension to a Prisma client.\n *\n * This extension provides comprehensive workspace isolation by automatically\n * injecting workspaceId into ALL Prisma operations:\n *\n * **Writes**: Auto-populates workspaceId, tenantId, createdBy, updatedBy, context JSON\n * **Reads**: Auto-injects workspaceId into where clause (findMany, findFirst, etc.)\n * **Updates**: Auto-injects workspaceId into where clause + updatedBy into data\n * **Deletes**: Auto-injects workspaceId into where clause\n *\n * **Chain order matters**: Apply this extension AFTER the graph extension\n * (handled automatically by createDatabaseClient).\n *\n * @param baseClient - The Prisma client to extend\n * @param config - Extension configuration\n * @returns Extended Prisma client with workspace auto-injection\n *\n * @example\n * ```typescript\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { addWorkspaceExtension } from '@burdenoff/be-sdk/prisma';\n *\n * const baseClient = new PrismaClient({ adapter });\n * const client = addWorkspaceExtension(baseClient, {\n * populateContextJson: true,\n * populateCreatedBy: true,\n * enableReadIsolation: true,\n * debug: process.env.NODE_ENV === 'development',\n * excludeModels: ['CircuitBreakerState', 'SchedulerState'],\n * excludeModelsFromReadIsolation: ['Permission', 'RbacResourceType'],\n * });\n * ```\n */\n// ============================================================================\n// Connection Tagging (Phase 0.2)\n// ============================================================================\n\n/** Minimal Prisma raw-exec surface needed for SET application_name */\ntype RawPrismaForTagging = {\n $executeRawUnsafe: (query: string, ...values: unknown[]) => Promise<number>;\n};\n\n/**\n * WeakSet of contexts that have already had the connection tagged this request.\n * WorkspaceContext objects live only for the duration of a request, so entries\n * are automatically GC'd when the context goes out of scope — no manual cleanup.\n */\nconst taggedContexts = new WeakSet<WorkspaceContext>();\n\n/**\n * Tag the current Postgres connection with workspace attribution (once per context).\n * Sets `application_name = 'svc=<name>;ws=<workspaceId>'` at the session level.\n * Non-fatal: tagging failures are swallowed so the main operation still proceeds.\n *\n * @internal Exported for unit testing only — do not call from product code.\n */\nexport async function maybeTagConnection(rawPrisma: RawPrismaForTagging, wsCtx: WorkspaceContext): Promise<void> {\n if (taggedContexts.has(wsCtx)) return;\n taggedContexts.add(wsCtx);\n // Strip non-safe chars; workspace IDs are UUIDs/CUIDs, service names are kebab-case\n const safeSvc = (process.env['SERVICE_NAME'] ?? 'svc').replace(/[^a-zA-Z0-9\\-_]/g, '');\n const safeWs = (wsCtx.workspaceId ?? '').replace(/[^a-zA-Z0-9\\-_]/g, '');\n const tag = `svc=${safeSvc};ws=${safeWs}`;\n try {\n await rawPrisma.$executeRawUnsafe(`SET application_name = '${tag}'`);\n } catch {\n // Retry on the next operation if this one failed\n taggedContexts.delete(wsCtx);\n }\n}\n\n// ============================================================================\n// RLS GUC Tagging (Phase 3)\n// ============================================================================\n\n/**\n * WeakSet of contexts that have already had the RLS GUC set this request.\n */\nconst rlsTaggedContexts = new WeakSet<WorkspaceContext>();\n\n/**\n * Set `app.workspace_id` GUC for RLS enforcement (once per context, session-level).\n *\n * When set, RLS policies using `current_setting('app.workspace_id', true)` filter\n * rows to the current workspace. Non-fatal: failures are swallowed and retried on\n * the next operation via WeakSet entry removal.\n *\n * NOT used by the extension's operation handlers below (see\n * `runOperationWithRlsGuc`) — session-level `SET` is unsafe once traffic is routed\n * through PgBouncer in transaction-pooling mode (see that function's doc comment\n * for the full incident writeup, BOFF-5488). Kept as a standalone export, still\n * unit tested, for any caller that genuinely runs on an unpooled/session-pooled\n * connection where session-level `SET` is sufficient.\n *\n * @internal Exported for unit testing only — do not call from product code.\n */\nexport async function maybeSetRlsGuc(rawPrisma: RawPrismaForTagging, wsCtx: WorkspaceContext): Promise<void> {\n if (rlsTaggedContexts.has(wsCtx)) return;\n rlsTaggedContexts.add(wsCtx);\n // Allow alphanumeric, hyphens, underscores — CUID/UUID safe, prevents SQL injection\n const safeWs = (wsCtx.workspaceId ?? '').replace(/[^a-zA-Z0-9\\-_]/g, '');\n try {\n await rawPrisma.$executeRawUnsafe(`SET app.workspace_id = '${safeWs}'`);\n } catch {\n // Retry on the next operation if this one failed\n rlsTaggedContexts.delete(wsCtx);\n }\n}\n\n/**\n * A Prisma interactive-transaction client (`tx` inside `$transaction(async (tx) =>\n * …)`), typed with just enough surface for `runOperationWithRlsGuc`: raw SQL\n * execution, plus one delegate per model keyed by its Prisma Client property name\n * (e.g. `customer`, `driver`). The index signature is `unknown` (not a concrete\n * delegate shape) because this helper is generic across every model in the schema\n * — callers narrow and verify the specific delegate/method they need at runtime.\n */\ntype PrismaTxForRlsGuc = {\n $executeRawUnsafe: (query: string, ...values: unknown[]) => Promise<number>;\n [modelClientProperty: string]: unknown;\n};\n\n/** Minimal Prisma client surface needed to open an interactive transaction. */\ntype RawPrismaForRlsTransaction = {\n $transaction: <TResult>(fn: (tx: PrismaTxForRlsGuc) => Promise<TResult>) => Promise<TResult>;\n};\n\n/**\n * Prisma DMMF model name (e.g. `Customer`) -> Prisma Client delegate property\n * (e.g. `customer`). Matches Prisma's own client-generation rule: lower-case the\n * first character, leave the rest untouched.\n */\nfunction modelToClientProperty(model: string): string {\n return model.length > 0 ? model.charAt(0).toLowerCase() + model.slice(1) : model;\n}\n\n/**\n * Run a single Prisma operation with `app.workspace_id` set as a\n * **transaction-scoped** (`SET LOCAL`) GUC immediately ahead of it, so Postgres\n * RLS policies using `current_setting('app.workspace_id', true)` see the right\n * value for both the `USING` (read) and `WITH CHECK` (write) clauses.\n *\n * Session-level `SET` (`maybeSetRlsGuc` above, the original Phase 3\n * implementation) is NOT safe once traffic goes through PgBouncer in\n * **transaction pooling mode** — the mode configured on all four\n * `boff-pg-{global,wspace}-{alpha,prod}-cin` servers' built-in PgBouncer (see\n * infra-specs/current-architecture/02-database-postgres-age.md). PgBouncer hands\n * the physical backend connection back to the pool after every standalone\n * statement/implicit transaction, so a `SET` executed by one statement is not\n * guaranteed visible to the very next one, even over what looks like the same\n * logical client connection.\n *\n * This was exactly BOFF-5488: `wspace-movethewheels-svc`'s RLS Phase 3b (FORCE\n * ROW LEVEL SECURITY + a non-owner runtime role, `wspace_movethewheels_app`,\n * pointed at the pooled `:6432` connection) made the `ws_isolation` policy bind\n * for real, but the session-level `SET` from `maybeSetRlsGuc` was landing on a\n * different pooled backend connection than the write that followed it — so every\n * write failed `WITH CHECK` (`new row violates row-level security policy`) and\n * every read matched zero rows.\n *\n * A Prisma **interactive transaction** (`$transaction(async (tx) => …)`) pins one\n * physical connection for the callback's full duration — PgBouncer sees a single\n * unbroken `BEGIN … COMMIT` and cannot reassign the backend mid-transaction — so\n * `SET LOCAL` inside it is guaranteed visible to the operation issued right after\n * it in the same callback. Safe under transaction-mode pooling, session-mode\n * pooling, and with no pooler in front of Postgres at all. The extra round trip\n * (one interactive transaction instead of one direct call) only applies to\n * services that opt into `enableRlsGucTagging` — off by default.\n *\n * @internal Legacy exported helper retained for compatibility and its historical\n * tests. It reissues a model call and cannot preserve surrounding query hooks;\n * addWorkspaceExtension uses the continuation-based route below instead. Do not\n * call this helper from product code.\n */\nexport async function runOperationWithRlsGuc<TResult>(\n rootClient: RawPrismaForRlsTransaction,\n wsCtx: WorkspaceContext,\n model: string,\n operation: string,\n args: unknown\n): Promise<TResult> {\n const safeWs = (wsCtx.workspaceId ?? '').replace(/[^a-zA-Z0-9\\-_]/g, '');\n const clientProperty = modelToClientProperty(model);\n return rootClient.$transaction(async (tx) => {\n await tx.$executeRawUnsafe(`SET LOCAL app.workspace_id = '${safeWs}'`);\n // `tx[clientProperty]` is typed `unknown` (see PrismaTxForRlsGuc) because this\n // helper is generic across every model; narrow to the minimal callable shape\n // needed and verify at runtime before invoking rather than trusting a cast.\n const delegate = tx[clientProperty] as Record<string, (opArgs: unknown) => Promise<TResult>> | undefined;\n const method = delegate?.[operation];\n if (typeof method !== 'function') {\n throw new Error(\n `[WorkspaceExtension] Unable to resolve ${model}.${operation} (client property \"${clientProperty}\") ` +\n 'on the interactive-transaction client for RLS GUC tagging.'\n );\n }\n return method(args);\n });\n}\n\n/** Minimal batch surface; both operations must stay lazy until Prisma binds them. */\ntype RawPrismaForRlsContinuation = {\n $executeRawUnsafe: (sql: string, ...values: unknown[]) => PendingRawStatement;\n $transaction: <TResult>(input: [PendingRawStatement, Promise<TResult>]) => Promise<[unknown, TResult]>;\n};\n\n/**\n * Keep the original query continuation, including later query extensions, inside\n * the GUC-tagged transaction. Reissuing a model call on the root client would\n * skip later hooks, or execute an earlier hook twice (BOFF-8874).\n */\nasync function runQueryWithRlsGuc<TResult>(\n rootClient: RawPrismaForRlsContinuation,\n wsCtx: WorkspaceContext,\n query: () => Promise<TResult>\n): Promise<TResult> {\n // Prisma types this as Promise, but its extension callback returns a lazy\n // PrismaPromise. Require the binding capability instead of falling back to an\n // independent model call or executing the query outside the transaction.\n const pendingQuery = query() as Promise<TResult> & { requestTransaction?: unknown };\n const pendingContext = rootClient.$executeRawUnsafe(\n \"SELECT set_config('app.workspace_id', $1, true), \" +\n \"set_config('statement_timeout', CASE \" +\n \"WHEN current_setting('statement_timeout')::interval > interval '0' \" +\n \"AND current_setting('statement_timeout')::interval < interval '5 seconds' \" +\n \"THEN current_setting('statement_timeout') ELSE '5000ms' END, true)\",\n sanitizeWorkspaceId(wsCtx.workspaceId)\n );\n if (\n typeof pendingQuery.requestTransaction !== 'function' ||\n typeof pendingContext.requestTransaction !== 'function'\n ) {\n throw new Error(\n '[WorkspaceExtension] RLS query continuation requires transaction-bindable PrismaPromises; ' +\n 'refusing the unsupported Prisma integration (BOFF-8874).'\n );\n }\n const [, result] = await rootClient.$transaction([pendingContext, pendingQuery]);\n return result;\n}\n\n// ============================================================================\n// Caller transactions (BOFF-8874)\n// ============================================================================\n//\n// `runOperationWithRlsGuc` above opens its OWN interactive transaction per\n// operation. That is right for a standalone call, but wrong when the operation is\n// issued on the `tx` client inside a caller's `prisma.$transaction(...)`: the\n// operation would commit on another connection, so the caller's transaction\n// would not be atomic and its `SELECT … FOR UPDATE` fences would run without the\n// GUC (matching no rows under FORCE RLS, so locking nothing).\n//\n// Inside a caller transaction the extension now runs the context statement\n// (`set_config(..., is_local => true)`, identical to `SET LOCAL`) on the caller's\n// transaction itself, once per transaction and workspace, and then executes the\n// operation in place. Batch transactions (`$transaction([...])`) get the same\n// statement prepended to the batch by the client-level `$transaction` wrapper in\n// `addWorkspaceExtension`. Outside any transaction nothing changes.\n\n/**\n * Prisma passes the transaction an operation belongs to on the query-extension\n * callback's `__internalParams.transaction`: `{ kind: 'itx', id, payload }` for an\n * interactive transaction, `{ kind: 'batch', … }` for `$transaction([...])`, and\n * nothing for a standalone call. The `live-pg` contract test pins this down\n * against the installed Prisma version.\n */\nexport interface PrismaQueryInternalParams {\n transaction?: unknown;\n}\n\n/** The caller transaction an operation runs in, if any. */\nexport type CallerTransaction = { kind: 'itx'; id: string; descriptor: object } | { kind: 'batch' };\n\n/**\n * Classify the transaction an extension callback is running in.\n *\n * Throws on a transaction descriptor this version does not understand rather\n * than guessing: running such an operation down the standalone path would\n * silently break the caller's atomicity again.\n *\n * @internal Exported for unit testing only — do not call from product code.\n */\nexport function getCallerTransaction(\n internalParams: PrismaQueryInternalParams | undefined\n): CallerTransaction | undefined {\n const transaction = internalParams?.transaction;\n if (transaction === undefined || transaction === null) return undefined;\n if (typeof transaction === 'object') {\n const { kind, id } = transaction as { kind?: unknown; id?: unknown };\n if (kind === 'itx' && typeof id === 'string' && id.length > 0) {\n return { kind: 'itx', id, descriptor: transaction };\n }\n if (kind === 'batch') return { kind: 'batch' };\n }\n throw new Error(\n '[WorkspaceExtension] Unrecognised Prisma transaction descriptor on __internalParams.transaction; ' +\n 'refusing to run the operation outside the caller transaction. This Prisma version is not supported ' +\n 'by the be-sdk RLS transaction integration (BOFF-8874).'\n );\n}\n\n/** Same sanitisation as the standalone path: CUID/UUID-safe, prevents SQL injection. */\nfunction sanitizeWorkspaceId(workspaceId: string | undefined): string {\n return (workspaceId ?? '').replace(/[^a-zA-Z0-9\\-_]/g, '');\n}\n\n/** Same tag `maybeTagConnection` sets: `svc=<SERVICE_NAME>;ws=<workspaceId>`. */\nfunction buildApplicationNameTag(wsCtx: WorkspaceContext): string {\n const safeSvc = (process.env['SERVICE_NAME'] ?? 'svc').replace(/[^a-zA-Z0-9\\-_]/g, '');\n return `svc=${safeSvc};ws=${sanitizeWorkspaceId(wsCtx.workspaceId)}`;\n}\n\n/** A single parameterised statement that sets the transaction-local context. */\nexport interface TransactionContextStatement {\n sql: string;\n params: string[];\n /** Identifies the values set, so a transaction only re-runs it when they change. */\n key: string;\n}\n\n/**\n * Build the transaction-local context statement for the enabled tagging modes,\n * or `undefined` when neither RLS GUC nor application_name tagging is on.\n * `set_config(name, value, true)` is exactly `SET LOCAL name = value`.\n *\n * @internal Exported for unit testing only — do not call from product code.\n */\nexport function buildTransactionContextStatement(\n wsCtx: WorkspaceContext,\n config: Pick<Required<WorkspaceExtensionConfig>, 'enableRlsGucTagging' | 'enableApplicationNameTagging'>\n): TransactionContextStatement | undefined {\n const settings: string[] = [];\n const params: string[] = [];\n if (config.enableRlsGucTagging) {\n params.push(sanitizeWorkspaceId(wsCtx.workspaceId));\n settings.push(`set_config('app.workspace_id', $${params.length}, true)`);\n }\n if (config.enableApplicationNameTagging) {\n params.push(buildApplicationNameTag(wsCtx));\n settings.push(`set_config('application_name', $${params.length}, true)`);\n }\n if (settings.length === 0) return undefined;\n return { sql: `SELECT ${settings.join(', ')}`, params, key: params.join('\\u0000') };\n}\n\n/**\n * A raw Prisma statement before it runs. Prisma's lazy `PrismaPromise` exposes\n * `requestTransaction(descriptor)`, which is how `$transaction` binds statements to\n * a transaction; the extension uses it to run the context statement on the\n * caller's transaction instead of a pooled connection of its own.\n */\ntype PendingRawStatement = PromiseLike<number> & {\n requestTransaction?: (transaction: object) => PromiseLike<unknown>;\n};\n\n/** Unextended client surface for issuing the context statement. */\nexport type RawPrismaForCallerTransaction = {\n $executeRawUnsafe: (query: string, ...values: unknown[]) => PendingRawStatement;\n};\n\ninterface CallerTransactionState {\n /** Descriptor of the (possibly nested) transaction level the context was set on. */\n descriptor: object;\n key: string;\n ready: Promise<void>;\n inflight: number;\n}\n\n/**\n * Context already applied per caller transaction id. Bounded: an evicted entry\n * only costs one repeated context statement, never correctness.\n */\nconst MAX_TRACKED_CALLER_TRANSACTIONS = 4096;\nconst callerTransactionStates = new Map<string, CallerTransactionState>();\n\nfunction rememberCallerTransaction(id: string, state: CallerTransactionState): void {\n callerTransactionStates.delete(id);\n callerTransactionStates.set(id, state);\n if (callerTransactionStates.size > MAX_TRACKED_CALLER_TRANSACTIONS) {\n const oldest = callerTransactionStates.keys().next().value;\n if (oldest !== undefined) callerTransactionStates.delete(oldest);\n }\n}\n\nasync function applyCallerTransactionContext(\n rawPrisma: RawPrismaForCallerTransaction,\n descriptor: object,\n statement: TransactionContextStatement\n): Promise<void> {\n const pending = rawPrisma.$executeRawUnsafe(statement.sql, ...statement.params);\n if (typeof pending.requestTransaction !== 'function') {\n throw new Error(\n '[WorkspaceExtension] Cannot bind the RLS context statement to the caller transaction ' +\n '(PrismaPromise.requestTransaction is unavailable); refusing to run it on another connection (BOFF-8874).'\n );\n }\n await pending.requestTransaction(descriptor);\n}\n\n/**\n * Run `run` (the operation, already bound to the caller's interactive\n * transaction by Prisma) after making sure that transaction carries the\n * workspace context. The context statement runs on the caller's transaction,\n * once per transaction level and workspace: a later operation for the same\n * workspace costs no extra round trip, a workspace switch re-runs it, and so does\n * the first operation after entering or leaving a nested transaction (a\n * savepoint rollback reverts `SET LOCAL`, a release keeps it).\n *\n * Concurrent operations for *different* workspaces on one transaction cannot be\n * isolated from each other, so that case throws instead of risking one running\n * under the other's GUC.\n *\n * @internal Exported for unit testing only — do not call from product code.\n */\nexport async function runOperationInCallerTransaction<TResult>(\n rawPrisma: RawPrismaForCallerTransaction,\n transaction: { id: string; descriptor: object },\n wsCtx: WorkspaceContext,\n config: Pick<Required<WorkspaceExtensionConfig>, 'enableRlsGucTagging' | 'enableApplicationNameTagging'>,\n run: () => Promise<TResult>\n): Promise<TResult> {\n const statement = buildTransactionContextStatement(wsCtx, config);\n if (!statement) return run();\n\n let state = callerTransactionStates.get(transaction.id);\n if (!state || state.descriptor !== transaction.descriptor || state.key !== statement.key) {\n if (state && state.inflight > 0 && state.key !== statement.key) {\n throw new Error(\n '[WorkspaceExtension] Concurrent operations for different workspaces inside one transaction are not ' +\n 'supported: the RLS context is per transaction. Await the other workspace’s operations first.'\n );\n }\n const next: CallerTransactionState = {\n descriptor: transaction.descriptor,\n key: statement.key,\n ready: applyCallerTransactionContext(rawPrisma, transaction.descriptor, statement),\n inflight: 0,\n };\n next.ready.catch(() => {\n if (callerTransactionStates.get(transaction.id) === next) callerTransactionStates.delete(transaction.id);\n });\n rememberCallerTransaction(transaction.id, next);\n state = next;\n }\n\n state.inflight += 1;\n try {\n await state.ready;\n return await run();\n } finally {\n state.inflight -= 1;\n }\n}\n\n/** @internal Test hook: forget all tracked caller transactions. */\nexport function resetCallerTransactionStateForTests(): void {\n callerTransactionStates.clear();\n}\n\nexport function addWorkspaceExtension<T>(baseClient: T, config?: WorkspaceExtensionConfig): T {\n const fullConfig: Required<WorkspaceExtensionConfig> = {\n ...defaultWorkspaceExtensionConfig,\n ...config,\n };\n\n if (!fullConfig.enabled) {\n logger.info('[WorkspaceExtension] Extension disabled by configuration');\n return baseClient;\n }\n\n // Capture the unwrapped client for connection tagging (pre-extension, avoids recursion)\n const rawPrisma = baseClient as unknown as RawPrismaForTagging;\n // Same unwrapped client, typed for a lazy query-continuation batch; no new pool.\n const rawPrismaForContinuations = baseClient as unknown as RawPrismaForRlsContinuation;\n // Capture the pre-wrapper transaction method, but preserve its final receiver\n // when invoked. Selecting $parent would discard query extensions added later.\n const transactionDelegate = (baseClient as unknown as TransactionDelegate).$transaction;\n // Same unwrapped client again, typed for binding the context statement to a\n // caller's transaction (see runOperationInCallerTransaction).\n const rawPrismaForCallerTransactions = baseClient as unknown as RawPrismaForCallerTransaction;\n const tagsTransactions = fullConfig.enableRlsGucTagging || fullConfig.enableApplicationNameTagging;\n\n /**\n * Execute an operation whose args have already been workspace-injected.\n *\n * - Inside a caller's interactive transaction: set the context on that\n * transaction (once) and run the operation in place, so it is atomic with\n * the rest of the caller's transaction and its locks last until commit.\n * - Inside a batch `$transaction([...])`: run in place; the `$transaction`\n * wrapper below prepended the context statement to the batch.\n * - Standalone: unchanged — session application_name tag, then the\n * operation in its own `SET LOCAL` transaction when RLS tagging is on.\n */\n const dispatch = async (\n params: { model: string; query: (args: unknown) => Promise<unknown>; __internalParams?: PrismaQueryInternalParams },\n wsCtx: WorkspaceContext,\n _operation: string,\n finalArgs: unknown\n ): Promise<unknown> => {\n // No tagging: nothing is set per operation, so every call runs in place\n // exactly as before (inside a caller transaction or not).\n if (!tagsTransactions) return params.query(finalArgs);\n const callerTransaction = getCallerTransaction(params.__internalParams);\n if (callerTransaction?.kind === 'itx') {\n return runOperationInCallerTransaction(rawPrismaForCallerTransactions, callerTransaction, wsCtx, fullConfig, () =>\n params.query(finalArgs)\n );\n }\n if (callerTransaction?.kind === 'batch') {\n return params.query(finalArgs);\n }\n if (fullConfig.enableApplicationNameTagging) {\n await maybeTagConnection(rawPrisma, wsCtx);\n }\n if (fullConfig.enableRlsGucTagging) {\n return runQueryWithRlsGuc(rawPrismaForContinuations, wsCtx, () => params.query(finalArgs));\n }\n return params.query(finalArgs);\n };\n\n /**\n * Raw SQL inside a caller's interactive transaction gets the same context, so\n * `SELECT … FOR UPDATE` fences and raw reads/writes see the caller's workspace\n * under FORCE RLS. Standalone raw SQL is unchanged (no context statement).\n */\n const rawOperation = async ({ args, query, __internalParams }: RawOperationHandlerParams): Promise<unknown> => {\n if (!tagsTransactions) return query(args);\n const callerTransaction = getCallerTransaction(__internalParams);\n if (callerTransaction?.kind !== 'itx') return query(args);\n const wsCtx = getWorkspaceContext();\n if (!wsCtx?.workspaceId) return query(args);\n return runOperationInCallerTransaction(rawPrismaForCallerTransactions, callerTransaction, wsCtx, fullConfig, () =>\n query(args)\n );\n };\n\n // Type assertion for Prisma client $extends\n const prismaClient = baseClient as { $extends: (args: unknown) => T };\n\n logger.info('[WorkspaceExtension] Workspace extension enabled', {\n populateContextJson: fullConfig.populateContextJson,\n populateCreatedBy: fullConfig.populateCreatedBy,\n populateUpdatedBy: fullConfig.populateUpdatedBy,\n populateTenantId: fullConfig.populateTenantId,\n enableReadIsolation: fullConfig.enableReadIsolation,\n enableDeleteIsolation: fullConfig.enableDeleteIsolation,\n enableUpdateWhereIsolation: fullConfig.enableUpdateWhereIsolation,\n strictMode: fullConfig.strictMode,\n excludeModels: fullConfig.excludeModels,\n excludeModelsFromReadIsolation: fullConfig.excludeModelsFromReadIsolation,\n allowedUnguardedOperations: fullConfig.allowedUnguardedOperations,\n enableApplicationNameTagging: fullConfig.enableApplicationNameTagging,\n enableRlsGucTagging: fullConfig.enableRlsGucTagging,\n });\n\n // Raw SQL hooks only matter when a context statement exists to apply.\n const rawOperationHooks = tagsTransactions\n ? {\n $queryRaw: rawOperation,\n $executeRaw: rawOperation,\n $queryRawUnsafe: rawOperation,\n $executeRawUnsafe: rawOperation,\n $queryRawTyped: rawOperation,\n }\n : {};\n\n const withQueryHooks = prismaClient.$extends({\n query: {\n ...rawOperationHooks,\n $allModels: {\n // ================================================================\n // WRITE OPERATIONS - inject workspaceId into data\n // ================================================================\n\n async create({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n data: Record<string, unknown>;\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n // Skip if model is excluded or injection is explicitly skipped\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'create', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n // Inject fields into data\n const injectedData = injectCreateFields(args.data, wsCtx, fullConfig);\n\n if (fullConfig.debug) {\n const injectedKeys = Object.keys(injectedData).filter((k) => !(k in args.data));\n if (injectedKeys.length > 0) {\n logger.debug(`[WorkspaceExtension] ${model}.create - injected: ${injectedKeys.join(', ')}`, {\n workspaceId: wsCtx.workspaceId,\n actorId: wsCtx.actorId,\n });\n }\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n data: injectedData,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'create', finalArgs);\n },\n\n async createMany({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n data: Record<string, unknown> | Record<string, unknown>[];\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'createMany', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n // Handle both single object and array\n const dataArray = Array.isArray(args.data) ? args.data : [args.data];\n const injectedData = dataArray.map((item) => injectCreateFields(item, wsCtx, fullConfig));\n\n const finalArgs = {\n ...stripSkipFlag(args),\n data: Array.isArray(args.data) ? injectedData : injectedData[0],\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'createMany', finalArgs);\n },\n\n async createManyAndReturn({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n data: Record<string, unknown> | Record<string, unknown>[];\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'createManyAndReturn', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const dataArray = Array.isArray(args.data) ? args.data : [args.data];\n const injectedData = dataArray.map((item) => injectCreateFields(item, wsCtx, fullConfig));\n\n const finalArgs = {\n ...stripSkipFlag(args),\n data: Array.isArray(args.data) ? injectedData : injectedData[0],\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'createManyAndReturn', finalArgs);\n },\n\n // ================================================================\n // UPDATE OPERATIONS - inject updatedBy into data + workspaceId into where\n // ================================================================\n\n async update({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n data: Record<string, unknown>;\n where?: Record<string, unknown>;\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'update', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedData = injectUpdateFields(args.data, wsCtx, fullConfig);\n\n // Inject workspaceId into where clause for update isolation\n let injectedWhere = args.where;\n if (fullConfig.enableUpdateWhereIsolation && !isExcludedFromReadIsolation(model, fullConfig)) {\n injectedWhere = injectWhereClause(args.where, wsCtx);\n }\n\n if (fullConfig.debug) {\n const injectedDataKeys = Object.keys(injectedData).filter((k) => !(k in args.data));\n const whereChanged = injectedWhere !== args.where;\n if (injectedDataKeys.length > 0 || whereChanged) {\n logger.debug(\n `[WorkspaceExtension] ${model}.update - injected data: ${injectedDataKeys.join(', ')}${whereChanged ? ', where: workspaceId' : ''}`\n );\n }\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n data: injectedData,\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'update', finalArgs);\n },\n\n async updateMany({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n data: Record<string, unknown>;\n where?: Record<string, unknown>;\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'updateMany', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedData = injectUpdateFields(args.data, wsCtx, fullConfig);\n\n // Inject workspaceId into where clause for update isolation\n let injectedWhere = args.where;\n if (fullConfig.enableUpdateWhereIsolation && !isExcludedFromReadIsolation(model, fullConfig)) {\n injectedWhere = injectWhereClause(args.where, wsCtx);\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n data: injectedData,\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'updateMany', finalArgs);\n },\n\n async upsert({\n model,\n args,\n query,\n __internalParams,\n }: ExtensionHandlerParams<{\n create: Record<string, unknown>;\n update: Record<string, unknown>;\n where?: Record<string, unknown>;\n _skipWorkspaceInjection?: boolean;\n [key: string]: unknown;\n }>) {\n if (fullConfig.excludeModels.includes(model) || args._skipWorkspaceInjection) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'upsert', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedCreate = injectCreateFields(args.create, wsCtx, fullConfig);\n const injectedUpdate = injectUpdateFields(args.update, wsCtx, fullConfig);\n\n // Inject workspaceId into where clause for upsert isolation\n let injectedWhere = args.where;\n if (fullConfig.enableUpdateWhereIsolation && !isExcludedFromReadIsolation(model, fullConfig)) {\n injectedWhere = injectWhereClause(args.where, wsCtx);\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n create: injectedCreate,\n update: injectedUpdate,\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'upsert', finalArgs);\n },\n\n // ================================================================\n // READ OPERATIONS - inject workspaceId into where clause\n // ================================================================\n\n async findMany({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'findMany', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.findMany - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'findMany', finalArgs);\n },\n\n async findFirst({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'findFirst', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.findFirst - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'findFirst', finalArgs);\n },\n\n async findFirstOrThrow({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'findFirstOrThrow', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.findFirstOrThrow - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'findFirstOrThrow', finalArgs);\n },\n\n async findUnique({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'findUnique', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n // For findUnique, the where clause uses unique fields.\n // We inject workspaceId only if the where clause is a plain object\n // (compound unique keys with workspaceId are common and already include it).\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.findUnique - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'findUnique', finalArgs);\n },\n\n async findUniqueOrThrow({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'findUniqueOrThrow', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.findUniqueOrThrow - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'findUniqueOrThrow', finalArgs);\n },\n\n async count({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'count', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.count - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'count', finalArgs);\n },\n\n async aggregate({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'aggregate', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.aggregate - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'aggregate', finalArgs);\n },\n\n async groupBy({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableReadIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'groupBy', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.groupBy - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'groupBy', finalArgs);\n },\n\n // ================================================================\n // DELETE OPERATIONS - inject workspaceId into where clause\n // ================================================================\n\n async delete({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableDeleteIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'delete', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.delete - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'delete', finalArgs);\n },\n\n async deleteMany({ model, args, query, __internalParams }: ExtensionHandlerParams<WhereArgs>) {\n if (\n !fullConfig.enableDeleteIsolation ||\n isExcludedFromReadIsolation(model, fullConfig) ||\n args._skipWorkspaceInjection\n ) {\n return query(stripSkipFlag(args));\n }\n\n const wsCtx = getWorkspaceContext();\n enforceStrictMode(model, 'deleteMany', wsCtx, fullConfig);\n if (!wsCtx?.workspaceId) {\n return query(args);\n }\n\n const injectedWhere = injectWhereClause(args.where, wsCtx);\n\n if (fullConfig.debug) {\n logger.debug(`[WorkspaceExtension] ${model}.deleteMany - injected workspaceId into where`, {\n workspaceId: wsCtx.workspaceId,\n });\n }\n\n const finalArgs = {\n ...stripSkipFlag(args),\n where: injectedWhere,\n };\n return dispatch({ model, query, __internalParams }, wsCtx, 'deleteMany', finalArgs);\n },\n },\n },\n });\n\n if (!tagsTransactions) return withQueryHooks;\n\n // Batch transactions: Prisma runs `$transaction([...])` members in one database\n // transaction, but an operation hook cannot add a statement to the batch. So\n // wrap `$transaction` itself and prepend the context statement; its result is\n // dropped so callers get exactly their own members' results. The function form\n // passes straight through — the hooks above handle interactive transactions.\n // `$parent` is the client one extension layer down (the query-hooked client\n // above), so members and nested transactions keep every hook.\n const wrapped = withQueryHooks as unknown as { $extends: (args: unknown) => T };\n return wrapped.$extends({\n client: {\n $transaction(this: { $parent?: TransactionDelegate }, input: unknown, options?: unknown): Promise<unknown> {\n const parent = this.$parent;\n if (!parent) {\n throw new Error('[WorkspaceExtension] $transaction wrapper could not resolve its parent client.');\n }\n if (Array.isArray(input)) {\n const wsCtx = getWorkspaceContext();\n const statement = wsCtx?.workspaceId ? buildTransactionContextStatement(wsCtx, fullConfig) : undefined;\n if (statement) {\n const setContext = rawPrismaForCallerTransactions.$executeRawUnsafe(statement.sql, ...statement.params);\n return parent\n .$transaction([setContext, ...input], options)\n .then((results) => (Array.isArray(results) ? results.slice(1) : results));\n }\n }\n // The native delegate reads the final client's extension chain. Calling\n // it on $parent would silently omit later graph/audit query hooks.\n return transactionDelegate.call(this, input, options);\n },\n },\n });\n}\n"]}