backfill_user_properties.mjs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { batchedUpdateWithResultHandling } from '@overleaf/mongo-utils/batchedUpdate.js'
  2. import { promiseMapWithLimit } from '@overleaf/promise-utils'
  3. import SubscriptionLocator from '../app/src/Features/Subscription/SubscriptionLocator.mjs'
  4. import PlansLocator from '../app/src/Features/Subscription/PlansLocator.mjs'
  5. import FeaturesHelper from '../app/src/Features/Subscription/FeaturesHelper.mjs'
  6. import AnalyticsManager from '../app/src/Features/Analytics/AnalyticsManager.mjs'
  7. import { db } from '../app/src/infrastructure/mongodb.mjs'
  8. const WRITE_CONCURRENCY = parseInt(process.env.WRITE_CONCURRENCY, 10) || 10
  9. async function getGroupSubscriptionPlanCode(userId) {
  10. const subscriptions =
  11. await SubscriptionLocator.promises.getMemberSubscriptions(userId)
  12. let bestPlanCode = null
  13. let bestFeatures = {}
  14. for (const subscription of subscriptions) {
  15. const plan = PlansLocator.findLocalPlanInSettings(subscription.planCode)
  16. if (
  17. plan &&
  18. FeaturesHelper.isFeatureSetBetter(plan.features, bestFeatures)
  19. ) {
  20. bestPlanCode = plan.planCode
  21. bestFeatures = plan.features
  22. }
  23. }
  24. return bestPlanCode
  25. }
  26. async function processUser(user) {
  27. const analyticsId = user.analyticsId || user._id
  28. const groupSubscriptionPlanCode = await getGroupSubscriptionPlanCode(user._id)
  29. if (groupSubscriptionPlanCode) {
  30. await AnalyticsManager.setUserPropertyForAnalyticsId(
  31. analyticsId,
  32. 'group-subscription-plan-code',
  33. groupSubscriptionPlanCode
  34. )
  35. }
  36. const matchedFeatureSet = FeaturesHelper.getMatchedFeatureSet(user.features)
  37. if (matchedFeatureSet !== 'personal') {
  38. await AnalyticsManager.setUserPropertyForAnalyticsId(
  39. analyticsId,
  40. 'feature-set',
  41. matchedFeatureSet
  42. )
  43. }
  44. }
  45. async function processBatch(users) {
  46. await promiseMapWithLimit(WRITE_CONCURRENCY, users, async user => {
  47. await processUser(user)
  48. })
  49. }
  50. batchedUpdateWithResultHandling(db.users, {}, processBatch, {
  51. _id: true,
  52. analyticsId: true,
  53. features: true,
  54. })