From a62702354b293ccca08487a9b6889ba7bef20096 Mon Sep 17 00:00:00 2001 From: Konstantin Wohlwend Date: Tue, 19 May 2026 17:35:27 -0700 Subject: [PATCH] Don't show alpha apps during onboarding --- .../project-onboarding-wizard.test.tsx | 13 ++++++++++++- .../new-project/page-client-parts/shared.ts | 8 +++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/project-onboarding-wizard.test.tsx b/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/project-onboarding-wizard.test.tsx index ddccb656d..71494dbb0 100644 --- a/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/project-onboarding-wizard.test.tsx +++ b/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/project-onboarding-wizard.test.tsx @@ -137,7 +137,8 @@ vi.mock("./link-existing-onboarding", () => ({ })); import { ProjectOnboardingWizard } from "./project-onboarding-wizard"; -import { normalizeProjectOnboardingState, REQUIRED_APP_IDS } from "./shared"; +import { normalizeProjectOnboardingState, orderedAppIds, REQUIRED_APP_IDS } from "./shared"; +import { ALL_APPS } from "@stackframe/stack-shared/dist/apps/apps-config"; afterEach(() => { cleanup(); @@ -156,6 +157,16 @@ describe("ProjectOnboardingWizard", () => { expect(normalizedState.selected_apps).toEqual(REQUIRED_APP_IDS); }); + it("does not offer alpha apps during app selection", () => { + const alphaAppIds = Object.entries(ALL_APPS) + .filter(([, app]) => app.stage === "alpha") + .map(([appId]) => appId); + + for (const alphaAppId of alphaAppIds) { + expect(orderedAppIds()).not.toContain(alphaAppId); + } + }); + it("completes onboarding automatically after Stripe setup returns successfully", async () => { const setStatus = vi.fn(async () => {}); const onComplete = vi.fn(); diff --git a/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/shared.ts b/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/shared.ts index 621dce0c2..fee08aa52 100644 --- a/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/shared.ts +++ b/apps/dashboard/src/app/(main)/(protected)/(outside-dashboard)/new-project/page-client-parts/shared.ts @@ -22,6 +22,7 @@ export const SIGN_IN_METHODS: Array<{ id: SignInMethod, label: string }> = [ export const REQUIRED_APP_IDS: AppId[] = ["authentication", "emails"]; export const PRIMARY_APP_IDS: AppId[] = ["authentication", "emails", "payments", "analytics"]; export const ALL_APP_IDS = Object.keys(ALL_APPS) as AppId[]; +export const ONBOARDING_APP_IDS = ALL_APP_IDS.filter((appId) => ALL_APPS[appId].stage !== "alpha"); export const OAUTH_SIGN_IN_METHODS: SignInMethod[] = ["google", "github", "microsoft"]; export type ProjectOnboardingState = { @@ -149,11 +150,12 @@ export function isProjectOnboardingStatus(value: unknown): value is ProjectOnboa } export function orderedAppIds() { - const primarySet = new Set(PRIMARY_APP_IDS); - const secondary = ALL_APP_IDS.filter((appId) => !primarySet.has(appId)).sort((a, b) => { + const primary = PRIMARY_APP_IDS.filter((appId) => ONBOARDING_APP_IDS.some((onboardingAppId) => onboardingAppId === appId)); + const primarySet = new Set(primary); + const secondary = ONBOARDING_APP_IDS.filter((appId) => !primarySet.has(appId)).sort((a, b) => { return stringCompare(ALL_APPS[a].displayName, ALL_APPS[b].displayName); }); - return [...PRIMARY_APP_IDS, ...secondary]; + return [...primary, ...secondary]; } export function normalizeTrustedDomain(input: string): string {