Remove Writefull.enabled (#31476)

* feat: migrate from aiErrorAssist naming for disabling AI features to aiFeatures.enabled to avoid confusion

feat: keep aiErrorAssistant as setting on user object until migration is run

* feat: migrate writefull.enabled unset to instead use promotionSet false

* feat: remove wf.enabled in favor for aiFeatures.enabled for display, and writefull.promotionSet for determining if we should autoload or autocreate

GitOrigin-RevId: 2b7a5b8a430a804f6c9804cc926cb5c057e34df5
This commit is contained in:
Jimmy Domagala-Tang
2026-02-19 09:09:00 -05:00
committed by Copybot
parent 48a5de31e1
commit 8e5c207f6b
7 changed files with 17 additions and 50 deletions
@@ -473,7 +473,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 aiFeatures aiErrorAssistant'
'email first_name last_name referal_id signUpDate featureSwitches features featuresEpoch refProviders alphaProgram betaProgram isAdmin ace labsProgram labsExperiments completedTutorials writefull aiFeatures'
).exec()
// Handle case of deleted user
if (!user) {
@@ -845,10 +845,7 @@ const _ProjectController = {
}
const hasPaidSubscription = isPaidSubscription(subscription)
// 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 aiFeaturesDisabled = user.aiFeatures?.enabled === false
const addonPrices =
isOverleafAssistBundleEnabled &&
@@ -909,9 +906,7 @@ const _ProjectController = {
featureUsage,
refProviders: _.mapValues(user.refProviders, Boolean),
writefull: {
enabled: Boolean(user.writefull?.enabled && aiFeaturesAllowed),
autoCreatedAccount: Boolean(user.writefull?.autoCreatedAccount),
firstAutoLoad: Boolean(user.writefull?.firstAutoLoad),
},
alphaProgram: user.alphaProgram,
betaProgram: user.betaProgram,
@@ -1242,6 +1237,10 @@ const _ProjectController = {
aiFeaturesAllowed,
userIsMemberOfGroupSubscription
) {
if (!aiFeaturesAllowed) {
return
}
const affiliations = userValues.affiliations
const affiliateLookupFailed = affiliations === false
@@ -1252,13 +1251,8 @@ const _ProjectController = {
affiliation => affiliation.institution?.enterpriseCommons
)
// check if a user has never tried writefull before (writefull.enabled will be null)
// if they previously accepted writefull, or are have been already assigned to a trial, user.writefull will be true,
// if they explicitly disabled it, user.writefull will be false
const shouldPushWritefull =
aiFeaturesAllowed &&
user.writefull?.enabled === null &&
!userIsMemberOfGroupSubscription
user.writefull?.initialized === false && !userIsMemberOfGroupSubscription
// we dont have legal approval to push enterprise commons into WF auto-account-create, but we are able to auto-load it into the toolbar
const shouldAutoCreateAccount = shouldPushWritefull && !inEnterpriseCommons
@@ -1267,28 +1261,16 @@ const _ProjectController = {
if (shouldAutoCreateAccount) {
await UserUpdater.promises.updateUser(userId, {
$set: {
writefull: {
enabled: true,
initialized: true,
autoCreatedAccount: true,
},
writefull: { autoCreatedAccount: true, initialized: true },
},
})
user.writefull.enabled = true
user.writefull.initialized = true
user.writefull.autoCreatedAccount = true
} else if (shouldAutoLoad) {
await UserUpdater.promises.updateUser(userId, {
$set: {
writefull: {
enabled: true,
initialized: true,
autoCreatedAccount: false,
},
writefull: { autoCreatedAccount: false, initialized: true },
},
})
user.writefull.enabled = true
user.writefull.initialized = true
user.writefull.autoCreatedAccount = false
}
},
@@ -1316,6 +1298,9 @@ const defaultSettingsForAnonymousUser = userId => ({
alphaProgram: false,
betaProgram: false,
writefull: {
initialized: true,
},
aiFeatures: {
enabled: false,
},
})
@@ -918,11 +918,7 @@ 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
// todo: assist clean-up: remove other case once migration finishes
if (
user.aiErrorAssistant?.enabled === false ||
user.aiFeatures?.enabled === false
) {
if (user.aiFeatures?.enabled === false) {
return false
}
@@ -144,13 +144,8 @@ async function settingsPage(req, res) {
zotero: Boolean(user.refProviders?.zotero),
papers: Boolean(user.refProviders?.papers),
},
writefull: {
enabled: Boolean(user.writefull?.enabled),
},
aiFeatures: {
enabled: Boolean(user.aiFeatures?.enabled),
},
},
showAiFeatures: Boolean(user.aiFeatures?.enabled),
labsExperiments: user.labsExperiments ?? [],
hasPassword: !!user.hashedPassword,
shouldAllowEditingDetails,
-5
View File
@@ -193,7 +193,6 @@ export const UserSchema = new Schema(
papers: Schema.Types.Mixed,
},
writefull: {
enabled: { type: Boolean, default: null },
// whether we have attached an autocreated account or autoloading for the user
initialized: { type: Boolean, default: false },
autoCreatedAccount: { type: Boolean, default: false },
@@ -203,10 +202,6 @@ export const UserSchema = new Schema(
aiFeatures: {
enabled: { type: Boolean, default: true },
},
// todo: assist clean-up: remove this once migration is finished
aiErrorAssistant: {
enabled: { type: Boolean, default: true },
},
alphaProgram: { type: Boolean, default: false }, // experimental features
betaProgram: { type: Boolean, default: false },
labsProgram: { type: Boolean, default: false },
+1
View File
@@ -37,6 +37,7 @@ block append meta
content=externalAuthenticationSystemUsed()
)
meta(name='ol-user' data-type='json' content=user)
meta(name='ol-showAiFeatures' data-type='boolean' content=showAiFeatures)
meta(name='ol-labsExperiments' data-type='json' content=labsExperiments)
meta(name='ol-dropbox' data-type='json' content=dropbox)
meta(name='ol-github' data-type='json' content=github)
+2 -2
View File
@@ -38,8 +38,8 @@ async function createUser(email) {
// Override features.
features,
featuresOverrides: [{ features }],
// disable Writefull
'writefull.enabled': false,
// disable AI features
'aiFeatures.enabled': false,
},
}
)
-5
View File
@@ -49,14 +49,9 @@ export type User = {
features?: Features
refProviders?: RefProviders
writefull?: {
enabled: boolean
autoCreatedAccount: boolean
firstAutoLoad: boolean
premiumSource: string
}
aiErrorAssistant?: {
enabled: boolean
}
featureUsage?: FeatureUsage
planCode?: string
planName?: string