delete_orphaned_doc_comment_ranges.js 1.7 KB

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