From 29a4276bbddb9c54a96e8b98d0925d6eff2ab793 Mon Sep 17 00:00:00 2001 From: Kristina Date: Wed, 21 Aug 2024 19:27:38 +0400 Subject: [PATCH] Remove duplicated contexts (#6366) Signed-off-by: Kristina Fefelova --- models/notification/src/index.ts | 5 ++- models/notification/src/migration.ts | 40 +++++++++++++++++++ plugins/notification/src/index.ts | 4 ++ .../activity-resources/src/references.ts | 3 +- .../notification-resources/src/index.ts | 25 ++++++++---- server-plugins/time-resources/src/index.ts | 4 +- 6 files changed, 70 insertions(+), 11 deletions(-) diff --git a/models/notification/src/index.ts b/models/notification/src/index.ts index a4331e44a1..7894bcc583 100644 --- a/models/notification/src/index.ts +++ b/models/notification/src/index.ts @@ -34,7 +34,8 @@ import { type Ref, type Space, type Timestamp, - type Tx + type Tx, + type TxCUD } from '@hcengineering/core' import { ArrOf, @@ -216,6 +217,8 @@ export class TDocNotifyContext extends TDoc implements DocNotifyContext { @Prop(TypeBoolean(), notification.string.Pinned) isPinned!: boolean + + tx?: Ref> } @Model(notification.class.InboxNotification, core.class.Doc, DOMAIN_NOTIFICATION) diff --git a/models/notification/src/migration.ts b/models/notification/src/migration.ts index 92aa49e111..43eb4f450a 100644 --- a/models/notification/src/migration.ts +++ b/models/notification/src/migration.ts @@ -186,6 +186,42 @@ export async function migrateNotificationsSpace (client: MigrationClient): Promi await client.deleteMany(DOMAIN_USER_NOTIFY, { _class: notification.class.BrowserNotification }) } +export async function migrateDuplicateContexts (client: MigrationClient): Promise { + const personSpaces = await client.find(DOMAIN_SPACE, { _class: contact.class.PersonSpace }, {}) + + for (const space of personSpaces) { + const contexts = await client.find( + DOMAIN_DOC_NOTIFY, + { _class: notification.class.DocNotifyContext, space: space._id }, + {} + ) + const toRemove = new Set>() + const contextByUser = new Map() + + for (const context of contexts) { + const key = context.objectId + '.' + context.user + const existContext = contextByUser.get(key) + + if (existContext != null) { + const existLastViewedTimestamp = existContext.lastViewedTimestamp ?? 0 + const newLastViewedTimestamp = context.lastViewedTimestamp ?? 0 + if (existLastViewedTimestamp > newLastViewedTimestamp) { + toRemove.add(context._id) + } else { + toRemove.add(existContext._id) + contextByUser.set(key, context) + } + } else { + contextByUser.set(key, context) + } + } + if (toRemove.size > 0) { + await client.deleteMany(DOMAIN_DOC_NOTIFY, { _id: { $in: Array.from(toRemove) } }) + await client.deleteMany(DOMAIN_NOTIFICATION, { docNotifyContext: { $in: Array.from(toRemove) } }) + } + } +} + export async function migrateSettings (client: MigrationClient): Promise { await client.update( DOMAIN_PREFERENCE, @@ -343,6 +379,10 @@ export const notificationOperation: MigrateOperation = { { objectSpace: core.space.Space } ) } + }, + { + state: 'migrate-duplicated-contexts-v1', + func: migrateDuplicateContexts } ]) diff --git a/plugins/notification/src/index.ts b/plugins/notification/src/index.ts index 8dbbd39259..dbb22a3843 100644 --- a/plugins/notification/src/index.ts +++ b/plugins/notification/src/index.ts @@ -27,6 +27,7 @@ import { Space, Timestamp, Tx, + TxCUD, TxOperations } from '@hcengineering/core' import type { Asset, IntlString, Metadata, Plugin, Resource } from '@hcengineering/platform' @@ -286,6 +287,9 @@ export interface DocNotifyContext extends Doc { isPinned: boolean lastViewedTimestamp?: Timestamp lastUpdateTimestamp?: Timestamp + + // Only for debug + tx?: Ref> } /** diff --git a/server-plugins/activity-resources/src/references.ts b/server-plugins/activity-resources/src/references.ts index 781b515d8f..f145c99843 100644 --- a/server-plugins/activity-resources/src/references.ts +++ b/server-plugins/activity-resources/src/references.ts @@ -227,7 +227,8 @@ export async function getPersonNotificationTxes ( doc.space, originTx.modifiedOn, notifyResult, - notification.class.MentionInboxNotification + notification.class.MentionInboxNotification, + originTx ) res.push(...txes) } else { diff --git a/server-plugins/notification-resources/src/index.ts b/server-plugins/notification-resources/src/index.ts index 565f255867..e81ec345c4 100644 --- a/server-plugins/notification-resources/src/index.ts +++ b/server-plugins/notification-resources/src/index.ts @@ -136,7 +136,8 @@ export async function getCommonNotificationTxes ( space: Ref, modifiedOn: Timestamp, notifyResult: NotifyResult, - _class = notification.class.CommonInboxNotification + _class = notification.class.CommonInboxNotification, + tx?: TxCUD ): Promise { if (notifyResult.size === 0 || !notifyResult.has(notification.providers.InboxNotificationProvider)) { return [] @@ -156,7 +157,9 @@ export async function getCommonNotificationTxes ( notifyContexts, data, _class, - modifiedOn + modifiedOn, + true, + tx ) if (notificationTx !== undefined) { @@ -340,7 +343,8 @@ export async function pushInboxNotifications ( data: Partial>, _class: Ref>, modifiedOn: Timestamp, - shouldUpdateTimestamp = true + shouldUpdateTimestamp = true, + tx?: TxCUD ): Promise | undefined> { const context = getDocNotifyContext(control, contexts, objectId, receiver._id) let docNotifyContextId: Ref @@ -353,7 +357,8 @@ export async function pushInboxNotifications ( objectClass, objectSpace, receiver, - shouldUpdateTimestamp ? modifiedOn : undefined + shouldUpdateTimestamp ? modifiedOn : undefined, + tx ) } else { docNotifyContextId = context._id @@ -618,7 +623,8 @@ export async function pushActivityInboxNotifications ( data, notification.class.ActivityInboxNotification, activityMessage.modifiedOn, - shouldUpdateTimestamp + shouldUpdateTimestamp, + originTx ) } @@ -675,7 +681,8 @@ async function createNotifyContext ( objectClass: Ref>, objectSpace: Ref, receiver: ReceiverInfo, - updateTimestamp?: Timestamp + updateTimestamp?: Timestamp, + tx?: TxCUD ): Promise> { const createTx = control.txFactory.createTxCreateDoc(notification.class.DocNotifyContext, receiver.space, { user: receiver._id, @@ -683,6 +690,7 @@ async function createNotifyContext ( objectClass, objectSpace, isPinned: false, + tx: tx?._id, lastUpdateTimestamp: updateTimestamp }) await ctx.with('apply', {}, () => control.apply([createTx])) @@ -770,7 +778,8 @@ export async function getNotificationTxes ( message.attachedToClass, message.space, receiver, - params.shouldUpdateTimestamp ? originTx.modifiedOn : undefined + params.shouldUpdateTimestamp ? originTx.modifiedOn : undefined, + tx ) } } @@ -1632,7 +1641,7 @@ async function updateCollaborators (ctx: MeasureContext, control: TriggerControl if (info === undefined) continue const context = getDocNotifyContext(control, contexts, objectId, info._id) if (context !== undefined) continue - await createNotifyContext(ctx, control, objectId, objectClass, objectSpace, info) + await createNotifyContext(ctx, control, objectId, objectClass, objectSpace, info, undefined, tx) } await removeContexts(ctx, contexts, removedCollaborators as Ref[], control) diff --git a/server-plugins/time-resources/src/index.ts b/server-plugins/time-resources/src/index.ts index c24bb09b05..7180b7fc55 100644 --- a/server-plugins/time-resources/src/index.ts +++ b/server-plugins/time-resources/src/index.ts @@ -241,7 +241,9 @@ export async function OnToDoCreate (tx: TxCUD, control: TriggerControl): Pr object._class, object.space, createTx.modifiedOn, - notifyResult + notifyResult, + notification.class.CommonInboxNotification, + tx ) await control.apply(txes)