@memberjunction/server 6.1.0-edge.1 → 6.1.0-edge.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (261) hide show
  1. package/LICENSE +180 -4
  2. package/dist/auth/AuthProviderCatalogRouter.d.ts +31 -0
  3. package/dist/auth/AuthProviderCatalogRouter.d.ts.map +1 -0
  4. package/dist/auth/AuthProviderCatalogRouter.js +69 -0
  5. package/dist/auth/AuthProviderCatalogRouter.js.map +1 -0
  6. package/dist/auth/AuthProviderEngine.d.ts +96 -0
  7. package/dist/auth/AuthProviderEngine.d.ts.map +1 -0
  8. package/dist/auth/AuthProviderEngine.js +245 -0
  9. package/dist/auth/AuthProviderEngine.js.map +1 -0
  10. package/dist/auth/exampleNewUserSubClass.js +1 -1
  11. package/dist/auth/exampleNewUserSubClass.js.map +1 -1
  12. package/dist/auth/index.d.ts +11 -0
  13. package/dist/auth/index.d.ts.map +1 -1
  14. package/dist/auth/index.js +65 -18
  15. package/dist/auth/index.js.map +1 -1
  16. package/dist/auth/initializeProviders.d.ts +64 -1
  17. package/dist/auth/initializeProviders.d.ts.map +1 -1
  18. package/dist/auth/initializeProviders.js +117 -5
  19. package/dist/auth/initializeProviders.js.map +1 -1
  20. package/dist/auth/magicLink/MagicLinkService.js +1 -1
  21. package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
  22. package/dist/auth/newUsers.js +1 -1
  23. package/dist/auth/newUsers.js.map +1 -1
  24. package/dist/config.d.ts +89 -0
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js +52 -35
  27. package/dist/config.js.map +1 -1
  28. package/dist/context.js +2 -2
  29. package/dist/context.js.map +1 -1
  30. package/dist/generated/generated.d.ts +540 -1595
  31. package/dist/generated/generated.d.ts.map +1 -1
  32. package/dist/generated/generated.js +2755 -16857
  33. package/dist/generated/generated.js.map +1 -1
  34. package/dist/generic/ResolverBase.d.ts +20 -4
  35. package/dist/generic/ResolverBase.d.ts.map +1 -1
  36. package/dist/generic/ResolverBase.js +58 -21
  37. package/dist/generic/ResolverBase.js.map +1 -1
  38. package/dist/generic/RunViewResolver.d.ts +4 -0
  39. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  40. package/dist/generic/RunViewResolver.js +31 -0
  41. package/dist/generic/RunViewResolver.js.map +1 -1
  42. package/dist/index.d.ts +3 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +183 -54
  45. package/dist/index.js.map +1 -1
  46. package/dist/integration/RSUProgressBridge.d.ts +83 -0
  47. package/dist/integration/RSUProgressBridge.d.ts.map +1 -0
  48. package/dist/integration/RSUProgressBridge.js +230 -0
  49. package/dist/integration/RSUProgressBridge.js.map +1 -0
  50. package/dist/integration/SchemaRefreshLaunch.d.ts +52 -0
  51. package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -0
  52. package/dist/integration/SchemaRefreshLaunch.js +50 -0
  53. package/dist/integration/SchemaRefreshLaunch.js.map +1 -0
  54. package/dist/logging/secretRedactor.d.ts +9 -0
  55. package/dist/logging/secretRedactor.d.ts.map +1 -1
  56. package/dist/logging/secretRedactor.js +39 -0
  57. package/dist/logging/secretRedactor.js.map +1 -1
  58. package/dist/middleware/BaseServerMiddleware.d.ts +5 -0
  59. package/dist/middleware/BaseServerMiddleware.d.ts.map +1 -1
  60. package/dist/middleware/BaseServerMiddleware.js +5 -0
  61. package/dist/middleware/BaseServerMiddleware.js.map +1 -1
  62. package/dist/providerConfigUnits.d.ts +20 -0
  63. package/dist/providerConfigUnits.d.ts.map +1 -0
  64. package/dist/providerConfigUnits.js +22 -0
  65. package/dist/providerConfigUnits.js.map +1 -0
  66. package/dist/realtimeWidget/WidgetSessionService.js +1 -1
  67. package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
  68. package/dist/realtimeWidget/widgetGuestElevation.js +1 -1
  69. package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
  70. package/dist/resolvers/ActionResolver.d.ts.map +1 -1
  71. package/dist/resolvers/ActionResolver.js +12 -0
  72. package/dist/resolvers/ActionResolver.js.map +1 -1
  73. package/dist/resolvers/ComponentRegistryResolver.js +1 -1
  74. package/dist/resolvers/ComponentRegistryResolver.js.map +1 -1
  75. package/dist/resolvers/EntityPermissionResolver.js +1 -1
  76. package/dist/resolvers/EntityPermissionResolver.js.map +1 -1
  77. package/dist/resolvers/FileResolver.d.ts +34 -4
  78. package/dist/resolvers/FileResolver.d.ts.map +1 -1
  79. package/dist/resolvers/FileResolver.js +218 -28
  80. package/dist/resolvers/FileResolver.js.map +1 -1
  81. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +85 -3
  82. package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
  83. package/dist/resolvers/IntegrationDiscoveryResolver.js +302 -82
  84. package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
  85. package/dist/resolvers/PotentialDuplicateRecordResolver.js +1 -1
  86. package/dist/resolvers/PotentialDuplicateRecordResolver.js.map +1 -1
  87. package/dist/resolvers/QueryResolver.d.ts +5 -4
  88. package/dist/resolvers/QueryResolver.d.ts.map +1 -1
  89. package/dist/resolvers/QueryResolver.js +29 -14
  90. package/dist/resolvers/QueryResolver.js.map +1 -1
  91. package/dist/resolvers/QuerySystemUserResolver.d.ts +12 -3
  92. package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
  93. package/dist/resolvers/QuerySystemUserResolver.js +33 -14
  94. package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
  95. package/dist/resolvers/RealtimeClientSessionResolver.d.ts +10 -0
  96. package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
  97. package/dist/resolvers/RealtimeClientSessionResolver.js +5 -0
  98. package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
  99. package/dist/resolvers/RunAIAgentResolver.d.ts +3 -1
  100. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  101. package/dist/resolvers/RunAIAgentResolver.js +20 -7
  102. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  103. package/dist/resolvers/SearchEntitiesResolver.js +1 -1
  104. package/dist/resolvers/SearchEntitiesResolver.js.map +1 -1
  105. package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
  106. package/dist/resolvers/SqlLoggingConfigResolver.js +1 -1
  107. package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
  108. package/dist/resolvers/SyncRolesUsersResolver.js +2 -2
  109. package/dist/resolvers/SyncRolesUsersResolver.js.map +1 -1
  110. package/dist/resolvers/TaskGraphFrameResolver.d.ts +18 -0
  111. package/dist/resolvers/TaskGraphFrameResolver.d.ts.map +1 -1
  112. package/dist/resolvers/TaskGraphFrameResolver.js +75 -0
  113. package/dist/resolvers/TaskGraphFrameResolver.js.map +1 -1
  114. package/dist/resolvers/UserFavoriteResolver.js +1 -1
  115. package/dist/resolvers/UserFavoriteResolver.js.map +1 -1
  116. package/dist/resolvers/UserResolver.d.ts +19 -17
  117. package/dist/resolvers/UserResolver.d.ts.map +1 -1
  118. package/dist/resolvers/UserResolver.js +66 -67
  119. package/dist/resolvers/UserResolver.js.map +1 -1
  120. package/dist/resolvers/currentUserRoles.d.ts +19 -0
  121. package/dist/resolvers/currentUserRoles.d.ts.map +1 -0
  122. package/dist/resolvers/currentUserRoles.js +36 -0
  123. package/dist/resolvers/currentUserRoles.js.map +1 -0
  124. package/dist/rest/MediaAccessKeys.d.ts +17 -0
  125. package/dist/rest/MediaAccessKeys.d.ts.map +1 -1
  126. package/dist/rest/MediaAccessKeys.js +42 -1
  127. package/dist/rest/MediaAccessKeys.js.map +1 -1
  128. package/dist/rest/MediaStreamHandler.d.ts +3 -2
  129. package/dist/rest/MediaStreamHandler.d.ts.map +1 -1
  130. package/dist/rest/MediaStreamHandler.js +83 -2
  131. package/dist/rest/MediaStreamHandler.js.map +1 -1
  132. package/dist/rest/OAuthCallbackHandler.d.ts +49 -1
  133. package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
  134. package/dist/rest/OAuthCallbackHandler.js +130 -44
  135. package/dist/rest/OAuthCallbackHandler.js.map +1 -1
  136. package/dist/rest/SignatureWebhookHandler.js +1 -1
  137. package/dist/rest/SignatureWebhookHandler.js.map +1 -1
  138. package/dist/rest/UploadTokenManager.d.ts +90 -0
  139. package/dist/rest/UploadTokenManager.d.ts.map +1 -0
  140. package/dist/rest/UploadTokenManager.js +156 -0
  141. package/dist/rest/UploadTokenManager.js.map +1 -0
  142. package/dist/services/DurableEntityActionTaskSubmitter.d.ts +26 -0
  143. package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -0
  144. package/dist/services/DurableEntityActionTaskSubmitter.js +55 -0
  145. package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -0
  146. package/dist/services/IntegrationSyncWorkerService.d.ts +48 -0
  147. package/dist/services/IntegrationSyncWorkerService.d.ts.map +1 -0
  148. package/dist/services/IntegrationSyncWorkerService.js +132 -0
  149. package/dist/services/IntegrationSyncWorkerService.js.map +1 -0
  150. package/dist/services/ScheduledJobsService.js +1 -1
  151. package/dist/services/ScheduledJobsService.js.map +1 -1
  152. package/dist/services/StartTaskGraphDispatcher.d.ts +0 -10
  153. package/dist/services/StartTaskGraphDispatcher.d.ts.map +1 -1
  154. package/dist/services/StartTaskGraphDispatcher.js +37 -2
  155. package/dist/services/StartTaskGraphDispatcher.js.map +1 -1
  156. package/dist/services/TaskGraphActionRunner.d.ts +34 -0
  157. package/dist/services/TaskGraphActionRunner.d.ts.map +1 -0
  158. package/dist/services/TaskGraphActionRunner.js +95 -0
  159. package/dist/services/TaskGraphActionRunner.js.map +1 -0
  160. package/dist/services/TaskGraphAgentRunner.d.ts +20 -0
  161. package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
  162. package/dist/services/TaskGraphAgentRunner.js +53 -0
  163. package/dist/services/TaskGraphAgentRunner.js.map +1 -1
  164. package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
  165. package/dist/services/TaskGraphContinuationDeliverer.js +12 -1
  166. package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
  167. package/dist/services/TaskGraphPromptRunner.d.ts +31 -0
  168. package/dist/services/TaskGraphPromptRunner.d.ts.map +1 -0
  169. package/dist/services/TaskGraphPromptRunner.js +134 -0
  170. package/dist/services/TaskGraphPromptRunner.js.map +1 -0
  171. package/dist/telephony/RingCentralTelephonyService.js +1 -1
  172. package/dist/telephony/RingCentralTelephonyService.js.map +1 -1
  173. package/dist/telephony/TwilioTelephonyRouter.js +1 -1
  174. package/dist/telephony/TwilioTelephonyRouter.js.map +1 -1
  175. package/dist/telephony/VonageTelephonyRouter.js +1 -1
  176. package/dist/telephony/VonageTelephonyRouter.js.map +1 -1
  177. package/dist/types.d.ts +6 -0
  178. package/dist/types.d.ts.map +1 -1
  179. package/dist/types.js.map +1 -1
  180. package/package.json +91 -91
  181. package/src/__tests__/APIKeyScopeAuth.test.ts +475 -0
  182. package/src/__tests__/AuthProviderEngine.test.ts +278 -0
  183. package/src/__tests__/EntityCRUDHandler.test.ts +378 -0
  184. package/src/__tests__/IntegrationSyncWorkerService.test.ts +275 -0
  185. package/src/__tests__/OAuthCallbackHandler.openRedirect.test.ts +117 -0
  186. package/src/__tests__/OAuthCallbackHandler.xss.test.ts +4 -1
  187. package/src/__tests__/RESTEndpointHandler.test.ts +672 -0
  188. package/src/__tests__/RSUProgressBridge.test.ts +250 -0
  189. package/src/__tests__/RealtimeBridgeResolver.test.ts +10 -2
  190. package/src/__tests__/RealtimeClientSessionResolver.test.ts +1 -1
  191. package/src/__tests__/ResolverBase.frozenRecordMapping.test.ts +133 -0
  192. package/src/__tests__/ResolverBase.transportMapping.test.ts +289 -0
  193. package/src/__tests__/SchemaRefreshLaunch.test.ts +114 -0
  194. package/src/__tests__/SessionManager.test.ts +1 -1
  195. package/src/__tests__/UserResolver.currentUser.test.ts +87 -0
  196. package/src/__tests__/ViewOperationsHandler.test.ts +277 -0
  197. package/src/__tests__/WidgetSessionService.test.ts +1 -1
  198. package/src/__tests__/config-units.test.ts +74 -0
  199. package/src/__tests__/databaseAbstraction.test.ts +1 -1
  200. package/src/__tests__/initializeProviders.refresh.test.ts +146 -0
  201. package/src/__tests__/magicLinkService.provisionLog.test.ts +1 -1
  202. package/src/__tests__/mjapi-bootstrap.test.ts +0 -6
  203. package/src/__tests__/newUsers.test.ts +726 -0
  204. package/src/__tests__/resolverBase.rls.test.ts +3 -0
  205. package/src/__tests__/secretRedactor.failOpen.test.ts +135 -0
  206. package/src/__tests__/uploadTokenManager.test.ts +159 -0
  207. package/src/__tests__/widgetGuestElevation.test.ts +1 -1
  208. package/src/auth/AuthProviderCatalogRouter.ts +76 -0
  209. package/src/auth/AuthProviderEngine.ts +253 -0
  210. package/src/auth/exampleNewUserSubClass.ts +1 -1
  211. package/src/auth/index.ts +69 -21
  212. package/src/auth/initializeProviders.ts +128 -7
  213. package/src/auth/magicLink/MagicLinkService.ts +1 -1
  214. package/src/auth/newUsers.ts +1 -1
  215. package/src/config.ts +55 -36
  216. package/src/context.ts +2 -2
  217. package/src/generated/generated.ts +2038 -10529
  218. package/src/generic/ResolverBase.ts +63 -21
  219. package/src/generic/RunViewResolver.ts +31 -0
  220. package/src/index.ts +199 -56
  221. package/src/integration/RSUProgressBridge.ts +248 -0
  222. package/src/integration/SchemaRefreshLaunch.ts +77 -0
  223. package/src/logging/secretRedactor.ts +43 -0
  224. package/src/middleware/BaseServerMiddleware.ts +5 -0
  225. package/src/providerConfigUnits.ts +21 -0
  226. package/src/realtimeWidget/WidgetSessionService.ts +1 -1
  227. package/src/realtimeWidget/widgetGuestElevation.ts +1 -1
  228. package/src/resolvers/ActionResolver.ts +13 -0
  229. package/src/resolvers/ComponentRegistryResolver.ts +1 -1
  230. package/src/resolvers/EntityPermissionResolver.ts +1 -1
  231. package/src/resolvers/FileResolver.ts +200 -40
  232. package/src/resolvers/IntegrationDiscoveryResolver.ts +328 -70
  233. package/src/resolvers/PotentialDuplicateRecordResolver.ts +1 -1
  234. package/src/resolvers/QueryResolver.ts +25 -11
  235. package/src/resolvers/QuerySystemUserResolver.ts +28 -13
  236. package/src/resolvers/RealtimeClientSessionResolver.ts +13 -0
  237. package/src/resolvers/RunAIAgentResolver.ts +21 -6
  238. package/src/resolvers/SearchEntitiesResolver.ts +1 -1
  239. package/src/resolvers/SqlLoggingConfigResolver.ts +1 -2
  240. package/src/resolvers/SyncRolesUsersResolver.ts +2 -2
  241. package/src/resolvers/TaskGraphFrameResolver.ts +67 -0
  242. package/src/resolvers/UserFavoriteResolver.ts +1 -1
  243. package/src/resolvers/UserResolver.ts +99 -60
  244. package/src/resolvers/currentUserRoles.ts +47 -0
  245. package/src/rest/MediaAccessKeys.ts +47 -1
  246. package/src/rest/MediaStreamHandler.ts +98 -3
  247. package/src/rest/OAuthCallbackHandler.ts +150 -42
  248. package/src/rest/SignatureWebhookHandler.ts +1 -1
  249. package/src/rest/UploadTokenManager.ts +211 -0
  250. package/src/services/DurableEntityActionTaskSubmitter.ts +78 -0
  251. package/src/services/IntegrationSyncWorkerService.ts +141 -0
  252. package/src/services/ScheduledJobsService.ts +1 -1
  253. package/src/services/StartTaskGraphDispatcher.ts +38 -1
  254. package/src/services/TaskGraphActionRunner.ts +99 -0
  255. package/src/services/TaskGraphAgentRunner.ts +58 -1
  256. package/src/services/TaskGraphContinuationDeliverer.ts +11 -1
  257. package/src/services/TaskGraphPromptRunner.ts +144 -0
  258. package/src/telephony/RingCentralTelephonyService.ts +1 -1
  259. package/src/telephony/TwilioTelephonyRouter.ts +1 -1
  260. package/src/telephony/VonageTelephonyRouter.ts +1 -1
  261. package/src/types.ts +6 -0
