mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-23 11:31:57 +03:00
UBER-476: Duplicate comment fix (#3425)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
e809a67451
commit
14b7806967
@ -14,8 +14,21 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import attachment from '@hcengineering/attachment'
|
import attachment from '@hcengineering/attachment'
|
||||||
|
import chunter, { Comment } from '@hcengineering/chunter'
|
||||||
import contact from '@hcengineering/contact'
|
import contact from '@hcengineering/contact'
|
||||||
import core, { BackupClient, Client as CoreClient, DOMAIN_TX, TxOperations, WorkspaceId } from '@hcengineering/core'
|
import core, {
|
||||||
|
BackupClient,
|
||||||
|
Client as CoreClient,
|
||||||
|
DOMAIN_TX,
|
||||||
|
Doc,
|
||||||
|
Domain,
|
||||||
|
Ref,
|
||||||
|
TxCreateDoc,
|
||||||
|
TxOperations,
|
||||||
|
TxProcessor,
|
||||||
|
WorkspaceId,
|
||||||
|
generateId
|
||||||
|
} from '@hcengineering/core'
|
||||||
import { MinioService } from '@hcengineering/minio'
|
import { MinioService } from '@hcengineering/minio'
|
||||||
import { getWorkspaceDB } from '@hcengineering/mongo'
|
import { getWorkspaceDB } from '@hcengineering/mongo'
|
||||||
import recruit from '@hcengineering/recruit'
|
import recruit from '@hcengineering/recruit'
|
||||||
@ -23,6 +36,8 @@ import { connect } from '@hcengineering/server-tool'
|
|||||||
import tracker from '@hcengineering/tracker'
|
import tracker from '@hcengineering/tracker'
|
||||||
import { MongoClient } from 'mongodb'
|
import { MongoClient } from 'mongodb'
|
||||||
|
|
||||||
|
export const DOMAIN_COMMENT = 'comment' as Domain
|
||||||
|
|
||||||
export async function cleanWorkspace (
|
export async function cleanWorkspace (
|
||||||
mongoUrl: string,
|
mongoUrl: string,
|
||||||
workspaceId: WorkspaceId,
|
workspaceId: WorkspaceId,
|
||||||
@ -204,3 +219,54 @@ export async function cleanArchivedSpaces (workspaceId: WorkspaceId, transactorU
|
|||||||
await connection.close()
|
await connection.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function fixCommentDoubleIdCreate (workspaceId: WorkspaceId, transactorUrl: string): Promise<void> {
|
||||||
|
const connection = (await connect(transactorUrl, workspaceId, undefined, {
|
||||||
|
mode: 'backup'
|
||||||
|
})) as unknown as CoreClient & BackupClient
|
||||||
|
try {
|
||||||
|
const commentTxes = await connection.findAll(core.class.TxCollectionCUD, {
|
||||||
|
'tx._class': core.class.TxCreateDoc,
|
||||||
|
'tx.objectClass': chunter.class.Comment
|
||||||
|
})
|
||||||
|
const commentTxesRemoved = await connection.findAll(core.class.TxCollectionCUD, {
|
||||||
|
'tx._class': core.class.TxRemoveDoc,
|
||||||
|
'tx.objectClass': chunter.class.Comment
|
||||||
|
})
|
||||||
|
const removed = new Map(commentTxesRemoved.map((it) => [it.tx.objectId, it]))
|
||||||
|
// Do not checked removed
|
||||||
|
const objSet = new Set<Ref<Doc>>()
|
||||||
|
const oldValue = new Map<Ref<Doc>, string>()
|
||||||
|
for (const c of commentTxes) {
|
||||||
|
const cid = c.tx.objectId
|
||||||
|
if (removed.has(cid)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const has = objSet.has(cid)
|
||||||
|
objSet.add(cid)
|
||||||
|
if (has) {
|
||||||
|
// We have found duplicate one, let's rename it.
|
||||||
|
const doc = TxProcessor.createDoc2Doc<Comment>(c.tx as unknown as TxCreateDoc<Comment>)
|
||||||
|
if (doc.message !== '' && doc.message.trim() !== '<p></p>') {
|
||||||
|
await connection.clean(DOMAIN_TX, [c._id])
|
||||||
|
if (oldValue.get(cid) === doc.message.trim()) {
|
||||||
|
console.log('delete tx', cid, doc.message)
|
||||||
|
} else {
|
||||||
|
oldValue.set(doc._id, doc.message)
|
||||||
|
console.log('renaming', cid, doc.message)
|
||||||
|
// Remove previous transaction.
|
||||||
|
c.tx.objectId = generateId()
|
||||||
|
doc._id = c.tx.objectId as Ref<Comment>
|
||||||
|
await connection.upload(DOMAIN_TX, [c])
|
||||||
|
// Also we need to create snapsot
|
||||||
|
await connection.upload(DOMAIN_COMMENT, [doc])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
console.trace(err)
|
||||||
|
} finally {
|
||||||
|
await connection.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -52,7 +52,7 @@ import { MinioService } from '@hcengineering/minio'
|
|||||||
import { MigrateOperation } from '@hcengineering/model'
|
import { MigrateOperation } from '@hcengineering/model'
|
||||||
import { openAIConfigDefaults } from '@hcengineering/openai'
|
import { openAIConfigDefaults } from '@hcengineering/openai'
|
||||||
import { benchmark } from './benchmark'
|
import { benchmark } from './benchmark'
|
||||||
import { cleanArchivedSpaces, cleanRemovedTransactions, cleanWorkspace } from './clean'
|
import { cleanArchivedSpaces, cleanRemovedTransactions, cleanWorkspace, fixCommentDoubleIdCreate } from './clean'
|
||||||
import { changeConfiguration } from './configuration'
|
import { changeConfiguration } from './configuration'
|
||||||
import { openAIConfig } from './openai'
|
import { openAIConfig } from './openai'
|
||||||
|
|
||||||
@ -455,6 +455,13 @@ export function devTool (
|
|||||||
await cleanArchivedSpaces(getWorkspaceId(workspace, productId), transactorUrl)
|
await cleanArchivedSpaces(getWorkspaceId(workspace, productId), transactorUrl)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
program
|
||||||
|
.command('chunter-fix-comments <workspace>')
|
||||||
|
.description('chunter-fix-comments')
|
||||||
|
.action(async (workspace: string, cmd: any) => {
|
||||||
|
await fixCommentDoubleIdCreate(getWorkspaceId(workspace, productId), transactorUrl)
|
||||||
|
})
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('configure <workspace>')
|
.command('configure <workspace>')
|
||||||
.description('clean archived spaces')
|
.description('clean archived spaces')
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import { AttachmentRefInput } from '@hcengineering/attachment-resources'
|
import { AttachmentRefInput } from '@hcengineering/attachment-resources'
|
||||||
import { Comment } from '@hcengineering/chunter'
|
import { Comment } from '@hcengineering/chunter'
|
||||||
import { AttachedData, Doc, generateId, Ref } from '@hcengineering/core'
|
import { AttachedData, Doc, generateId, Ref } from '@hcengineering/core'
|
||||||
import { DraftController, draftsStore, getClient } from '@hcengineering/presentation'
|
import { createQuery, DraftController, draftsStore, getClient } from '@hcengineering/presentation'
|
||||||
import { createBacklinks } from '../backlinks'
|
import { createBacklinks } from '../backlinks'
|
||||||
import chunter from '../plugin'
|
import chunter from '../plugin'
|
||||||
|
|
||||||
@ -40,10 +40,22 @@
|
|||||||
|
|
||||||
let commentInputBox: AttachmentRefInput
|
let commentInputBox: AttachmentRefInput
|
||||||
const draftComment = shouldSaveDraft ? $draftsStore[draftKey] : undefined
|
const draftComment = shouldSaveDraft ? $draftsStore[draftKey] : undefined
|
||||||
|
|
||||||
let comment: CommentDraft = draftComment ?? getDefault()
|
let comment: CommentDraft = draftComment ?? getDefault()
|
||||||
let _id: Ref<Comment> = comment._id
|
let _id: Ref<Comment> = comment._id
|
||||||
let inputContent: string = comment.message
|
let inputContent: string = comment.message
|
||||||
|
|
||||||
|
const createdQuery = createQuery()
|
||||||
|
|
||||||
|
$: createdQuery.query(chunter.class.Comment, { _id }, (docs) => {
|
||||||
|
if (docs.length > 0) {
|
||||||
|
// Ouch we have got comment with same id created already.
|
||||||
|
comment = getDefault()
|
||||||
|
_id = comment._id
|
||||||
|
commentInputBox.removeDraft(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function objectChange (object: CommentDraft, empty: any) {
|
function objectChange (object: CommentDraft, empty: any) {
|
||||||
if (shouldSaveDraft) {
|
if (shouldSaveDraft) {
|
||||||
draftController.save(object, empty)
|
draftController.save(object, empty)
|
||||||
@ -98,8 +110,8 @@
|
|||||||
await createBacklinks(client, object._id, object._class, _id, message)
|
await createBacklinks(client, object._id, object._class, _id, message)
|
||||||
|
|
||||||
// Remove draft from Local Storage
|
// Remove draft from Local Storage
|
||||||
_id = generateId()
|
|
||||||
comment = getDefault()
|
comment = getDefault()
|
||||||
|
_id = comment._id
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
} finally {
|
} finally {
|
||||||
|
Loading…
Reference in New Issue
Block a user