Files
sean-brydonGitHubcoderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>Hariom Balhara
fa35cc5210 chore: organization onboarding refactor (#24381)
* feat: redirect to new onboarding flow

* Getting started

* Brand details

* Preview organization brands

* Orgs team pages

* Invite team steps

* Move to global zustand store

* Few darkmdoe fixes

* Wip onboarding + stripe flow

* Default plan state

Server Action for gettting slug satus of org

* Remove onboardingId

* Confirmation prompt

* Update old onboarding flow handlers to handle new fields

* update onboarding hook

* Filter out organization section for none -company emails

* Match placeholders to users domain

* Drop migration

* Wip new onboarding intent

* WIP flow for self-hosted. Same service call just split logic

* WIP

* Add TODO

* Use onboarding user type instead of trpc session

* WIP

* WIP

* pass role and team name from onboarding to save in schema

* Add test to ensure role + name + team are persisted into onboarding table

* migrate roles to enum values

* Update ENUM

* Fix type error

* Redirect if flag is disabled

* Remove web

* WIP

* WIP

* Fix migration

* Fix calls

* User onboarding User types instead of trpc session

* Fix factory tests

* Fix flow for self hoste

* Type error

* More type fixes

* Fix handler tests

* Fix enum return type being different

* Use consistant types across the oganization stuff

* Fix

* Use TEAM_BILLING for e2e test

* Refactor is not company email and add tests

* Fix

* Fix

* Refactor flow to submit after form complete

* Fix flow with billing disabled

* Fix tests

* Apply suggestion from @coderabbitai[bot]

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Rename and move test files

* WIP

* Fix types

* Update repo paths + tests

* Move to service folder

* Fix tests

* Fix types

* Remove old test files

* Restore lock

* Fix path

* Fix tests with new paths and factory logic

* Fix updaetdAt

* WIP onboardingID isolation

* Fix e2e test

* verify test

* Code rabbit

* Rename SelfHostedOnboardongService -> SelfHostedOrganizationOnboardingService

* Fix stores

* Fix type error

* Fix types

* remove tsignore

* Apply suggestion from @coderabbitai[bot]

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* NITS

* Add the logic to auto complete admin org when billing enabled

* Fix store being weird

* We need to return the parsed value

* fixes

* sync from db always

* Add onboardingSgtore tests

* fix test

* remove step and status

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <[email protected]>
2025-10-18 14:13:30 +00:00

84 lines
2.6 KiB
TypeScript

import { SelfHostedOrganizationOnboardingService } from "@calcom/features/ee/organizations/lib/service/onboarding/SelfHostedOnboardingService";
import { IS_SELF_HOSTED } from "@calcom/lib/constants";
import { OrganizationOnboardingRepository } from "@calcom/lib/server/repository/organizationOnboarding";
import { TRPCError } from "@trpc/server";
import type { TrpcSessionUser } from "../../../types";
import type { TCreateSelfHostedInputSchema } from "./createSelfHosted.schema";
type CreateSelfHostedOptions = {
ctx: {
user: NonNullable<TrpcSessionUser>;
};
input: TCreateSelfHostedInputSchema;
};
export const createSelfHostedHandler = async ({ input, ctx }: CreateSelfHostedOptions) => {
if (!IS_SELF_HOSTED) {
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: "Self-hosted is not enabled",
});
}
if (!input.onboardingId) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "onboardingId is required",
});
}
const organizationOnboarding = await OrganizationOnboardingRepository.findById(input.onboardingId);
if (!organizationOnboarding) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Organization onboarding not found",
});
}
if (!organizationOnboarding.orgOwnerEmail) {
throw new TRPCError({
code: "BAD_REQUEST",
message: "Organization owner email not found",
});
}
const userContext = {
id: ctx.user.id,
email: ctx.user.email,
role: ctx.user.role as "ADMIN" | "USER",
name: ctx.user.name || undefined,
};
const onboardingService = new SelfHostedOrganizationOnboardingService(userContext);
const { organization } = await onboardingService.createOrganization({
id: input.onboardingId,
logo: input.logo ?? null,
bio: input.bio ?? null,
brandColor: input.brandColor ?? null,
bannerUrl: input.bannerUrl ?? null,
invitedMembers: input.invitedMembers ?? [],
teams: input.teams ?? [],
orgOwnerEmail: organizationOnboarding.orgOwnerEmail,
slug: organizationOnboarding.slug,
name: organizationOnboarding.name,
billingPeriod: organizationOnboarding.billingPeriod,
seats: organizationOnboarding.seats,
pricePerSeat: organizationOnboarding.pricePerSeat,
stripeCustomerId: organizationOnboarding.stripeCustomerId,
isPlatform: organizationOnboarding.isPlatform,
isDomainConfigured: organizationOnboarding.isDomainConfigured,
organizationId: organizationOnboarding.organizationId,
});
await OrganizationOnboardingRepository.markAsComplete(organizationOnboarding.id);
return {
organization,
};
};
export default createSelfHostedHandler;