@taskforcehq/taskforce 0.3.327 → 0.3.329
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/dist/Taskforce.module.css +257 -87
- package/dist/TaskforceCore.js +237 -230
- package/dist/annotatedAttachments/AnnotatedAttachmentSessionStore.js +1 -1
- package/dist/cli.js +34 -0
- package/dist/cliCloudTargetGuard.d.ts +5 -0
- package/dist/cliCloudTargetGuard.js +11 -0
- package/dist/components/activity/EntityActivityTimeline.js +15 -5
- package/dist/components/context/AttachmentPreviewHost.js +1 -1
- package/dist/components/context/ContextAttachmentManager.d.ts +3 -0
- package/dist/components/context/ContextAttachmentManager.js +116 -20
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +24 -8
- package/dist/components/features/TaskSettings.d.ts +12 -1
- package/dist/components/features/TaskSettings.js +147 -40
- package/dist/components/features/agentCapabilities/AgentCapabilitiesPrototype.d.ts +1 -1
- package/dist/components/features/planning/PlanningEntitySummary.d.ts +3 -1
- package/dist/components/features/planning/PlanningEntitySummary.js +3 -2
- package/dist/components/features/planning/PlanningLinkPicker.d.ts +3 -1
- package/dist/components/features/planning/PlanningLinkPicker.js +5 -3
- package/dist/components/features/planning/PlanningModule.js +28 -14
- package/dist/components/features/planning/PlanningTaskOrderList.d.ts +1 -1
- package/dist/components/features/planning/PlanningTaskOrderList.js +17 -6
- package/dist/components/features/planning/PlanningVisualIdentity.d.ts +14 -0
- package/dist/components/features/planning/PlanningVisualIdentity.js +106 -0
- package/dist/components/features/planning/planningTaskArrangement.d.ts +1 -0
- package/dist/components/features/planning/planningTaskArrangement.js +5 -5
- package/dist/components/features/planning/planningWorkspaceModel.d.ts +11 -0
- package/dist/components/features/taskforceAgentEditorModel.js +3 -1
- package/dist/components/task/TaskActionHeader.d.ts +2 -1
- package/dist/components/task/TaskActionHeader.js +2 -2
- package/dist/components/task/TaskCard.d.ts +5 -0
- package/dist/components/task/TaskCard.js +101 -13
- package/dist/components/task/TaskContextUpload.d.ts +3 -0
- package/dist/components/task/TaskContextUpload.js +2 -2
- package/dist/components/task/TaskForm.d.ts +4 -0
- package/dist/components/task/TaskForm.js +32 -7
- package/dist/components/task/TaskImageReviews.js +28 -19
- package/dist/components/task/TaskKanban.d.ts +6 -1
- package/dist/components/task/TaskKanban.js +152 -6
- package/dist/components/task/TaskList.d.ts +5 -0
- package/dist/components/task/TaskList.js +3 -3
- package/dist/components/task/TaskStatusActions.js +11 -2
- package/dist/components/task/TaskWorkstreamPicker.js +2 -1
- package/dist/components/ui/DocumentTypeIcon.d.ts +7 -0
- package/dist/components/ui/DocumentTypeIcon.js +8 -0
- package/dist/components/ui/PasswordInput.d.ts +6 -0
- package/dist/components/ui/PasswordInput.js +11 -0
- package/dist/components/ui/TaxonomyDropdown.d.ts +9 -1
- package/dist/components/ui/TaxonomyDropdown.js +30 -3
- package/dist/components/ui/TopNoticeLayer.js +1 -1
- package/dist/components/views/AppShellHeader.js +32 -11
- package/dist/components/views/PlanComparisonPage.js +12 -0
- package/dist/components/views/StandaloneLayout.js +68 -39
- package/dist/components/views/WidgetView.js +10 -7
- package/dist/components/views/panels/PlanningDrawer.d.ts +7 -1
- package/dist/components/views/panels/PlanningDrawer.js +51 -54
- package/dist/components/views/standalone/modals/AccountSettingsModal.js +26 -17
- package/dist/config/envSchema.js +13 -0
- package/dist/config/localServiceCloudTarget.d.ts +10 -0
- package/dist/config/localServiceCloudTarget.js +76 -0
- package/dist/config/localServiceRuntimeContract.d.ts +13 -0
- package/dist/config/localServiceRuntimeContract.js +135 -0
- package/dist/core/AiProfileService.d.ts +1 -0
- package/dist/core/AiProfileService.js +48 -9
- package/dist/core/AttachmentLinkService.js +7 -4
- package/dist/core/DeletedTaskLifecycleService.d.ts +5 -0
- package/dist/core/DeletedTaskLifecycleService.js +55 -3
- package/dist/core/McpTokenService.d.ts +4 -0
- package/dist/core/McpTokenService.js +52 -0
- package/dist/core/TaskAttachmentLinksDurableMutationService.d.ts +8 -2
- package/dist/core/TaskAttachmentLinksDurableMutationService.js +51 -18
- package/dist/core/Taskforce.d.ts +124 -2
- package/dist/core/Taskforce.js +1175 -87
- package/dist/core/types.d.ts +8 -1
- package/dist/documentReviews/DocumentReviewCommentStore.d.ts +11 -0
- package/dist/documentReviews/DocumentReviewCommentStore.js +35 -2
- package/dist/documentReviews/service.d.ts +4 -0
- package/dist/documentReviews/service.js +141 -46
- package/dist/hooks/sync/useDurableLocalOutboxDrain.d.ts +1 -1
- package/dist/hooks/sync/useDurableTaskCreateMutation.js +1 -1
- package/dist/hooks/sync/useDurableTaskMetadataMutation.d.ts +1 -0
- package/dist/hooks/sync/useDurableTaskMetadataMutation.js +1 -0
- package/dist/hooks/sync/useDurableTaskStatusMutation.d.ts +1 -0
- package/dist/hooks/tasks/taskHttpMutation.js +1 -0
- package/dist/hooks/tasks/useCloudTaskSearch.d.ts +12 -0
- package/dist/hooks/tasks/useCloudTaskSearch.js +71 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.d.ts +16 -0
- package/dist/hooks/tasks/useTaskDescriptionImageDraftRecovery.js +197 -0
- package/dist/hooks/tasks/useTaskEditorNavigation.d.ts +16 -3
- package/dist/hooks/tasks/useTaskEditorNavigation.js +72 -13
- package/dist/hooks/tasks/useTaskFormActions.d.ts +9 -0
- package/dist/hooks/tasks/useTaskFormActions.js +96 -17
- package/dist/hooks/ui/useSettingsModel.d.ts +24 -2
- package/dist/hooks/ui/useSettingsModel.js +13 -2
- package/dist/hooks/ui/useSettingsPersistence.d.ts +12 -1
- package/dist/hooks/ui/useSettingsPersistence.js +74 -47
- package/dist/hooks/useFilterSort.d.ts +7 -3
- package/dist/hooks/useFilterSort.js +15 -5
- package/dist/hooks/useTaskData.d.ts +10 -1
- package/dist/hooks/useTaskData.js +216 -7
- package/dist/hooks/useTaskMutations.d.ts +10 -2
- package/dist/hooks/useTaskMutations.js +223 -43
- package/dist/hooks/useTaskforce.d.ts +94 -57
- package/dist/hooks/useTaskforce.js +428 -16
- package/dist/hooks/useUiNotice.d.ts +4 -0
- package/dist/hooks/useUiNotice.js +4 -0
- package/dist/mcp/adminWorkspaceRegistrar.js +3 -3
- package/dist/mcp/canonicalAssetHelpers.d.ts +13 -0
- package/dist/mcp/canonicalAssetHelpers.js +39 -5
- package/dist/mcp/collaborationRegistrar.js +15 -13
- package/dist/mcp/documentAssetRegistrar.js +60 -44
- package/dist/mcp/documentHelpers.d.ts +1 -0
- package/dist/mcp/documentHelpers.js +7 -3
- package/dist/mcp/localServiceProxy.js +4 -1
- package/dist/mcp/runtime.d.ts +16 -0
- package/dist/mcp/runtime.js +735 -210
- package/dist/mcp/taskAttachmentCommandAdapter.d.ts +2 -0
- package/dist/mcp/taskAttachmentCommandAdapter.js +14 -8
- package/dist/mcp/taskPlanningRegistrar.js +78 -67
- package/dist/mcp/toolCallCompatibility.js +38 -1
- package/dist/mcp/toolCatalog.d.ts +1 -0
- package/dist/mcp/toolRegistry.js +2 -2
- package/dist/migrations/taskSchemaMigrations.js +47 -0
- package/dist/runtime/appGateDefinitions.d.ts +30 -6
- package/dist/runtime/appGateDefinitions.js +6 -6
- package/dist/runtime/appGates.d.ts +12 -13
- package/dist/runtime/appGates.js +29 -13
- package/dist/runtime/nodeAppGates.d.ts +8 -0
- package/dist/runtime/nodeAppGates.js +27 -0
- package/dist/server/appAccess.d.ts +12 -0
- package/dist/server/appAccess.js +21 -0
- package/dist/server/authorizedWorkspaceAccess.d.ts +12 -0
- package/dist/server/authorizedWorkspaceAccess.js +40 -0
- package/dist/server/cloudCollectionRead.d.ts +25 -0
- package/dist/server/cloudCollectionRead.js +120 -0
- package/dist/server/cloudCollectionReadPool.d.ts +52 -0
- package/dist/server/cloudCollectionReadPool.js +140 -0
- package/dist/server/cloudCollectionReadWorker.d.ts +1 -0
- package/dist/server/cloudCollectionReadWorker.js +36 -0
- package/dist/server/index.d.ts +6 -11
- package/dist/server/index.js +67 -42
- package/dist/server/localServiceLease.d.ts +6 -0
- package/dist/server/localServiceLease.js +17 -1
- package/dist/server/localWorkspaceSyncServerRuntime.js +10 -3
- package/dist/server/rateLimit.d.ts +1 -0
- package/dist/server/rateLimit.js +4 -0
- package/dist/server/realtimeSyncWs.js +36 -12
- package/dist/server/routes/admin.js +1 -0
- package/dist/server/routes/agentRoles.js +3 -2
- package/dist/server/routes/agentSkills.js +3 -2
- package/dist/server/routes/agents.js +118 -16
- package/dist/server/routes/annotatedAttachments.js +3 -2
- package/dist/server/routes/auth.js +3 -1
- package/dist/server/routes/documents.d.ts +5 -2
- package/dist/server/routes/documents.js +160 -13
- package/dist/server/routes/durableTaskHttpRouters.d.ts +11 -2
- package/dist/server/routes/durableTaskHttpRouters.js +2 -2
- package/dist/server/routes/localService.js +4 -0
- package/dist/server/routes/primitives.d.ts +4 -0
- package/dist/server/routes/shared.d.ts +24 -0
- package/dist/server/routes/shared.js +114 -18
- package/dist/server/routes/sync.js +22 -0
- package/dist/server/routes/syncAuxRoutes.js +5 -2
- package/dist/server/routes/syncPullApplyRoutes.js +23 -4
- package/dist/server/routes/syncV3FeedRoutes.js +22 -18
- package/dist/server/routes/syncV3LocalCaptureRoutes.js +48 -4
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.d.ts +1 -0
- package/dist/server/routes/syncV3LocalFeedApplyRoutes.js +26 -0
- package/dist/server/routes/syncV3OperationRoutes.js +27 -2
- package/dist/server/routes/tasks.js +299 -97
- package/dist/server/routes/workspaces.js +43 -1
- package/dist/server/routes.js +35 -7
- package/dist/server/workspaceDeletionAdmission.d.ts +23 -0
- package/dist/server/workspaceDeletionAdmission.js +50 -0
- package/dist/service/localServiceCli.js +52 -25
- package/dist/service/localServiceClientLifecycle.js +93 -6
- package/dist/services/codexAppServerModelGateway.d.ts +112 -0
- package/dist/services/codexAppServerModelGateway.js +438 -0
- package/dist/services/taskforceAgentMcpBridge.d.ts +7 -1
- package/dist/services/taskforceAgentMcpBridge.js +23 -3
- package/dist/shared/planningIdentity.d.ts +20 -0
- package/dist/shared/planningIdentity.js +79 -0
- package/dist/shared/taskforceAgentDefinition.js +7 -1
- package/dist/shared/taskforceAgentModels.d.ts +1 -0
- package/dist/shared/taskforceAgentModels.js +30 -1
- package/dist/storage/postgresAdapter.d.ts +20 -3
- package/dist/storage/postgresAdapter.js +110 -14
- package/dist/storage/postgresRequestDiagnostics.d.ts +8 -0
- package/dist/storage/postgresRequestDiagnostics.js +24 -0
- package/dist/storage/postgresWorker.js +13 -4
- package/dist/storage/postgresWorkerProtocol.d.ts +29 -0
- package/dist/storage/postgresWorkerProtocol.js +30 -0
- package/dist/storage/workspaceAssetStore.d.ts +32 -0
- package/dist/storage/workspaceAssetStore.js +70 -0
- package/dist/sync/cloudSyncApi.d.ts +4 -1
- package/dist/sync/cloudSyncApi.js +7 -2
- package/dist/sync/contentSyncState.d.ts +1 -1
- package/dist/sync/coordinator/localSyncExecutionPermitStore.d.ts +17 -0
- package/dist/sync/coordinator/localSyncExecutionPermitStore.js +77 -23
- package/dist/sync/coordinator/localWorkspaceSyncRunner.js +6 -2
- package/dist/sync/coordinator/workspaceSyncTransportGateway.js +4 -2
- package/dist/sync/engine/workspaceSyncEngineBrowserGatewayRemoteServices.js +20 -2
- package/dist/sync/engine/workspaceSyncEngineLocalServices.d.ts +4 -0
- package/dist/sync/engine/workspaceSyncEngineLocalServices.js +11 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.d.ts +16 -0
- package/dist/sync/engine/workspaceSyncEngineRemoteServices.js +2 -1
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.d.ts +1 -1
- package/dist/sync/engine/workspaceSyncEngineServerRemoteServices.js +46 -4
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.d.ts +3 -1
- package/dist/sync/engine/workspaceSyncEngineServerRunnerOperations.js +51 -11
- package/dist/sync/engine/workspaceSyncEngineTransfers.d.ts +1 -1
- package/dist/sync/engine/workspaceSyncEngineTransfers.js +8 -3
- package/dist/sync/engine/workspaceSyncV2ChangeDispatcher.js +2 -0
- package/dist/sync/syncApplyHandlers.d.ts +3 -1
- package/dist/sync/syncApplyHandlers.js +29 -0
- package/dist/sync/syncService.d.ts +2 -0
- package/dist/sync/syncService.js +13 -1
- package/dist/sync/taskSyncPayload.d.ts +1 -0
- package/dist/sync/taskSyncPayload.js +6 -0
- package/dist/sync/v3/combinedFeedCapability.js +4 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.d.ts +3 -0
- package/dist/sync/v3/durableTaskAttachmentLinksMutationRouter.js +31 -3
- package/dist/sync/v3/durableTaskChecklistMutationRouter.d.ts +2 -0
- package/dist/sync/v3/durableTaskChecklistMutationRouter.js +4 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.d.ts +1 -0
- package/dist/sync/v3/durableTaskHttpBulkMutationRouter.js +47 -12
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.d.ts +5 -3
- package/dist/sync/v3/durableTaskHttpRootMutationRouter.js +27 -2
- package/dist/sync/v3/localInitiativeOutboxService.js +4 -2
- package/dist/sync/v3/localOutboxDispatcher.js +5 -1
- package/dist/sync/v3/localTaskAttachmentLinksOutboxHandler.js +12 -2
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.d.ts +3 -0
- package/dist/sync/v3/localTaskAttachmentLinksOutboxService.js +62 -10
- package/dist/sync/v3/localTaskCreateOutboxService.js +15 -6
- package/dist/sync/v3/localTaskMetadataClient.d.ts +1 -0
- package/dist/sync/v3/localTaskMetadataClient.js +1 -0
- package/dist/sync/v3/localTaskMetadataOutboxHandler.js +5 -1
- package/dist/sync/v3/localTaskMetadataOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskMetadataOutboxService.js +7 -0
- package/dist/sync/v3/localTaskRestoreOutboxService.js +14 -6
- package/dist/sync/v3/localTaskStatusClient.d.ts +1 -0
- package/dist/sync/v3/localTaskStatusClient.js +6 -1
- package/dist/sync/v3/localTaskStatusOutboxService.d.ts +2 -0
- package/dist/sync/v3/localTaskStatusOutboxService.js +54 -13
- package/dist/sync/v3/localWorkstreamOutboxService.js +4 -2
- package/dist/sync/v3/syncDurabilityStore.d.ts +15 -0
- package/dist/sync/v3/syncDurabilityStore.js +201 -43
- package/dist/sync/v3/taskAttachmentLinksMutationService.d.ts +7 -4
- package/dist/sync/v3/taskAttachmentLinksMutationService.js +37 -12
- package/dist/sync/v3/taskChecklistMutationService.d.ts +4 -2
- package/dist/sync/v3/taskChecklistMutationService.js +4 -0
- package/dist/sync/v3/taskCreateMutationService.d.ts +2 -2
- package/dist/sync/v3/taskCreateMutationService.js +7 -4
- package/dist/sync/v3/taskMetadataCoexistence.js +4 -0
- package/dist/sync/v3/taskMetadataMutationService.d.ts +3 -0
- package/dist/sync/v3/taskMetadataMutationService.js +4 -0
- package/dist/sync/v3/taskRestoreMutationService.d.ts +2 -2
- package/dist/sync/v3/taskRestoreMutationService.js +7 -4
- package/dist/sync/v3/taskStatusMutationService.d.ts +2 -0
- package/dist/sync/v3/taskStatusMutationService.js +4 -0
- package/dist/sync/v3/workflowAssignmentSync.d.ts +1 -0
- package/dist/sync/v3/workflowAssignmentSync.js +3 -0
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV2ProjectionExclusions.js +14 -12
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.d.ts +11 -0
- package/dist/sync/v3/workspaceSyncV3AttachmentApplyObligationStore.js +27 -10
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3AttachmentAssetHydration.js +52 -10
- package/dist/sync/v3/workspaceSyncV3CloudOperationHandler.js +10 -1
- package/dist/sync/v3/workspaceSyncV3CombinedFeedOrchestrator.js +15 -4
- package/dist/sync/v3/workspaceSyncV3CombinedLocalApply.js +66 -13
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.d.ts +11 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairBaseline.js +57 -22
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.d.ts +10 -4
- package/dist/sync/v3/workspaceSyncV3CombinedRepairMaterialization.js +124 -51
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.d.ts +10 -0
- package/dist/sync/v3/workspaceSyncV3CombinedRepairSnapshot.js +120 -28
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.d.ts +3 -1
- package/dist/sync/v3/workspaceSyncV3CombinedWireContract.js +18 -0
- package/dist/sync/v3/workspaceSyncV3CoverageRegistry.js +6 -0
- package/dist/sync/v3/workspaceSyncV3FeedProfile.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.d.ts +1 -0
- package/dist/sync/v3/workspaceSyncV3LegacyBoundaryAttestation.js +23 -10
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskApply.js +64 -13
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.d.ts +9 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskCodecs.js +26 -0
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.d.ts +15 -5
- package/dist/sync/v3/workspaceSyncV3NestedTaskProjection.js +50 -14
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.d.ts +2 -1
- package/dist/sync/v3/workspaceSyncV3NestedTaskRepairSnapshot.js +11 -3
- package/dist/sync/v3/workspaceSyncV3OperationProtocol.d.ts +3 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3OperatorDiagnostics.js +19 -7
- package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.d.ts +2 -0
- package/dist/sync/v3/workspaceSyncV3RepairSqlBatching.js +10 -0
- package/dist/sync/v3/workspaceSyncV3TaskCommentAudit.js +9 -2
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.d.ts +7 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverCoverage.js +37 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.d.ts +6 -0
- package/dist/sync/v3/workspaceSyncV3TaskCoverWireContract.js +9 -0
- package/dist/sync/v3/workspaceSyncV3TaskRootProjection.d.ts +1 -1
- package/dist/sync/v3/workspaceSyncV3TaskRootProjection.js +1 -1
- package/dist/sync/workspacePullFeed.d.ts +6 -1
- package/dist/sync/workspacePullFeed.js +174 -162
- package/dist/sync/workspaceRepair.d.ts +3 -0
- package/dist/sync/workspaceRepair.js +67 -6
- package/dist/sync/workspaceSyncModel.d.ts +11 -0
- package/dist/sync/workspaceSyncModel.js +27 -2
- package/dist/types.d.ts +55 -1
- package/dist/types.js +6 -0
- package/dist/ui/assets/{AiIdentityRosterCard-DB1BLO_j.js → AiIdentityRosterCard-BZM4aQnM.js} +1 -1
- package/dist/ui/assets/AiProfilesModule-BbAEWtHH.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-B68Wg-RV.js +3 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-TzYu7pkG.css +1 -0
- package/dist/ui/assets/AssetTraySortControl-C8Rztyal.js +1 -0
- package/dist/ui/assets/ContextAttachmentManager-Cj3c7X9y.js +3 -0
- package/dist/ui/assets/{DocumentWorkspace-BC7sy5TG.js → DocumentWorkspace-B5uvzems.js} +4 -4
- package/dist/ui/assets/EntityActivityTimeline-BVFvCB5R.js +1 -0
- package/dist/ui/assets/PlanningModule-B5DWQOGz.js +1 -0
- package/dist/ui/assets/PlanningModule-CoIR9hbV.css +1 -0
- package/dist/ui/assets/PlansPage-AY4cGWco.js +1 -0
- package/dist/ui/assets/TaskContextUpload-DZxTVesW.js +1 -0
- package/dist/ui/assets/TaskContextUpload-qmBeUw3u.css +1 -0
- package/dist/ui/assets/TaskSettings-BeWAuyZj.js +12 -0
- package/dist/ui/assets/{TaskforceAgentsModule-CkAxW19K.js → TaskforceAgentsModule-BifCYtjR.js} +6 -6
- package/dist/ui/assets/WorkflowManagerModule-DEr5di_r.js +1 -0
- package/dist/ui/assets/index-I5zhdtgt.js +7 -0
- package/dist/ui/assets/index-VRFsx3wz.css +1 -0
- package/dist/ui/assets/{vendor-icons-B8ZNsH1g.js → vendor-icons-D9Lpw-j4.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/utils/constants.d.ts +2 -2
- package/dist/utils/constants.js +1 -1
- package/dist/utils/contextAttachmentUpload.d.ts +2 -0
- package/dist/utils/contextAttachmentUpload.js +7 -0
- package/dist/utils/contextFiles.d.ts +1 -1
- package/dist/utils/contextFiles.js +4 -4
- package/dist/utils/taskActivity.d.ts +3 -2
- package/dist/utils/taskActivity.js +19 -2
- package/dist/utils/taskEditorReconciliation.d.ts +40 -0
- package/dist/utils/taskEditorReconciliation.js +217 -0
- package/dist/utils/taskNormalization.d.ts +1 -0
- package/dist/utils/taskNormalization.js +39 -0
- package/dist/utils/taskSearch.js +2 -2
- package/dist/utils/uiNotice.d.ts +4 -0
- package/package.json +21 -4
- package/dist/ui/assets/AiProfilesModule-DPxQeF9N.js +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-CBRZ8rca.css +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-DHNYaNg6.js +0 -3
- package/dist/ui/assets/AssetTraySortControl-DphbyHVc.js +0 -1
- package/dist/ui/assets/ContextAttachmentManager-CMxSzHqc.js +0 -3
- package/dist/ui/assets/EntityActivityTimeline-pJ2ZjZ-k.js +0 -1
- package/dist/ui/assets/PlanningModule-CeTqXMMz.css +0 -1
- package/dist/ui/assets/PlanningModule-t5GbvVR9.js +0 -1
- package/dist/ui/assets/PlansPage-BVH_NfgT.js +0 -1
- package/dist/ui/assets/TaskContextUpload-Ds4LnDzV.css +0 -1
- package/dist/ui/assets/TaskContextUpload-bl4fOOUz.js +0 -1
- package/dist/ui/assets/TaskSettings-xVsxSa0g.js +0 -12
- package/dist/ui/assets/WorkflowManagerModule-BKqIGVnF.js +0 -1
- package/dist/ui/assets/index-BzJlVnNS.css +0 -1
- package/dist/ui/assets/index-Cx7vZJHL.js +0 -7
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { createHmac, randomUUID, timingSafeEqual } from 'crypto';
|
|
2
2
|
import { canonicalWorkspaceSyncJson } from './canonicalWorkspaceSyncJson.js';
|
|
3
3
|
import { decodeCanonicalWorkspaceSyncBase64Url } from './workspaceSyncV3CursorEncoding.js';
|
|
4
|
-
import { prepareWorkspaceSyncV3CombinedRepairSnapshot, prepareWorkspaceSyncV3NestedRepairSnapshot, prepareWorkspaceSyncV3PlanningOrderRepairSnapshot, prepareWorkspaceSyncV3WorkflowRepairSnapshot, } from './workspaceSyncV3CombinedRepairBaseline.js';
|
|
4
|
+
import { prepareWorkspaceSyncV3CombinedRepairSnapshot, prepareWorkspaceSyncV3NestedRepairSnapshot, prepareWorkspaceSyncV3PlanningOrderRepairSnapshot, prepareWorkspaceSyncV3TaskCoverRepairSnapshot, prepareWorkspaceSyncV3WorkflowRepairSnapshot, } from './workspaceSyncV3CombinedRepairBaseline.js';
|
|
5
5
|
import { validateWorkspaceSyncV3CombinedFeedEntry, WORKSPACE_SYNC_V3_COMBINED_COVERAGE_PROFILE, } from './workspaceSyncV3CombinedCoverage.js';
|
|
6
6
|
import { validateWorkspaceSyncV3NestedCoverageFeedEntry, WORKSPACE_SYNC_V3_NESTED_COVERAGE_PROFILE, } from './workspaceSyncV3NestedCoverage.js';
|
|
7
7
|
import { validateWorkspaceSyncV3WorkflowCoverageFeedEntry, WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_PROFILE, } from './workspaceSyncV3WorkflowCoverage.js';
|
|
8
8
|
import { validateWorkspaceSyncV3PlanningOrderCoverageFeedEntry, WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_PROFILE, } from './workspaceSyncV3PlanningOrderCoverage.js';
|
|
9
|
+
import { validateWorkspaceSyncV3TaskCoverCoverageFeedEntry, WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_PROFILE, } from './workspaceSyncV3TaskCoverCoverage.js';
|
|
9
10
|
import { createWorkspaceSyncV3FeedResumeCursor, WorkspaceSyncV3FeedOperationTooLargeError, } from './workspaceSyncV3Feed.js';
|
|
10
11
|
import { findWorkspaceSyncV3FeedCursorVerificationKey, } from './workspaceSyncV3FeedCursorKeys.js';
|
|
11
12
|
import { WORKSPACE_SYNC_COMBINED_PROJECTION, WORKSPACE_SYNC_CONTRACT_VERSION, } from './syncDurabilityStore.js';
|
|
@@ -14,7 +15,11 @@ const MAX_PAGE_SIZE = 100;
|
|
|
14
15
|
const DEFAULT_MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
15
16
|
const DEFAULT_SNAPSHOT_TTL_MS = 60 * 60_000;
|
|
16
17
|
const MAX_SNAPSHOT_TTL_MS = 24 * 60 * 60_000;
|
|
17
|
-
const
|
|
18
|
+
const SQLITE_INSERT_BATCH_SIZE = 50;
|
|
19
|
+
// Postgres permits 65,535 bind parameters. Each materialized entry uses 15,
|
|
20
|
+
// so 1,000 entries keeps a wide safety margin while avoiding hundreds of
|
|
21
|
+
// synchronous worker/database round trips for large repair snapshots.
|
|
22
|
+
const POSTGRES_INSERT_BATCH_SIZE = 1000;
|
|
18
23
|
export class WorkspaceSyncV3CombinedRepairSnapshotUnavailableError extends Error {
|
|
19
24
|
code = 'WORKSPACE_SYNC_V3_COMBINED_REPAIR_SNAPSHOT_UNAVAILABLE';
|
|
20
25
|
statusCode = 410;
|
|
@@ -91,14 +96,19 @@ export function decodeWorkspaceSyncV3WorkflowRepairCursor(raw, keyring) {
|
|
|
91
96
|
export function decodeWorkspaceSyncV3PlanningOrderRepairCursor(raw, keyring) {
|
|
92
97
|
return decodeRepairCursor(raw, keyring, WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_PROFILE);
|
|
93
98
|
}
|
|
99
|
+
export function decodeWorkspaceSyncV3TaskCoverRepairCursor(raw, keyring) {
|
|
100
|
+
return decodeRepairCursor(raw, keyring, WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_PROFILE);
|
|
101
|
+
}
|
|
94
102
|
function repairProfile(coverage) {
|
|
95
103
|
return coverage === 'workflow'
|
|
96
104
|
? WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_PROFILE
|
|
97
|
-
: coverage === '
|
|
98
|
-
?
|
|
99
|
-
: coverage === '
|
|
100
|
-
?
|
|
101
|
-
:
|
|
105
|
+
: coverage === 'task-cover'
|
|
106
|
+
? WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_PROFILE
|
|
107
|
+
: coverage === 'planning-order'
|
|
108
|
+
? WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_PROFILE
|
|
109
|
+
: coverage === 'nested'
|
|
110
|
+
? WORKSPACE_SYNC_V3_NESTED_COVERAGE_PROFILE
|
|
111
|
+
: WORKSPACE_SYNC_V3_COMBINED_COVERAGE_PROFILE;
|
|
102
112
|
}
|
|
103
113
|
function containsCurrentEntityEventInventory(input) {
|
|
104
114
|
if (input.coverage === 'combined')
|
|
@@ -136,27 +146,70 @@ function containsCurrentEntityEventInventory(input) {
|
|
|
136
146
|
AND entry.domain = 'entity-event'
|
|
137
147
|
AND entry.entity_id = event.id
|
|
138
148
|
)
|
|
149
|
+
AND NOT EXISTS (
|
|
150
|
+
SELECT 1
|
|
151
|
+
FROM workspace_sync_journal journal
|
|
152
|
+
WHERE journal.tenant_id = event.tenant_id
|
|
153
|
+
AND journal.workspace_id = event.workspace_id
|
|
154
|
+
AND journal.domain = 'entity-event'
|
|
155
|
+
AND journal.entity_id = event.id
|
|
156
|
+
-- Later sequenced events are delivered after the immutable
|
|
157
|
+
-- repair boundary; only unsequenced legacy adoption makes the
|
|
158
|
+
-- snapshot incomplete and requires rematerialization.
|
|
159
|
+
AND journal.sequence > ?
|
|
160
|
+
)
|
|
139
161
|
LIMIT 1
|
|
140
|
-
`).get(input.tenantId, input.workspaceId, input.snapshotId);
|
|
162
|
+
`).get(input.tenantId, input.workspaceId, input.snapshotId, input.snapshotSequence);
|
|
141
163
|
return !missing;
|
|
142
164
|
}
|
|
143
|
-
|
|
165
|
+
export const WORKSPACE_SYNC_REPAIR_SNAPSHOT_CLEANUP_BATCH_SIZE = 500;
|
|
166
|
+
function cleanupExpiredBestEffort(core, tenantId, workspaceId, now, excludingSnapshotId) {
|
|
144
167
|
const db = core.getDatabaseAdapter();
|
|
145
168
|
const exclusion = excludingSnapshotId ? ' AND snapshot_id <> ?' : '';
|
|
146
169
|
const args = excludingSnapshotId
|
|
147
170
|
? [tenantId, workspaceId, now, excludingSnapshotId]
|
|
148
171
|
: [tenantId, workspaceId, now];
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
172
|
+
try {
|
|
173
|
+
db.transaction(() => {
|
|
174
|
+
const expired = db.prepare(`
|
|
175
|
+
SELECT snapshot_id
|
|
176
|
+
FROM workspace_sync_repair_snapshots
|
|
177
|
+
WHERE tenant_id = ? AND workspace_id = ? AND expires_at <= ?${exclusion}
|
|
178
|
+
ORDER BY expires_at ASC, snapshot_id ASC
|
|
179
|
+
LIMIT 1
|
|
180
|
+
`).get(...args);
|
|
181
|
+
const snapshotId = String(expired?.snapshot_id || '').trim();
|
|
182
|
+
if (!snapshotId)
|
|
183
|
+
return;
|
|
184
|
+
db.prepare(`
|
|
185
|
+
DELETE FROM workspace_sync_repair_snapshot_entries
|
|
186
|
+
WHERE tenant_id = ? AND workspace_id = ? AND snapshot_id = ?
|
|
187
|
+
AND entry_index IN (
|
|
188
|
+
SELECT entry_index
|
|
189
|
+
FROM workspace_sync_repair_snapshot_entries
|
|
190
|
+
WHERE tenant_id = ? AND workspace_id = ? AND snapshot_id = ?
|
|
191
|
+
ORDER BY entry_index ASC
|
|
192
|
+
LIMIT ?
|
|
193
|
+
)
|
|
194
|
+
`).run(tenantId, workspaceId, snapshotId, tenantId, workspaceId, snapshotId, WORKSPACE_SYNC_REPAIR_SNAPSHOT_CLEANUP_BATCH_SIZE);
|
|
195
|
+
db.prepare(`
|
|
196
|
+
DELETE FROM workspace_sync_repair_snapshots
|
|
197
|
+
WHERE tenant_id = ? AND workspace_id = ? AND snapshot_id = ? AND expires_at <= ?
|
|
198
|
+
AND NOT EXISTS (
|
|
199
|
+
SELECT 1 FROM workspace_sync_repair_snapshot_entries
|
|
200
|
+
WHERE tenant_id = ? AND workspace_id = ? AND snapshot_id = ?
|
|
201
|
+
)
|
|
202
|
+
`).run(tenantId, workspaceId, snapshotId, now, tenantId, workspaceId, snapshotId);
|
|
203
|
+
})();
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
// Expired snapshot removal is opportunistic maintenance. A cleanup
|
|
207
|
+
// timeout must not invalidate an otherwise valid repair response.
|
|
208
|
+
console.warn('[Taskforce Sync Repair Cleanup Deferred]', JSON.stringify({
|
|
209
|
+
workspaceId,
|
|
210
|
+
error: String(error?.message || error),
|
|
211
|
+
}));
|
|
212
|
+
}
|
|
160
213
|
}
|
|
161
214
|
function persistMaterialization(input) {
|
|
162
215
|
const db = input.core.getDatabaseAdapter();
|
|
@@ -170,8 +223,11 @@ function persistMaterialization(input) {
|
|
|
170
223
|
coverage_version, coverage_digest, snapshot_sequence, entry_count, created_at, expires_at
|
|
171
224
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
172
225
|
`).run(input.tenantId, input.workspaceId, snapshotId, WORKSPACE_SYNC_CONTRACT_VERSION, profile.coverageProfileId, profile.coverageVersion, profile.coverageDigest, snapshot.snapshotSequence, snapshot.entries.length, input.startedAt, provisionalExpiresAt);
|
|
173
|
-
|
|
174
|
-
|
|
226
|
+
const insertBatchSize = db.provider === 'postgres'
|
|
227
|
+
? POSTGRES_INSERT_BATCH_SIZE
|
|
228
|
+
: SQLITE_INSERT_BATCH_SIZE;
|
|
229
|
+
for (let offset = 0; offset < snapshot.entries.length; offset += insertBatchSize) {
|
|
230
|
+
const batch = snapshot.entries.slice(offset, offset + insertBatchSize);
|
|
175
231
|
const values = batch.map(() => '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)').join(', ');
|
|
176
232
|
const args = [];
|
|
177
233
|
batch.forEach((entry, index) => args.push(input.tenantId, input.workspaceId, snapshotId, offset + index, entry.projection, entry.domain, entry.entityId, entry.sequence, entry.mutationKind, entry.entityRevision, entry.lifecycleRevision, entry.canonicalFingerprint ?? null, entry.payloadFingerprint, canonicalWorkspaceSyncJson(entry.payload), entry.occurredAt));
|
|
@@ -218,6 +274,7 @@ function readMetadata(input) {
|
|
|
218
274
|
tenantId: input.tenantId,
|
|
219
275
|
workspaceId: input.workspaceId,
|
|
220
276
|
snapshotId: input.cursor.snapshotId,
|
|
277
|
+
snapshotSequence: input.cursor.snapshotSequence,
|
|
221
278
|
coverage: input.coverage,
|
|
222
279
|
})) {
|
|
223
280
|
throw new WorkspaceSyncV3CombinedRepairSnapshotUnavailableError();
|
|
@@ -268,6 +325,7 @@ function readReusableMetadata(input) {
|
|
|
268
325
|
tenantId: input.tenantId,
|
|
269
326
|
workspaceId: input.workspaceId,
|
|
270
327
|
snapshotId: String(row.snapshot_id),
|
|
328
|
+
snapshotSequence: sequence(row.snapshot_sequence, 'Combined repair snapshot sequence'),
|
|
271
329
|
coverage: input.coverage,
|
|
272
330
|
}))
|
|
273
331
|
return null;
|
|
@@ -299,11 +357,13 @@ function mapEntry(row, coverage) {
|
|
|
299
357
|
};
|
|
300
358
|
(coverage === 'workflow'
|
|
301
359
|
? validateWorkspaceSyncV3WorkflowCoverageFeedEntry
|
|
302
|
-
: coverage === '
|
|
303
|
-
?
|
|
304
|
-
: coverage === '
|
|
305
|
-
?
|
|
306
|
-
:
|
|
360
|
+
: coverage === 'task-cover'
|
|
361
|
+
? validateWorkspaceSyncV3TaskCoverCoverageFeedEntry
|
|
362
|
+
: coverage === 'planning-order'
|
|
363
|
+
? validateWorkspaceSyncV3PlanningOrderCoverageFeedEntry
|
|
364
|
+
: coverage === 'nested'
|
|
365
|
+
? validateWorkspaceSyncV3NestedCoverageFeedEntry
|
|
366
|
+
: validateWorkspaceSyncV3CombinedFeedEntry)(entry);
|
|
307
367
|
return entry;
|
|
308
368
|
}
|
|
309
369
|
function finalizePage(input) {
|
|
@@ -362,22 +422,15 @@ export function buildWorkspaceSyncV3CombinedRepairPage(input) {
|
|
|
362
422
|
const db = input.core.getDatabaseAdapter();
|
|
363
423
|
const coverage = input.workflowCoverage
|
|
364
424
|
? 'workflow'
|
|
365
|
-
: input.
|
|
366
|
-
? '
|
|
367
|
-
: input.
|
|
368
|
-
? '
|
|
369
|
-
:
|
|
425
|
+
: input.taskCoverCoverage
|
|
426
|
+
? 'task-cover'
|
|
427
|
+
: input.planningOrderCoverage
|
|
428
|
+
? 'planning-order'
|
|
429
|
+
: input.nestedCoverage
|
|
430
|
+
? 'nested'
|
|
431
|
+
: 'combined';
|
|
370
432
|
if (input.cursor && Date.parse(input.cursor.expiresAt) <= Date.parse(now)) {
|
|
371
|
-
|
|
372
|
-
db.prepare(`DELETE FROM workspace_sync_repair_snapshot_entries
|
|
373
|
-
WHERE tenant_id = ? AND workspace_id = ? AND snapshot_id = ? AND EXISTS (
|
|
374
|
-
SELECT 1 FROM workspace_sync_repair_snapshots
|
|
375
|
-
WHERE tenant_id = ? AND workspace_id = ? AND snapshot_id = ? AND expires_at <= ?
|
|
376
|
-
)`).run(tenantId, workspaceId, input.cursor.snapshotId, tenantId, workspaceId, input.cursor.snapshotId, now);
|
|
377
|
-
db.prepare(`DELETE FROM workspace_sync_repair_snapshots
|
|
378
|
-
WHERE tenant_id = ? AND workspace_id = ? AND snapshot_id = ? AND expires_at <= ?`)
|
|
379
|
-
.run(tenantId, workspaceId, input.cursor.snapshotId, now);
|
|
380
|
-
})();
|
|
433
|
+
cleanupExpiredBestEffort(input.core, tenantId, workspaceId, now);
|
|
381
434
|
throw new WorkspaceSyncV3CombinedRepairSnapshotUnavailableError();
|
|
382
435
|
}
|
|
383
436
|
let insertedBaselineEntities = 0;
|
|
@@ -386,17 +439,17 @@ export function buildWorkspaceSyncV3CombinedRepairPage(input) {
|
|
|
386
439
|
let metadata;
|
|
387
440
|
let nextIndex;
|
|
388
441
|
if (input.cursor) {
|
|
442
|
+
cleanupExpiredBestEffort(input.core, tenantId, workspaceId, now, input.cursor.snapshotId);
|
|
389
443
|
metadata = db.transaction(() => {
|
|
390
|
-
|
|
444
|
+
return readMetadata({
|
|
391
445
|
core: input.core, tenantId, workspaceId, cursor: input.cursor, now,
|
|
392
446
|
coverage,
|
|
393
447
|
});
|
|
394
|
-
cleanupExpired(input.core, tenantId, workspaceId, now, current.snapshotId);
|
|
395
|
-
return current;
|
|
396
448
|
})();
|
|
397
449
|
nextIndex = input.cursor.nextIndex;
|
|
398
450
|
}
|
|
399
451
|
else {
|
|
452
|
+
cleanupExpiredBestEffort(input.core, tenantId, workspaceId, now);
|
|
400
453
|
const materialized = db.transaction(() => {
|
|
401
454
|
// Serialize cursorless materialization and reuse decisions with
|
|
402
455
|
// durable writers and competing repair requests.
|
|
@@ -406,7 +459,6 @@ export function buildWorkspaceSyncV3CombinedRepairPage(input) {
|
|
|
406
459
|
ON CONFLICT (tenant_id, workspace_id) DO UPDATE SET updated_at = excluded.updated_at
|
|
407
460
|
RETURNING CAST(last_sequence AS TEXT) AS last_sequence
|
|
408
461
|
`).get(tenantId, workspaceId, now);
|
|
409
|
-
cleanupExpired(input.core, tenantId, workspaceId, now);
|
|
410
462
|
const reusable = readReusableMetadata({
|
|
411
463
|
core: input.core, tenantId, workspaceId, now,
|
|
412
464
|
coverage,
|
|
@@ -414,18 +466,27 @@ export function buildWorkspaceSyncV3CombinedRepairPage(input) {
|
|
|
414
466
|
if (reusable)
|
|
415
467
|
return { metadata: reusable, reused: true,
|
|
416
468
|
insertedBaselineEntities: 0, insertedBaselineJournalRows: 0 };
|
|
469
|
+
const repairStartedAt = Date.now();
|
|
417
470
|
const prepared = coverage === 'workflow'
|
|
418
|
-
? prepareWorkspaceSyncV3WorkflowRepairSnapshot({ core: input.core, workspaceId, now
|
|
471
|
+
? prepareWorkspaceSyncV3WorkflowRepairSnapshot({ core: input.core, workspaceId, now,
|
|
472
|
+
coveredLegacyWritesFenced: input.coveredLegacyWritesFenced })
|
|
419
473
|
: coverage === 'planning-order'
|
|
420
|
-
? prepareWorkspaceSyncV3PlanningOrderRepairSnapshot({ core: input.core, workspaceId, now
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
474
|
+
? prepareWorkspaceSyncV3PlanningOrderRepairSnapshot({ core: input.core, workspaceId, now,
|
|
475
|
+
coveredLegacyWritesFenced: input.coveredLegacyWritesFenced })
|
|
476
|
+
: coverage === 'task-cover'
|
|
477
|
+
? prepareWorkspaceSyncV3TaskCoverRepairSnapshot({ core: input.core, workspaceId, now,
|
|
478
|
+
coveredLegacyWritesFenced: input.coveredLegacyWritesFenced })
|
|
479
|
+
: coverage === 'nested'
|
|
480
|
+
? prepareWorkspaceSyncV3NestedRepairSnapshot({ core: input.core, workspaceId, now,
|
|
481
|
+
coveredLegacyWritesFenced: input.coveredLegacyWritesFenced })
|
|
482
|
+
: prepareWorkspaceSyncV3CombinedRepairSnapshot({ core: input.core, workspaceId, now,
|
|
483
|
+
coveredLegacyWritesFenced: input.coveredLegacyWritesFenced });
|
|
424
484
|
// Production expiry is sampled at the end of persistence, after
|
|
425
485
|
// every immutable payload row has committed in the same lock.
|
|
426
486
|
const materializationStartedAt = input.now
|
|
427
487
|
? now
|
|
428
488
|
: timestamp(new Date().toISOString(), 'Combined repair materialization start time');
|
|
489
|
+
const persistenceStartedAt = Date.now();
|
|
429
490
|
const persisted = persistMaterialization({
|
|
430
491
|
core: input.core, tenantId, workspaceId, startedAt: materializationStartedAt,
|
|
431
492
|
fixedCompletionTime: input.now ? now : undefined, ttlMs,
|
|
@@ -434,6 +495,15 @@ export function buildWorkspaceSyncV3CombinedRepairPage(input) {
|
|
|
434
495
|
insertedBaselineJournalRows: prepared.insertedJournalRows,
|
|
435
496
|
coverage,
|
|
436
497
|
});
|
|
498
|
+
console.info('[Taskforce Sync Repair Timing]', JSON.stringify({
|
|
499
|
+
workspaceId,
|
|
500
|
+
coverage,
|
|
501
|
+
entries: prepared.snapshot.entries.length,
|
|
502
|
+
insertedBaselineEntities: prepared.insertedEntities,
|
|
503
|
+
insertedBaselineJournalRows: prepared.insertedJournalRows,
|
|
504
|
+
persistence: Date.now() - persistenceStartedAt,
|
|
505
|
+
endToEnd: Date.now() - repairStartedAt,
|
|
506
|
+
}));
|
|
437
507
|
return { metadata: persisted, reused: false,
|
|
438
508
|
insertedBaselineEntities: prepared.insertedEntities,
|
|
439
509
|
insertedBaselineJournalRows: prepared.insertedJournalRows };
|
|
@@ -503,3 +573,6 @@ export function buildWorkspaceSyncV3WorkflowRepairPage(input) {
|
|
|
503
573
|
export function buildWorkspaceSyncV3PlanningOrderRepairPage(input) {
|
|
504
574
|
return buildWorkspaceSyncV3CombinedRepairPage({ ...input, planningOrderCoverage: true });
|
|
505
575
|
}
|
|
576
|
+
export function buildWorkspaceSyncV3TaskCoverRepairPage(input) {
|
|
577
|
+
return buildWorkspaceSyncV3CombinedRepairPage({ ...input, taskCoverCoverage: true });
|
|
578
|
+
}
|
|
@@ -31,6 +31,8 @@ export declare class WorkspaceSyncV3CombinedRepairBaselineRequiredError extends
|
|
|
31
31
|
export declare function listWorkspaceSyncV3CombinedRepairCandidates(core: TaskforceCore, workspaceId: string): WorkspaceSyncV3CombinedRepairCandidate[];
|
|
32
32
|
/** Candidate v4 inventory. The coverage-v3 inventory above intentionally remains unchanged. */
|
|
33
33
|
export declare function listWorkspaceSyncV3NestedRepairCandidates(core: TaskforceCore, workspaceId: string): WorkspaceSyncV3CombinedRepairCandidate[];
|
|
34
|
+
/** Candidate v7 inventory. It is the v4 family with attachment-link schema v2. */
|
|
35
|
+
export declare function listWorkspaceSyncV3TaskCoverRepairCandidates(core: TaskforceCore, workspaceId: string): WorkspaceSyncV3CombinedRepairCandidate[];
|
|
34
36
|
/** Candidate v5 inventory. Coverage-v3/v4 inventories intentionally remain unchanged. */
|
|
35
37
|
export declare function listWorkspaceSyncV3WorkflowRepairCandidates(core: TaskforceCore, workspaceId: string): WorkspaceSyncV3CombinedRepairCandidate[];
|
|
36
38
|
/** Candidate v6 inventory. Workflow v5 remains an independent dark contract. */
|
|
@@ -50,6 +52,7 @@ export declare function buildWorkspaceSyncV3CombinedRepairSnapshotFromLockedCand
|
|
|
50
52
|
nestedCoverage?: boolean;
|
|
51
53
|
workflowCoverage?: boolean;
|
|
52
54
|
planningOrderCoverage?: boolean;
|
|
55
|
+
taskCoverCoverage?: boolean;
|
|
53
56
|
}): {
|
|
54
57
|
snapshotSequence: string;
|
|
55
58
|
entries: WorkspaceSyncV3FeedEntry[];
|
|
@@ -75,4 +78,11 @@ export declare function buildWorkspaceSyncV3PlanningOrderRepairSnapshot(input: {
|
|
|
75
78
|
snapshotSequence: string;
|
|
76
79
|
entries: WorkspaceSyncV3FeedEntry[];
|
|
77
80
|
};
|
|
81
|
+
export declare function buildWorkspaceSyncV3TaskCoverRepairSnapshot(input: {
|
|
82
|
+
core: TaskforceCore;
|
|
83
|
+
workspaceId: string;
|
|
84
|
+
}): {
|
|
85
|
+
snapshotSequence: string;
|
|
86
|
+
entries: WorkspaceSyncV3FeedEntry[];
|
|
87
|
+
};
|
|
78
88
|
export {};
|
|
@@ -8,18 +8,19 @@ import { serializeTaskRootForSync, projectWorkspaceSyncV3TaskRootJournalRow } fr
|
|
|
8
8
|
import { projectWorkspaceSyncV3TaxonomyJournalRow } from './workspaceSyncV3TaxonomyFeedProjection.js';
|
|
9
9
|
import { projectWorkspaceSyncV3WorkstreamJournalRow } from './workspaceSyncV3WorkstreamProjection.js';
|
|
10
10
|
import { buildWorkspaceSyncV3NestedTaskRepairCandidates, } from './workspaceSyncV3NestedTaskRepairSnapshot.js';
|
|
11
|
-
import { projectWorkspaceSyncV3NestedTaskJournalRow } from './workspaceSyncV3NestedTaskProjection.js';
|
|
11
|
+
import { projectWorkspaceSyncV3NestedTaskJournalRow, projectWorkspaceSyncV3NestedTaskV2JournalRow, } from './workspaceSyncV3NestedTaskProjection.js';
|
|
12
12
|
import { validateWorkspaceSyncV3NestedCoverageFeedEntry, WORKSPACE_SYNC_V3_NESTED_COVERAGE_PROFILE, } from './workspaceSyncV3NestedCoverage.js';
|
|
13
13
|
import { serializeWorkflowExecutionEventSyncPayload, serializeWorkflowExecutionRootSyncPayload, serializeWorkflowPublishedDefinitionSyncPayload, } from './workflowRuntimeSync.js';
|
|
14
14
|
import { projectWorkspaceSyncV3WorkflowRuntimeJournalRow, } from './workspaceSyncV3WorkflowRuntimeProjection.js';
|
|
15
15
|
import { validateWorkspaceSyncV3WorkflowCoverageFeedEntry, WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_PROFILE, } from './workspaceSyncV3WorkflowCoverage.js';
|
|
16
16
|
import { validateWorkspaceSyncV3PlanningOrderCoverageFeedEntry, WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_PROFILE, } from './workspaceSyncV3PlanningOrderCoverage.js';
|
|
17
|
+
import { validateWorkspaceSyncV3TaskCoverCoverageFeedEntry, WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_PROFILE, } from './workspaceSyncV3TaskCoverCoverage.js';
|
|
17
18
|
import { projectWorkspaceSyncV3WorkstreamTaskOrderJournalRow } from './workspaceSyncV3WorkstreamTaskOrderProjection.js';
|
|
18
19
|
import { serializeWorkstreamTaskOrderForSync } from './workstreamTaskOrderSync.js';
|
|
19
20
|
import { serializeTaxonomyStateForSync } from './taxonomySyncPayload.js';
|
|
20
21
|
import { fingerprintWorkspaceSyncPayload, WORKSPACE_SYNC_CONTRACT_VERSION } from './syncDurabilityStore.js';
|
|
22
|
+
import { workspaceSyncV3RepairEntityReadBatchSize } from './workspaceSyncV3RepairSqlBatching.js';
|
|
21
23
|
const READ_PAGE_SIZE = 1000;
|
|
22
|
-
const SQL_BATCH_SIZE = 400;
|
|
23
24
|
const COMBINED_PROJECTION_RANK = new Map(WORKSPACE_SYNC_V3_COMBINED_COVERAGE_PROFILE.projections
|
|
24
25
|
.map((projection, index) => [projection.projectionId, index]));
|
|
25
26
|
const NESTED_PROJECTION_RANK = new Map(WORKSPACE_SYNC_V3_NESTED_COVERAGE_PROFILE.projections
|
|
@@ -28,6 +29,8 @@ const WORKFLOW_PROJECTION_RANK = new Map(WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_PRO
|
|
|
28
29
|
.map((projection, index) => [projection.projectionId, index]));
|
|
29
30
|
const PLANNING_ORDER_PROJECTION_RANK = new Map(WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_PROFILE.projections
|
|
30
31
|
.map((projection, index) => [projection.projectionId, index]));
|
|
32
|
+
const TASK_COVER_PROJECTION_RANK = new Map(WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_PROFILE.projections
|
|
33
|
+
.map((projection, index) => [projection.projectionId, index]));
|
|
31
34
|
export class WorkspaceSyncV3CombinedRepairBaselineRequiredError extends Error {
|
|
32
35
|
missing;
|
|
33
36
|
code = 'WORKSPACE_SYNC_V3_COMBINED_REPAIR_BASELINE_REQUIRED';
|
|
@@ -42,17 +45,22 @@ function compareCodeUnits(left, right) {
|
|
|
42
45
|
function projectionRank(entry, coverage) {
|
|
43
46
|
const ranks = coverage === 'workflow'
|
|
44
47
|
? WORKFLOW_PROJECTION_RANK
|
|
45
|
-
: coverage === '
|
|
46
|
-
?
|
|
47
|
-
: coverage === '
|
|
48
|
-
?
|
|
49
|
-
:
|
|
48
|
+
: coverage === 'task-cover'
|
|
49
|
+
? TASK_COVER_PROJECTION_RANK
|
|
50
|
+
: coverage === 'planning-order'
|
|
51
|
+
? PLANNING_ORDER_PROJECTION_RANK
|
|
52
|
+
: coverage === 'nested'
|
|
53
|
+
? NESTED_PROJECTION_RANK
|
|
54
|
+
: COMBINED_PROJECTION_RANK;
|
|
50
55
|
const rank = ranks.get(entry.projection);
|
|
51
56
|
if (rank === undefined)
|
|
52
57
|
throw new Error(`Unsupported combined repair projection: ${entry.projection}.`);
|
|
53
58
|
return rank;
|
|
54
59
|
}
|
|
55
60
|
function listTasks(core, workspaceId) {
|
|
61
|
+
if (typeof core.listTasksForAuthoritativeRepair === 'function') {
|
|
62
|
+
return core.listTasksForAuthoritativeRepair(workspaceId);
|
|
63
|
+
}
|
|
56
64
|
const result = [];
|
|
57
65
|
let cursor = null;
|
|
58
66
|
for (;;) {
|
|
@@ -148,20 +156,28 @@ function listLiveEvents(core, workspaceId, liveEntityIds) {
|
|
|
148
156
|
cursor = { watermark: last.createdAt, id: eventCursorId(last) };
|
|
149
157
|
}
|
|
150
158
|
}
|
|
151
|
-
|
|
152
|
-
|
|
159
|
+
function listNestedRepairCandidates(core, workspaceId, attachmentProjection) {
|
|
160
|
+
const startedAt = Date.now();
|
|
153
161
|
const tasks = listTasks(core, workspaceId);
|
|
162
|
+
const tasksCompletedAt = Date.now();
|
|
154
163
|
const relationships = listRelationships(core, workspaceId);
|
|
164
|
+
const relationshipsCompletedAt = Date.now();
|
|
155
165
|
const initiatives = listInitiatives(core, workspaceId);
|
|
166
|
+
const initiativesCompletedAt = Date.now();
|
|
156
167
|
const workstreams = listWorkstreams(core, workspaceId);
|
|
168
|
+
const workstreamsCompletedAt = Date.now();
|
|
157
169
|
const taxonomy = serializeTaxonomyStateForSync(core.getTaxonomyState(workspaceId));
|
|
170
|
+
const taxonomyCompletedAt = Date.now();
|
|
158
171
|
const liveEntityIds = new Set([
|
|
159
172
|
...tasks.map((task) => `task\0${task.id}`),
|
|
160
173
|
...initiatives.map((candidate) => `initiative\0${candidate.entityId}`),
|
|
161
174
|
...workstreams.map((candidate) => `workstream\0${candidate.entityId}`),
|
|
162
175
|
]);
|
|
163
176
|
const attachmentLinksByTaskId = core.listWorkspaceTaskAttachmentLinksForDurableSync(new Set(tasks.map((task) => task.id)), workspaceId);
|
|
164
|
-
|
|
177
|
+
const attachmentLinksCompletedAt = Date.now();
|
|
178
|
+
const events = listLiveEvents(core, workspaceId, liveEntityIds);
|
|
179
|
+
const eventsCompletedAt = Date.now();
|
|
180
|
+
const candidates = [
|
|
165
181
|
...tasks.map((task) => ({
|
|
166
182
|
domain: 'task', entityId: task.id, payload: serializeTaskRootForSync(task),
|
|
167
183
|
})),
|
|
@@ -171,10 +187,41 @@ export function listWorkspaceSyncV3NestedRepairCandidates(core, workspaceId) {
|
|
|
171
187
|
...workstreams,
|
|
172
188
|
...buildWorkspaceSyncV3NestedTaskRepairCandidates({
|
|
173
189
|
tasks,
|
|
174
|
-
events
|
|
190
|
+
events,
|
|
175
191
|
attachmentLinksByTaskId,
|
|
192
|
+
attachmentProjection,
|
|
176
193
|
}),
|
|
177
194
|
];
|
|
195
|
+
const completedAt = Date.now();
|
|
196
|
+
if (completedAt - startedAt >= 1_000) {
|
|
197
|
+
console.info('[Taskforce Sync Repair Inventory Timing]', JSON.stringify({
|
|
198
|
+
workspaceId,
|
|
199
|
+
tasks: tasks.length,
|
|
200
|
+
relationships: relationships.length,
|
|
201
|
+
initiatives: initiatives.length,
|
|
202
|
+
workstreams: workstreams.length,
|
|
203
|
+
events: events.length,
|
|
204
|
+
candidates: candidates.length,
|
|
205
|
+
listTasks: tasksCompletedAt - startedAt,
|
|
206
|
+
listRelationships: relationshipsCompletedAt - tasksCompletedAt,
|
|
207
|
+
listInitiatives: initiativesCompletedAt - relationshipsCompletedAt,
|
|
208
|
+
listWorkstreams: workstreamsCompletedAt - initiativesCompletedAt,
|
|
209
|
+
taxonomy: taxonomyCompletedAt - workstreamsCompletedAt,
|
|
210
|
+
attachmentLinks: attachmentLinksCompletedAt - taxonomyCompletedAt,
|
|
211
|
+
listEvents: eventsCompletedAt - attachmentLinksCompletedAt,
|
|
212
|
+
serializeCandidates: completedAt - eventsCompletedAt,
|
|
213
|
+
total: completedAt - startedAt,
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
216
|
+
return candidates;
|
|
217
|
+
}
|
|
218
|
+
/** Candidate v4 inventory. The coverage-v3 inventory above intentionally remains unchanged. */
|
|
219
|
+
export function listWorkspaceSyncV3NestedRepairCandidates(core, workspaceId) {
|
|
220
|
+
return listNestedRepairCandidates(core, workspaceId, 'task-attachment-links/full-v1');
|
|
221
|
+
}
|
|
222
|
+
/** Candidate v7 inventory. It is the v4 family with attachment-link schema v2. */
|
|
223
|
+
export function listWorkspaceSyncV3TaskCoverRepairCandidates(core, workspaceId) {
|
|
224
|
+
return listNestedRepairCandidates(core, workspaceId, 'task-attachment-links/full-v2');
|
|
178
225
|
}
|
|
179
226
|
/** Candidate v5 inventory. Coverage-v3/v4 inventories intentionally remain unchanged. */
|
|
180
227
|
export function listWorkspaceSyncV3WorkflowRepairCandidates(core, workspaceId) {
|
|
@@ -258,10 +305,11 @@ function journalRow(row) {
|
|
|
258
305
|
}
|
|
259
306
|
function readLastRows(db, tenantId, workspaceId, inventory) {
|
|
260
307
|
const result = new Map();
|
|
308
|
+
const batchSize = workspaceSyncV3RepairEntityReadBatchSize(db);
|
|
261
309
|
for (const domain of [...new Set(inventory.map((candidate) => candidate.domain))]) {
|
|
262
310
|
const ids = inventory.filter((candidate) => candidate.domain === domain).map((candidate) => candidate.entityId);
|
|
263
|
-
for (let offset = 0; offset < ids.length; offset +=
|
|
264
|
-
const batch = ids.slice(offset, offset +
|
|
311
|
+
for (let offset = 0; offset < ids.length; offset += batchSize) {
|
|
312
|
+
const batch = ids.slice(offset, offset + batchSize);
|
|
265
313
|
const placeholders = batch.map(() => '?').join(', ');
|
|
266
314
|
const rows = db.prepare(`
|
|
267
315
|
SELECT journal.*
|
|
@@ -284,8 +332,9 @@ function readLastRows(db, tenantId, workspaceId, inventory) {
|
|
|
284
332
|
}
|
|
285
333
|
function readTaskFullProvenanceRows(input) {
|
|
286
334
|
const result = new Map();
|
|
287
|
-
|
|
288
|
-
|
|
335
|
+
const batchSize = workspaceSyncV3RepairEntityReadBatchSize(input.db);
|
|
336
|
+
for (let offset = 0; offset < input.taskIds.length; offset += batchSize) {
|
|
337
|
+
const batch = input.taskIds.slice(offset, offset + batchSize);
|
|
289
338
|
const placeholders = batch.map(() => '?').join(', ');
|
|
290
339
|
const rows = input.db.prepare(`
|
|
291
340
|
SELECT journal.*
|
|
@@ -344,7 +393,7 @@ function taskEntry(candidate, row, priorFullRow) {
|
|
|
344
393
|
return { ...projected, mutationKind, payload: candidate.payload,
|
|
345
394
|
payloadFingerprint: fingerprintWorkspaceSyncPayload(candidate.payload) };
|
|
346
395
|
}
|
|
347
|
-
function entry(candidate, row, taskFullProvenance) {
|
|
396
|
+
function entry(candidate, row, taskFullProvenance, taskCoverCoverage = false) {
|
|
348
397
|
if (candidate.domain === 'workstream-task-order') {
|
|
349
398
|
const projected = projectWorkspaceSyncV3WorkstreamTaskOrderJournalRow(row);
|
|
350
399
|
if (!projected
|
|
@@ -365,7 +414,9 @@ function entry(candidate, row, taskFullProvenance) {
|
|
|
365
414
|
}
|
|
366
415
|
if (candidate.domain === 'task-comments' || candidate.domain === 'task-checklist'
|
|
367
416
|
|| candidate.domain === 'task-attachment-links' || candidate.domain === 'entity-event') {
|
|
368
|
-
const projected =
|
|
417
|
+
const projected = taskCoverCoverage && candidate.domain === 'task-attachment-links'
|
|
418
|
+
? projectWorkspaceSyncV3NestedTaskV2JournalRow(row)
|
|
419
|
+
: projectWorkspaceSyncV3NestedTaskJournalRow(row);
|
|
369
420
|
if (!projected) {
|
|
370
421
|
throw new Error(`${candidate.domain} repair revision does not match canonical state: ${candidate.entityId}.`);
|
|
371
422
|
}
|
|
@@ -427,7 +478,9 @@ export function buildWorkspaceSyncV3CombinedRepairSnapshotFromLockedCandidates(i
|
|
|
427
478
|
const tenantId = input.core.getTenantId();
|
|
428
479
|
const db = input.core.getDatabaseAdapter();
|
|
429
480
|
const inventory = input.inventory;
|
|
481
|
+
const startedAt = Date.now();
|
|
430
482
|
const rows = readLastRows(db, tenantId, workspaceId, inventory);
|
|
483
|
+
const rowsCompletedAt = Date.now();
|
|
431
484
|
const missing = inventory.filter((candidate) => !rows.has(`${candidate.domain}\0${candidate.entityId}`))
|
|
432
485
|
.map((candidate) => ({ domain: candidate.domain, entityId: candidate.entityId }));
|
|
433
486
|
if (missing.length > 0)
|
|
@@ -436,27 +489,48 @@ export function buildWorkspaceSyncV3CombinedRepairSnapshotFromLockedCandidates(i
|
|
|
436
489
|
.filter((candidate) => rows.get(`task\0${candidate.entityId}`)?.mutationKind === 'taxonomy-remap')
|
|
437
490
|
.map((candidate) => candidate.entityId);
|
|
438
491
|
const taskFullProvenance = readTaskFullProvenanceRows({ db, tenantId, workspaceId, taskIds: remappedTaskIds });
|
|
439
|
-
const
|
|
492
|
+
const provenanceCompletedAt = Date.now();
|
|
493
|
+
const entries = inventory.map((candidate) => entry(candidate, rows.get(`${candidate.domain}\0${candidate.entityId}`), taskFullProvenance, input.taskCoverCoverage === true));
|
|
494
|
+
const entriesCompletedAt = Date.now();
|
|
440
495
|
const coverage = input.workflowCoverage
|
|
441
496
|
? 'workflow'
|
|
442
|
-
: input.
|
|
443
|
-
? '
|
|
444
|
-
: input.
|
|
445
|
-
? '
|
|
446
|
-
:
|
|
497
|
+
: input.taskCoverCoverage
|
|
498
|
+
? 'task-cover'
|
|
499
|
+
: input.planningOrderCoverage
|
|
500
|
+
? 'planning-order'
|
|
501
|
+
: input.nestedCoverage
|
|
502
|
+
? 'nested'
|
|
503
|
+
: 'combined';
|
|
447
504
|
entries.forEach(coverage === 'workflow'
|
|
448
505
|
? validateWorkspaceSyncV3WorkflowCoverageFeedEntry
|
|
449
|
-
: coverage === '
|
|
450
|
-
?
|
|
451
|
-
: coverage === '
|
|
452
|
-
?
|
|
453
|
-
:
|
|
506
|
+
: coverage === 'task-cover'
|
|
507
|
+
? validateWorkspaceSyncV3TaskCoverCoverageFeedEntry
|
|
508
|
+
: coverage === 'planning-order'
|
|
509
|
+
? validateWorkspaceSyncV3PlanningOrderCoverageFeedEntry
|
|
510
|
+
: coverage === 'nested'
|
|
511
|
+
? validateWorkspaceSyncV3NestedCoverageFeedEntry
|
|
512
|
+
: validateWorkspaceSyncV3CombinedFeedEntry);
|
|
513
|
+
const validationCompletedAt = Date.now();
|
|
454
514
|
if (entries.some((candidate) => BigInt(candidate.sequence) > BigInt(snapshotSequence))) {
|
|
455
515
|
throw new Error('Combined repair entry exceeds the locked snapshot sequence.');
|
|
456
516
|
}
|
|
457
517
|
entries.sort((left, right) => (projectionRank(left, coverage)
|
|
458
518
|
- projectionRank(right, coverage))
|
|
459
519
|
|| compareCodeUnits(left.entityId, right.entityId));
|
|
520
|
+
const completedAt = Date.now();
|
|
521
|
+
if (completedAt - startedAt >= 1_000) {
|
|
522
|
+
console.info('[Taskforce Sync Repair Snapshot Timing]', JSON.stringify({
|
|
523
|
+
workspaceId,
|
|
524
|
+
coverage,
|
|
525
|
+
entries: entries.length,
|
|
526
|
+
readRows: rowsCompletedAt - startedAt,
|
|
527
|
+
readProvenance: provenanceCompletedAt - rowsCompletedAt,
|
|
528
|
+
projectEntries: entriesCompletedAt - provenanceCompletedAt,
|
|
529
|
+
validateEntries: validationCompletedAt - entriesCompletedAt,
|
|
530
|
+
sortEntries: completedAt - validationCompletedAt,
|
|
531
|
+
total: completedAt - startedAt,
|
|
532
|
+
}));
|
|
533
|
+
}
|
|
460
534
|
return { snapshotSequence: BigInt(snapshotSequence).toString(10), entries };
|
|
461
535
|
}
|
|
462
536
|
export function buildWorkspaceSyncV3NestedRepairSnapshot(input) {
|
|
@@ -509,3 +583,21 @@ export function buildWorkspaceSyncV3PlanningOrderRepairSnapshot(input) {
|
|
|
509
583
|
});
|
|
510
584
|
})();
|
|
511
585
|
}
|
|
586
|
+
export function buildWorkspaceSyncV3TaskCoverRepairSnapshot(input) {
|
|
587
|
+
const workspaceId = String(input.workspaceId || '').trim();
|
|
588
|
+
if (!workspaceId)
|
|
589
|
+
throw new Error('Workspace id is required.');
|
|
590
|
+
const tenantId = input.core.getTenantId();
|
|
591
|
+
const db = input.core.getDatabaseAdapter();
|
|
592
|
+
return db.transaction(() => {
|
|
593
|
+
const snapshotSequence = lockAndReadHighWatermark(db, tenantId, workspaceId);
|
|
594
|
+
const inventory = listWorkspaceSyncV3TaskCoverRepairCandidates(input.core, workspaceId);
|
|
595
|
+
return buildWorkspaceSyncV3CombinedRepairSnapshotFromLockedCandidates({
|
|
596
|
+
core: input.core,
|
|
597
|
+
workspaceId,
|
|
598
|
+
snapshotSequence,
|
|
599
|
+
inventory,
|
|
600
|
+
taskCoverCoverage: true,
|
|
601
|
+
});
|
|
602
|
+
})();
|
|
603
|
+
}
|
|
@@ -2,6 +2,7 @@ import type { WorkspaceSyncV2ProjectionExclusion } from './workspaceSyncV2Projec
|
|
|
2
2
|
import { WORKSPACE_SYNC_V3_NESTED_COVERAGE_SELECTOR } from './workspaceSyncV3NestedWireContract.js';
|
|
3
3
|
import { WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR } from './workspaceSyncV3WorkflowWireContract.js';
|
|
4
4
|
import { WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_SELECTOR } from './workspaceSyncV3PlanningOrderWireContract.js';
|
|
5
|
+
import { WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR } from './workspaceSyncV3TaskCoverWireContract.js';
|
|
5
6
|
export declare const WORKSPACE_SYNC_V3_COMBINED_COVERAGE_SELECTOR: Readonly<{
|
|
6
7
|
coverageProfileId: "task-planning-metadata";
|
|
7
8
|
coverageVersion: 3;
|
|
@@ -9,13 +10,14 @@ export declare const WORKSPACE_SYNC_V3_COMBINED_COVERAGE_SELECTOR: Readonly<{
|
|
|
9
10
|
}>;
|
|
10
11
|
export declare const WORKSPACE_SYNC_V3_COMBINED_CAPABILITY_VERSION: 1;
|
|
11
12
|
export declare const WORKSPACE_SYNC_V3_COMBINED_EXCLUDED_V2_PROJECTIONS: readonly ["task/root-v1", "task-relationship/full-v1", "taxonomy/full-v1", "initiative/full-v1", "workstream/full-v1"];
|
|
12
|
-
export type WorkspaceSyncV3CombinedCoverageSelector = typeof WORKSPACE_SYNC_V3_COMBINED_COVERAGE_SELECTOR | typeof WORKSPACE_SYNC_V3_NESTED_COVERAGE_SELECTOR | typeof WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR | typeof WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_SELECTOR;
|
|
13
|
+
export type WorkspaceSyncV3CombinedCoverageSelector = typeof WORKSPACE_SYNC_V3_COMBINED_COVERAGE_SELECTOR | typeof WORKSPACE_SYNC_V3_NESTED_COVERAGE_SELECTOR | typeof WORKSPACE_SYNC_V3_WORKFLOW_COVERAGE_SELECTOR | typeof WORKSPACE_SYNC_V3_PLANNING_ORDER_COVERAGE_SELECTOR | typeof WORKSPACE_SYNC_V3_TASK_COVER_COVERAGE_SELECTOR;
|
|
13
14
|
export interface WorkspaceSyncV3CombinedWireContract {
|
|
14
15
|
coverage: WorkspaceSyncV3CombinedCoverageSelector;
|
|
15
16
|
excludedProjections: readonly WorkspaceSyncV2ProjectionExclusion[];
|
|
16
17
|
nestedWriterPrerequisitesRequired: boolean;
|
|
17
18
|
workflowWriterPrerequisitesRequired: boolean;
|
|
18
19
|
planningOrderWriterPrerequisitesRequired: boolean;
|
|
20
|
+
taskCoverProjectionRequired: boolean;
|
|
19
21
|
}
|
|
20
22
|
export declare function resolveWorkspaceSyncV3CombinedWireContract(input: {
|
|
21
23
|
coverageProfileId: unknown;
|