@@ -8,7 +8,7 @@ import {
8
8
  PotentialDuplicateResult,
9
9
  } from '@memberjunction/core';
10
10
  import { AppContext } from '../types.js';
11
- import { UserCache } from '@memberjunction/sqlserver-dataprovider';
11
+ import { UserCache } from '@memberjunction/generic-database-provider';
12
12
 
13
13
  import { CompositeKeyInputType, CompositeKeyOutputType, KeyValuePairOutputType } from '../generic/KeyInputOutputTypes.js';
14
14
  import { GetReadOnlyProvider } from '../util.js';
@@ -43,6 +43,9 @@ export class RunQueryInput {
43
43
 
44
44
  @Field(() => GraphQLJSONObject, { nullable: true, description: 'Optional runtime-only directive to post-process result rows through a registered query result enricher ({ EnricherKey, Config })' })
45
45
  Enrichment?: RunQueryEnrichment;
46
+
47
+ @Field(() => String, { nullable: true, description: "Read source: 'Live' (default) or 'Materialized' (serve from a fresh RowFilterBroad materialization when available; falls back to live otherwise)" })
48
+ DataSource?: 'Live' | 'Materialized';
46
49
  }
47
50
 
48
51
  @ObjectType()
@@ -195,7 +198,8 @@ export class RunQueryResolver extends ResolverBase {
195
198
  @Arg('StartRow', () => Int, {nullable: true}) StartRow?: number,
196
199
  @Arg('ForceAuditLog', () => Boolean, {nullable: true}) ForceAuditLog?: boolean,
197
200
  @Arg('AuditLogDescription', () => String, {nullable: true}) AuditLogDescription?: string,
198
- @Arg('Enrichment', () => GraphQLJSONObject, {nullable: true}) Enrichment?: RunQueryEnrichment): Promise<RunQueryResultType> {
201
+ @Arg('Enrichment', () => GraphQLJSONObject, {nullable: true}) Enrichment?: RunQueryEnrichment,
202
+ @Arg('DataSource', () => String, {nullable: true, description: "Read source: 'Live' (default) or 'Materialized' (serve from a fresh RowFilterBroad materialization when available; falls back to live otherwise)"}) DataSource?: 'Live' | 'Materialized'): Promise<RunQueryResultType> {
199
203
  // Check API key scope authorization for query execution
200
204
  await this.CheckAPIKeyScopeAuthorization('query:run', QueryID, context.userPayload);
201
205
 
@@ -212,7 +216,8 @@ export class RunQueryResolver extends ResolverBase {
212
216
  StartRow: StartRow,
213
217
  ForceAuditLog: ForceAuditLog,
214
218
  AuditLogDescription: AuditLogDescription,
215
- Enrichment: Enrichment
219
+ Enrichment: Enrichment,
220
+ DataSource: DataSource
216
221
  },
217
222
  context.userPayload.userRecord);
