delete_orphaned_doc_comment_ranges.mjs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import minimist from 'minimist'
  2. import ChatApiHandler from '../app/src/Features/Chat/ChatApiHandler.js'
  3. import DocstoreManager from '../app/src/Features/Docstore/DocstoreManager.js'
  4. import DocumentUpdaterHandler from '../app/src/Features/DocumentUpdater/DocumentUpdaterHandler.js'
  5. import { promiseMapWithLimit } from '@overleaf/promise-utils'
  6. const WRITE_CONCURRENCY = parseInt(process.env.WRITE_CONCURRENCY, 10) || 10
  7. /**
  8. * Remove doc comment ranges that are "orphaned" as they do have matching chat
  9. * threads. This can happen when adding comments and the HTTP request fails, but
  10. * the ShareJS op succeeded (eventually). See https://github.com/overleaf/internal/issues/3425
  11. * for more detail.
  12. */
  13. async function main() {
  14. const argv = minimist(process.argv.slice(2))
  15. const { projectId, docId } = argv
  16. const threads = await ChatApiHandler.promises.getThreads(projectId)
  17. const threadIds = Object.keys(threads)
  18. const doc = await DocstoreManager.promises.getDoc(projectId, docId)
  19. const comments = doc.ranges.comments
  20. const orphanedCommentIds = comments.filter(comment => {
  21. const commentThreadId = comment.op.t
  22. return !threadIds.includes(commentThreadId)
  23. })
  24. await promiseMapWithLimit(
  25. WRITE_CONCURRENCY,
  26. orphanedCommentIds,
  27. async comment => {
  28. await DocumentUpdaterHandler.promises.deleteThread(
  29. projectId,
  30. docId,
  31. comment.op.t
  32. )
  33. }
  34. )
  35. await DocumentUpdaterHandler.promises.flushDocToMongo(projectId, docId)
  36. }
  37. try {
  38. await main()
  39. console.log('Done.')
  40. process.exit(0)
  41. } catch (error) {
  42. console.error({ error })
  43. process.exit(1)
  44. }