diff --git a/dev/tool/src/index.ts b/dev/tool/src/index.ts index 0ac46cfe95a..97b17e971bf 100644 --- a/dev/tool/src/index.ts +++ b/dev/tool/src/index.ts @@ -75,6 +75,7 @@ import path from 'path' import { buildStorageFromConfig, createStorageFromConfig, storageConfigFromEnv } from '@hcengineering/server-storage' import { program, type Command } from 'commander' +import { addControlledDocumentRank } from './qms' import { clearTelegramHistory } from './telegram' import { diffWorkspace, recreateElastic, updateField } from './workspace' @@ -2101,6 +2102,55 @@ export function devTool ( }) }) + program + .command('add-controlled-doc-rank-mongo') + .description('add rank to controlled documents') + .option('-w, --workspace ', 'Selected workspace only', '') + .action(async (cmd: { workspace: string }) => { + const { version } = prepareTools() + + let workspaces: Workspace[] = [] + await withAccountDatabase(async (db) => { + workspaces = await listWorkspacesPure(db) + workspaces = workspaces + .filter((p) => isActiveMode(p.mode)) + .filter((p) => cmd.workspace === '' || p.workspace === cmd.workspace) + .sort((a, b) => b.lastVisit - a.lastVisit) + }) + + console.log('found workspaces', workspaces.length) + + const mongodbUri = getMongoDBUrl() + const client = getMongoClient(mongodbUri) + const _client = await client.getClient() + + try { + const count = workspaces.length + let index = 0 + for (const workspace of workspaces) { + index++ + + toolCtx.info('processing workspace', { + workspace: workspace.workspace, + version: workspace.version, + index, + count + }) + + if (workspace.version === undefined || !deepEqual(workspace.version, version)) { + console.log(`upgrade to ${versionToString(version)} is required`) + continue + } + const workspaceId = getWorkspaceId(workspace.workspace) + const wsDb = getWorkspaceMongoDB(_client, { name: workspace.workspace }) + + await addControlledDocumentRank(toolCtx, wsDb, workspaceId) + } + } finally { + client.close() + } + }) + extendProgram?.(program) program.parse(process.argv) diff --git a/dev/tool/src/qms.ts b/dev/tool/src/qms.ts new file mode 100644 index 00000000000..43f26b2a3ea --- /dev/null +++ b/dev/tool/src/qms.ts @@ -0,0 +1,55 @@ +// +// Copyright © 2024 Hardcore Engineering Inc. +// +// Licensed under the Eclipse Public License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. You may +// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import { type MeasureContext, type Ref, type WorkspaceId } from '@hcengineering/core' +import documents, { type DocumentMeta, type ProjectMeta } from '@hcengineering/controlled-documents' +import { DOMAIN_DOCUMENTS } from '@hcengineering/model-controlled-documents' +import { type Db } from 'mongodb' +import { makeRank } from '@hcengineering/task' + +export async function addControlledDocumentRank (ctx: MeasureContext, db: Db, workspaceId: WorkspaceId): Promise { + const collections = await db.listCollections().toArray() + if (collections.find((it) => it.name === DOMAIN_DOCUMENTS) === undefined) { + ctx.error('skipping migration, no collection found', { workspace: workspaceId.name }) + return + } + + const prjMeta = await db + .collection(DOMAIN_DOCUMENTS) + .find({ _class: documents.class.ProjectMeta }) + .toArray() + + const docMeta = await db + .collection(DOMAIN_DOCUMENTS) + .find({ _class: documents.class.DocumentMeta }) + .toArray() + + const docMetaById = new Map, DocumentMeta>() + for (const doc of docMeta) { + docMetaById.set(doc._id, doc) + } + + prjMeta.sort((a, b) => { + const titleA = docMetaById.get(a.meta)?.title ?? '' + const titleB = docMetaById.get(b.meta)?.title ?? '' + return titleA.localeCompare(titleB, undefined, { numeric: true }) + }) + + let rank = makeRank(undefined, undefined) + for (const doc of prjMeta) { + await db.collection(DOMAIN_DOCUMENTS).updateOne({ _id: doc._id }, { $set: { rank } }) + rank = makeRank(rank, undefined) + } +}