218
223
 
@@ -256,7 +261,8 @@ export class RunQueryResolver extends ResolverBase {
256
261
  @Arg('StartRow', () => Int, {nullable: true}) StartRow?: number,
257
262
  @Arg('ForceAuditLog', () => Boolean, {nullable: true}) ForceAuditLog?: boolean,
258
263
  @Arg('AuditLogDescription', () => String, {nullable: true}) AuditLogDescription?: string,
259
- @Arg('Enrichment', () => GraphQLJSONObject, {nullable: true}) Enrichment?: RunQueryEnrichment): Promise<RunQueryResultType> {
264
+ @Arg('Enrichment', () => GraphQLJSONObject, {nullable: true}) Enrichment?: RunQueryEnrichment,
265
+ @Arg('DataSource', () => String, {nullable: true, description: "Read source: 'Live' (default) or 'Materialized' (serve from a fresh RowFilterBroad materialization when available; falls back to live otherwise)"}) DataSource?: 'Live' | 'Materialized'): Promise<RunQueryResultType> {
260
266
  // Check API key scope authorization for query execution
261
267
  await this.CheckAPIKeyScopeAuthorization('query:run', QueryName, context.userPayload);
262
268
 
@@ -272,7 +278,8 @@ export class RunQueryResolver extends ResolverBase {
272
278
  StartRow: StartRow,
273
279
  ForceAuditLog: ForceAuditLog,
274
280
  AuditLogDescription: AuditLogDescription,
275
- Enrichment: Enrichment
281
+ Enrichment: Enrichment,
282
+ DataSource: DataSource
276
283
  },
277
284
  context.userPayload.userRecord);
