UBERF-10413: Fix update of %hash% and update migration (#8771)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2025-04-29 22:58:39 +07:00 committed by GitHub
parent 5c0ea43eda
commit 1c9127b0a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 55 additions and 11 deletions

View File

@ -16,40 +16,43 @@
import { saveCollabJson } from '@hcengineering/collaboration'
import core, {
buildSocialIdString,
configUserAccountUuid,
coreId,
DOMAIN_MODEL_TX,
DOMAIN_SPACE,
DOMAIN_STATUS,
DOMAIN_TX,
generateId,
groupByArray,
makeCollabJsonId,
makeCollabYdocId,
makeDocCollabId,
MeasureMetricsContext,
RateLimiter,
SocialIdType,
type PersonId,
systemAccountUuid,
toIdMap,
TxProcessor,
type AccountUuid,
type AnyAttribute,
type AttachedDoc,
type Blob,
type Class,
type Doc,
type Domain,
type MeasureContext,
type PersonId,
type Ref,
type Role,
type SocialKey,
type Space,
type SpaceType,
type Status,
type TxCreateDoc,
type TxCUD,
type SpaceType,
type TxMixin,
type TxUpdateDoc,
type Role,
toIdMap,
type TypedSpace,
TxProcessor,
type SocialKey,
type AccountUuid,
systemAccountUuid,
configUserAccountUuid
type TypedSpace
} from '@hcengineering/core'
import {
createDefaultSpace,
@ -264,6 +267,41 @@ async function processMigrateContentFor (
}
}
async function migrateBackupMixins (client: MigrationClient): Promise<void> {
// Go via classes with domain and check if mixin exists and need to flush %hash%
const hierarchy = client.hierarchy
const curHash = Date.now().toString(16) // Current hash value
const txIterator = await client.traverse<TxMixin<Doc, AttachedDoc>>(DOMAIN_TX, { _class: core.class.TxMixin })
while (true) {
const mixinOps = await txIterator.next(500)
if (mixinOps === null || mixinOps.length === 0) break
const _classes = groupByArray(mixinOps, (it) => it.objectClass)
for (const [_class, ops] of _classes.entries()) {
const domain = hierarchy.findDomain(_class)
if (domain === undefined) continue
let docs = await client.find(domain, { _id: { $in: ops.map((it) => it.objectId) } })
docs = docs.filter((it) => {
// Check if mixin is last operation by modifiedOn
const mops = ops.filter((mi) => mi.objectId === it._id)
if (mops.length === 0) return false
return mops.some((mi) => mi.modifiedOn === it.modifiedOn && mi.modifiedBy === it.modifiedBy)
})
if (docs.length > 0) {
// Check if docs has mixins from list
const toUpdate = docs.filter((it) => hierarchy.findAllMixins(it).length > 0)
if (toUpdate.length > 0) {
await client.update(domain, { _id: { $in: toUpdate.map((it) => it._id) } }, { '%hash%': curHash })
}
}
}
}
}
async function migrateCollaborativeDocsToJson (client: MigrationClient): Promise<void> {
const ctx = new MeasureMetricsContext('migrateCollaborativeDocsToJson', {})
const storageAdapter = client.storageAdapter
@ -921,6 +959,11 @@ export const coreOperation: MigrateOperation = {
state: 'accounts-to-social-ids',
mode: 'upgrade',
func: migrateAccounts
},
{
state: 'migrate-backup-mixins',
mode: 'upgrade',
func: migrateBackupMixins
}
])
},

View File

@ -1401,7 +1401,8 @@ class MongoAdapter extends MongoAdapterBase {
const filter = { _id: tx.objectId }
const modifyOp = {
modifiedBy: tx.modifiedBy,
modifiedOn: tx.modifiedOn
modifiedOn: tx.modifiedOn,
'%hash%': this.curHash()
}
if (isOperator(tx.attributes)) {
const update = { ...this.translateMixinAttrs(tx.mixin, tx.attributes), $set: { ...modifyOp } }