ezqms-1023: remove old migrations from qms (#5823)

Signed-off-by: Alexey Zinoviev <alexey.zinoviev@xored.com>
This commit is contained in:
Alexey Zinoviev 2024-06-14 16:12:28 +04:00 committed by GitHub
parent cf71e49e53
commit 3090ae6032
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 9 additions and 581 deletions

View File

@ -2,18 +2,7 @@
// Copyright @ 2022-2023 Hardcore Engineering Inc. // Copyright @ 2022-2023 Hardcore Engineering Inc.
// //
import { import { type Data, type Ref, TxOperations, generateId, DOMAIN_TX, getCollaborativeDoc } from '@hcengineering/core'
type Data,
type Ref,
TxOperations,
type Class,
type Space,
generateId,
DOMAIN_TX,
AccountRole,
DOMAIN_DOC_INDEX_STATE,
getCollaborativeDoc
} from '@hcengineering/core'
import { import {
createDefaultSpace, createDefaultSpace,
createOrUpdate, createOrUpdate,
@ -22,20 +11,11 @@ import {
type MigrationClient, type MigrationClient,
type MigrationUpgradeClient type MigrationUpgradeClient
} from '@hcengineering/model' } from '@hcengineering/model'
import core, { DOMAIN_SPACE } from '@hcengineering/model-core' import core from '@hcengineering/model-core'
import contact from '@hcengineering/model-contact'
import tags from '@hcengineering/tags' import tags from '@hcengineering/tags'
import { import {
type ChangeControl, type ChangeControl,
type DocumentCategory, type DocumentCategory,
type Document,
type DocumentMeta,
type DocumentSpace,
type HierarchyDocument,
type ProjectDocument,
type ProjectMeta,
TEMPLATE_PREFIX,
getDocumentId,
DocumentState, DocumentState,
documentsId, documentsId,
createDocumentTemplate, createDocumentTemplate,
@ -43,154 +23,7 @@ import {
createChangeControl createChangeControl
} from '@hcengineering/controlled-documents' } from '@hcengineering/controlled-documents'
import documents, { DOMAIN_DOCUMENTS } from './index' import documents from './index'
async function migrateDocumentCategories (client: MigrationClient): Promise<void> {
const oldSpace = 'documents:space:Documents' as Ref<Space>
await client.update(
DOMAIN_DOCUMENTS,
{
_class: documents.class.DocumentCategory,
space: oldSpace
},
{
$set: {
space: documents.space.QualityDocuments
}
}
)
}
async function migrateUnusedDocumentSpaces (client: MigrationClient): Promise<void> {
const spaces: Ref<DocumentSpace>[] = [
'events:space:EventsDocuments' as Ref<DocumentSpace>,
'clients:space:ClientsDocuments' as Ref<DocumentSpace>,
'supplier:space:SuppliersDocuments' as Ref<DocumentSpace>,
'trainings:space:TrainingsDocuments' as Ref<DocumentSpace>
]
await client.update(
DOMAIN_SPACE,
{
_id: { $in: spaces },
_class: documents.class.DocumentSpace,
archived: false
},
{
$set: {
archived: true
}
}
)
}
async function migrateProjectMeta (client: MigrationClient): Promise<void> {
type ExDocumentMeta = DocumentMeta & { path: Ref<DocumentMeta>[] }
const metaToMigrate = await client.find<ExDocumentMeta>(DOMAIN_DOCUMENTS, {
_class: documents.class.DocumentMeta,
path: { $exists: true }
})
for (const meta of metaToMigrate) {
const projectMetaId: Ref<ProjectMeta> = generateId()
const docs = await client.find<HierarchyDocument>(DOMAIN_DOCUMENTS, {
attachedTo: meta._id
})
for (const doc of docs) {
await client.create<ProjectDocument>(DOMAIN_DOCUMENTS, {
_id: generateId(),
_class: documents.class.ProjectDocument,
space: doc.space,
modifiedBy: core.account.System,
modifiedOn: Date.now(),
attachedTo: projectMetaId,
attachedToClass: documents.class.ProjectMeta,
collection: 'documents',
project: documents.ids.NoProject,
initial: documents.ids.NoProject,
document: doc._id
})
}
await client.create<ProjectMeta>(DOMAIN_DOCUMENTS, {
_id: projectMetaId,
_class: documents.class.ProjectMeta,
space: meta.space,
modifiedBy: core.account.System,
modifiedOn: Date.now(),
project: documents.ids.NoProject,
meta: meta._id,
path: meta.path,
parent: meta.path[0] ?? documents.ids.NoParent,
documents: docs.length
})
await client.update(
DOMAIN_DOCUMENTS,
{ _id: meta._id },
{
$unset: {
path: undefined
}
}
)
}
}
async function migrateDocumentSpaces (client: MigrationClient): Promise<void> {
const affectedClasses: Ref<Class<DocumentSpace>>[] = [
documents.class.DocumentSpace,
documents.class.OrgSpace,
documents.class.ExternalSpace
]
await client.update(
DOMAIN_SPACE,
{
_class: { $in: affectedClasses },
type: { $exists: false }
},
{
$set: {
type: documents.spaceType.DocumentSpaceType
}
}
)
await client.update(
DOMAIN_SPACE,
{
_class: { $in: affectedClasses },
type: 'documents:spaceType:DefaultDocLibraryType'
},
{
$set: {
type: documents.spaceType.DocumentSpaceType
},
$rename: {
'documents:spaceType:DefaultDocLibraryType:type:mixin': 'documents:spaceType:DocumentSpaceType:type:mixin'
}
}
)
}
async function migrateLibraryDocumentSpace (client: MigrationClient): Promise<void> {
await client.update(
DOMAIN_SPACE,
{
_class: 'documents:class:LibraryDocumentSpace' as Ref<Class<DocumentSpace>>
},
{
$set: {
_class: documents.class.DocumentSpace
}
}
)
}
async function createTemplatesSpace (tx: TxOperations): Promise<void> { async function createTemplatesSpace (tx: TxOperations): Promise<void> {
const existingSpace = await tx.findOne(documents.class.DocumentSpace, { const existingSpace = await tx.findOne(documents.class.DocumentSpace, {
@ -239,153 +72,6 @@ async function createQualityDocumentsSpace (tx: TxOperations): Promise<void> {
} }
} }
async function migrateSpace (client: MigrationClient): Promise<void> {
await client.update(
DOMAIN_SPACE,
{
_id: documents.space.Documents,
_class: documents.class.DocumentSpace
},
{
$set: {
_class: core.class.Space
}
}
)
}
async function migrateEffectiveDates (client: MigrationClient): Promise<void> {
await client.update(
DOMAIN_DOCUMENTS,
{
effectiveDate: 0
},
{
$set: {
plannedEffectiveDate: 0
},
$unset: {
effectiveDate: undefined
}
}
)
const docsToRelease = await client.find(DOMAIN_DOCUMENTS, { effectiveDate: { $gt: Date.now() } })
for (const doc of docsToRelease) {
const plannedEffectiveDate = (doc as any).effectiveDate
await client.update(
DOMAIN_DOCUMENTS,
{ _id: doc._id },
{
$set: {
plannedEffectiveDate
},
$unset: {
effectiveDate: undefined
}
}
)
}
}
async function migrateChangeControls (client: MigrationClient): Promise<void> {
await client.update(
DOMAIN_DOCUMENTS,
{ _class: documents.class.ChangeControl, impactedDocuments: { $exists: false } },
{
$set: {
impactedDocuments: []
}
}
)
}
async function migrateTemplatePrefixes (client: MigrationClient): Promise<void> {
const templatesToMigrate = await client.find<Document>(DOMAIN_DOCUMENTS, {
[documents.mixin.DocumentTemplate]: { $exists: true },
prefix: { $ne: TEMPLATE_PREFIX }
})
for (const tmp of templatesToMigrate) {
await client.update(
DOMAIN_DOCUMENTS,
{
_id: tmp._id
},
{
$set: {
prefix: TEMPLATE_PREFIX,
[`${documents.mixin.DocumentTemplate}.docPrefix`]: tmp.prefix
}
}
)
}
}
async function migrateDocumentCodes (client: MigrationClient): Promise<void> {
const classes = client.hierarchy.getDescendants(documents.class.Document)
const docsToMigrate = await client.find<Document>(DOMAIN_DOCUMENTS, {
_class: { $in: classes },
code: { $exists: false }
})
for (const doc of docsToMigrate) {
await client.update(
DOMAIN_DOCUMENTS,
{
_id: doc._id
},
{
$set: {
code: getDocumentId(doc)
}
}
)
}
}
async function migrateCollaborativeDocument (client: MigrationClient): Promise<void> {
const mixin = 'documents:mixin:CollaborativeDocument'
const docsToMigrate = await client.find(DOMAIN_DOCUMENTS, {
[`${mixin}.document`]: { $exists: true }
})
for (const doc of docsToMigrate) {
const content = (doc as any)[mixin].document
const snapshots = (doc as any)[mixin].snapshots ?? []
// move mixin document -> content field
await client.update(
DOMAIN_DOCUMENTS,
{ _id: doc._id },
{
$set: {
content,
snapshots: snapshots.length
},
$unset: {
[mixin]: undefined
}
}
)
// make snapshots attached docs
await client.update(
DOMAIN_DOCUMENTS,
{ _id: { $in: snapshots } },
{
$set: {
attachedTo: doc._id,
attachedToClass: doc._class,
collection: 'snapshots'
}
}
)
}
}
async function fixChangeControlsForDocs (tx: TxOperations): Promise<void> { async function fixChangeControlsForDocs (tx: TxOperations): Promise<void> {
const defaultCCSpec: Data<ChangeControl> = { const defaultCCSpec: Data<ChangeControl> = {
description: '', description: '',
@ -582,104 +268,6 @@ async function createTagCategories (tx: TxOperations): Promise<void> {
) )
} }
async function migrateDocumentSpacesMixins (client: MigrationClient): Promise<void> {
const oldSpaceTypeMixin = `${documents.spaceType.DocumentSpaceType}:type:mixin`
const newSpaceTypeMixin = documents.mixin.DocumentSpaceTypeData
const affectedClasses: Ref<Class<DocumentSpace>>[] = [
documents.class.DocumentSpace,
documents.class.OrgSpace,
documents.class.ExternalSpace
]
await client.update(
DOMAIN_TX,
{
objectClass: core.class.Attribute,
'attributes.attributeOf': oldSpaceTypeMixin
},
{
$set: {
'attributes.attributeOf': newSpaceTypeMixin
}
}
)
await client.update(
DOMAIN_SPACE,
{
_class: { $in: affectedClasses },
[oldSpaceTypeMixin]: { $exists: true }
},
{
$rename: {
[oldSpaceTypeMixin]: newSpaceTypeMixin
}
}
)
}
async function migrateDefaultProjectOwners (client: MigrationClient): Promise<void> {
const workspaceOwners = await client.model.findAll(contact.class.PersonAccount, {
role: AccountRole.Owner
})
await client.update(
DOMAIN_SPACE,
{
_id: documents.space.QualityDocuments,
$or: [{ owners: { $exists: false } }, { owners: [core.account.System] }]
},
{
$set: {
owners: workspaceOwners.map((it) => it._id)
}
}
)
}
async function migrateMetaTitles (client: MigrationClient): Promise<void> {
const targetMetas = await client.find<DocumentMeta>(DOMAIN_DOCUMENTS, { title: { $exists: false } })
for (const meta of targetMetas) {
let targetDoc = (
await client.find<Document>(DOMAIN_DOCUMENTS, { attachedTo: meta._id, state: DocumentState.Effective })
)[0]
if (targetDoc === undefined) {
targetDoc = (await client.find<Document>(DOMAIN_DOCUMENTS, { attachedTo: meta._id }))[0]
}
if (targetDoc === undefined) {
continue
}
await client.update(
DOMAIN_DOCUMENTS,
{ _id: meta._id },
{
$set: {
title: `${getDocumentId(targetDoc)} ${targetDoc.title}`
}
}
)
}
}
async function migrateMetaIndexState (client: MigrationClient): Promise<void> {
await client.update(
DOMAIN_DOC_INDEX_STATE,
{
_class: core.class.DocIndexState,
objectClass: documents.class.DocumentMeta
},
{
$set: {
stages: {}
}
}
)
}
async function migrateSpaceTypes (client: MigrationClient): Promise<void> { async function migrateSpaceTypes (client: MigrationClient): Promise<void> {
await client.update( await client.update(
DOMAIN_TX, DOMAIN_TX,
@ -698,26 +286,7 @@ async function migrateSpaceTypes (client: MigrationClient): Promise<void> {
export const documentsOperation: MigrateOperation = { export const documentsOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> { async migrate (client: MigrationClient): Promise<void> {
await migrateSpace(client)
await migrateEffectiveDates(client)
await migrateChangeControls(client)
await migrateTemplatePrefixes(client)
// Note: Order matters! It is important to migrate template prefixes first.
await migrateDocumentCodes(client)
await migrateCollaborativeDocument(client)
await migrateLibraryDocumentSpace(client)
await migrateDocumentSpaces(client)
await migrateDocumentCategories(client)
await migrateUnusedDocumentSpaces(client)
await migrateProjectMeta(client)
await migrateDocumentSpacesMixins(client)
await migrateDefaultProjectOwners(client)
await migrateMetaTitles(client)
await tryMigrate(client, documentsId, [ await tryMigrate(client, documentsId, [
{
state: 'migrateMetaIndexState',
func: migrateMetaIndexState
},
{ {
state: 'migrateSpaceTypes', state: 'migrateSpaceTypes',
func: migrateSpaceTypes func: migrateSpaceTypes

View File

@ -13,101 +13,9 @@
// limitations under the License. // limitations under the License.
// //
import { type Employee } from '@hcengineering/contact' import { type MigrateOperation, type MigrationClient, type MigrationUpgradeClient } from '@hcengineering/model'
import { type Ref, DOMAIN_TX } from '@hcengineering/core'
import {
tryMigrate,
type MigrateOperation,
type MigrationClient,
type MigrationUpgradeClient
} from '@hcengineering/model'
import core, { DOMAIN_SPACE } from '@hcengineering/model-core'
import { type Product, productsId } from '@hcengineering/products'
import documents from '@hcengineering/controlled-documents'
import products from './plugin'
async function migrateProductSpacesMixins (client: MigrationClient): Promise<void> {
const oldSpaceTypeMixin = `${products.spaceType.ProductType}:type:mixin`
const newSpaceTypeMixin = products.mixin.ProductTypeData
await client.update(
DOMAIN_TX,
{
objectClass: core.class.Attribute,
'attributes.attributeOf': oldSpaceTypeMixin
},
{
$set: {
'attributes.attributeOf': newSpaceTypeMixin
}
}
)
await client.update(
DOMAIN_SPACE,
{
_class: products.class.Product,
[oldSpaceTypeMixin]: { $exists: true }
},
{
$rename: {
[oldSpaceTypeMixin]: newSpaceTypeMixin
}
}
)
}
async function migrateProductOwner (client: MigrationClient): Promise<void> {
type ExProduct = Product & { owner: Ref<Employee> }
const docs = await client.find<ExProduct>(DOMAIN_SPACE, { _class: products.class.Product, owner: { $exists: true } })
for (const doc of docs) {
if (doc.owner == null) continue
const currentOwners = doc.owners ?? []
const currenMembers = doc.members ?? []
const owners = Array.from(new Set(...currentOwners, doc.owner))
const members = Array.from(new Set(...currenMembers, ...owners))
await client.update(
DOMAIN_SPACE,
{ _id: doc._id },
{
$set: { owners, members },
$unset: { owner: undefined }
}
)
}
}
async function migrateSpaceTypes (client: MigrationClient): Promise<void> {
await client.update(
DOMAIN_TX,
{
_class: core.class.TxCreateDoc,
objectClass: core.class.SpaceType,
'attributes.descriptor': products.spaceTypeDescriptor.ProductType
},
{
$set: {
objectClass: documents.class.DocumentSpaceType,
'attributes.projects': true
}
}
)
}
export const productsOperation: MigrateOperation = { export const productsOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> { async migrate (client: MigrationClient): Promise<void> {},
await migrateProductSpacesMixins(client)
await migrateProductOwner(client)
await tryMigrate(client, productsId, [
{
state: 'migrateSpaceTypes',
func: migrateSpaceTypes
}
])
},
async upgrade (client: MigrationUpgradeClient): Promise<void> {} async upgrade (client: MigrationUpgradeClient): Promise<void> {}
} }

View File

@ -13,27 +13,13 @@
// limitations under the License. // limitations under the License.
// //
import { import { type MigrateOperation, type MigrationClient, type MigrationUpgradeClient } from '@hcengineering/model'
tryMigrate,
type MigrateOperation,
type MigrationClient,
type MigrationUpgradeClient
} from '@hcengineering/model'
import { type Ref, TxOperations, type TypedSpace } from '@hcengineering/core' import { type Ref, TxOperations, type TypedSpace } from '@hcengineering/core'
import core, { DOMAIN_SPACE } from '@hcengineering/model-core' import core from '@hcengineering/model-core'
import training, { trainingId, type Sequence } from '@hcengineering/training' import training, { type Sequence } from '@hcengineering/training'
import contact, { DOMAIN_CONTACT } from '@hcengineering/model-contact'
import { Person, PersonAccount } from '@hcengineering/contact'
export const trainingOperation: MigrateOperation = { export const trainingOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> { async migrate (client: MigrationClient): Promise<void> {},
await tryMigrate(client, trainingId, [
{
state: 'migrateDefaultSpaceMembers',
func: migrateDefaultSpaceMembers
}
])
},
async upgrade (client: MigrationUpgradeClient): Promise<void> { async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System) const tx = new TxOperations(client, core.account.System)
await ensureTypedSpace(tx) await ensureTypedSpace(tx)
@ -41,41 +27,6 @@ export const trainingOperation: MigrateOperation = {
} }
} }
async function migrateDefaultSpaceMembers (client: MigrationClient): Promise<void> {
await client.update(
DOMAIN_SPACE,
{
_id: training.space.Trainings,
autoJoin: false
},
{
$set: {
autoJoin: true
}
}
)
const employees = await client.find<Person>(DOMAIN_CONTACT, {
_class: contact.class.Person,
[contact.mixin.Employee]: { $exists: true }
})
const empAccs = await client.model.findAll<PersonAccount>(contact.class.PersonAccount, {
person: { $in: employees.map((e) => e._id) }
})
await client.update(
DOMAIN_SPACE,
{
_id: training.space.Trainings
},
{
$addToSet: {
members: { $each: empAccs.map((e) => e._id) }
}
}
)
}
async function ensureTypedSpace (tx: TxOperations): Promise<Ref<TypedSpace>> { async function ensureTypedSpace (tx: TxOperations): Promise<Ref<TypedSpace>> {
const existing = await tx.findOne(core.class.TypedSpace, { const existing = await tx.findOne(core.class.TypedSpace, {
_id: training.space.Trainings _id: training.space.Trainings