278
285
 
@@ -304,7 +311,8 @@ export class RunQueryResolver extends ResolverBase {
304
311
  @Arg('StartRow', () => Int, {nullable: true}) StartRow?: number,
305
312
  @Arg('ForceAuditLog', () => Boolean, {nullable: true}) ForceAuditLog?: boolean,
306
313
  @Arg('AuditLogDescription', () => String, {nullable: true}) AuditLogDescription?: string,
307
- @Arg('Enrichment', () => GraphQLJSONObject, {nullable: true}) Enrichment?: RunQueryEnrichment): Promise<RunQueryResultType> {
314
+ @Arg('Enrichment', () => GraphQLJSONObject, {nullable: true}) Enrichment?: RunQueryEnrichment,
315
+ @Arg('DataSource', () => String, {nullable: true, description: "Read source: 'Live' (default) or 'Materialized' (serve from a fresh RowFilterBroad materialization when available; falls back to live otherwise)"}) DataSource?: 'Live' | 'Materialized'): Promise<RunQueryResultType> {
308
316
  const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true});
309
317
  const md = provider as unknown as IMetadataProvider;
310
318
  const rq = new RunQuery(provider as unknown as IRunQueryProvider);
@@ -319,10 +327,11 @@ export class RunQueryResolver extends ResolverBase {
319
327
  StartRow: StartRow,
320
328
  ForceAuditLog: ForceAuditLog,
321
329
  AuditLogDescription: AuditLogDescription,
322
- Enrichment: Enrichment
330
+ Enrichment: Enrichment,
331
+ DataSource: DataSource
323
332
  },
