Create script to update track changes stored format for all users (#26876)

* Create script to update track changes stored format for all users

* Create script to update track changes stored format for all users

* Dont remove guests

* Fix typo

* fix updateOne

---------

Co-authored-by: Domagoj Kriskovic <dom.kriskovic@overleaf.com>
GitOrigin-RevId: c2fddc46b78e84807243a752facdf0215d3ff082
This commit is contained in:
David
2025-11-24 11:29:42 +00:00
committed by Copybot
parent 44bd4ab790
commit dd8451d51d
@@ -0,0 +1,88 @@
// @ts-check
import { db } from '../app/src/infrastructure/mongodb.js'
import { batchedUpdate } from '@overleaf/mongo-utils/batchedUpdate.js'
import { scriptRunner } from './lib/ScriptRunner.mjs'
import CollaboratorsHandler from '../app/src/Features/Collaborators/CollaboratorsHandler.js'
const DRY_RUN = !process.argv.includes('--dry-run=false')
const DEBUG = process.argv.includes('--debug=true')
// Deployment procedure:
// Run it locally (not dry run)
// Run it on staging (dry run then real and then real). Maybe leave it a few days but might not get good feedback
// Run on prod on a small number of projects to start with, then on all projects (using BATCH_RANGE_START and BATCH_RANGE_END env vars)
// Are there race conditions here? If someone is editing in parallel. Is it worth doing atomic queries?
/**
* @typedef {Object} Project
* @property {any} _id
* @property {Object} track_changes
*/
/**
* @param {(progress: string) => Promise<void>} trackProgress
* @returns {Promise<void>}
* @async
*/
async function main(trackProgress) {
let projectsProcessed = 0
await batchedUpdate(
db.projects,
{},
/**
* @param {Array<Project>} projects
* @return {Promise<void>}
*/
async function projects(projects) {
for (const project of projects) {
projectsProcessed += 1
if (projectsProcessed % 100000 === 0) {
console.log(projectsProcessed, 'projects processed')
}
await processProject(project)
}
},
{ _id: 1, track_changes: 1 },
undefined,
{ trackProgress }
)
}
async function processProject(project) {
if (DEBUG) {
console.log(
`Processing project ${project._id} with track_changes: ${JSON.stringify(
project.track_changes
)}`
)
}
const newTrackChangesState =
await CollaboratorsHandler.promises.convertTrackChangesToExplicitFormat(
project._id,
project.track_changes
)
if (DEBUG) {
console.log(
`Processed project ${project._id} to have new track_changes: ${JSON.stringify(
newTrackChangesState
)}`
)
}
if (!DRY_RUN) {
await db.projects.updateOne(
{ _id: project._id },
{ $set: { track_changes: newTrackChangesState } }
)
}
}
try {
await scriptRunner(main)
process.exit(0)
} catch (error) {
console.error(error)
process.exit(1)
}