| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- // @ts-check
- import { db } from '../app/src/infrastructure/mongodb.mjs'
- import { batchedUpdate } from '@overleaf/mongo-utils/batchedUpdate.js'
- import { scriptRunner } from './lib/ScriptRunner.mjs'
- import CollaboratorsHandler from '../app/src/Features/Collaborators/CollaboratorsHandler.mjs'
- 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
- )}`
- )
- }
- if (typeof project.track_changes === 'object') {
- if (DEBUG) {
- console.log(
- `Skipping project ${project._id} as it is already in the new format`
- )
- }
- return
- }
- 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 } }
- )
- console.log(
- `Updated project ${project._id} track_changes from ${JSON.stringify(project.track_changes)} to ${JSON.stringify(newTrackChangesState)}`
- )
- } else {
- console.log(
- `Dry run - would have updated project ${project._id} track_changes from ${JSON.stringify(project.track_changes)} to ${JSON.stringify(newTrackChangesState)}`
- )
- }
- }
- try {
- await scriptRunner(main)
- process.exit(0)
- } catch (error) {
- console.error(error)
- process.exit(1)
- }
|