324
333
  context.userPayload.userRecord);
325
-
334
+
326
335
  // If QueryName is not populated by the provider, use efficient lookup
327
336
  let queryName = result.QueryName;
328
337
  if (!queryName) {
@@ -364,7 +373,8 @@ export class RunQueryResolver extends ResolverBase {
364
373
  @Arg('StartRow', () => Int, {nullable: true}) StartRow?: number,
365
374
  @Arg('ForceAuditLog', () => Boolean, {nullable: true}) ForceAuditLog?: boolean,
366
375
  @Arg('AuditLogDescription', () => String, {nullable: true}) AuditLogDescription?: string,
367
- @Arg('Enrichment', () => GraphQLJSONObject, {nullable: true}) Enrichment?: RunQueryEnrichment): Promise<RunQueryResultType> {
376
+ @Arg('Enrichment', () => GraphQLJSONObject, {nullable: true}) Enrichment?: RunQueryEnrichment,
377
+ @Arg('DataSource', () => String, {nullable: true, description: "Read source: 'Live' (default) or 'Materialized' (serve from a fresh RowFilterBroad materialization when available; falls back to live otherwise)"}) DataSource?: 'Live' | 'Materialized'): Promise<RunQueryResultType> {
368
378
  const provider = GetReadOnlyProvider(context.providers, {allowFallbackToReadWrite: true});
369
379
  const rq = new RunQuery(provider as unknown as IRunQueryProvider);
370
380
 
@@ -378,7 +388,8 @@ export class RunQueryResolver extends ResolverBase {
378
388
  StartRow: StartRow,
379
389
  ForceAuditLog: ForceAuditLog,
380
390
  AuditLogDescription: AuditLogDescription,
381
- Enrichment: Enrichment
391
+ Enrichment: Enrichment,
392
+ DataSource: DataSource
382
393
  },
383
394
  context.userPayload.userRecord);
384
395
 
@@ -426,7 +437,8 @@ export class RunQueryResolver extends ResolverBase {
426
437
  StartRow: i.StartRow,
427
438
  ForceAuditLog: i.ForceAuditLog,
428
439
  AuditLogDescription: i.AuditLogDescription,
429
- Enrichment: i.Enrichment
440
+ Enrichment: i.Enrichment,
441
+ DataSource: i.DataSource
430
442
  }));
431
443
 
432
444
  // Execute all queries in parallel using the batch method
@@ -476,7 +488,8 @@ export class RunQueryResolver extends ResolverBase {
476
488
  StartRow: i.StartRow,
477
489
  ForceAuditLog: i.ForceAuditLog,
478
490
  AuditLogDescription: i.AuditLogDescription,
479
- Enrichment: i.Enrichment
491
+ Enrichment: i.Enrichment,
492
+ DataSource: i.DataSource
480
493
  }));
481
494
 
482
495
  // Execute all queries in parallel using the batch method
@@ -540,6 +553,7 @@ export class RunQueryResolver extends ResolverBase {
540
553
  ForceAuditLog: item.params.ForceAuditLog,
541
554
  AuditLogDescription: item.params.AuditLogDescription,
542
555
  Enrichment: item.params.Enrichment,
556
+ DataSource: item.params.DataSource,
543
557
  },
