@taskforcehq/taskforce 0.3.306 → 0.3.307
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 +0 -2
- package/dist/Taskforce.module.css +317 -27
- package/dist/TaskforceCore.js +1 -0
- package/dist/TaskforceCore.test.js +178 -0
- package/dist/components/activity/EntityActivityTimeline.d.ts +34 -0
- package/dist/components/activity/EntityActivityTimeline.js +81 -0
- package/dist/components/context/ContextAttachmentManager.js +15 -3
- package/dist/components/features/AgentsModule.d.ts +5 -1
- package/dist/components/features/AgentsModule.js +142 -39
- package/dist/components/features/AgentsModule.test.js +260 -11
- package/dist/components/features/AnnotatedAttachmentWorkspace.d.ts +3 -1
- package/dist/components/features/AnnotatedAttachmentWorkspace.js +118 -4
- package/dist/components/features/AnnotatedAttachmentWorkspace.test.js +52 -0
- package/dist/components/features/DocumentIndex.d.ts +2 -2
- package/dist/components/features/DocumentIndex.js +3 -4
- package/dist/components/features/DocumentViewer.d.ts +3 -1
- package/dist/components/features/DocumentViewer.js +6 -5
- package/dist/components/features/DocumentWorkspace.d.ts +10 -2
- package/dist/components/features/DocumentWorkspace.js +15 -4
- package/dist/components/features/DocumentWorkspace.test.js +20 -3
- package/dist/components/features/TaskSettings.d.ts +2 -0
- package/dist/components/features/TaskSettings.js +83 -78
- package/dist/components/features/TaskSettings.test.js +171 -82
- package/dist/components/task/TaskActionHeader.js +11 -5
- package/dist/components/task/TaskActionHeader.test.js +10 -0
- package/dist/components/task/TaskCard.js +6 -2
- package/dist/components/task/TaskContextUpload.test.js +3 -3
- package/dist/components/task/TaskForm.js +14 -64
- package/dist/components/task/TaskKanban.js +0 -8
- package/dist/components/task/TaskList.js +5 -1
- package/dist/components/task/TaskList.test.js +4 -0
- package/dist/components/ui/HierarchyActionBadge.d.ts +10 -0
- package/dist/components/ui/HierarchyActionBadge.js +5 -0
- package/dist/components/views/AppShellHeader.d.ts +3 -1
- package/dist/components/views/AppShellHeader.js +27 -11
- package/dist/components/views/AppShellHeader.test.js +18 -1
- package/dist/components/views/PlanComparisonPage.js +9 -1
- package/dist/components/views/PlanComparisonPage.test.js +19 -0
- package/dist/components/views/PlansPage.js +1 -1
- package/dist/components/views/StandaloneLayout.js +256 -69
- package/dist/components/views/WidgetView.js +10 -8
- package/dist/components/views/panels/PlanningDrawer.d.ts +19 -6
- package/dist/components/views/panels/PlanningDrawer.js +259 -51
- package/dist/components/views/panels/PlanningDrawer.test.js +392 -4
- package/dist/config/envSchema.js +1 -0
- package/dist/core/AiProfileService.d.ts +7 -0
- package/dist/core/AiProfileService.js +460 -35
- package/dist/core/AiProfiles.test.js +648 -2
- package/dist/core/AttachmentLinkService.d.ts +3 -0
- package/dist/core/AttachmentLinkService.js +58 -13
- package/dist/core/GlobalSettingsService.js +12 -0
- package/dist/core/McpTokenService.d.ts +12 -0
- package/dist/core/McpTokenService.js +44 -1
- package/dist/core/PlanningEntities.test.js +366 -4
- package/dist/core/TaskActivityService.d.ts +28 -1
- package/dist/core/TaskActivityService.js +227 -46
- package/dist/core/TaskActivitySync.test.d.ts +1 -0
- package/dist/core/TaskActivitySync.test.js +90 -0
- package/dist/core/TaskAuditTimeline.test.js +96 -0
- package/dist/core/Taskforce.d.ts +190 -26
- package/dist/core/Taskforce.ids.test.js +58 -0
- package/dist/core/Taskforce.js +775 -71
- package/dist/core/Taskforce.mcpAuth.test.js +109 -0
- package/dist/core/types.d.ts +7 -0
- package/dist/hooks/auth/useTaskforceAuthBootstrap.js +2 -1
- package/dist/hooks/bootstrapTimeouts.d.ts +4 -0
- package/dist/hooks/bootstrapTimeouts.js +8 -0
- package/dist/hooks/bootstrapTimeouts.test.d.ts +1 -0
- package/dist/hooks/bootstrapTimeouts.test.js +12 -0
- package/dist/hooks/sync/orchestratorShared.d.ts +3 -3
- package/dist/hooks/sync/orchestratorShared.js +61 -1
- package/dist/hooks/sync/recovery.js +8 -0
- package/dist/hooks/sync/recovery.test.js +5 -5
- package/dist/hooks/sync/transfers.d.ts +2 -1
- package/dist/hooks/sync/transfers.js +36 -9
- package/dist/hooks/sync/transfers.test.js +534 -2
- package/dist/hooks/useFilterSort.js +13 -13
- package/dist/hooks/useFilterSort.test.js +87 -1
- package/dist/hooks/useSyncOrchestrator.js +50 -5
- package/dist/hooks/useTaskforce.d.ts +85 -50
- package/dist/hooks/useTaskforce.js +44 -14
- package/dist/hooks/useTaskforce.runtime-routing.test.js +94 -0
- package/dist/hooks/useTaskforce.sync-behavior.test.js +99 -0
- package/dist/hooks/useWorkspaceSyncController.js +7 -1
- package/dist/hooks/useWorkspaceSyncController.test.js +48 -0
- package/dist/hooks/workspace/useTaskforceWorkspaceBootstrap.js +14 -7
- package/dist/mcp/canonicalAssetHelpers.d.ts +16 -4
- package/dist/mcp/canonicalAssetHelpers.js +18 -10
- package/dist/mcp/canonicalAssetHelpers.test.d.ts +1 -0
- package/dist/mcp/canonicalAssetHelpers.test.js +67 -0
- package/dist/mcp/clientIntegrations.d.ts +1 -0
- package/dist/mcp/clientIntegrations.js +25 -0
- package/dist/mcp/clientIntegrations.test.js +14 -3
- package/dist/mcp/clientProfileDefaults.js +3 -3
- package/dist/mcp/collaborationRegistrar.js +7 -7
- package/dist/mcp/documentAssetRegistrar.js +113 -7
- package/dist/mcp/runtime.d.ts +1 -0
- package/dist/mcp/runtime.js +969 -122
- package/dist/mcp/runtime.test.js +1083 -11
- package/dist/mcp/taskAttachmentTypes.d.ts +1 -1
- package/dist/mcp/taskPlanningRegistrar.js +48 -0
- package/dist/mcp/toolRegistry.d.ts +56 -0
- package/dist/mcp/toolRegistry.js +8 -0
- package/dist/mcp/toolRegistry.test.js +4 -0
- package/dist/migrations/taskSchemaMigrations.js +21 -0
- package/dist/server/aiProfileAvatarAssets.d.ts +49 -0
- package/dist/server/aiProfileAvatarAssets.js +319 -0
- package/dist/server/aiProfileAvatarAssets.test.d.ts +1 -0
- package/dist/server/aiProfileAvatarAssets.test.js +213 -0
- package/dist/server/annotatedAttachmentsRoutes.test.js +66 -7
- package/dist/server/index.js +4 -0
- package/dist/server/index.test.js +6 -1
- package/dist/server/routes/admin.js +187 -9
- package/dist/server/routes/annotatedAttachments.js +51 -0
- package/dist/server/routes/auth.d.ts +11 -0
- package/dist/server/routes/auth.js +189 -27
- package/dist/server/routes/authSupport.d.ts +4 -0
- package/dist/server/routes/authSupport.js +12 -1
- package/dist/server/routes/billing.js +11 -0
- package/dist/server/routes/billing.test.js +3 -0
- package/dist/server/routes/documents.js +10 -0
- package/dist/server/routes/shared.js +0 -10
- package/dist/server/routes/sync.integration.test.js +221 -0
- package/dist/server/routes/sync.js +13 -3
- package/dist/server/routes/syncSnapshotRoutes.js +2 -0
- package/dist/server/routes/tasks.js +12 -9
- package/dist/server/routes.js +87 -8
- package/dist/server/routes.test.js +890 -22
- package/dist/shared/aiProfileSurfaceType.d.ts +1 -1
- package/dist/shared/aiProfileSurfaceType.js +10 -8
- package/dist/storage/objectStorage.d.ts +1 -0
- package/dist/storage/objectStorage.js +2 -1
- package/dist/storage/objectStorageClient.d.ts +1 -0
- package/dist/storage/objectStorageClient.js +41 -8
- package/dist/storage/objectStorageClient.test.js +26 -1
- package/dist/storage/objectStorageConfig.js +3 -1
- package/dist/storage/objectStorageConfig.test.js +13 -1
- package/dist/sync/collaborationSyncPayload.js +2 -0
- package/dist/sync/collaborationSyncPayload.test.js +1 -0
- package/dist/sync/collaborationSyncState.d.ts +3 -3
- package/dist/sync/collaborationSyncState.js +19 -12
- package/dist/sync/contentSyncPayload.d.ts +5 -1
- package/dist/sync/contentSyncPayload.js +9 -0
- package/dist/sync/contentSyncPayload.test.js +39 -0
- package/dist/sync/contentSyncState.d.ts +5 -1
- package/dist/sync/contentSyncState.js +231 -37
- package/dist/sync/planningSyncPayload.js +5 -0
- package/dist/sync/planningSyncPayload.test.js +24 -0
- package/dist/sync/syncApplyHandlers.d.ts +4 -4
- package/dist/sync/syncApplyHandlers.js +89 -31
- package/dist/sync/syncApplyHandlers.test.js +184 -4
- package/dist/sync/syncResourceAdapters.d.ts +2 -0
- package/dist/sync/syncResourceAdapters.js +2 -0
- package/dist/sync/syncService.d.ts +1 -0
- package/dist/sync/syncService.js +13 -1
- package/dist/sync/syncService.test.js +39 -0
- package/dist/sync/workspacePullFeed.d.ts +4 -0
- package/dist/sync/workspacePullFeed.js +129 -70
- package/dist/sync/workspacePullFeed.test.js +49 -0
- package/dist/sync/workspaceSyncModel.d.ts +28 -6
- package/dist/sync/workspaceSyncModel.js +159 -45
- package/dist/sync/workspaceSyncModel.test.js +269 -3
- package/dist/types.d.ts +33 -2
- package/dist/ui/assets/AgentsModule-2y82_3DO.js +1 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BTLZZCiQ.js +3 -0
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BVKew-mH.css +1 -0
- package/dist/ui/assets/ContextAttachmentManager-D2epuNnG.js +3 -0
- package/dist/ui/assets/DocumentWorkspace-D4rJKXzd.css +1 -0
- package/dist/ui/assets/DocumentWorkspace-sVa-3Do6.js +252 -0
- package/dist/ui/assets/EntityActivityTimeline-DyqvvhuF.css +1 -0
- package/dist/ui/assets/EntityActivityTimeline-Zods27y_.js +1 -0
- package/dist/ui/assets/{InitiativesModule-9E6ParrY.js → InitiativesModule-D4XseTwW.js} +1 -1
- package/dist/ui/assets/PlansPage-D5AcbO0L.js +1 -0
- package/dist/ui/assets/PlansPage-Dvqsz5zc.css +1 -0
- package/dist/ui/assets/TaskContextUpload-uC5qx4Bv.js +1 -0
- package/dist/ui/assets/TaskSettings-CqvPAsTv.js +9 -0
- package/dist/ui/assets/{WorkflowsModule-BA7jcEpH.js → WorkflowsModule-oOA9bcdK.js} +4 -4
- package/dist/ui/assets/documentReferences-DPZuTgHh.js +1 -0
- package/dist/ui/assets/index-607WPo_X.js +4 -0
- package/dist/ui/assets/index-CYyodXsg.css +1 -0
- package/dist/ui/assets/{vendor-icons-DuEd_65c.js → vendor-icons-B32hGuF2.js} +1 -1
- package/dist/ui/index.html +3 -3
- package/dist/ui/product/agent manager.png +0 -0
- package/dist/ui/product/agent_manager_02.png +0 -0
- package/dist/utils/aiProfileEvents.d.ts +7 -0
- package/dist/utils/aiProfileEvents.js +6 -0
- package/dist/utils/assignees.d.ts +6 -0
- package/dist/utils/assignees.js +8 -1
- package/dist/utils/assignees.test.d.ts +1 -0
- package/dist/utils/assignees.test.js +25 -0
- package/dist/utils/avatarDisplay.d.ts +1 -0
- package/dist/utils/avatarDisplay.js +15 -0
- package/dist/utils/contextFiles.d.ts +3 -1
- package/dist/utils/contextFiles.js +2 -1
- package/dist/utils/taskActivity.d.ts +7 -1
- package/dist/utils/taskActivity.js +63 -1
- package/dist/utils/taskActivity.test.js +23 -1
- package/dist/utils/taskSearch.d.ts +22 -0
- package/dist/utils/taskSearch.js +87 -0
- package/dist/utils/taskSearch.test.d.ts +1 -0
- package/dist/utils/taskSearch.test.js +69 -0
- package/dist/utils/taskUtils.js +10 -3
- package/dist/utils/taskUtils.test.d.ts +1 -0
- package/dist/utils/taskUtils.test.js +19 -0
- package/package.json +1 -1
- package/dist/ui/assets/AgentsModule-DrLawwNl.js +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-BaS2VwIr.css +0 -1
- package/dist/ui/assets/AnnotatedAttachmentWorkspace-Z9_whf7F.js +0 -3
- package/dist/ui/assets/DocumentWorkspace-B03MaSkw.js +0 -252
- package/dist/ui/assets/DocumentWorkspace-Dhdso07p.css +0 -1
- package/dist/ui/assets/PlansPage-CvfnMiWq.css +0 -1
- package/dist/ui/assets/PlansPage-DRXscYxH.js +0 -1
- package/dist/ui/assets/TaskSettings-DZX4jk7e.js +0 -9
- package/dist/ui/assets/index-9eT8e0Lu.css +0 -1
- package/dist/ui/assets/index-C6k75jr8.js +0 -6
|
@@ -29,6 +29,9 @@ function sortTasksForSync(tasks) {
|
|
|
29
29
|
return leftId.localeCompare(rightId);
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
+
function clonePlanningAttachmentsForSync(value) {
|
|
33
|
+
return Array.isArray(value) ? value : undefined;
|
|
34
|
+
}
|
|
32
35
|
export function buildWorkspaceSyncPayloadModel(input) {
|
|
33
36
|
const payloadBuiltAt = new Date().toISOString();
|
|
34
37
|
const pendingDeleteIds = new Set(Array.from(input.pendingDeletedTaskIds)
|
|
@@ -142,6 +145,7 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
142
145
|
createdAt: String(initiative?.createdAt || '').trim(),
|
|
143
146
|
updatedAt: String(initiative?.updatedAt || initiative?.createdAt || '').trim(),
|
|
144
147
|
order: Number.isFinite(Number(initiative?.order)) ? Math.floor(Number(initiative.order)) : null,
|
|
148
|
+
attachments: clonePlanningAttachmentsForSync(initiative?.attachments),
|
|
145
149
|
isArchived: Boolean(initiative?.isArchived)
|
|
146
150
|
}
|
|
147
151
|
}))
|
|
@@ -184,6 +188,7 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
184
188
|
createdAt: String(workstream?.createdAt || '').trim(),
|
|
185
189
|
updatedAt: String(workstream?.updatedAt || workstream?.createdAt || '').trim(),
|
|
186
190
|
order: Number.isFinite(Number(workstream?.order)) ? Math.floor(Number(workstream.order)) : null,
|
|
191
|
+
attachments: clonePlanningAttachmentsForSync(workstream?.attachments),
|
|
187
192
|
isArchived: Boolean(workstream?.isArchived)
|
|
188
193
|
}
|
|
189
194
|
}))
|
|
@@ -218,6 +223,10 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
218
223
|
color: String(profile.color || '#8b5cf6').trim() || '#8b5cf6',
|
|
219
224
|
avatarUrl: normalizeSyncSameOriginAssetUrl(profile.avatarUrl),
|
|
220
225
|
avatarSourceUrl: normalizeSyncSameOriginAssetUrl(profile.avatarSourceUrl),
|
|
226
|
+
avatarRevision: Number.isFinite(Number(profile.avatarRevision)) ? Math.max(0, Math.floor(Number(profile.avatarRevision))) : 0,
|
|
227
|
+
avatarUpdatedAt: typeof profile.avatarUpdatedAt === 'string' && profile.avatarUpdatedAt.trim().length > 0
|
|
228
|
+
? profile.avatarUpdatedAt.trim()
|
|
229
|
+
: null,
|
|
221
230
|
description: typeof profile.description === 'string' ? profile.description.trim() || null : null,
|
|
222
231
|
role: typeof profile.role === 'string' ? profile.role.trim() || null : null,
|
|
223
232
|
provider: typeof profile.provider === 'string' ? profile.provider.trim() || null : null,
|
|
@@ -277,6 +286,10 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
277
286
|
referenceNumber: Number.isFinite(Number(doc.referenceNumber)) ? Math.max(1, Math.floor(Number(doc.referenceNumber))) : null,
|
|
278
287
|
version: Number.isFinite(Number(doc.version)) ? Math.max(1, Math.floor(Number(doc.version))) : null,
|
|
279
288
|
taskId: typeof doc.taskId === 'string' && doc.taskId.trim().length > 0 ? doc.taskId.trim() : null,
|
|
289
|
+
linkTargetType: doc.linkTargetType === 'initiative' || doc.linkTargetType === 'workstream' || doc.linkTargetType === 'task'
|
|
290
|
+
? doc.linkTargetType
|
|
291
|
+
: null,
|
|
292
|
+
linkTargetId: typeof doc.linkTargetId === 'string' && doc.linkTargetId.trim().length > 0 ? doc.linkTargetId.trim() : null,
|
|
280
293
|
logicalName: typeof doc.logicalName === 'string' && doc.logicalName.trim().length > 0 ? doc.logicalName.trim() : null,
|
|
281
294
|
caption: typeof doc.caption === 'string' && doc.caption.trim().length > 0 ? doc.caption.trim() : null,
|
|
282
295
|
originalFilename: typeof doc.originalFilename === 'string' && doc.originalFilename.trim().length > 0 ? doc.originalFilename.trim() : null,
|
|
@@ -309,6 +322,10 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
309
322
|
mimeType: typeof asset.mimeType === 'string' && asset.mimeType.trim().length > 0 ? asset.mimeType.trim() : 'application/octet-stream',
|
|
310
323
|
referenceNumber: Number.isFinite(Number(asset.referenceNumber)) ? Math.max(1, Math.floor(Number(asset.referenceNumber))) : null,
|
|
311
324
|
taskId: typeof asset.taskId === 'string' && asset.taskId.trim().length > 0 ? asset.taskId.trim() : null,
|
|
325
|
+
linkTargetType: asset.linkTargetType === 'initiative' || asset.linkTargetType === 'workstream' || asset.linkTargetType === 'task'
|
|
326
|
+
? asset.linkTargetType
|
|
327
|
+
: null,
|
|
328
|
+
linkTargetId: typeof asset.linkTargetId === 'string' && asset.linkTargetId.trim().length > 0 ? asset.linkTargetId.trim() : null,
|
|
312
329
|
logicalName: typeof asset.logicalName === 'string' && asset.logicalName.trim().length > 0 ? asset.logicalName.trim() : null,
|
|
313
330
|
caption: typeof asset.caption === 'string' && asset.caption.trim().length > 0 ? asset.caption.trim() : null,
|
|
314
331
|
originalFilename: typeof asset.originalFilename === 'string' && asset.originalFilename.trim().length > 0 ? asset.originalFilename.trim() : null,
|
|
@@ -325,21 +342,19 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
325
342
|
return previousAssetWatermarks.get(asset.path) !== asset.updatedAt;
|
|
326
343
|
});
|
|
327
344
|
const reviewSessions = Array.isArray(input.documentReviewSessions) ? input.documentReviewSessions : [];
|
|
345
|
+
const allDocumentReviewSessionIds = new Set(reviewSessions
|
|
346
|
+
.map((session) => String(session?.id || '').trim())
|
|
347
|
+
.filter((sessionId) => sessionId.length > 0));
|
|
328
348
|
const currentDocumentReviewSessionIds = new Set(reviewSessions
|
|
329
349
|
.filter((session) => String(session?.deletedAt || '').trim().length === 0)
|
|
330
350
|
.map((session) => String(session?.id || '').trim())
|
|
331
351
|
.filter((sessionId) => sessionId.length > 0));
|
|
332
|
-
const
|
|
333
|
-
...Array.from(input.lastPushedDocumentReviewSessionIds || new Set())
|
|
334
|
-
.map((sessionId) => String(sessionId || '').trim())
|
|
335
|
-
.filter((sessionId) => sessionId.length > 0 && !currentDocumentReviewSessionIds.has(sessionId)),
|
|
336
|
-
...reviewSessions
|
|
337
|
-
.filter((session) => String(session?.deletedAt || '').trim().length > 0)
|
|
338
|
-
.map((session) => String(session?.id || '').trim())
|
|
339
|
-
.filter((sessionId) => sessionId.length > 0)
|
|
340
|
-
]);
|
|
352
|
+
const previousDocumentReviewSessionIds = input.lastPushedDocumentReviewSessionIds || new Set();
|
|
341
353
|
const currentDocumentReviewSessionWatermarks = new Map(reviewSessions
|
|
342
|
-
.map((session) => [
|
|
354
|
+
.map((session) => [
|
|
355
|
+
String(session?.id || '').trim(),
|
|
356
|
+
String(session?.deletedAt || session?.updatedAt || session?.createdAt || '').trim()
|
|
357
|
+
])
|
|
343
358
|
.filter(([sessionId]) => sessionId.length > 0));
|
|
344
359
|
const previousDocumentReviewSessionWatermarks = input.lastPushedDocumentReviewSessionWatermarks;
|
|
345
360
|
const shouldSendAllDocumentReviewSessions = !previousDocumentReviewSessionWatermarks || previousDocumentReviewSessionWatermarks.size === 0;
|
|
@@ -367,22 +382,46 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
367
382
|
return true;
|
|
368
383
|
return previousDocumentReviewSessionWatermarks.get(change.session.id) !== change.session.updatedAt;
|
|
369
384
|
});
|
|
385
|
+
const deletedReviewSessionChanges = reviewSessions
|
|
386
|
+
.filter((session) => String(session?.deletedAt || '').trim().length > 0)
|
|
387
|
+
.map((session) => ({
|
|
388
|
+
sessionId: String(session?.id || '').trim(),
|
|
389
|
+
deletedAt: String(session?.deletedAt || session?.updatedAt || session?.createdAt || payloadBuiltAt).trim() || payloadBuiltAt
|
|
390
|
+
}))
|
|
391
|
+
.filter((change) => change.sessionId.length > 0)
|
|
392
|
+
.filter((change) => {
|
|
393
|
+
if (shouldSendAllDocumentReviewSessions)
|
|
394
|
+
return true;
|
|
395
|
+
return previousDocumentReviewSessionWatermarks.get(change.sessionId) !== change.deletedAt;
|
|
396
|
+
});
|
|
397
|
+
const missingDocumentReviewSessionDeleteIds = Array.from(previousDocumentReviewSessionIds)
|
|
398
|
+
.map((sessionId) => String(sessionId || '').trim())
|
|
399
|
+
.filter((sessionId) => sessionId.length > 0 && !allDocumentReviewSessionIds.has(sessionId));
|
|
400
|
+
const documentReviewSessionDeleteChanges = [
|
|
401
|
+
...missingDocumentReviewSessionDeleteIds.map((sessionId) => ({
|
|
402
|
+
sessionId,
|
|
403
|
+
deletedAt: payloadBuiltAt
|
|
404
|
+
})),
|
|
405
|
+
...deletedReviewSessionChanges
|
|
406
|
+
];
|
|
407
|
+
const deleteDocumentReviewSessionIds = new Set([
|
|
408
|
+
...missingDocumentReviewSessionDeleteIds,
|
|
409
|
+
...deletedReviewSessionChanges.map((change) => change.sessionId)
|
|
410
|
+
]);
|
|
370
411
|
const reviewComments = Array.isArray(input.documentReviewComments) ? input.documentReviewComments : [];
|
|
412
|
+
const allDocumentReviewCommentIds = new Set(reviewComments
|
|
413
|
+
.map((comment) => String(comment?.id || '').trim())
|
|
414
|
+
.filter((commentId) => commentId.length > 0));
|
|
371
415
|
const currentDocumentReviewCommentIds = new Set(reviewComments
|
|
372
416
|
.filter((comment) => String(comment?.deletedAt || '').trim().length === 0)
|
|
373
417
|
.map((comment) => String(comment?.id || '').trim())
|
|
374
418
|
.filter((commentId) => commentId.length > 0));
|
|
375
|
-
const
|
|
376
|
-
...Array.from(input.lastPushedDocumentReviewCommentIds || new Set())
|
|
377
|
-
.map((commentId) => String(commentId || '').trim())
|
|
378
|
-
.filter((commentId) => commentId.length > 0 && !currentDocumentReviewCommentIds.has(commentId)),
|
|
379
|
-
...reviewComments
|
|
380
|
-
.filter((comment) => String(comment?.deletedAt || '').trim().length > 0)
|
|
381
|
-
.map((comment) => String(comment?.id || '').trim())
|
|
382
|
-
.filter((commentId) => commentId.length > 0)
|
|
383
|
-
]);
|
|
419
|
+
const previousDocumentReviewCommentIds = input.lastPushedDocumentReviewCommentIds || new Set();
|
|
384
420
|
const currentDocumentReviewCommentWatermarks = new Map(reviewComments
|
|
385
|
-
.map((comment) => [
|
|
421
|
+
.map((comment) => [
|
|
422
|
+
String(comment?.id || '').trim(),
|
|
423
|
+
String(comment?.deletedAt || comment?.updatedAt || comment?.createdAt || '').trim()
|
|
424
|
+
])
|
|
386
425
|
.filter(([commentId]) => commentId.length > 0));
|
|
387
426
|
const previousDocumentReviewCommentWatermarks = input.lastPushedDocumentReviewCommentWatermarks;
|
|
388
427
|
const shouldSendAllDocumentReviewComments = !previousDocumentReviewCommentWatermarks || previousDocumentReviewCommentWatermarks.size === 0;
|
|
@@ -407,22 +446,46 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
407
446
|
return true;
|
|
408
447
|
return previousDocumentReviewCommentWatermarks.get(change.comment.id) !== change.comment.updatedAt;
|
|
409
448
|
});
|
|
449
|
+
const deletedReviewCommentChanges = reviewComments
|
|
450
|
+
.filter((comment) => String(comment?.deletedAt || '').trim().length > 0)
|
|
451
|
+
.map((comment) => ({
|
|
452
|
+
commentId: String(comment?.id || '').trim(),
|
|
453
|
+
deletedAt: String(comment?.deletedAt || comment?.updatedAt || comment?.createdAt || payloadBuiltAt).trim() || payloadBuiltAt
|
|
454
|
+
}))
|
|
455
|
+
.filter((change) => change.commentId.length > 0)
|
|
456
|
+
.filter((change) => {
|
|
457
|
+
if (shouldSendAllDocumentReviewComments)
|
|
458
|
+
return true;
|
|
459
|
+
return previousDocumentReviewCommentWatermarks.get(change.commentId) !== change.deletedAt;
|
|
460
|
+
});
|
|
461
|
+
const missingDocumentReviewCommentDeleteIds = Array.from(previousDocumentReviewCommentIds)
|
|
462
|
+
.map((commentId) => String(commentId || '').trim())
|
|
463
|
+
.filter((commentId) => commentId.length > 0 && !allDocumentReviewCommentIds.has(commentId));
|
|
464
|
+
const documentReviewCommentDeleteChanges = [
|
|
465
|
+
...missingDocumentReviewCommentDeleteIds.map((commentId) => ({
|
|
466
|
+
commentId,
|
|
467
|
+
deletedAt: payloadBuiltAt
|
|
468
|
+
})),
|
|
469
|
+
...deletedReviewCommentChanges
|
|
470
|
+
];
|
|
471
|
+
const deleteDocumentReviewCommentIds = new Set([
|
|
472
|
+
...missingDocumentReviewCommentDeleteIds,
|
|
473
|
+
...deletedReviewCommentChanges.map((change) => change.commentId)
|
|
474
|
+
]);
|
|
410
475
|
const annotatedSessions = Array.isArray(input.annotatedAttachmentSessions) ? input.annotatedAttachmentSessions : [];
|
|
476
|
+
const allAnnotatedAttachmentSessionIds = new Set(annotatedSessions
|
|
477
|
+
.map((session) => String(session?.id || '').trim())
|
|
478
|
+
.filter((sessionId) => sessionId.length > 0));
|
|
411
479
|
const currentAnnotatedAttachmentSessionIds = new Set(annotatedSessions
|
|
412
480
|
.filter((session) => String(session?.deletedAt || '').trim().length === 0)
|
|
413
481
|
.map((session) => String(session?.id || '').trim())
|
|
414
482
|
.filter((sessionId) => sessionId.length > 0));
|
|
415
|
-
const
|
|
416
|
-
...Array.from(input.lastPushedAnnotatedAttachmentSessionIds || new Set())
|
|
417
|
-
.map((sessionId) => String(sessionId || '').trim())
|
|
418
|
-
.filter((sessionId) => sessionId.length > 0 && !currentAnnotatedAttachmentSessionIds.has(sessionId)),
|
|
419
|
-
...annotatedSessions
|
|
420
|
-
.filter((session) => String(session?.deletedAt || '').trim().length > 0)
|
|
421
|
-
.map((session) => String(session?.id || '').trim())
|
|
422
|
-
.filter((sessionId) => sessionId.length > 0)
|
|
423
|
-
]);
|
|
483
|
+
const previousAnnotatedAttachmentSessionIds = input.lastPushedAnnotatedAttachmentSessionIds || new Set();
|
|
424
484
|
const currentAnnotatedAttachmentSessionWatermarks = new Map(annotatedSessions
|
|
425
|
-
.map((session) => [
|
|
485
|
+
.map((session) => [
|
|
486
|
+
String(session?.id || '').trim(),
|
|
487
|
+
String(session?.deletedAt || session?.updatedAt || session?.createdAt || '').trim()
|
|
488
|
+
])
|
|
426
489
|
.filter(([sessionId]) => sessionId.length > 0));
|
|
427
490
|
const previousAnnotatedAttachmentSessionWatermarks = input.lastPushedAnnotatedAttachmentSessionWatermarks;
|
|
428
491
|
const shouldSendAllAnnotatedAttachmentSessions = !previousAnnotatedAttachmentSessionWatermarks || previousAnnotatedAttachmentSessionWatermarks.size === 0;
|
|
@@ -453,6 +516,32 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
453
516
|
return true;
|
|
454
517
|
return previousAnnotatedAttachmentSessionWatermarks.get(change.session.id) !== change.session.updatedAt;
|
|
455
518
|
});
|
|
519
|
+
const deletedAnnotatedAttachmentSessionChanges = annotatedSessions
|
|
520
|
+
.filter((session) => String(session?.deletedAt || '').trim().length > 0)
|
|
521
|
+
.map((session) => ({
|
|
522
|
+
sessionId: String(session?.id || '').trim(),
|
|
523
|
+
deletedAt: String(session?.deletedAt || session?.updatedAt || session?.createdAt || payloadBuiltAt).trim() || payloadBuiltAt
|
|
524
|
+
}))
|
|
525
|
+
.filter((change) => change.sessionId.length > 0)
|
|
526
|
+
.filter((change) => {
|
|
527
|
+
if (shouldSendAllAnnotatedAttachmentSessions)
|
|
528
|
+
return true;
|
|
529
|
+
return previousAnnotatedAttachmentSessionWatermarks.get(change.sessionId) !== change.deletedAt;
|
|
530
|
+
});
|
|
531
|
+
const missingAnnotatedAttachmentSessionDeleteIds = Array.from(previousAnnotatedAttachmentSessionIds)
|
|
532
|
+
.map((sessionId) => String(sessionId || '').trim())
|
|
533
|
+
.filter((sessionId) => sessionId.length > 0 && !allAnnotatedAttachmentSessionIds.has(sessionId));
|
|
534
|
+
const annotatedAttachmentSessionDeleteChanges = [
|
|
535
|
+
...missingAnnotatedAttachmentSessionDeleteIds.map((sessionId) => ({
|
|
536
|
+
sessionId,
|
|
537
|
+
deletedAt: payloadBuiltAt
|
|
538
|
+
})),
|
|
539
|
+
...deletedAnnotatedAttachmentSessionChanges
|
|
540
|
+
];
|
|
541
|
+
const deleteAnnotatedAttachmentSessionIds = new Set([
|
|
542
|
+
...missingAnnotatedAttachmentSessionDeleteIds,
|
|
543
|
+
...deletedAnnotatedAttachmentSessionChanges.map((change) => change.sessionId)
|
|
544
|
+
]);
|
|
456
545
|
const taskEvents = sortTaskEventsForSync(Array.isArray(input.taskEvents) ? input.taskEvents : []);
|
|
457
546
|
const currentTaskEventWatermarks = new Map(taskEvents
|
|
458
547
|
.map((event) => [String(event?.id || '').trim(), String(event?.createdAt || '').trim()])
|
|
@@ -460,12 +549,17 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
460
549
|
const previousTaskEventWatermarks = input.lastPushedTaskEventWatermarks;
|
|
461
550
|
const shouldSendAllTaskEvents = !previousTaskEventWatermarks || previousTaskEventWatermarks.size === 0;
|
|
462
551
|
const taskEventUpsertChanges = taskEvents
|
|
463
|
-
.map((event) =>
|
|
464
|
-
|
|
465
|
-
|
|
552
|
+
.map((event) => {
|
|
553
|
+
const entityType = event.entityType === 'initiative' || event.entityType === 'workstream'
|
|
554
|
+
? event.entityType
|
|
555
|
+
: 'task';
|
|
556
|
+
const entityId = String(event.entityId || event.taskId || '').trim();
|
|
557
|
+
const normalizedEvent = {
|
|
466
558
|
id: String(event.id || '').trim(),
|
|
467
|
-
taskId: String(event.taskId || '').trim(),
|
|
468
559
|
workspaceId: String(event.workspaceId || '').trim(),
|
|
560
|
+
entityType,
|
|
561
|
+
entityId,
|
|
562
|
+
taskId: entityType === 'task' ? String(event.taskId || entityId).trim() : undefined,
|
|
469
563
|
action: String(event.action || '').trim(),
|
|
470
564
|
actor: String(event.actor || 'system').trim() || 'system',
|
|
471
565
|
actorType: event.actorType === 'ai' || event.actorType === 'human' || event.actorType === 'system'
|
|
@@ -475,10 +569,28 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
475
569
|
? event.details
|
|
476
570
|
: {},
|
|
477
571
|
createdAt: String(event.createdAt || '').trim(),
|
|
572
|
+
};
|
|
573
|
+
if (entityType === 'task') {
|
|
574
|
+
return {
|
|
575
|
+
op: 'task-event-upsert',
|
|
576
|
+
event: {
|
|
577
|
+
...normalizedEvent,
|
|
578
|
+
entityType: 'task',
|
|
579
|
+
taskId: String(normalizedEvent.taskId || entityId).trim(),
|
|
580
|
+
}
|
|
581
|
+
};
|
|
478
582
|
}
|
|
479
|
-
|
|
583
|
+
return {
|
|
584
|
+
op: 'entity-event-upsert',
|
|
585
|
+
event: {
|
|
586
|
+
...normalizedEvent,
|
|
587
|
+
entityType,
|
|
588
|
+
taskId: undefined,
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
})
|
|
480
592
|
.filter((change) => (change.event.id.length > 0
|
|
481
|
-
&& change.event.
|
|
593
|
+
&& change.event.entityId.length > 0
|
|
482
594
|
&& change.event.workspaceId.length > 0
|
|
483
595
|
&& change.event.action.length > 0
|
|
484
596
|
&& Number.isFinite(Date.parse(change.event.createdAt))))
|
|
@@ -517,22 +629,22 @@ export function buildWorkspaceSyncPayloadModel(input) {
|
|
|
517
629
|
deletedAt: payloadBuiltAt
|
|
518
630
|
})),
|
|
519
631
|
...documentReviewSessionUpsertChanges,
|
|
520
|
-
...
|
|
632
|
+
...documentReviewSessionDeleteChanges.map((change) => ({
|
|
521
633
|
op: 'document-review-session-delete',
|
|
522
|
-
sessionId,
|
|
523
|
-
deletedAt:
|
|
634
|
+
sessionId: change.sessionId,
|
|
635
|
+
deletedAt: change.deletedAt
|
|
524
636
|
})),
|
|
525
637
|
...documentReviewCommentUpsertChanges,
|
|
526
|
-
...
|
|
638
|
+
...documentReviewCommentDeleteChanges.map((change) => ({
|
|
527
639
|
op: 'document-review-comment-delete',
|
|
528
|
-
commentId,
|
|
529
|
-
deletedAt:
|
|
640
|
+
commentId: change.commentId,
|
|
641
|
+
deletedAt: change.deletedAt
|
|
530
642
|
})),
|
|
531
643
|
...annotatedAttachmentSessionUpsertChanges,
|
|
532
|
-
...
|
|
644
|
+
...annotatedAttachmentSessionDeleteChanges.map((change) => ({
|
|
533
645
|
op: 'annotated-attachment-session-delete',
|
|
534
|
-
sessionId,
|
|
535
|
-
deletedAt:
|
|
646
|
+
sessionId: change.sessionId,
|
|
647
|
+
deletedAt: change.deletedAt
|
|
536
648
|
})),
|
|
537
649
|
...taskEventUpsertChanges,
|
|
538
650
|
...activeChanges,
|
|
@@ -694,6 +806,7 @@ export function buildWorkspaceSyncSignatureModel(input) {
|
|
|
694
806
|
updatedAt: String(initiative.updatedAt || initiative.createdAt || '').trim(),
|
|
695
807
|
title: String(initiative.title || '').trim(),
|
|
696
808
|
ownerId: typeof initiative.ownerId === 'string' ? initiative.ownerId.trim() : '',
|
|
809
|
+
attachments: clonePlanningAttachmentsForSync(initiative.attachments) || [],
|
|
697
810
|
isArchived: Boolean(initiative.isArchived)
|
|
698
811
|
}))
|
|
699
812
|
.filter((initiative) => initiative.id.length > 0)
|
|
@@ -705,6 +818,7 @@ export function buildWorkspaceSyncSignatureModel(input) {
|
|
|
705
818
|
initiativeId: typeof workstream.initiativeId === 'string' ? workstream.initiativeId.trim() : '',
|
|
706
819
|
title: String(workstream.title || '').trim(),
|
|
707
820
|
ownerId: typeof workstream.ownerId === 'string' ? workstream.ownerId.trim() : '',
|
|
821
|
+
attachments: clonePlanningAttachmentsForSync(workstream.attachments) || [],
|
|
708
822
|
isArchived: Boolean(workstream.isArchived)
|
|
709
823
|
}))
|
|
710
824
|
.filter((workstream) => workstream.id.length > 0)
|