Sfoglia il codice sorgente

[web] Update survey filters (#32189)

Updates the filters to support different subscription cohorts: group plans, professional plans, etc.

GitOrigin-RevId: cc9ef4a2460942baa449fe7e6b8c14a88ae2f92f
Miguel Serrano 4 mesi fa
parent
commit
34fc7e2c7a

+ 12 - 10
services/web/app/src/Features/Subscription/SubscriptionLocator.mjs

@@ -71,17 +71,19 @@ const SubscriptionLocator = {
     return subscription?.admin_id
   },
 
-  async hasGroupSubscription(userOrId) {
-    if (!Features.hasFeature('saas')) return false
+  async getAllAssociatedSubscriptions(userOrId, projection = {}) {
+    if (!Features.hasFeature('saas')) return []
     const userId = SubscriptionLocator._getUserId(userOrId)
-    return await Subscription.exists({
-      groupPlan: true,
-      $or: [
-        { member_ids: userId },
-        { manager_ids: userId },
-        { admin_id: userId },
-      ],
-    }).exec()
+    return await Subscription.find(
+      {
+        $or: [
+          { admin_id: userId },
+          { manager_ids: userId },
+          { member_ids: userId },
+        ],
+      },
+      projection
+    ).exec()
   },
 
   async getSubscription(subscriptionId) {

+ 44 - 4
services/web/app/src/Features/Survey/SurveyHandler.mjs

@@ -3,6 +3,7 @@ import crypto from 'node:crypto'
 
 import SurveyCache from './SurveyCache.mjs'
 import SubscriptionLocator from '../Subscription/SubscriptionLocator.mjs'
+import PlansHelper from '../Subscription/PlansHelper.mjs'
 import { callbackify } from '@overleaf/promise-utils'
 import UserGetter from '../User/UserGetter.mjs'
 
@@ -19,10 +20,31 @@ import UserGetter from '../User/UserGetter.mjs'
 async function getSurvey(userId) {
   const survey = await SurveyCache.get(true)
   if (survey) {
-    if (survey.options?.hasGroupSubscription) {
-      const hasGroupSubscription =
-        await SubscriptionLocator.promises.hasGroupSubscription(userId)
-      if (!hasGroupSubscription) {
+    const hasFilters =
+      survey.options.hasFreeSubscription ||
+      survey.options.hasIndividualStandardSubscription ||
+      survey.options.hasIndividualProfessionalSubscription ||
+      survey.options.hasGroupStandardSubscription ||
+      survey.options.hasGroupProfessionalSubscription
+
+    if (hasFilters) {
+      const subscriptions =
+        await SubscriptionLocator.promises.getAllAssociatedSubscriptions(
+          userId,
+          {
+            groupPlan: 1,
+            planCode: 1,
+          }
+        )
+      const isFreeSubscription = Boolean(!subscriptions?.length)
+
+      if (isFreeSubscription) {
+        if (!survey.options?.hasFreeSubscription) {
+          return
+        }
+      } else if (
+        !subscriptions.some(sub => _canDisplaySurvey(sub, survey.options))
+      ) {
         return
       }
     }
@@ -64,6 +86,24 @@ async function getSurvey(userId) {
   }
 }
 
+function _canDisplaySurvey(subscription, options = {}) {
+  const {
+    hasIndividualStandardSubscription,
+    hasIndividualProfessionalSubscription,
+    hasGroupStandardSubscription,
+    hasGroupProfessionalSubscription,
+  } = options
+  const isGroupPlan = subscription.groupPlan
+  const isProfessional = PlansHelper.isProfessionalPlan(subscription.planCode)
+
+  return (
+    (hasIndividualStandardSubscription && !isGroupPlan && !isProfessional) ||
+    (hasIndividualProfessionalSubscription && !isGroupPlan && isProfessional) ||
+    (hasGroupStandardSubscription && isGroupPlan && !isProfessional) ||
+    (hasGroupProfessionalSubscription && isGroupPlan && isProfessional)
+  )
+}
+
 function _userRolloutPercentile(userId, surveyName) {
   const hash = crypto
     .createHash('md5')

+ 17 - 1
services/web/app/src/models/Survey.mjs

@@ -36,7 +36,23 @@ export const SurveySchema = new Schema(
       required: true,
     },
     options: {
-      hasGroupSubscription: {
+      hasFreeSubscription: {
+        type: Boolean,
+        default: false,
+      },
+      hasIndividualStandardSubscription: {
+        type: Boolean,
+        default: false,
+      },
+      hasIndividualProfessionalSubscription: {
+        type: Boolean,
+        default: false,
+      },
+      hasGroupStandardSubscription: {
+        type: Boolean,
+        default: false,
+      },
+      hasGroupProfessionalSubscription: {
         type: Boolean,
         default: false,
       },