544
558
  cacheStatus: item.cacheStatus ? {
545
559
  maxUpdatedAt: item.cacheStatus.maxUpdatedAt,
@@ -182,8 +182,13 @@ export class UpdateQuerySystemUserInput {
182
182
  * Composes the CodeGen-generated MJQuery_ type so that new entity fields
183
183
  * are automatically available in the GraphQL schema without manual sync.
184
184
  *
185
- * On success, Query contains the full query data (scalars + related entities).
186
- * On failure, Query is null and ErrorMessage describes the problem.
185
+ * Child collections live on this result type (not as generated `*Array`
186
+ * FieldResolvers on MJQuery_) so the mutation can return the graph it already
187
+ * loaded without a per-parent SELECT *.
188
+ *
189
+ * On success, Query contains the query scalars and Fields/Parameters/Entities/
190
+ * Permissions hold the related rows. On failure, Query is null and
191
+ * ErrorMessage describes the problem.
187
192
  */
188
193
  @ObjectType()
189
194
  export class QueryMutationResultType {
@@ -195,6 +200,18 @@ export class QueryMutationResultType {
195
200
 
196
201
  @Field(() => MJQuery_, { nullable: true })
197
202
  Query?: MJQuery_;
203
+
204
+ @Field(() => [MJQueryField_], { nullable: true })
205
+ Fields?: MJQueryField_[];
206
+
207
+ @Field(() => [MJQueryParameter_], { nullable: true })
208
+ Parameters?: MJQueryParameter_[];
209
+
210
+ @Field(() => [MJQueryEntity_], { nullable: true })
211
+ Entities?: MJQueryEntity_[];
212
+
213
+ @Field(() => [MJQueryPermission_], { nullable: true })
214
+ Permissions?: MJQueryPermission_[];
198
215
  }
199
216
 
200
217
  @ObjectType()
@@ -306,7 +323,7 @@ export class MJQueryResolverExtended extends MJQueryResolver {
306
323
  }
307
324
 
308
325
 
309
- return this.buildSuccessResult(record);
326
+ return await this.buildSuccessResult(record);
310
327
  }
311
328
  else {
312
329
  // Save failed - check if another request created the same query (race condition)
@@ -319,7 +336,7 @@ export class MJQueryResolverExtended extends MJQueryResolver {
319
336
  LogStatus(`[CreateQuery] Unique constraint detected for query '${input.Name}'. Using existing query (ID: ${existingQuery.ID}) created by concurrent request.`);
320
337
  const existingEntity = await provider.GetEntityObject<MJQueryEntityServer>('MJ: Queries', context.userPayload.userRecord);
321
338
  if (await existingEntity.Load(existingQuery.ID)) {
322
- return this.buildSuccessResult(existingEntity);
339
+ return await this.buildSuccessResult(existingEntity);
323
340
  }
324
341
  // Entity load failed after confirming the row exists — extremely rare
325
342
  return {
@@ -350,16 +367,14 @@ export class MJQueryResolverExtended extends MJQueryResolver {
350
367
  * Uses entity.GetAll() for scalar fields so that new CodeGen-generated fields are included
351
368
  * automatically without manual updates. Related entity arrays are mapped explicitly.
352
369
  */
353
- private buildSuccessResult(entity: MJQueryEntityServer): QueryMutationResultType {
370
+ private async buildSuccessResult(entity: MJQueryEntityServer): Promise<QueryMutationResultType> {
354
371
  return {
355
372
  Success: true,
356
- Query: {
357
- ...entity.GetAll(),
358
- MJQueryFields_QueryIDArray: this.mapFields(entity.QueryFields),
359
- MJQueryParameters_QueryIDArray: this.mapParameters(entity.QueryParameters),
360
- MJQueryEntities_QueryIDArray: this.mapEntities(entity.QueryEntities),
361
- MJQueryPermissions_QueryIDArray: this.mapPermissions(entity.QueryPermissions),
362
- } as MJQuery_
373
+ Query: await this.MapFieldNamesToCodeNames('MJ: Queries', entity.GetAll()) as MJQuery_,
374
+ Fields: this.mapFields(entity.QueryFields),
375
+ Parameters: this.mapParameters(entity.QueryParameters),
376
+ Entities: this.mapEntities(entity.QueryEntities),
377
+ Permissions: this.mapPermissions(entity.QueryPermissions),
363
378
  };
364
379
  }
365
380
 
@@ -538,7 +553,7 @@ export class MJQueryResolverExtended extends MJQueryResolver {
538
553
  await this.createPermissions(provider, input.Permissions, queryID, context.userPayload.userRecord);
539
554
  }
540
555
 
541
- return this.buildSuccessResult(queryEntity);
556
+ return await this.buildSuccessResult(queryEntity);
542
557
 
543
558
  } catch (err) {
544
559
  LogError(err);
@@ -227,6 +227,18 @@ export class StartRealtimeClientSessionResult {
227
227
  @Field(() => String, { nullable: true })
228
228
  ModelName?: string;
229
229
 
230
+ /**
231
+ * `DriverClass` of the vendor that actually runs the session (e.g. `OpenAIRealtime`,
232
+ * `ElevenLabsRealtime`). Null when unknown.
233
+ *
234
+ * Surfaced to the BROWSER because on the default-model path the framework picks the vendor itself:
235
+ * without this the caller cannot tell which vendor spoke, and so cannot diagnose a voice that did
236
+ * not land (issue #3530). `ModelName` alone is not enough — one model can resolve to different
237
+ * vendors depending on which API keys a deployment configures.
238
+ */
239
+ @Field(() => String, { nullable: true })
240
+ DriverClass?: string;
241
+
230
242
  /**
231
243
  * DB-driven progress-narration instruction template (contains a `{{ progressMessage }}`
232
244
  * placeholder). Null when the narration prompt is not present in this deployment's metadata —
@@ -1677,6 +1689,7 @@ export class RealtimeClientSessionResolver extends ResolverBase {
1677
1689
  ExpiresAt: cfg.ExpiresAt,
1678
1690
  SessionConfigJson: JSON.stringify(cfg.SessionConfig),
1679
1691
  ModelName: prep.ModelName,
1692
+ DriverClass: prep.DriverClass,
1680
1693
  NarrationInstructionsTemplate: prep.NarrationInstructionsTemplate,
1681
1694
  NarrationPaceMs: prep.NarrationPaceMs,
1682
1695
  EffectiveConfigJson: prep.EffectiveConfig ? JSON.stringify(prep.EffectiveConfig) : undefined,
@@ -387,7 +387,9 @@ export class RunAIAgentResolver extends ResolverBase {
387
387
  planMode?: boolean,
388
388
  /** Skill IDs the user requested (via `/skill-name`) — threaded into ExecuteAgentParams.requestedSkillIDs.
389
389
  * The framework intersects them with the agent's accepted skills AND the user's Run permission. */
390
- requestedSkillIDs?: string[]
390
+ requestedSkillIDs?: string[],
391
+ /** JSON `{ paused?: boolean }` — seeds `$.debug` on a submitted task graph at insert. */
392
+ taskGraphDebug?: string
391
393
  ): Promise<AIAgentRunResult> {
392
394
  const startTime = Date.now();
393
395
 
@@ -441,6 +443,7 @@ export class RunAIAgentResolver extends ResolverBase {
441
443
  configurationId: configurationId,
442
444
  planMode: planMode,
443
445
  requestedSkillIDs: requestedSkillIDs,
446
+ taskGraphDebug: parseTaskGraphDebug(taskGraphDebug),
444
447
  data: parsedData,
445
448
  context: {
446
449
  dataSource: dataSource
@@ -632,7 +635,9 @@ export class RunAIAgentResolver extends ResolverBase {
632
635
  @Arg('planMode', { nullable: true }) planMode?: boolean,
633
636
  /** Skill IDs the user requested — symmetric with RunAIAgentFromConversationDetail. Intersected
634
637
  * server-side with the agent's accepted skills AND the user's Run permission. */
635
- @Arg('requestedSkillIDs', () => [String], { nullable: true }) requestedSkillIDs?: string[]
638
+ @Arg('requestedSkillIDs', () => [String], { nullable: true }) requestedSkillIDs?: string[],
639
+ /** JSON `{ paused?: boolean }` — start-paused for a Flow agent that submits a graph. */
640
+ @Arg('taskGraphDebug', { nullable: true }) taskGraphDebug?: string
636
641
  ): Promise<AIAgentRunResult> {
637
642
  // Check API key scope authorization for agent execution
638
643
  await this.CheckAPIKeyScopeAuthorization('agent:execute', agentId, userPayload);
@@ -646,7 +651,7 @@ export class RunAIAgentResolver extends ResolverBase {
646
651
  p, dataSource, agentId, userPayload, messagesJson, sessionId, pubSub,
647
652
  data, payload, lastRunId, autoPopulateLastRunPayload, configurationId,
648
653
  conversationDetailId, createArtifacts || false, createNotification || false,
649
- sourceArtifactId, sourceArtifactVersionId, undefined /*conversationId*/, planMode, requestedSkillIDs
654
+ sourceArtifactId, sourceArtifactVersionId, undefined /*conversationId*/, planMode, requestedSkillIDs, taskGraphDebug
650
655
  );
651
656
 
652
657
  LogStatus(`🔥 Fire-and-forget: Agent ${agentId} execution started in background for session ${sessionId}`);
@@ -680,7 +685,8 @@ export class RunAIAgentResolver extends ResolverBase {
680
685
  undefined, // conversationId (not pre-resolved on this path)
681
686
  undefined, // runRef
682
687
  planMode,
683
- requestedSkillIDs
688
+ requestedSkillIDs,
689
+ taskGraphDebug
684
690
  );
685
691
  }
686
692
 
@@ -1276,7 +1282,8 @@ export class RunAIAgentResolver extends ResolverBase {
1276
1282
  /** Per-request Plan Mode toggle — threaded through to ExecuteAgentParams.planMode. */
1277
1283
  planMode?: boolean,
1278
1284
  /** Skill IDs the user requested — threaded through to ExecuteAgentParams.requestedSkillIDs. */
1279
- requestedSkillIDs?: string[]
1285
+ requestedSkillIDs?: string[],
1286
+ taskGraphDebug?: string
1280
1287
  ): void {
1281
1288
  // Ref the liveness pulse reads to enrich heartbeats once the run is created.
1282
1289
  const runRef: { current: MJAIAgentRunEntityExtended | null } = { current: null };
@@ -1295,7 +1302,7 @@ export class RunAIAgentResolver extends ResolverBase {
1295
1302
  p, dataSource, agentId, userPayload, messagesJson, sessionId, pubSub,
1296
1303
  data, payload, undefined, lastRunId, autoPopulateLastRunPayload,
1297
1304
  configurationId, conversationDetailId, createArtifacts, createNotification,
1298
- sourceArtifactId, sourceArtifactVersionId, conversationId, runRef, planMode, requestedSkillIDs
1305
+ sourceArtifactId, sourceArtifactVersionId, conversationId, runRef, planMode, requestedSkillIDs, taskGraphDebug
1299
1306
  ).catch((error: unknown) => {
1300
1307
  // Background execution failed unexpectedly (executeAIAgent has its own try-catch,
1301
1308
  // so this would only fire for truly unexpected errors).
@@ -1587,4 +1594,12 @@ export class RunAIAgentResolver extends ResolverBase {
1587
1594
  }
1588
1595
  }
1589
1596
 
1597
+ }
1598
+
1599
+ function parseTaskGraphDebug(raw?: string): { paused?: boolean } | undefined {
1600
+ if (!raw) return undefined;
1601
+ const parsed: unknown = SafeJSONParse(raw);
1602
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return undefined;
1603
+ const paused = (parsed as { paused?: unknown }).paused;
1604
+ return paused === true ? { paused: true } : undefined;
1590
1605
  }
@@ -1,7 +1,7 @@
1
1
  import { Arg, Ctx, Field, Float, InputType, Int, ObjectType, Query, Resolver } from 'type-graphql';
2
2
  import { EntitySearchResult, SearchEntityParams } from '@memberjunction/core';
3
3
  import { AppContext } from '../types.js';
4
- import { UserCache } from '@memberjunction/sqlserver-dataprovider';
4
+ import { UserCache } from '@memberjunction/generic-database-provider';
5
5
  import { GetReadOnlyProvider } from '../util.js';
6
6
 
7
7
  /**
@@ -2,14 +2,13 @@ import { Arg, Ctx, Field, InputType, Mutation, ObjectType, Query, Int, Resolver
2
2
  import { AppContext } from '../types.js';
3
3
  import { Metadata, UserInfo } from '@memberjunction/core';
4
4
  import { SQLServerDataProvider } from '@memberjunction/sqlserver-dataprovider';
5
- import { UserCache } from '@memberjunction/sqlserver-dataprovider';
6
5
  import { v4 as uuidv4 } from 'uuid';
7
6
  import * as path from 'path';
8
7
  import * as fs from 'fs/promises';
9
8
  import { loadConfig } from '../config.js';
10
9
  import { ResolverBase } from '../generic/ResolverBase.js';
11
10
  import { GetReadOnlyProvider } from '../util.js';
12
- import { SqlLoggingOptions as ProviderSqlLoggingOptions } from '@memberjunction/generic-database-provider';
11
+ import { UserCache, SqlLoggingOptions as ProviderSqlLoggingOptions } from '@memberjunction/generic-database-provider';
13
12
 
14
13
  /**
15
14
  * Configuration options for SQL logging sessions.
@@ -4,7 +4,7 @@ import { DatabaseProviderBase, EntityDeleteOptions, EntitySaveOptions, IMetadata
4
4
  import { UUIDsEqual } from '@memberjunction/global';
5
5
  import { RequireSystemUser } from '../directives/RequireSystemUser.js';
6
6
  import { MJRoleEntity, MJUserEntity, MJUserRoleEntity } from '@memberjunction/core-entities';
7
- import { UserCache } from '@memberjunction/sqlserver-dataprovider';
7
+ import { UserCache } from '@memberjunction/generic-database-provider';
8
8
  import { GetReadWriteProvider } from '../util.js';
9
9
 
10
10
  @ObjectType()
@@ -112,7 +112,7 @@ export class SyncRolesAndUsersResolver {
112
112
  await provider.CommitTransaction();
113
113
 
114
114
  // refresh the user cache — one-time, since the normal auto-refresh is already scheduled
115
- await UserCache.Instance.Refresh(context.dataSource);
115
+ await UserCache.Instance.Refresh(provider);
116
116
  return usersResult;
117
117
  } catch (txErr) {
118
118
  await provider.RollbackTransaction();
@@ -52,6 +52,58 @@ export class TaskGraphFrameNotification {
52
52
  @Field(() => Number, { nullable: true })
53
53
  totalCount?: number;
54
54
 
55
+ // ── GateDecision ──────────────────────────────────────────────────────────
56
+ @Field(() => ID, { nullable: true })
57
+ edgeId?: string;
58
+
59
+ @Field(() => ID, { nullable: true })
60
+ dependsOnTaskId?: string;
61
+
62
+ /** 'satisfied' | 'notTaken' | 'held' */
63
+ @Field(() => String, { nullable: true })
64
+ verdict?: string;
65
+
66
+ @Field(() => String, { nullable: true })
67
+ conditionText?: string;
68
+
69
+ @Field(() => String, { nullable: true })
70
+ reason?: string;
71
+
72
+ // ── ClaimChanged ──────────────────────────────────────────────────────────
73
+ /** 'claimed' | 'heartbeat-lost' | 'reclaimed' */
74
+ @Field(() => String, { nullable: true })
75
+ claimEvent?: string;
76
+
77
+ @Field(() => String, { nullable: true })
78
+ claimedBy?: string;
79
+
80
+ @Field(() => String, { nullable: true })
81
+ claimExpiresAt?: string;
82
+
83
+ // ── PassCompleted ─────────────────────────────────────────────────────────
84
+ @Field(() => Number, { nullable: true })
85
+ passNumber?: number;
86
+
87
+ @Field(() => Number, { nullable: true })
88
+ eligibleCount?: number;
89
+
90
+ @Field(() => Number, { nullable: true })
91
+ heldCount?: number;
92
+
93
+ @Field(() => Number, { nullable: true })
94
+ claimedCount?: number;
95
+
96
+ /** The dispatcher instance's own load across every graph — not this graph's in-flight count. */
97
+ @Field(() => Number, { nullable: true })
98
+ instanceInFlightCount?: number;
99
+
100
+ // ── NodeProgress ──────────────────────────────────────────────────────────
101
+ @Field(() => String, { nullable: true })
102
+ progressMessage?: string;
103
+
104
+ @Field(() => Number, { nullable: true })
105
+ progressPercent?: number;
106
+
55
107
  @Field(() => Date)
56
108
  date!: Date;
57
109
  }
@@ -154,6 +206,21 @@ export class TaskGraphFrameResolver {
154
206
  assignedUserId: payload.AssignedUserID,
155
207
  completedCount: payload.CompletedCount,
156
208
  totalCount: payload.TotalCount,
209
+ edgeId: payload.EdgeID,
210
+ dependsOnTaskId: payload.DependsOnTaskID,
211
+ verdict: payload.Verdict,
212
+ conditionText: payload.ConditionText,
213
+ reason: payload.Reason,
214
+ claimEvent: payload.ClaimEvent,
215
+ claimedBy: payload.ClaimedBy,
216
+ claimExpiresAt: payload.ClaimExpiresAt,
217
+ passNumber: payload.PassNumber,
218
+ eligibleCount: payload.EligibleCount,
219
+ heldCount: payload.HeldCount,
220
+ claimedCount: payload.ClaimedCount,
221
+ instanceInFlightCount: payload.InstanceInFlightCount,
222
+ progressMessage: payload.ProgressMessage,
223
+ progressPercent: payload.ProgressPercent,
157
224
  date: new Date(),
158
225
  };
159
226
  }
@@ -14,7 +14,7 @@ import {
14
14
  Query,
15
15
  Resolver,
16
16
  } from '@memberjunction/server';
17
- import { UserCache } from '@memberjunction/sqlserver-dataprovider';
17
+ import { UserCache } from '@memberjunction/generic-database-provider';
18
18
 
19
19
  import { MJUserFavorite_, MJUserFavoriteResolverBase } from '../generated/generated.js';
20
20
  import { GetReadOnlyProvider } from '../util.js';