Просмотр исходного кода

Merge pull request #20937 from overleaf/jdt-ai-addon-grants-feat

Grant feature access to users purchasing the ai add-on

GitOrigin-RevId: a4183beab957e4d0c362c8f0978be395b86ce398
Jimmy Domagala-Tang 1 год назад
Родитель
Сommit
27fb9aadf3

+ 21 - 1
services/web/app/src/Features/Subscription/FeaturesUpdater.js

@@ -15,6 +15,8 @@ const AnalyticsManager = require('../Analytics/AnalyticsManager')
 const Queues = require('../../infrastructure/Queues')
 const Modules = require('../../infrastructure/Modules')
 
+const AI_ADDON_CODE = 'assistant'
+
 /**
  * Enqueue a job for refreshing features for the given user
  */
@@ -147,7 +149,13 @@ async function _getV1Features(user) {
 }
 
 function _subscriptionToFeatures(subscription) {
-  return _planCodeToFeatures(subscription && subscription.planCode)
+  const addonFeatures = _subscriptionAddonsToFeatures(
+    subscription && subscription.addOns
+  )
+  const planFeatures = _planCodeToFeatures(
+    subscription && subscription.planCode
+  )
+  return FeaturesHelper.mergeFeatures(addonFeatures, planFeatures)
 }
 
 function _planCodeToFeatures(planCode) {
@@ -162,6 +170,18 @@ function _planCodeToFeatures(planCode) {
   }
 }
 
+function _subscriptionAddonsToFeatures(addOns) {
+  if (!addOns) {
+    return {}
+  }
+  const hasAiAddon = addOns.some(addOn => addOn.addOnCode === AI_ADDON_CODE)
+  if (hasAiAddon) {
+    return { aiErrorAssistant: true }
+  } else {
+    return {}
+  }
+}
+
 async function doSyncFromV1(v1UserId) {
   logger.debug({ v1UserId }, '[AccountSync] starting account sync')
   const user = await UserGetter.promises.getUser(

+ 6 - 0
services/web/app/src/Features/Subscription/RecurlyClient.js

@@ -44,6 +44,10 @@ async function getSubscription(subscriptionId) {
   return await client.getSubscription(subscriptionId)
 }
 
+async function getSubscriptionByUuid(subscriptionUuid) {
+  return await client.getSubscription('uuid-' + subscriptionUuid)
+}
+
 async function changeSubscription(subscriptionId, body) {
   const change = await client.createSubscriptionChange(subscriptionId, body)
   logger.debug(
@@ -101,6 +105,7 @@ module.exports = {
   getAccountForUserId: callbackify(getAccountForUserId),
   createAccountForUserId: callbackify(createAccountForUserId),
   getSubscription: callbackify(getSubscription),
+  getSubscriptionByUuid: callbackify(getSubscriptionByUuid),
   changeSubscription: callbackify(changeSubscription),
   changeSubscriptionByUuid: callbackify(changeSubscriptionByUuid),
   removeSubscriptionChange: callbackify(removeSubscriptionChange),
@@ -111,6 +116,7 @@ module.exports = {
 
   promises: {
     getSubscription,
+    getSubscriptionByUuid,
     getAccountForUserId,
     createAccountForUserId,
     changeSubscription,

+ 9 - 0
services/web/app/src/Features/Subscription/SubscriptionUpdater.js

@@ -305,8 +305,17 @@ async function updateSubscriptionFromRecurly(
     return
   }
 
+  const addOns = recurlySubscription?.subscription_add_ons?.map(addOn => {
+    return {
+      addOnCode: addOn.add_on_code,
+      quantity: addOn.quantity,
+      unitAmountInCents: addOn.unit_amount_in_cents,
+    }
+  })
+
   subscription.recurlySubscription_id = recurlySubscription.uuid
   subscription.planCode = updatedPlanCode
+  subscription.addOns = addOns || []
   subscription.recurlyStatus = {
     state: recurlySubscription.state,
     trialStartedAt: recurlySubscription.trial_started_at,

+ 1 - 0
services/web/app/src/models/Subscription.js

@@ -36,6 +36,7 @@ const SubscriptionSchema = new Schema(
       managedUsers: { type: Boolean, default: null },
       groupSSO: { type: Boolean, default: null },
     },
+    addOns: Schema.Types.Mixed,
     overleaf: {
       id: {
         type: Number,