@memberjunction/server 6.2.0-edge.6 → 6.2.0-edge.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +69 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/agentSessions/BridgeHostInstance.d.ts +8 -3
- package/dist/agentSessions/BridgeHostInstance.d.ts.map +1 -1
- package/dist/agentSessions/BridgeHostInstance.js +14 -4
- package/dist/agentSessions/BridgeHostInstance.js.map +1 -1
- package/dist/agentSessions/HandoffOfferExpiry.d.ts +10 -0
- package/dist/agentSessions/HandoffOfferExpiry.d.ts.map +1 -0
- package/dist/agentSessions/HandoffOfferExpiry.js +18 -0
- package/dist/agentSessions/HandoffOfferExpiry.js.map +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js +1 -0
- package/dist/agentSessions/ReturningVisitorRecap.js.map +1 -1
- package/dist/agentSessions/SessionJanitor.d.ts +31 -8
- package/dist/agentSessions/SessionJanitor.d.ts.map +1 -1
- package/dist/agentSessions/SessionJanitor.js +85 -41
- package/dist/agentSessions/SessionJanitor.js.map +1 -1
- package/dist/agentSessions/SessionManager.d.ts +14 -4
- package/dist/agentSessions/SessionManager.d.ts.map +1 -1
- package/dist/agentSessions/SessionManager.js +28 -4
- package/dist/agentSessions/SessionManager.js.map +1 -1
- package/dist/agentSessions/conversationBrowsers.d.ts +61 -0
- package/dist/agentSessions/conversationBrowsers.d.ts.map +1 -0
- package/dist/agentSessions/conversationBrowsers.js +118 -0
- package/dist/agentSessions/conversationBrowsers.js.map +1 -0
- package/dist/agentSessions/sessionDeadline.d.ts +43 -0
- package/dist/agentSessions/sessionDeadline.d.ts.map +1 -0
- package/dist/agentSessions/sessionDeadline.js +68 -0
- package/dist/agentSessions/sessionDeadline.js.map +1 -0
- package/dist/auth/APIKeyScopeAuth.d.ts.map +1 -1
- package/dist/auth/APIKeyScopeAuth.js +5 -4
- package/dist/auth/APIKeyScopeAuth.js.map +1 -1
- package/dist/auth/loginEmailResolution.d.ts +41 -0
- package/dist/auth/loginEmailResolution.d.ts.map +1 -0
- package/dist/auth/loginEmailResolution.js +47 -0
- package/dist/auth/loginEmailResolution.js.map +1 -0
- package/dist/auth/magicLink/MagicLinkKeys.d.ts +50 -2
- package/dist/auth/magicLink/MagicLinkKeys.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkKeys.js +129 -12
- package/dist/auth/magicLink/MagicLinkKeys.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.d.ts +3 -0
- package/dist/auth/magicLink/MagicLinkRouter.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkRouter.js +23 -5
- package/dist/auth/magicLink/MagicLinkRouter.js.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.d.ts +39 -5
- package/dist/auth/magicLink/MagicLinkService.d.ts.map +1 -1
- package/dist/auth/magicLink/MagicLinkService.js +221 -9
- package/dist/auth/magicLink/MagicLinkService.js.map +1 -1
- package/dist/auth/magicLink/index.d.ts +1 -1
- package/dist/auth/magicLink/index.d.ts.map +1 -1
- package/dist/auth/magicLink/index.js +1 -1
- package/dist/auth/magicLink/index.js.map +1 -1
- package/dist/auth/magicLink/redeemLanding.d.ts +2 -2
- package/dist/auth/magicLink/redeemLanding.d.ts.map +1 -1
- package/dist/auth/magicLink/redeemLanding.js +7 -4
- package/dist/auth/magicLink/redeemLanding.js.map +1 -1
- package/dist/auth/magicLink/types.d.ts +27 -3
- package/dist/auth/magicLink/types.d.ts.map +1 -1
- package/dist/auth/magicLink/types.js +0 -4
- package/dist/auth/magicLink/types.js.map +1 -1
- package/dist/auth/newUsers.d.ts.map +1 -1
- package/dist/auth/newUsers.js +1 -0
- package/dist/auth/newUsers.js.map +1 -1
- package/dist/backgroundSweepConfigUnits.d.ts +231 -0
- package/dist/backgroundSweepConfigUnits.d.ts.map +1 -0
- package/dist/backgroundSweepConfigUnits.js +180 -0
- package/dist/backgroundSweepConfigUnits.js.map +1 -0
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.d.ts.map +1 -1
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js +2 -1
- package/dist/broadcast/BaseCacheInvalidationBroadcastProvider.js.map +1 -1
- package/dist/config.d.ts +906 -8
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +59 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +2 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +41 -12
- package/dist/context.js.map +1 -1
- package/dist/coreRoutes.d.ts +3 -1
- package/dist/coreRoutes.d.ts.map +1 -1
- package/dist/coreRoutes.js +6 -4
- package/dist/coreRoutes.js.map +1 -1
- package/dist/generated/graphql-schemas/__mj.d.ts +1072 -5
- package/dist/generated/graphql-schemas/__mj.d.ts.map +1 -1
- package/dist/generated/graphql-schemas/__mj.js +10174 -4618
- package/dist/generated/graphql-schemas/__mj.js.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts +11 -0
- package/dist/generic/OrphanedConversationDetailReconciler.d.ts.map +1 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js +27 -1
- package/dist/generic/OrphanedConversationDetailReconciler.js.map +1 -1
- package/dist/generic/ResolverBase.d.ts +50 -5
- package/dist/generic/ResolverBase.d.ts.map +1 -1
- package/dist/generic/ResolverBase.js +329 -132
- package/dist/generic/ResolverBase.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts +4 -0
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js +47 -7
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/globalCors.d.ts.map +1 -1
- package/dist/globalCors.js +1 -0
- package/dist/globalCors.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +201 -43
- package/dist/index.js.map +1 -1
- package/dist/integration/ConnectionPause.d.ts +121 -0
- package/dist/integration/ConnectionPause.d.ts.map +1 -0
- package/dist/integration/ConnectionPause.js +183 -0
- package/dist/integration/ConnectionPause.js.map +1 -0
- package/dist/integration/CustomColumnPromoter.d.ts +72 -6
- package/dist/integration/CustomColumnPromoter.d.ts.map +1 -1
- package/dist/integration/CustomColumnPromoter.js +87 -46
- package/dist/integration/CustomColumnPromoter.js.map +1 -1
- package/dist/integration/EntityMapLifecycle.d.ts +78 -4
- package/dist/integration/EntityMapLifecycle.d.ts.map +1 -1
- package/dist/integration/EntityMapLifecycle.js +199 -5
- package/dist/integration/EntityMapLifecycle.js.map +1 -1
- package/dist/integration/InactiveRowWarnings.d.ts +31 -0
- package/dist/integration/InactiveRowWarnings.d.ts.map +1 -1
- package/dist/integration/InactiveRowWarnings.js +29 -0
- package/dist/integration/InactiveRowWarnings.js.map +1 -1
- package/dist/integration/ObjectNamesByID.d.ts +28 -0
- package/dist/integration/ObjectNamesByID.d.ts.map +1 -0
- package/dist/integration/ObjectNamesByID.js +87 -0
- package/dist/integration/ObjectNamesByID.js.map +1 -0
- package/dist/integration/PostRestartIntrospect.d.ts +26 -0
- package/dist/integration/PostRestartIntrospect.d.ts.map +1 -0
- package/dist/integration/PostRestartIntrospect.js +27 -0
- package/dist/integration/PostRestartIntrospect.js.map +1 -0
- package/dist/integration/RSUPostRestartProgress.d.ts +176 -0
- package/dist/integration/RSUPostRestartProgress.d.ts.map +1 -0
- package/dist/integration/RSUPostRestartProgress.js +323 -0
- package/dist/integration/RSUPostRestartProgress.js.map +1 -0
- package/dist/integration/RSUProgressBridge.d.ts +41 -2
- package/dist/integration/RSUProgressBridge.d.ts.map +1 -1
- package/dist/integration/RSUProgressBridge.js +84 -1
- package/dist/integration/RSUProgressBridge.js.map +1 -1
- package/dist/integration/RunArtifactAuthorization.d.ts +39 -0
- package/dist/integration/RunArtifactAuthorization.d.ts.map +1 -0
- package/dist/integration/RunArtifactAuthorization.js +45 -0
- package/dist/integration/RunArtifactAuthorization.js.map +1 -0
- package/dist/integration/SchemaRefreshLaunch.d.ts +9 -0
- package/dist/integration/SchemaRefreshLaunch.d.ts.map +1 -1
- package/dist/integration/SchemaRefreshLaunch.js +3 -2
- package/dist/integration/SchemaRefreshLaunch.js.map +1 -1
- package/dist/integration/ScopedFieldsForBuild.d.ts +46 -0
- package/dist/integration/ScopedFieldsForBuild.d.ts.map +1 -0
- package/dist/integration/ScopedFieldsForBuild.js +91 -0
- package/dist/integration/ScopedFieldsForBuild.js.map +1 -0
- package/dist/integration/TargetConfigGuard.d.ts +40 -0
- package/dist/integration/TargetConfigGuard.d.ts.map +1 -0
- package/dist/integration/TargetConfigGuard.js +40 -0
- package/dist/integration/TargetConfigGuard.js.map +1 -0
- package/dist/logging/StartupLogger.d.ts +50 -0
- package/dist/logging/StartupLogger.d.ts.map +1 -1
- package/dist/logging/StartupLogger.js +15 -22
- package/dist/logging/StartupLogger.js.map +1 -1
- package/dist/middleware/BaseServerMiddleware.d.ts +21 -3
- package/dist/middleware/BaseServerMiddleware.d.ts.map +1 -1
- package/dist/middleware/BaseServerMiddleware.js +4 -2
- package/dist/middleware/BaseServerMiddleware.js.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.d.ts.map +1 -1
- package/dist/realtimeSessions/ownedRealtimeSession.js +2 -3
- package/dist/realtimeSessions/ownedRealtimeSession.js.map +1 -1
- package/dist/realtimeSessions/sessionAccess.d.ts +15 -0
- package/dist/realtimeSessions/sessionAccess.d.ts.map +1 -1
- package/dist/realtimeSessions/sessionAccess.js +22 -0
- package/dist/realtimeSessions/sessionAccess.js.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.d.ts.map +1 -1
- package/dist/realtimeWidget/WidgetSessionService.js +2 -0
- package/dist/realtimeWidget/WidgetSessionService.js.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.d.ts.map +1 -1
- package/dist/realtimeWidget/visitorIdentity.js +1 -0
- package/dist/realtimeWidget/visitorIdentity.js.map +1 -1
- package/dist/realtimeWidget/widgetCore.d.ts.map +1 -1
- package/dist/realtimeWidget/widgetCore.js +4 -7
- package/dist/realtimeWidget/widgetCore.js.map +1 -1
- package/dist/realtimeWidget/widgetGuestElevation.js +1 -0
- package/dist/realtimeWidget/widgetGuestElevation.js.map +1 -1
- package/dist/requestOrigin.d.ts +22 -0
- package/dist/requestOrigin.d.ts.map +1 -0
- package/dist/requestOrigin.js +60 -0
- package/dist/requestOrigin.js.map +1 -0
- package/dist/resolvers/AgentRunStatusPublisher.d.ts +10 -0
- package/dist/resolvers/AgentRunStatusPublisher.d.ts.map +1 -1
- package/dist/resolvers/AgentRunStatusPublisher.js +18 -2
- package/dist/resolvers/AgentRunStatusPublisher.js.map +1 -1
- package/dist/resolvers/AgentSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/AgentSessionResolver.js +6 -2
- package/dist/resolvers/AgentSessionResolver.js.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.d.ts +1 -1
- package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.js +61 -16
- package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.d.ts.map +1 -1
- package/dist/resolvers/ConversationRunEventsResolver.js +2 -0
- package/dist/resolvers/ConversationRunEventsResolver.js.map +1 -1
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts +6 -0
- package/dist/resolvers/ExecuteRemoteOperationResolver.d.ts.map +1 -1
- package/dist/resolvers/ExecuteRemoteOperationResolver.js +30 -7
- package/dist/resolvers/ExecuteRemoteOperationResolver.js.map +1 -1
- package/dist/resolvers/GetDataResolver.d.ts.map +1 -1
- package/dist/resolvers/GetDataResolver.js +34 -13
- package/dist/resolvers/GetDataResolver.js.map +1 -1
- package/dist/resolvers/InfoResolver.js +1 -1
- package/dist/resolvers/InfoResolver.js.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts +401 -11
- package/dist/resolvers/IntegrationDiscoveryResolver.d.ts.map +1 -1
- package/dist/resolvers/IntegrationDiscoveryResolver.js +2690 -1305
- package/dist/resolvers/IntegrationDiscoveryResolver.js.map +1 -1
- package/dist/resolvers/MCPResolver.d.ts.map +1 -1
- package/dist/resolvers/MCPResolver.js +13 -2
- package/dist/resolvers/MCPResolver.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +38 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +181 -88
- package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeBridgeResolver.js +1 -0
- package/dist/resolvers/RealtimeBridgeResolver.js.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts +6 -0
- package/dist/resolvers/RealtimeClientSessionResolver.d.ts.map +1 -1
- package/dist/resolvers/RealtimeClientSessionResolver.js +36 -5
- package/dist/resolvers/RealtimeClientSessionResolver.js.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts +62 -10
- package/dist/resolvers/RemoteBrowserActionResolver.d.ts.map +1 -1
- package/dist/resolvers/RemoteBrowserActionResolver.js +217 -34
- package/dist/resolvers/RemoteBrowserActionResolver.js.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts +24 -8
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +185 -67
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.d.ts +5 -3
- package/dist/resolvers/RunAIPromptResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIPromptResolver.js +19 -18
- package/dist/resolvers/RunAIPromptResolver.js.map +1 -1
- package/dist/resolvers/RunTemplateResolver.d.ts.map +1 -1
- package/dist/resolvers/RunTemplateResolver.js +3 -1
- package/dist/resolvers/RunTemplateResolver.js.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.d.ts.map +1 -1
- package/dist/resolvers/SqlLoggingConfigResolver.js +7 -8
- package/dist/resolvers/SqlLoggingConfigResolver.js.map +1 -1
- package/dist/resolvers/TagGovernanceResolver.d.ts +12 -0
- package/dist/resolvers/TagGovernanceResolver.d.ts.map +1 -1
- package/dist/resolvers/TagGovernanceResolver.js +84 -0
- package/dist/resolvers/TagGovernanceResolver.js.map +1 -1
- package/dist/resolvers/TelemetryResolver.d.ts +13 -8
- package/dist/resolvers/TelemetryResolver.d.ts.map +1 -1
- package/dist/resolvers/TelemetryResolver.js +40 -9
- package/dist/resolvers/TelemetryResolver.js.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.d.ts.map +1 -1
- package/dist/resolvers/meetingRecordingRegistration.js +2 -0
- package/dist/resolvers/meetingRecordingRegistration.js.map +1 -1
- package/dist/resolvers/meetings/meetingMutations.d.ts.map +1 -1
- package/dist/resolvers/meetings/meetingMutations.js +34 -4
- package/dist/resolvers/meetings/meetingMutations.js.map +1 -1
- package/dist/rest/MediaAccessKeys.d.ts.map +1 -1
- package/dist/rest/MediaAccessKeys.js +6 -2
- package/dist/rest/MediaAccessKeys.js.map +1 -1
- package/dist/rest/OAuthCallbackHandler.d.ts.map +1 -1
- package/dist/rest/OAuthCallbackHandler.js +11 -5
- package/dist/rest/OAuthCallbackHandler.js.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.d.ts +3 -3
- package/dist/rest/RealtimeRecordingHandler.d.ts.map +1 -1
- package/dist/rest/RealtimeRecordingHandler.js +2 -4
- package/dist/rest/RealtimeRecordingHandler.js.map +1 -1
- package/dist/rest/ViewOperationsHandler.d.ts.map +1 -1
- package/dist/rest/ViewOperationsHandler.js +2 -1
- package/dist/rest/ViewOperationsHandler.js.map +1 -1
- package/dist/rest/setupRESTEndpoints.d.ts +3 -1
- package/dist/rest/setupRESTEndpoints.d.ts.map +1 -1
- package/dist/rest/setupRESTEndpoints.js +11 -2
- package/dist/rest/setupRESTEndpoints.js.map +1 -1
- package/dist/services/DurableEntityActionTaskSubmitter.d.ts.map +1 -1
- package/dist/services/DurableEntityActionTaskSubmitter.js +6 -1
- package/dist/services/DurableEntityActionTaskSubmitter.js.map +1 -1
- package/dist/services/TaskGraphActionRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphActionRunner.js +2 -26
- package/dist/services/TaskGraphActionRunner.js.map +1 -1
- package/dist/services/TaskGraphAgentRunner.d.ts +6 -0
- package/dist/services/TaskGraphAgentRunner.d.ts.map +1 -1
- package/dist/services/TaskGraphAgentRunner.js +38 -0
- package/dist/services/TaskGraphAgentRunner.js.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.d.ts.map +1 -1
- package/dist/services/TaskGraphContinuationDeliverer.js +1 -0
- package/dist/services/TaskGraphContinuationDeliverer.js.map +1 -1
- package/dist/services/WorkQueueHostService.d.ts +2 -1
- package/dist/services/WorkQueueHostService.d.ts.map +1 -1
- package/dist/services/WorkQueueHostService.js +19 -4
- package/dist/services/WorkQueueHostService.js.map +1 -1
- package/dist/services/workQueueConfig.d.ts +2 -2
- package/dist/services/workQueueConfig.js +5 -5
- package/dist/services/workQueueConfig.js.map +1 -1
- package/dist/sharedCache.js +1 -1
- package/dist/sharedCache.js.map +1 -1
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +55 -2
- package/dist/util.js.map +1 -1
- package/package.json +107 -100
- package/src/__tests__/APIKeyScopeAuth.test.ts +4 -8
- package/src/__tests__/ActiveOperations.test.ts +68 -0
- package/src/__tests__/AgentSessionResolver.ownership.test.ts +13 -0
- package/src/__tests__/AssertTargetConfigs.test.ts +75 -0
- package/src/__tests__/BatchApplyParity.test.ts +109 -0
- package/src/__tests__/BridgeHostInstance.test.ts +42 -0
- package/src/__tests__/CollectInactiveRowWarnings.test.ts +115 -0
- package/src/__tests__/ConnectionPause.test.ts +192 -0
- package/src/__tests__/ConnectionPauseResolver.test.ts +166 -0
- package/src/__tests__/ConnectionPauseSave.test.ts +143 -0
- package/src/__tests__/CustomColumnPromoterCompletion.test.ts +142 -0
- package/src/__tests__/DeleteConnectionRemovesPerConnectionCatalog.test.ts +51 -0
- package/src/__tests__/DetachedDiscoveryStart.test.ts +65 -0
- package/src/__tests__/DurableEntityActionTaskSubmitter.test.ts +73 -0
- package/src/__tests__/EntityMapLifecycle.rekey.test.ts +252 -0
- package/src/__tests__/ExecuteRemoteOperationResolver.test.ts +213 -0
- package/src/__tests__/HandoffOfferExpiry.test.ts +40 -0
- package/src/__tests__/IntegrationRunArtifactAuthorization.test.ts +126 -0
- package/src/__tests__/MagicLinkKeys.test.ts +102 -0
- package/src/__tests__/MediaAccessKeys.test.ts +57 -10
- package/src/__tests__/NewArrivalsDefaultDisabled.test.ts +50 -0
- package/src/__tests__/ObjectNamesByID.test.ts +176 -0
- package/src/__tests__/PostRestartMapsInCatalogScope.test.ts +146 -0
- package/src/__tests__/QuerySystemUserResolver.childRows.test.ts +80 -0
- package/src/__tests__/QuerySystemUserResolver.collision.test.ts +200 -0
- package/src/__tests__/QuerySystemUserResolver.permissions.test.ts +132 -0
- package/src/__tests__/RSUPostRestartProgress.test.ts +343 -0
- package/src/__tests__/RSUProgressBridge.test.ts +188 -5
- package/src/__tests__/RSUStartupSweepWiring.test.ts +30 -0
- package/src/__tests__/ReactivateRefreshMessage.test.ts +10 -3
- package/src/__tests__/RealtimeClientSessionResolver.test.ts +22 -0
- package/src/__tests__/{RefreshAdoptsNewColumns.test.ts → RefreshReportsNewColumns.test.ts} +25 -16
- package/src/__tests__/RemoteBrowserActionRecovery.test.ts +287 -0
- package/src/__tests__/RemoteBrowserActionResolver.goalRunLink.test.ts +3 -0
- package/src/__tests__/RemoteBrowserActionResolver.ownership.test.ts +6 -4
- package/src/__tests__/RemoteBrowserAudioStream.test.ts +3 -0
- package/src/__tests__/RemoteBrowserSnapshot.test.ts +3 -0
- package/src/__tests__/ResolverBase.clientOldValues.test.ts +327 -26
- package/src/__tests__/ResolverBase.diagnosticSenderRegistrations.test.ts +26 -0
- package/src/__tests__/ResolverBase.encryptedApiZeroReencrypt.test.ts +307 -0
- package/src/__tests__/ResolverBase.entityMessageRelay.test.ts +53 -2
- package/src/__tests__/ResolverBase.includeBinaryFields.test.ts +60 -0
- package/src/__tests__/RunAIAgentResolver.branch.test.ts +4 -0
- package/src/__tests__/RunAIAgentResolver.consultPredecessor.test.ts +289 -0
- package/src/__tests__/RunAIAgentResolver.handoff.test.ts +649 -0
- package/src/__tests__/RunAIAgentResolver.historyFrom.test.ts +2 -0
- package/src/__tests__/RunAIAgentResolver.runDataGuard.test.ts +2 -0
- package/src/__tests__/RunAIAgentResolver.stoppedPredecessor.test.ts +87 -12
- package/src/__tests__/RunAIAgentResolver.streaming.test.ts +28 -4
- package/src/__tests__/SchemaEvolutionCustomColumns.test.ts +119 -0
- package/src/__tests__/SchemaRefreshLaunch.test.ts +24 -2
- package/src/__tests__/ScopedFieldsForBuild.test.ts +192 -0
- package/src/__tests__/SessionJanitor.test.ts +195 -4
- package/src/__tests__/SessionManager.test.ts +69 -0
- package/src/__tests__/TagGovernanceAndAutotagResolvers.test.ts +261 -0
- package/src/__tests__/TagGovernanceResolver.test.ts +60 -2
- package/src/__tests__/TaskGraphActionRunner.durablePayload.test.ts +2 -2
- package/src/__tests__/TaskGraphAgentRunner.test.ts +272 -16
- package/src/__tests__/ViewOperationsHandler.test.ts +2 -5
- package/src/__tests__/WorkQueueHostService.test.ts +25 -7
- package/src/__tests__/backgroundSweepConfigUnits.test.ts +153 -0
- package/src/__tests__/contextRequestOrigin.test.ts +105 -0
- package/src/__tests__/conversationBrowsers.test.ts +62 -0
- package/src/__tests__/globalCors.test.ts +12 -0
- package/src/__tests__/magicLinkExtensionCapabilities.test.ts +413 -0
- package/src/__tests__/orphanedConversationDetailReconciler.start.test.ts +82 -0
- package/src/__tests__/ownedRealtimeSession.test.ts +14 -0
- package/src/__tests__/realtimeRecordingHandler.test.ts +7 -2
- package/src/__tests__/realtimeSessions/sessionAccess.test.ts +79 -1
- package/src/__tests__/requestOrigin.test.ts +104 -0
- package/src/__tests__/review-capture-valid-token-log.test.ts +98 -0
- package/src/__tests__/runStreams.fieldSecurity.test.ts +5 -5
- package/src/__tests__/securityHardeningPr6034.test.ts +120 -0
- package/src/__tests__/sessionDeadline.test.ts +51 -0
- package/src/__tests__/sharedCache.test.ts +11 -0
- package/src/__tests__/unifiedAuth.test.ts +73 -1
- package/src/agentSessions/BridgeHostInstance.ts +20 -5
- package/src/agentSessions/HandoffOfferExpiry.ts +18 -0
- package/src/agentSessions/ReturningVisitorRecap.ts +1 -0
- package/src/agentSessions/SessionJanitor.ts +92 -42
- package/src/agentSessions/SessionManager.ts +38 -8
- package/src/agentSessions/conversationBrowsers.ts +143 -0
- package/src/agentSessions/sessionDeadline.ts +81 -0
- package/src/auth/APIKeyScopeAuth.ts +5 -4
- package/src/auth/__tests__/loginEmailResolution.test.ts +67 -0
- package/src/auth/loginEmailResolution.ts +67 -0
- package/src/auth/magicLink/MagicLinkKeys.ts +146 -14
- package/src/auth/magicLink/MagicLinkRouter.ts +33 -6
- package/src/auth/magicLink/MagicLinkService.ts +250 -10
- package/src/auth/magicLink/index.ts +1 -1
- package/src/auth/magicLink/redeemLanding.ts +7 -4
- package/src/auth/magicLink/types.ts +28 -3
- package/src/auth/newUsers.ts +1 -0
- package/src/backgroundSweepConfigUnits.ts +213 -0
- package/src/broadcast/BaseCacheInvalidationBroadcastProvider.ts +2 -1
- package/src/config.ts +69 -0
- package/src/context.ts +46 -15
- package/src/coreRoutes.ts +14 -7
- package/src/generated/graphql-schemas/__mj.ts +10360 -6479
- package/src/generic/OrphanedConversationDetailReconciler.ts +32 -1
- package/src/generic/ResolverBase.ts +422 -143
- package/src/generic/RunViewResolver.ts +96 -49
- package/src/globalCors.ts +1 -0
- package/src/index.ts +246 -44
- package/src/integration/ConnectionPause.ts +222 -0
- package/src/integration/CustomColumnPromoter.ts +123 -53
- package/src/integration/EntityMapLifecycle.ts +229 -6
- package/src/integration/InactiveRowWarnings.ts +50 -0
- package/src/integration/ObjectNamesByID.ts +97 -0
- package/src/integration/PostRestartIntrospect.ts +49 -0
- package/src/integration/RSUPostRestartProgress.ts +359 -0
- package/src/integration/RSUProgressBridge.ts +85 -2
- package/src/integration/RunArtifactAuthorization.ts +65 -0
- package/src/integration/SchemaRefreshLaunch.ts +12 -2
- package/src/integration/ScopedFieldsForBuild.ts +113 -0
- package/src/integration/TargetConfigGuard.ts +71 -0
- package/src/logging/StartupLogger.ts +24 -0
- package/src/middleware/BaseServerMiddleware.ts +20 -3
- package/src/realtimeSessions/ownedRealtimeSession.ts +2 -6
- package/src/realtimeSessions/sessionAccess.ts +30 -0
- package/src/realtimeWidget/WidgetSessionService.ts +2 -0
- package/src/realtimeWidget/visitorIdentity.ts +1 -0
- package/src/realtimeWidget/widgetCore.ts +4 -8
- package/src/realtimeWidget/widgetGuestElevation.ts +1 -0
- package/src/requestOrigin.ts +64 -0
- package/src/resolvers/AgentRunStatusPublisher.ts +27 -2
- package/src/resolvers/AgentSessionResolver.ts +6 -2
- package/src/resolvers/AutotagPipelineResolver.ts +59 -14
- package/src/resolvers/ConversationRunEventsResolver.ts +2 -0
- package/src/resolvers/ExecuteRemoteOperationResolver.ts +41 -9
- package/src/resolvers/GetDataResolver.ts +35 -13
- package/src/resolvers/InfoResolver.ts +1 -1
- package/src/resolvers/IntegrationDiscoveryResolver.ts +1522 -203
- package/src/resolvers/MCPResolver.ts +15 -2
- package/src/resolvers/QuerySystemUserResolver.ts +211 -100
- package/src/resolvers/RealtimeBridgeResolver.ts +1 -0
- package/src/resolvers/RealtimeClientSessionResolver.ts +40 -7
- package/src/resolvers/RemoteBrowserActionResolver.ts +242 -32
- package/src/resolvers/RunAIAgentResolver.ts +265 -86
- package/src/resolvers/RunAIPromptResolver.ts +18 -18
- package/src/resolvers/RunTemplateResolver.ts +3 -1
- package/src/resolvers/SqlLoggingConfigResolver.ts +7 -9
- package/src/resolvers/TagGovernanceResolver.ts +65 -0
- package/src/resolvers/TelemetryResolver.ts +44 -9
- package/src/resolvers/__tests__/GetDataResolver.tokens.test.ts +52 -0
- package/src/resolvers/meetingRecordingRegistration.ts +2 -0
- package/src/resolvers/meetings/meetingMutations.ts +37 -7
- package/src/rest/MediaAccessKeys.ts +6 -2
- package/src/rest/OAuthCallbackHandler.ts +13 -5
- package/src/rest/RealtimeRecordingHandler.ts +5 -9
- package/src/rest/ViewOperationsHandler.ts +2 -1
- package/src/rest/setupRESTEndpoints.ts +11 -2
- package/src/services/DurableEntityActionTaskSubmitter.ts +10 -2
- package/src/services/TaskGraphActionRunner.ts +2 -23
- package/src/services/TaskGraphAgentRunner.ts +43 -0
- package/src/services/TaskGraphContinuationDeliverer.ts +1 -0
- package/src/services/WorkQueueHostService.ts +26 -4
- package/src/services/workQueueConfig.ts +5 -5
- package/src/sharedCache.ts +1 -1
- package/src/types.ts +18 -0
- package/src/util.ts +55 -3
- package/src/services/TaskOrchestration-Integration.md +0 -188
package/src/index.ts
CHANGED
|
@@ -4,13 +4,16 @@ dotenv.config({ quiet: true });
|
|
|
4
4
|
|
|
5
5
|
import { expressMiddleware } from '@as-integrations/express5';
|
|
6
6
|
import { mergeSchemas } from '@graphql-tools/schema';
|
|
7
|
-
import { Metadata, DatabasePlatform, SetProvider, StartupManager as StartupManagerImport, BaseEntity, BaseEntityEvent, RunView, DatabaseProviderBase, ProviderBase, ResolveStartupMode, UserInfo } from '@memberjunction/core';
|
|
8
|
-
import { UserCache, resolveDbPlatformFromEnv } from '@memberjunction/generic-database-provider';
|
|
7
|
+
import { Metadata, DatabasePlatform, SetProvider, StartupManager as StartupManagerImport, BaseEntity, BaseEntityEvent, RunView, DatabaseProviderBase, ProviderBase, ResolveStartupMode, UserInfo, GetDiagnosticContext, IsDiagnosticCaptureSuppressed } from '@memberjunction/core';
|
|
8
|
+
import { UserCache, resolveDbPlatformFromEnv, GenericDatabaseProvider, SummarizeSqlParameters } from '@memberjunction/generic-database-provider';
|
|
9
9
|
import { MJGlobal, MJEventType, UUIDsEqual, ShutdownRegistry } from '@memberjunction/global';
|
|
10
10
|
import { setupSQLServerClient, SQLServerDataProvider, SQLServerProviderConfigData } from '@memberjunction/sqlserver-dataprovider';
|
|
11
11
|
import { extendConnectionPoolWithQuery } from './util.js';
|
|
12
12
|
import { registerIntegrationCustomColumnPromoter, IntegrationCustomColumnPromoter } from './integration/CustomColumnPromoter.js';
|
|
13
13
|
import { DisableUnselectedEntityMaps, ReenableFieldMapsForEntityMap, selectFieldsToMap } from './integration/EntityMapLifecycle.js';
|
|
14
|
+
import { RSUPostRestartProgressSession } from './integration/RSUPostRestartProgress.js';
|
|
15
|
+
import type { RSUPostRestartProgress } from './integration/RSUPostRestartProgress.js';
|
|
16
|
+
import { IntrospectInCatalogScope } from './integration/PostRestartIntrospect.js';
|
|
14
17
|
import { default as BodyParser } from 'body-parser';
|
|
15
18
|
import compression from 'compression'; // Add compression middleware
|
|
16
19
|
import cors from 'cors';
|
|
@@ -31,7 +34,8 @@ import sql from 'mssql';
|
|
|
31
34
|
import { WebSocketServer } from 'ws';
|
|
32
35
|
import { RealtimeProxyServer } from './realtimeProxy/RealtimeProxyServer.js';
|
|
33
36
|
import buildApolloServer from './apolloServer/index.js';
|
|
34
|
-
import { configInfo, configFilePath, dbDatabase, dbHost, dbPort, dbUsername, graphqlPort, graphqlRootPath, mj_core_schema, websiteRunFromPackage, RESTApiOptions } from './config.js';
|
|
37
|
+
import { configInfo, configFilePath, dbDatabase, dbHost, dbPort, dbUsername, graphqlPort, graphqlRootPath, mj_core_schema, websiteRunFromPackage, RESTApiOptions, userEmailMap } from './config.js';
|
|
38
|
+
import { DescribeUserEmailMap } from './auth/loginEmailResolution.js';
|
|
35
39
|
import { TranslateBracketsToPG } from './postgresqlCompat.js';
|
|
36
40
|
import { BuildPostgreSQLConnectionConfig, DescribeReadOnlyLoginOverreach, PostgreSQLReadOnlyPool, ResolvePostgreSQLEndpoint, ResolvePostgreSQLReadOnlyCredentials, ToPGPoolConfig } from './postgresqlPoolSettings.js';
|
|
37
41
|
import { default as jwt } from 'jsonwebtoken';
|
|
@@ -46,7 +50,7 @@ import createMSSQLConfig from './orm.js';
|
|
|
46
50
|
import { setupRESTEndpoints } from './rest/setupRESTEndpoints.js';
|
|
47
51
|
import { CreateRealtimeRecordingRouter, REALTIME_RECORDING_MOUNT_PATH } from './rest/RealtimeRecordingHandler.js';
|
|
48
52
|
import { LoadOwnedRealtimeSession } from './realtimeSessions/ownedRealtimeSession.js';
|
|
49
|
-
import { AuthorizeAnonymousRoomSessions,
|
|
53
|
+
import { AuthorizeAnonymousRoomSessions, AuthorizeLoadedSession } from './realtimeSessions/sessionAccess.js';
|
|
50
54
|
import { RecordingAssemblyScheduler } from './realtimeSessions/RecordingAssemblyScheduler.js';
|
|
51
55
|
import {
|
|
52
56
|
RealtimeSessionEventService,
|
|
@@ -66,7 +70,7 @@ import { ActionEngineServer } from '@memberjunction/actions';
|
|
|
66
70
|
import { CreateAdhocSQLAuthorizer } from './resolvers/AdhocQueryResolver.js';
|
|
67
71
|
import { CacheManagerConfigFromSettings, CreateSharedCacheFromEnvironment, StartEngineSweeper, StartMetadataSweep, StartUserCacheChecks, WarmupLeaseMsFromSettings, WirePushStatusFanOut, WireSharedCacheEvents } from './sharedCache.js';
|
|
68
72
|
import { PubSubManager } from './generic/PubSubManager.js';
|
|
69
|
-
import {
|
|
73
|
+
import { StartOrphanedConversationDetailReconciler } from './generic/OrphanedConversationDetailReconciler.js';
|
|
70
74
|
import {
|
|
71
75
|
HANDOFF_OFFER_FANOUT_CHANNEL,
|
|
72
76
|
HANDOFF_OFFER_TOPIC,
|
|
@@ -82,6 +86,7 @@ import { PublishIntegrationProgress } from './resolvers/IntegrationProgressResol
|
|
|
82
86
|
import { RegisterRSUProgressBridge } from './integration/RSUProgressBridge.js';
|
|
83
87
|
import { ClientToolRequestManager, AgentRunWatchdog, SqlRealtimeRecordingLedger } from '@memberjunction/ai-agents';
|
|
84
88
|
import { BindBridgeEngineHostInstance, SessionJanitor, SetHostInstancePort, StartBridgeOrphanReconciliation } from './agentSessions/index.js';
|
|
89
|
+
import { ApplyHandoffOfferExpirySettings } from './agentSessions/HandoffOfferExpiry.js';
|
|
85
90
|
import { StartTaskGraphDispatcher } from './services/StartTaskGraphDispatcher.js';
|
|
86
91
|
import { MJServerWorkQueueProviderSource, StartWorkQueueHost } from './services/WorkQueueHostService.js';
|
|
87
92
|
import { GetAttachmentService } from '@memberjunction/aiengine';
|
|
@@ -96,7 +101,20 @@ import {
|
|
|
96
101
|
MJCompanyIntegrationFieldMapEntity,
|
|
97
102
|
MJScheduledJobEntity,
|
|
98
103
|
} from '@memberjunction/core-entities';
|
|
99
|
-
import {
|
|
104
|
+
import {
|
|
105
|
+
ServerExtensionLoader,
|
|
106
|
+
ServerExtensionConfig,
|
|
107
|
+
SERVER_EXTENSION_CORE_SERVICE_KEYS,
|
|
108
|
+
type IServerExtensionHostRuntimeService,
|
|
109
|
+
mergeServerExtensionConfigs,
|
|
110
|
+
prepareServerExtensionConfigs,
|
|
111
|
+
describeServerExtensionMount,
|
|
112
|
+
InstallMediaUpgradeDispatcher,
|
|
113
|
+
IsGraphQLWsPath,
|
|
114
|
+
GetCorsOwningServerExtensionRoots,
|
|
115
|
+
} from '@memberjunction/server-extensions-core';
|
|
116
|
+
import { CreateIsolatedProvider } from './isolatedProvider.js';
|
|
117
|
+
import { ResolveConfiguredPrincipal } from './auth/principals.js';
|
|
100
118
|
import { CreateExtensionOwnedPreflightFallback, CreateGlobalCorsMiddleware } from './globalCors.js';
|
|
101
119
|
import { CoreReservedServerExtensionRoots } from './serverExtensionReservedRoots.js';
|
|
102
120
|
import { ApiRoute, ApiRootPath, ConfiguredPublicUrl } from './apiRoot.js';
|
|
@@ -158,6 +176,7 @@ export * from './directives/index.js';
|
|
|
158
176
|
export { NoLog, hasNoLogParameter, getNoLogFields } from './logging/NoLog.js';
|
|
159
177
|
export * from './entitySubclasses/MJEntityPermissionEntityServer.server.js';
|
|
160
178
|
export * from './types.js';
|
|
179
|
+
export * from './requestOrigin.js';
|
|
161
180
|
export {
|
|
162
181
|
getSystemUser,
|
|
163
182
|
getSigningKeys,
|
|
@@ -280,10 +299,11 @@ export * from './multiTenancy/index.js';
|
|
|
280
299
|
export * from './middleware/index.js';
|
|
281
300
|
|
|
282
301
|
import { RegisterDataHook } from '@memberjunction/core';
|
|
302
|
+
import { EnsureAnchoredConversationReadHookRegistered } from '@memberjunction/core-entities-server';
|
|
283
303
|
import type { RequestHandler, ErrorRequestHandler } from 'express';
|
|
284
304
|
import type { ApolloServerPlugin } from '@apollo/server';
|
|
285
305
|
import type { GraphQLSchema } from 'graphql';
|
|
286
|
-
import { BaseServerMiddleware } from './middleware/BaseServerMiddleware.js';
|
|
306
|
+
import { BaseServerMiddleware, ServerMiddlewareContext } from './middleware/BaseServerMiddleware.js';
|
|
287
307
|
import { SuppressTaskGraphSubmission } from '@memberjunction/ai-core-plus';
|
|
288
308
|
|
|
289
309
|
export type MJServerOptions = {
|
|
@@ -338,8 +358,6 @@ function resolveServerVersion(): string | undefined {
|
|
|
338
358
|
}
|
|
339
359
|
}
|
|
340
360
|
|
|
341
|
-
/** How often to re-check for conversation details left behind by finished runs. */
|
|
342
|
-
const ORPHAN_DETAIL_SWEEP_INTERVAL_MS = 5 * 60_000;
|
|
343
361
|
|
|
344
362
|
/**
|
|
345
363
|
* Replicate handoff-offer updates across server instances over Redis.
|
|
@@ -482,7 +500,8 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
482
500
|
await WirePushStatusFanOut(sharedCache);
|
|
483
501
|
await wireHandoffOfferFanOut(sharedCache, startupLog);
|
|
484
502
|
await wireRealtimeSessionEventFanOut(sharedCache);
|
|
485
|
-
|
|
503
|
+
const safeRedisUrl = (process.env.REDIS_URL ?? '').replace(/:\/\/[^@]+@/, '://***@');
|
|
504
|
+
startupLog.LogIf('verbose', `Redis cache provider connected: ${safeRedisUrl}`);
|
|
486
505
|
}
|
|
487
506
|
const cacheManagerConfig = CacheManagerConfigFromSettings(configInfo.cacheSettings);
|
|
488
507
|
const warmupLeaseMs = WarmupLeaseMsFromSettings(configInfo.cacheSettings);
|
|
@@ -579,8 +598,38 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
579
598
|
const thePgPool = poolAny._pgPool as import('pg').Pool;
|
|
580
599
|
// Translate SQL Server bracket syntax to PostgreSQL double-quote syntax
|
|
581
600
|
const pgQuery = TranslateBracketsToPG(query);
|
|
582
|
-
const
|
|
583
|
-
|
|
601
|
+
const startTime = performance.now();
|
|
602
|
+
try {
|
|
603
|
+
const result = await thePgPool.query(pgQuery);
|
|
604
|
+
if (!IsDiagnosticCaptureSuppressed() && GenericDatabaseProvider.HasSqlObservers()) {
|
|
605
|
+
GenericDatabaseProvider.NotifySqlObservers({
|
|
606
|
+
ts: Date.now(),
|
|
607
|
+
sql: pgQuery,
|
|
608
|
+
parameterSummaries: SummarizeSqlParameters(parameters),
|
|
609
|
+
durationMs: performance.now() - startTime,
|
|
610
|
+
rowCount: result.rows?.length ?? 0,
|
|
611
|
+
isMutation: false,
|
|
612
|
+
description: 'ExecuteSQLWithPool(PG)',
|
|
613
|
+
diagnosticContext: GetDiagnosticContext(),
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
return result.rows;
|
|
617
|
+
} catch (err) {
|
|
618
|
+
if (!IsDiagnosticCaptureSuppressed() && GenericDatabaseProvider.HasSqlObservers()) {
|
|
619
|
+
GenericDatabaseProvider.NotifySqlObservers({
|
|
620
|
+
ts: Date.now(),
|
|
621
|
+
sql: pgQuery,
|
|
622
|
+
parameterSummaries: SummarizeSqlParameters(parameters),
|
|
623
|
+
durationMs: performance.now() - startTime,
|
|
624
|
+
rowCount: 0,
|
|
625
|
+
isMutation: false,
|
|
626
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
627
|
+
description: 'ExecuteSQLWithPool(PG)',
|
|
628
|
+
diagnosticContext: GetDiagnosticContext(),
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
throw err;
|
|
632
|
+
}
|
|
584
633
|
}
|
|
585
634
|
return origExecuteSQLWithPool.call(this, pool, query, parameters, contextUser);
|
|
586
635
|
};
|
|
@@ -611,10 +660,19 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
611
660
|
codegenTestClient.release();
|
|
612
661
|
|
|
613
662
|
const { RuntimeSchemaManager } = await import('@memberjunction/schema-engine');
|
|
663
|
+
// Adopt the already-loaded global Metadata.Provider catalog (ignoreExistingMetadata = false)
|
|
664
|
+
// so boot does not pay a second full metadata load. The refresh interval stays non-zero on
|
|
665
|
+
// PostgreSQL on purpose: PostgreSQLDataProvider.AllowRefresh is `CheckRefreshIntervalSeconds > 0`,
|
|
666
|
+
// so an interval of 0 would make every later codegenPgProvider.Refresh() — the one RSU CodeGen
|
|
667
|
+
// issues after DDL — return without reloading, leaving this provider frozen at the boot catalog.
|
|
668
|
+
// (SQL Server's AllowRefresh is independent of the interval, so its codegen provider can use 0.)
|
|
614
669
|
const codegenPgConfigData = new PostgreSQLProviderConfigData(
|
|
615
670
|
codegenPgConnectionConfig,
|
|
616
671
|
mj_core_schema,
|
|
617
672
|
cacheRefreshInterval / 1000, // ms → seconds
|
|
673
|
+
undefined,
|
|
674
|
+
undefined,
|
|
675
|
+
false,
|
|
618
676
|
);
|
|
619
677
|
const codegenPgProvider = new PostgreSQLDataProvider();
|
|
620
678
|
await codegenPgProvider.Config(codegenPgConfigData); // separate pool (per-instance manager); does NOT touch the global API provider
|
|
@@ -762,8 +820,18 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
762
820
|
await codegenPool.connect();
|
|
763
821
|
|
|
764
822
|
const { RuntimeSchemaManager } = await import('@memberjunction/schema-engine');
|
|
765
|
-
//
|
|
766
|
-
|
|
823
|
+
// Adopt the already-loaded global Metadata.Provider catalog (ignoreExistingMetadata = false)
|
|
824
|
+
// and disable a duplicate background refresh timer (0): avoids a second full metadata load
|
|
825
|
+
// on boot while explicit codegenProvider.Refresh() after DDL still reloads from the DB
|
|
826
|
+
// (SQLServerDataProvider.AllowRefresh does not depend on the interval; PostgreSQL's does — see above).
|
|
827
|
+
const codegenConfig = new SQLServerProviderConfigData(
|
|
828
|
+
codegenPool,
|
|
829
|
+
mj_core_schema,
|
|
830
|
+
0,
|
|
831
|
+
undefined,
|
|
832
|
+
undefined,
|
|
833
|
+
false,
|
|
834
|
+
);
|
|
767
835
|
const codegenProvider = new SQLServerDataProvider();
|
|
768
836
|
await codegenProvider.Config(codegenConfig);
|
|
769
837
|
RuntimeSchemaManager.Instance.SetDDLProvider(codegenProvider);
|
|
@@ -946,8 +1014,9 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
946
1014
|
}
|
|
947
1015
|
|
|
948
1016
|
// Initialize all middleware
|
|
1017
|
+
const middlewareContext: ServerMiddlewareContext = { ApiRoute: (subpath, options) => ApiRoute(subpath, options) };
|
|
949
1018
|
for (const mw of middlewares) {
|
|
950
|
-
await mw.Initialize();
|
|
1019
|
+
await mw.Initialize(middlewareContext);
|
|
951
1020
|
startupLog.LogIf('verbose', ` [Middleware] ${mw.Label}`);
|
|
952
1021
|
}
|
|
953
1022
|
|
|
@@ -969,7 +1038,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
969
1038
|
|
|
970
1039
|
// Express app configuration escape hatch
|
|
971
1040
|
if (mw.ConfigureExpressApp) {
|
|
972
|
-
await mw.ConfigureExpressApp(app);
|
|
1041
|
+
await mw.ConfigureExpressApp(app, middlewareContext);
|
|
973
1042
|
}
|
|
974
1043
|
|
|
975
1044
|
// Extract hook methods and register in the global hook store
|
|
@@ -978,6 +1047,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
978
1047
|
RegisterDataHook('PostRunView', mw.PostRunView.bind(mw));
|
|
979
1048
|
RegisterDataHook('PreSave', mw.PreSave.bind(mw));
|
|
980
1049
|
}
|
|
1050
|
+
EnsureAnchoredConversationReadHookRegistered();
|
|
981
1051
|
|
|
982
1052
|
// ─── Resolve middleware-contributed resolver paths and merge into resolvers ───
|
|
983
1053
|
let allResolvers = resolvers;
|
|
@@ -1270,6 +1340,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1270
1340
|
},
|
|
1271
1341
|
// context() now just reads the already-validated payload — no I/O, no logging
|
|
1272
1342
|
context: async (ctx) => {
|
|
1343
|
+
// No RequestOrigin here: the upgrade request's Origin is not carried onto subscription contexts.
|
|
1273
1344
|
return { userPayload: ctx.extra.userPayload as UserPayload };
|
|
1274
1345
|
},
|
|
1275
1346
|
onClose: (ctx) => {
|
|
@@ -1319,7 +1390,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1319
1390
|
},
|
|
1320
1391
|
// High compression level (good balance between CPU and compression ratio)
|
|
1321
1392
|
level: 6
|
|
1322
|
-
}));
|
|
1393
|
+
}) as object as express.RequestHandler);
|
|
1323
1394
|
|
|
1324
1395
|
// Health check — before every middleware contribution and the auth middleware, so cloud platform
|
|
1325
1396
|
// probes never generate auth noise. Every core route mounts under MJAPI_BASE_PATH (see apiRoot.ts).
|
|
@@ -1343,6 +1414,19 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1343
1414
|
const extensionLoader = new ServerExtensionLoader();
|
|
1344
1415
|
_currentExtensionLoader = extensionLoader;
|
|
1345
1416
|
|
|
1417
|
+
const hostRuntimeService: IServerExtensionHostRuntimeService = {
|
|
1418
|
+
CreateIsolatedProvider,
|
|
1419
|
+
GetSystemUser: () => getSystemUser(),
|
|
1420
|
+
ResolvePrincipal: (configuredEmailOrId, subsystemLabel) => ResolveConfiguredPrincipal(configuredEmailOrId, subsystemLabel),
|
|
1421
|
+
};
|
|
1422
|
+
extensionLoader.Services.RegisterService(SERVER_EXTENSION_CORE_SERVICE_KEYS.HostRuntime, hostRuntimeService);
|
|
1423
|
+
if (coreAuthenticatedRouters.MagicLinkService) {
|
|
1424
|
+
extensionLoader.Services.RegisterService(
|
|
1425
|
+
SERVER_EXTENSION_CORE_SERVICE_KEYS.MagicLink,
|
|
1426
|
+
coreAuthenticatedRouters.MagicLinkService,
|
|
1427
|
+
);
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1346
1430
|
// Open App packages publish their extensions; host mj.config.cjs overlays by DriverClass
|
|
1347
1431
|
// Backwards-compatibility shim: synthesize ServerExtensionConfig entries from legacy configInfo.telephony
|
|
1348
1432
|
const telephonyExtensionConfigs: ServerExtensionConfig[] = [];
|
|
@@ -1457,6 +1541,11 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1457
1541
|
MountAuthCatalogRoute(app, startupLog);
|
|
1458
1542
|
|
|
1459
1543
|
// ─── Unified auth middleware (replaces both REST authMiddleware and contextFunction auth) ─────
|
|
1544
|
+
// Always shown, whatever the log level: a configured map makes logins run as other people's records
|
|
1545
|
+
const userEmailMapWarning = DescribeUserEmailMap(userEmailMap);
|
|
1546
|
+
if (userEmailMapWarning) {
|
|
1547
|
+
console.warn(userEmailMapWarning);
|
|
1548
|
+
}
|
|
1460
1549
|
app.use(CreateUnifiedAuthMiddleware(dataSources));
|
|
1461
1550
|
|
|
1462
1551
|
// ─── Post-auth middleware from BaseServerMiddleware plugins ─────
|
|
@@ -1551,7 +1640,7 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1551
1640
|
app.use(
|
|
1552
1641
|
graphqlRootPath,
|
|
1553
1642
|
cors<cors.CorsRequest>({
|
|
1554
|
-
exposedHeaders: ['X-MJ-Cache-Seq', 'X-MJ-Server-ID'],
|
|
1643
|
+
exposedHeaders: ['X-MJ-Cache-Seq', 'X-MJ-Server-ID', 'X-MJ-Trace-ID', 'X-MJ-Diagnostic-Trigger'],
|
|
1555
1644
|
}),
|
|
1556
1645
|
BodyParser.json({ limit: '50mb' }),
|
|
1557
1646
|
// Express 5 leaves req.body as undefined for non-JSON or empty bodies;
|
|
@@ -1593,6 +1682,11 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1593
1682
|
LogStatus(`[ServerRole] Running in '${serverRole}' mode — background worker services are disabled on this replica.`);
|
|
1594
1683
|
}
|
|
1595
1684
|
|
|
1685
|
+
// Every role runs agents, so every role's watchdog takes the configured intervals (before any run starts).
|
|
1686
|
+
AgentRunWatchdog.Instance.Configure(configInfo.agentRunWatchdog);
|
|
1687
|
+
// The handoff offer registry starts its own expiry sweep when it loads, on every role; apply the host's setting.
|
|
1688
|
+
ApplyHandoffOfferExpirySettings(configInfo.agentSessions.handoffOfferExpiry);
|
|
1689
|
+
|
|
1596
1690
|
// Close out run artifacts a dead process left open, BEFORE anything below can start a new run.
|
|
1597
1691
|
//
|
|
1598
1692
|
// A killed process (OOM killer, SIGKILL, host reboot) never writes its run's terminal result, so
|
|
@@ -1602,7 +1696,17 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1602
1696
|
// to a process that no longer exists. That is why it runs here, ahead of the scheduler, the
|
|
1603
1697
|
// integration sync worker (its Start() polls immediately), the HTTP listener (a request can
|
|
1604
1698
|
// start a discovery) and pending RSU work, and why it is awaited. It needs none of them.
|
|
1605
|
-
|
|
1699
|
+
//
|
|
1700
|
+
// One exception: an RSU run killed inside its own RestartMJAPI step is not dead — THIS process is
|
|
1701
|
+
// its continuation, and processRSUPendingWork below re-attaches to it. Those are left in flight
|
|
1702
|
+
// (and named in `Skipped`); whichever of them nothing re-attaches to is closed out afterwards by
|
|
1703
|
+
// RSUPostRestartProgressSession.SweepUnattached. On a replica that runs no background workers
|
|
1704
|
+
// nothing would ever resume them, so there they are swept like any other.
|
|
1705
|
+
const bootSweep = await SweepInterruptedRuns(
|
|
1706
|
+
undefined,
|
|
1707
|
+
msg => console.warn(msg),
|
|
1708
|
+
runBackgroundWorkers ? RSUPostRestartProgressSession.WasKilledAtRestart : undefined
|
|
1709
|
+
);
|
|
1606
1710
|
|
|
1607
1711
|
// Initialize and start scheduled jobs service if enabled
|
|
1608
1712
|
let scheduledJobsService: ScheduledJobsService | null = null;
|
|
@@ -1662,7 +1766,12 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1662
1766
|
|
|
1663
1767
|
if (runBackgroundWorkers) {
|
|
1664
1768
|
// Process pending RSU work from pre-restart (entity maps, field maps, sync)
|
|
1665
|
-
processRSUPendingWork().catch(err => console.warn(`RSU pending work processing failed: ${err}`))
|
|
1769
|
+
processRSUPendingWork().catch(err => console.warn(`RSU pending work processing failed: ${err}`))
|
|
1770
|
+
.finally(() =>
|
|
1771
|
+
RSUPostRestartProgressSession.SweepUnattached(bootSweep.Skipped, undefined, msg => console.warn(msg)).catch(err =>
|
|
1772
|
+
console.warn(`RSU leftover run sweep failed: ${err}`)
|
|
1773
|
+
)
|
|
1774
|
+
);
|
|
1666
1775
|
|
|
1667
1776
|
// Resume any integration syncs that were orphaned by the previous process restart
|
|
1668
1777
|
if (resumeUser) {
|
|
@@ -1677,23 +1786,15 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1677
1786
|
if (resumeUser && Metadata.Provider instanceof DatabaseProviderBase) { // global-provider-ok: server startup recovery — one-shot orphaned-run sweep at boot
|
|
1678
1787
|
const sweepUser = resumeUser;
|
|
1679
1788
|
const sweepProvider = Metadata.Provider; // global-provider-ok: server startup recovery — one-shot orphaned-run sweep at boot
|
|
1680
|
-
AgentRunWatchdog.SweepOrphanedRuns(sweepProvider, sweepUser)
|
|
1789
|
+
AgentRunWatchdog.SweepOrphanedRuns(sweepProvider, sweepUser, configInfo.agentRunWatchdog)
|
|
1681
1790
|
.catch(err => console.warn(`[AgentRunWatchdog] Startup sweep failed: ${err}`));
|
|
1682
1791
|
|
|
1683
1792
|
// The watchdog repairs the RUN; nothing repaired the conversation detail, which is the row the
|
|
1684
1793
|
// chat actually renders from (MJ #4222). A process that dies mid-run leaves a terminal run
|
|
1685
1794
|
// beside a message that still claims to be generating, and it spins forever for anyone who
|
|
1686
|
-
// opens it. Runs at boot (closes restart orphans) and
|
|
1687
|
-
// mirroring the watchdog's own two-phase shape.
|
|
1688
|
-
|
|
1689
|
-
ReconcileOrphanedConversationDetails(sweepProvider, sweepUser)
|
|
1690
|
-
.catch(err => console.warn(`[OrphanDetailReconciler] Pass failed: ${err}`));
|
|
1691
|
-
void reconcileOrphans();
|
|
1692
|
-
const orphanDetailTimer = setInterval(() => void reconcileOrphans(), ORPHAN_DETAIL_SWEEP_INTERVAL_MS);
|
|
1693
|
-
ShutdownRegistry.Instance.Register({
|
|
1694
|
-
ShutdownName: 'OrphanDetailReconciler',
|
|
1695
|
-
Shutdown: () => { clearInterval(orphanDetailTimer); },
|
|
1696
|
-
});
|
|
1795
|
+
// opens it. Runs at boot (closes restart orphans) and, unless `conversationDetailReconciler.enabled`
|
|
1796
|
+
// is false, on a timer (closes mid-life orphans), mirroring the watchdog's own two-phase shape.
|
|
1797
|
+
StartOrphanedConversationDetailReconciler(sweepProvider, sweepUser, configInfo.conversationDetailReconciler);
|
|
1697
1798
|
}
|
|
1698
1799
|
|
|
1699
1800
|
// Launch the AI Agent Session janitor: run own-host orphan recovery once at boot, then a periodic tick
|
|
@@ -1701,11 +1802,12 @@ const setupComplete$ = new ReplaySubject(1);
|
|
|
1701
1802
|
// crash-recovery shards (storage reads and writes). Self-registers with ShutdownRegistry, so its timer
|
|
1702
1803
|
// is cleared by the gracefulShutdown drain below (no explicit Stop() wiring needed here).
|
|
1703
1804
|
if (resumeUser && Metadata.Provider instanceof DatabaseProviderBase) { // global-provider-ok: server startup recovery — boot-time session janitor uses the server's own provider
|
|
1704
|
-
|
|
1805
|
+
// `agentSessions.janitor.enabled: false` keeps the boot recovery and shutdown drain but schedules no tick.
|
|
1806
|
+
SessionJanitor.Instance.StartWithSettings(configInfo.agentSessions.janitor, Metadata.Provider, resumeUser) // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
|
|
1705
1807
|
.catch(err => console.warn(`[SessionJanitor] Startup failed: ${err}`));
|
|
1706
1808
|
// The bridge engine's orphan reconcile likewise starts only now that this process holds its port, so it can't
|
|
1707
1809
|
// take the live bridges of another MJAPI still serving that port for its own orphans (#5310).
|
|
1708
|
-
StartBridgeOrphanReconciliation(Metadata.Provider, resumeUser); // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
|
|
1810
|
+
StartBridgeOrphanReconciliation(Metadata.Provider, resumeUser, configInfo.agentSessions.bridgeReconciler); // global-provider-ok: server-owned background reconciler runs under the server's provider + system user
|
|
1709
1811
|
}
|
|
1710
1812
|
}
|
|
1711
1813
|
|
|
@@ -1908,9 +2010,18 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
1908
2010
|
// Wait a moment for metadata to be fully loaded
|
|
1909
2011
|
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
1910
2012
|
|
|
2013
|
+
// The RSU run these items belong to is still open: the pre-restart process was killed inside its
|
|
2014
|
+
// own RestartMJAPI step, so it never wrote a terminal result. This session re-attaches to that run
|
|
2015
|
+
// and reports the two steps that only ever happen here — CreateEntityMaps and StartSync — into the
|
|
2016
|
+
// SAME event stream, so a client that has been tailing since before the restart keeps its cursor
|
|
2017
|
+
// and finally learns whether the connector went live. Purely observational: every failure below is
|
|
2018
|
+
// swallowed, and the work proceeds whether or not a run was found to report into.
|
|
2019
|
+
const progressSession = new RSUPostRestartProgressSession();
|
|
2020
|
+
|
|
1911
2021
|
for (const pending of pendingItems) {
|
|
1912
2022
|
const pendingWorkID = pending.ID;
|
|
1913
2023
|
const item = pending.Work;
|
|
2024
|
+
let progress: RSUPostRestartProgress | null = null;
|
|
1914
2025
|
// Declared outside the try so the catch can narrow a retry to what is still outstanding: what
|
|
1915
2026
|
// actually got mapped this attempt. Each retry is then strictly smaller, and one poison object
|
|
1916
2027
|
// cannot keep re-running its healthy siblings.
|
|
@@ -1932,6 +2043,10 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
1932
2043
|
continue;
|
|
1933
2044
|
}
|
|
1934
2045
|
|
|
2046
|
+
// Attached only for apply-objects work: promote-columns is a follow-up to a DIFFERENT run
|
|
2047
|
+
// shape that has no CreateEntityMaps/StartSync steps to report.
|
|
2048
|
+
progress = await progressSession.For(item.CompanyIntegrationID);
|
|
2049
|
+
|
|
1935
2050
|
// Resolve connector
|
|
1936
2051
|
const rv = new RunView();
|
|
1937
2052
|
const ciResult = await rv.RunView<MJCompanyIntegrationEntity>({
|
|
@@ -1941,8 +2056,10 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
1941
2056
|
}, systemUser);
|
|
1942
2057
|
const companyIntegration = ciResult.Results[0];
|
|
1943
2058
|
if (!companyIntegration) {
|
|
1944
|
-
|
|
1945
|
-
|
|
2059
|
+
const missingCI = `CompanyIntegration ${item.CompanyIntegrationID} not found`;
|
|
2060
|
+
progress?.FailEntityMaps(missingCI, item.SourceObjectNames ?? []);
|
|
2061
|
+
await rsm.FailPendingWork(pendingWorkID, missingCI, systemUser);
|
|
2062
|
+
console.warn(`[RSU] ${missingCI}`);
|
|
1946
2063
|
continue;
|
|
1947
2064
|
}
|
|
1948
2065
|
|
|
@@ -1954,14 +2071,18 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
1954
2071
|
}, systemUser);
|
|
1955
2072
|
const integrationEntity = integrationResult.Results[0];
|
|
1956
2073
|
if (!integrationEntity) {
|
|
1957
|
-
|
|
1958
|
-
|
|
2074
|
+
const missingIntegration = `Integration entity for ${integrationName} not found`;
|
|
2075
|
+
progress?.FailEntityMaps(missingIntegration, item.SourceObjectNames ?? []);
|
|
2076
|
+
await rsm.FailPendingWork(pendingWorkID, missingIntegration, systemUser);
|
|
2077
|
+
console.warn(`[RSU] ${missingIntegration}`);
|
|
1959
2078
|
continue;
|
|
1960
2079
|
}
|
|
1961
2080
|
const connector = ConnectorFactory.Resolve(integrationEntity);
|
|
1962
2081
|
if (!connector) {
|
|
1963
|
-
|
|
1964
|
-
|
|
2082
|
+
const missingConnector = `Connector for ${integrationName} not found`;
|
|
2083
|
+
progress?.FailEntityMaps(missingConnector, item.SourceObjectNames ?? []);
|
|
2084
|
+
await rsm.FailPendingWork(pendingWorkID, missingConnector, systemUser);
|
|
2085
|
+
console.warn(`[RSU] ${missingConnector}`);
|
|
1965
2086
|
continue;
|
|
1966
2087
|
}
|
|
1967
2088
|
|
|
@@ -1970,10 +2091,28 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
1970
2091
|
const rvPending = new RunView();
|
|
1971
2092
|
const sourceObjectFields: Record<string, string[] | null> = item.SourceObjectFields ?? {};
|
|
1972
2093
|
|
|
1973
|
-
// Introspect schema ONCE for the entire connector, then reuse per object
|
|
2094
|
+
// Introspect schema ONCE for the entire connector, then reuse per object.
|
|
2095
|
+
//
|
|
2096
|
+
// IN THE CONNECTION'S CATALOG SCOPE. This runs at process start, outside any request, so
|
|
2097
|
+
// nothing upstream has entered a scope for it — and an unscoped catalog read falls back to
|
|
2098
|
+
// the SHARED catalog by design. That would build these field maps from the connector's
|
|
2099
|
+
// declared fields alone: every column this connection's own discovery sampled would get a
|
|
2100
|
+
// table column from the RSU (built in scope, from the per-connection rows) but no field map,
|
|
2101
|
+
// and its values would land in the overflow JSON instead of the column. Observed on the
|
|
2102
|
+
// sandbox 2026-09-11: 487 declared fields, 556 per-connection — 69 columns that this read
|
|
2103
|
+
// would have silently left unmapped. Entering the scope is not enough on a fresh process:
|
|
2104
|
+
// IntrospectInCatalogScope loads the catalog and warms each object's fields first.
|
|
1974
2105
|
const introspect = connector.IntrospectSchema.bind(connector) as
|
|
1975
2106
|
(ci: unknown, u: unknown) => Promise<{ Objects: Array<{ ExternalName: string; Fields: Array<{ Name: string; IsPrimaryKey?: boolean; IsRequired?: boolean }> }> }>;
|
|
1976
|
-
const schema = await
|
|
2107
|
+
const schema = await IntrospectInCatalogScope(
|
|
2108
|
+
item.CompanyIntegrationID,
|
|
2109
|
+
item.SourceObjectNames,
|
|
2110
|
+
() => introspect(companyIntegration, systemUser),
|
|
2111
|
+
systemUser,
|
|
2112
|
+
);
|
|
2113
|
+
|
|
2114
|
+
const objectsToMap = item.SourceObjectNames.length;
|
|
2115
|
+
progress?.BeginEntityMaps(objectsToMap);
|
|
1977
2116
|
|
|
1978
2117
|
for (const objName of item.SourceObjectNames) {
|
|
1979
2118
|
const tableName = objName.replace(/[^A-Za-z0-9_]/g, '_').toLowerCase();
|
|
@@ -2079,8 +2218,15 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
2079
2218
|
} catch (fieldErr) {
|
|
2080
2219
|
console.warn(`[RSU] Field map creation failed for ${objName}: ${fieldErr}`);
|
|
2081
2220
|
}
|
|
2221
|
+
|
|
2222
|
+
progress?.ObjectMapped(objName, mappedObjectNames.size, objectsToMap);
|
|
2082
2223
|
}
|
|
2083
2224
|
|
|
2225
|
+
// The applied rollup for this half of the run, in OBJECTS. `mappedObjectNames` is the same set
|
|
2226
|
+
// the retry path narrows against, so what is reported succeeded here is exactly what a retry
|
|
2227
|
+
// would NOT redo.
|
|
2228
|
+
progress?.CompleteEntityMaps(objectsToMap, mappedObjectNames.size, objectsToMap - mappedObjectNames.size);
|
|
2229
|
+
|
|
2084
2230
|
// Remove-as-disable: entity maps whose object is NOT in this apply's selection
|
|
2085
2231
|
// are disabled (data kept; re-selection re-enables). 'ignore' opts out for subset applies.
|
|
2086
2232
|
if ((item.UnselectedAction ?? 'disable') !== 'ignore') {
|
|
@@ -2096,8 +2242,11 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
2096
2242
|
}
|
|
2097
2243
|
}
|
|
2098
2244
|
|
|
2099
|
-
// Start sync if requested
|
|
2245
|
+
// Start sync if requested. This is the step the setup journey is actually waiting on — the
|
|
2246
|
+
// connector is not live until it begins — so it is a stage of its own rather than a footnote
|
|
2247
|
+
// on entity-map creation.
|
|
2100
2248
|
if (item.StartSync !== false) {
|
|
2249
|
+
progress?.BeginStartSync();
|
|
2101
2250
|
try {
|
|
2102
2251
|
await IntegrationEngine.Instance.Config(false, systemUser);
|
|
2103
2252
|
const syncOptions: IntegrationSyncOptions = {};
|
|
@@ -2107,11 +2256,18 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
2107
2256
|
const opts = Object.keys(syncOptions).length > 0 ? syncOptions : undefined;
|
|
2108
2257
|
IntegrationEngine.Instance.RunSync(item.CompanyIntegrationID, systemUser, 'Manual', undefined, undefined, opts);
|
|
2109
2258
|
console.log(`[RSU] Sync started for ${item.CompanyIntegrationID} (EntityMaps: ${createdEntityMapIDs.length}, FullSync: ${!!item.FullSync}, SyncDirection: ${item.SyncDirection ?? 'entity-map default'})`);
|
|
2259
|
+
// Looked up rather than returned: RunSync resolves only when the whole sync finishes, and
|
|
2260
|
+
// this stage closes when the sync STARTS. A null id closes the stage anyway — the sync did
|
|
2261
|
+
// start; only the hand-off to its own stream is missing.
|
|
2262
|
+
progress?.CompleteStartSync(await FindStartedSyncRunID(item.CompanyIntegrationID, systemUser));
|
|
2110
2263
|
} catch (syncErr) {
|
|
2111
2264
|
console.warn(`[RSU] Sync start failed: ${syncErr}`);
|
|
2265
|
+
progress?.FailStartSync(`Sync start failed: ${syncErr instanceof Error ? syncErr.message : String(syncErr)}`);
|
|
2112
2266
|
}
|
|
2113
2267
|
} else {
|
|
2114
2268
|
console.log(`[RSU] Sync skipped for ${item.CompanyIntegrationID} (StartSync=false)`);
|
|
2269
|
+
progress?.BeginStartSync();
|
|
2270
|
+
progress?.SkipStartSync('the caller asked for no initial sync (StartSync=false)');
|
|
2115
2271
|
}
|
|
2116
2272
|
|
|
2117
2273
|
// Create or update schedule if CronExpression provided
|
|
@@ -2150,6 +2306,7 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
2150
2306
|
EntityName: 'MJ: Scheduled Job Types',
|
|
2151
2307
|
ExtraFilter: `DriverClass='IntegrationSyncScheduledJobDriver'`,
|
|
2152
2308
|
MaxRows: 1,
|
|
2309
|
+
SkipTotalRowCount: true,
|
|
2153
2310
|
ResultType: 'simple',
|
|
2154
2311
|
Fields: ['ID']
|
|
2155
2312
|
}, systemUser);
|
|
@@ -2198,6 +2355,16 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
2198
2355
|
// Failing terminally on the first error means the objects this item would have mapped are
|
|
2199
2356
|
// silently never mapped, and the only recovery is someone noticing and re-applying by hand.
|
|
2200
2357
|
const remaining = (item.SourceObjectNames ?? []).filter(n => !mappedObjectNames.has(n));
|
|
2358
|
+
// Same list the retry narrows to, reported into the run stream: when this half fails, those
|
|
2359
|
+
// objects have tables and no way to sync into them, and this is the client's only signal.
|
|
2360
|
+
//
|
|
2361
|
+
// Reported under CreateEntityMaps because that is where the overwhelming majority of this
|
|
2362
|
+
// block's work — and so its failures — lives. A throw from further down (schedule creation,
|
|
2363
|
+
// say) lands here too, with an empty `remaining`; the stage attribution is then approximate
|
|
2364
|
+
// but the message is the real error and the run is correctly marked failed, which is what the
|
|
2365
|
+
// operator needs. The alternative — inventing a stage that is not in the pipeline's step list
|
|
2366
|
+
// — would break the determinate stepper for the sake of a nicer label.
|
|
2367
|
+
progress?.FailEntityMaps(message, remaining);
|
|
2201
2368
|
const requeued = await rsm.RetryPendingWork(pendingWorkID, item, remaining, systemUser);
|
|
2202
2369
|
if (!requeued) {
|
|
2203
2370
|
// Budget spent, or nothing left to retry. This message is the operator's only signal, so
|
|
@@ -2208,9 +2375,42 @@ async function processRSUPendingWork(): Promise<void> {
|
|
|
2208
2375
|
}
|
|
2209
2376
|
}
|
|
2210
2377
|
|
|
2378
|
+
// Terminates every RSU run this pass re-attached to. Until this lands, those runs have been
|
|
2379
|
+
// flagged in-flight since before the restart — which is exactly the state this whole mechanism
|
|
2380
|
+
// exists to end.
|
|
2381
|
+
await progressSession.FinishAll();
|
|
2382
|
+
|
|
2211
2383
|
console.log(`[RSU] Pending work processing complete`);
|
|
2212
2384
|
}
|
|
2213
2385
|
|
|
2386
|
+
/**
|
|
2387
|
+
* The ID of the sync run a just-launched sync created, or null if it is not readable yet.
|
|
2388
|
+
*
|
|
2389
|
+
* `RunSync` resolves only when the entire sync FINISHES, so it cannot be awaited for this — the
|
|
2390
|
+
* StartSync stage closes when the sync begins, not when it ends. The run row is written early in
|
|
2391
|
+
* the sync's own startup, so a short settle plus a newest-first lookup finds it. Null is a normal
|
|
2392
|
+
* outcome under load and is reported as such; it never fails anything.
|
|
2393
|
+
*/
|
|
2394
|
+
async function FindStartedSyncRunID(companyIntegrationID: string, systemUser: UserInfo): Promise<string | null> {
|
|
2395
|
+
try {
|
|
2396
|
+
await new Promise(resolve => setTimeout(resolve, 200));
|
|
2397
|
+
const rv = new RunView();
|
|
2398
|
+
const runResult = await rv.RunView<{ ID: string }>({
|
|
2399
|
+
EntityName: 'MJ: Company Integration Runs',
|
|
2400
|
+
ExtraFilter: `CompanyIntegrationID='${companyIntegrationID.replace(/'/g, "''")}' AND Status='In Progress'`,
|
|
2401
|
+
OrderBy: '__mj_CreatedAt DESC',
|
|
2402
|
+
MaxRows: 1,
|
|
2403
|
+
SkipTotalRowCount: true,
|
|
2404
|
+
ResultType: 'simple',
|
|
2405
|
+
Fields: ['ID'],
|
|
2406
|
+
}, systemUser);
|
|
2407
|
+
return runResult.Success && runResult.Results.length > 0 ? runResult.Results[0].ID : null;
|
|
2408
|
+
} catch (e) {
|
|
2409
|
+
console.warn(`[RSU] Could not resolve the started sync run id for ${companyIntegrationID}: ${e}`);
|
|
2410
|
+
return null;
|
|
2411
|
+
}
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2214
2414
|
/**
|
|
2215
2415
|
* Creates a MSSQL ConnectionPool-compatible wrapper around a pg.Pool.
|
|
2216
2416
|
* This allows existing code that references DataSourceInfo.dataSource (typed as sql.ConnectionPool)
|
|
@@ -2263,7 +2463,7 @@ function mountRealtimeRecordingRoutes(app: Application): boolean {
|
|
|
2263
2463
|
return user ? { ContextUser: user, Provider: provider } : null;
|
|
2264
2464
|
},
|
|
2265
2465
|
LoadOwnedSession: LoadOwnedRealtimeSession,
|
|
2266
|
-
|
|
2466
|
+
AuthorizeSession: AuthorizeLoadedSession,
|
|
2267
2467
|
CreateLedger: (ledgerProvider, contextUser) => new SqlRealtimeRecordingLedger(ledgerProvider, contextUser),
|
|
2268
2468
|
Scheduler: RecordingAssemblyScheduler.Instance,
|
|
2269
2469
|
GraceMs: graceMs,
|
|
@@ -2281,3 +2481,5 @@ export type { MagicLinkJWTClaims } from './auth/magicLink/index.js';
|
|
|
2281
2481
|
export { VerifyHostAssertion } from './realtimeWidget/host-identity.js';
|
|
2282
2482
|
export type { HostAssertedIdentity, HostAssertionResult } from './realtimeWidget/host-identity.js';
|
|
2283
2483
|
export { IsScopeLimitedPrincipal } from './auth/scopeLimitedPrincipal.js';
|
|
2484
|
+
export const GetServerStartupSummary = () => StartupLogger.GetLastStartupSnapshot();
|
|
2485
|
+
export type { StartupSummarySnapshot } from './logging/StartupLogger.js';
|