feat: migrate from aiErrorAssist naming for disabling AI features to aiFeatures.enabled to avoid confusion (#31273)

feat: keep aiErrorAssistant as setting on user object until migration is run
GitOrigin-RevId: df53914163566065d0b91b8d130476fbcdf1ea96
This commit is contained in:
Jimmy Domagala-Tang
2026-02-13 09:05:57 +00:00
committed by Copybot
parent df8190ec8c
commit 551d7b3908
10 changed files with 40 additions and 28 deletions
@@ -472,7 +472,7 @@ const _ProjectController = {
user: (async () => {
const user = await User.findById(
userId,
'email first_name last_name referal_id signUpDate featureSwitches features featuresEpoch refProviders alphaProgram betaProgram isAdmin ace labsProgram labsExperiments completedTutorials writefull aiErrorAssistant'
'email first_name last_name referal_id signUpDate featureSwitches features featuresEpoch refProviders alphaProgram betaProgram isAdmin ace labsProgram labsExperiments completedTutorials writefull aiFeatures aiErrorAssistant'
).exec()
// Handle case of deleted user
if (!user) {
@@ -844,13 +844,10 @@ const _ProjectController = {
}
const hasPaidSubscription = isPaidSubscription(subscription)
const hasManuallyCollectedSubscription =
subscription?.collectionMethod === 'manual'
const assistantDisabled = user.aiErrorAssistant?.enabled === false // the assistant has been manually disabled by the user
const canUseErrorAssistant =
(!hasManuallyCollectedSubscription ||
fullFeatureSet?.aiErrorAssistant) &&
!assistantDisabled
// todo: assist clean-up: remove other case once migration finishes
const aiFeaturesDisabled =
user.aiFeatures?.enabled === false ||
user.aiErrorAssistant?.enabled === false // the assistant has been manually disabled by the user
const addonPrices =
isOverleafAssistBundleEnabled &&
@@ -958,7 +955,7 @@ const _ProjectController = {
showSymbolPalette,
symbolPaletteAvailable: Features.hasFeature('symbol-palette'),
userRestrictions: Array.from(req.userRestrictions || []),
showAiErrorAssistant: aiFeaturesAllowed && canUseErrorAssistant,
showAiFeatures: aiFeaturesAllowed && !aiFeaturesDisabled,
detachRole,
metadata: { viewport: false },
showUpgradePrompt,
@@ -168,7 +168,9 @@ async function projectListPage(req, res, next) {
const user = await User.findById(
userId,
`email isAdmin emails features alphaProgram betaProgram lastPrimaryEmailCheck lastActive signUpDate ace refProviders${
isSaas ? ' enrollment writefull completedTutorials aiErrorAssistant' : ''
isSaas
? ' enrollment writefull completedTutorials aiFeatures aiErrorAssistant'
: ''
}`
)
@@ -904,7 +906,11 @@ async function _userHasAIAssist(user) {
// It does NOT determine if the user has AI Assist enabled
async function _canUseAIAssist(user) {
// Check if the assistant has been manually disabled by the user
if (user.aiErrorAssistant?.enabled === false) {
// todo: assist clean-up: remove other case once migration finishes
if (
user.aiErrorAssistant?.enabled === false ||
user.aiFeatures?.enabled === false
) {
return false
}
@@ -147,8 +147,8 @@ async function settingsPage(req, res) {
writefull: {
enabled: Boolean(user.writefull?.enabled),
},
aiErrorAssistant: {
enabled: Boolean(user.aiErrorAssistant?.enabled),
aiFeatures: {
enabled: Boolean(user.aiFeatures?.enabled),
},
},
labsExperiments: user.labsExperiments ?? [],
+4
View File
@@ -198,6 +198,10 @@ export const UserSchema = new Schema(
isPremium: { type: Boolean, default: false },
premiumSource: { type: String, default: null },
},
aiFeatures: {
enabled: { type: Boolean, default: true },
},
// todo: assist clean-up: remove this once migration is finished
aiErrorAssistant: {
enabled: { type: Boolean, default: true },
},
@@ -24,7 +24,7 @@ meta(name="ol-wsRetryHandshake" data-type="json" content=settings.wsRetryHandsha
meta(name="ol-debugPdfDetach" data-type="boolean" content=debugPdfDetach)
meta(name="ol-showSymbolPalette" data-type="boolean" content=showSymbolPalette)
meta(name="ol-symbolPaletteAvailable" data-type="boolean" content=symbolPaletteAvailable)
meta(name="ol-showAiErrorAssistant" data-type="boolean" content=showAiErrorAssistant)
meta(name="ol-showAiFeatures" data-type="boolean" content=showAiFeatures)
meta(name="ol-detachRole" data-type="string" content=detachRole)
meta(name="ol-imageNames" data-type="json" content=imageNames)
meta(name="ol-languages" data-type="json" content=languages)