convert_track_changes_to_explicit_format.mjs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // @ts-check
  2. import { db } from '../app/src/infrastructure/mongodb.js'
  3. import { batchedUpdate } from '@overleaf/mongo-utils/batchedUpdate.js'
  4. import { scriptRunner } from './lib/ScriptRunner.mjs'
  5. import CollaboratorsHandler from '../app/src/Features/Collaborators/CollaboratorsHandler.js'
  6. const DRY_RUN = !process.argv.includes('--dry-run=false')
  7. const DEBUG = process.argv.includes('--debug=true')
  8. // Deployment procedure:
  9. // Run it locally (not dry run)
  10. // Run it on staging (dry run then real and then real). Maybe leave it a few days but might not get good feedback
  11. // 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)
  12. // Are there race conditions here? If someone is editing in parallel. Is it worth doing atomic queries?
  13. /**
  14. * @typedef {Object} Project
  15. * @property {any} _id
  16. * @property {Object} track_changes
  17. */
  18. /**
  19. * @param {(progress: string) => Promise<void>} trackProgress
  20. * @returns {Promise<void>}
  21. * @async
  22. */
  23. async function main(trackProgress) {
  24. let projectsProcessed = 0
  25. await batchedUpdate(
  26. db.projects,
  27. {},
  28. /**
  29. * @param {Array<Project>} projects
  30. * @return {Promise<void>}
  31. */
  32. async function projects(projects) {
  33. for (const project of projects) {
  34. projectsProcessed += 1
  35. if (projectsProcessed % 100000 === 0) {
  36. console.log(projectsProcessed, 'projects processed')
  37. }
  38. await processProject(project)
  39. }
  40. },
  41. { _id: 1, track_changes: 1 },
  42. undefined,
  43. { trackProgress }
  44. )
  45. }
  46. async function processProject(project) {
  47. if (DEBUG) {
  48. console.log(
  49. `Processing project ${project._id} with track_changes: ${JSON.stringify(
  50. project.track_changes
  51. )}`
  52. )
  53. }
  54. const newTrackChangesState =
  55. await CollaboratorsHandler.promises.convertTrackChangesToExplicitFormat(
  56. project._id,
  57. project.track_changes
  58. )
  59. if (DEBUG) {
  60. console.log(
  61. `Processed project ${project._id} to have new track_changes: ${JSON.stringify(
  62. newTrackChangesState
  63. )}`
  64. )
  65. }
  66. if (!DRY_RUN) {
  67. await db.projects.updateOne(
  68. { _id: project._id },
  69. { $set: { track_changes: newTrackChangesState } }
  70. )
  71. }
  72. }
  73. try {
  74. await scriptRunner(main)
  75. process.exit(0)
  76. } catch (error) {
  77. console.error(error)
  78. process.exit(1)
  79. }