Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/composables/useFeatureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export enum ServerFeatureFlag {
MODEL_UPLOAD_BUTTON_ENABLED = 'model_upload_button_enabled',
ASSET_UPDATE_OPTIONS_ENABLED = 'asset_update_options_enabled',
PRIVATE_MODELS_ENABLED = 'private_models_enabled',
SUBSCRIPTION_TIERS_ENABLED = 'subscription_tiers_enabled'
SUBSCRIPTION_TIERS_ENABLED = 'subscription_tiers_enabled',
ONBOARDING_SURVEY_ENABLED = 'onboarding_survey_enabled'
}

/**
Expand Down Expand Up @@ -66,6 +67,12 @@ export function useFeatureFlags() {
true // Default to true (new design)
)
)
},
get onboardingSurveyEnabled() {
return (
remoteConfig.value.onboarding_survey_enabled ??
api.getServerFeature(ServerFeatureFlag.ONBOARDING_SURVEY_ENABLED, true)
)
}
})

Expand Down
17 changes: 15 additions & 2 deletions src/platform/cloud/onboarding/CloudSurveyView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ import { computed, onMounted, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'

import { useFeatureFlags } from '@/composables/useFeatureFlags'
import {
getSurveyCompletedStatus,
submitSurvey
Expand All @@ -234,14 +235,22 @@ import { useTelemetry } from '@/platform/telemetry'

const { t } = useI18n()
const router = useRouter()
const { flags } = useFeatureFlags()
const onboardingSurveyEnabled = computed(
() => flags.onboardingSurveyEnabled ?? true
)

// Check if survey is already completed on mount
onMounted(async () => {
if (!onboardingSurveyEnabled.value) {
await router.replace({ name: 'cloud-user-check' })
return
}
try {
const surveyCompleted = await getSurveyCompletedStatus()
if (surveyCompleted) {
// User already completed survey, redirect to waitlist
await router.replace({ name: 'cloud-waitlist' })
// User already completed survey, return to onboarding flow
await router.replace({ name: 'cloud-user-check' })
} else {
// Track survey opened event
if (isCloud) {
Expand Down Expand Up @@ -342,6 +351,10 @@ const goTo = (step: number, activate: (val: string | number) => void) => {
// Submit
const onSubmitSurvey = async () => {
try {
if (!onboardingSurveyEnabled.value) {
await router.replace({ name: 'cloud-user-check' })
return
}
isSubmitting.value = true
// prepare payload with consistent structure
const payload = {
Expand Down
12 changes: 11 additions & 1 deletion src/platform/cloud/onboarding/UserCheckView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { computed, nextTick, ref } from 'vue'
import { useRouter } from 'vue-router'

import { useErrorHandling } from '@/composables/useErrorHandling'
import { useFeatureFlags } from '@/composables/useFeatureFlags'
import {
getSurveyCompletedStatus,
getUserCloudStatus
Expand All @@ -40,6 +41,10 @@ import CloudSurveyViewSkeleton from './skeletons/CloudSurveyViewSkeleton.vue'

const router = useRouter()
const { wrapWithErrorHandlingAsync } = useErrorHandling()
const { flags } = useFeatureFlags()
const onboardingSurveyEnabled = computed(
() => flags.onboardingSurveyEnabled ?? true
)

const skeletonType = ref<'login' | 'survey' | 'waitlist' | 'loading'>('loading')

Expand All @@ -51,6 +56,11 @@ const {
wrapWithErrorHandlingAsync(async () => {
await nextTick()

if (!onboardingSurveyEnabled.value) {
await router.replace({ path: '/' })
return
}

const [cloudUserStats, surveyStatus] = await Promise.all([
getUserCloudStatus(),
getSurveyCompletedStatus()
Expand All @@ -63,7 +73,7 @@ const {
return
}

// Survey is required for all users
// Survey is required for all users when feature flag is enabled
if (!surveyStatus) {
skeletonType.value = 'survey'
await router.replace({ name: 'cloud-survey' })
Expand Down
1 change: 1 addition & 0 deletions src/platform/remoteConfig/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export type RemoteConfig = {
asset_update_options_enabled?: boolean
private_models_enabled?: boolean
subscription_tiers_enabled?: boolean
onboarding_survey_enabled?: boolean
stripe_publishable_key?: string
stripe_pricing_table_id?: string
}
9 changes: 7 additions & 2 deletions src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from 'vue-router'
import type { RouteLocationNormalized } from 'vue-router'

import { useFeatureFlags } from '@/composables/useFeatureFlags'
import { isCloud } from '@/platform/distribution/types'
import { useDialogService } from '@/services/dialogService'
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
Expand Down Expand Up @@ -89,6 +90,7 @@ installPreservedQueryTracker(router, [
])

if (isCloud) {
const { flags } = useFeatureFlags()
const PUBLIC_ROUTE_NAMES = new Set([
'cloud-login',
'cloud-signup',
Expand Down Expand Up @@ -165,17 +167,20 @@ if (isCloud) {
return next({ name: 'cloud-login' })
}

// User is logged in - check if they need onboarding
// User is logged in - check if they need onboarding (when enabled)
// For root path, check actual user status to handle waitlisted users
if (!isElectron() && isLoggedIn && to.path === '/') {
if (!flags.onboardingSurveyEnabled) {
return next()
}
// Import auth functions dynamically to avoid circular dependency
const { getSurveyCompletedStatus } =
await import('@/platform/cloud/onboarding/auth')
try {
// Check user's actual status
const surveyCompleted = await getSurveyCompletedStatus()

// Survey is required for all users regardless of whitelist status
// Survey is required for all users (when feature flag enabled)
if (!surveyCompleted) {
return next({ name: 'cloud-survey' })
}
Expand Down