import slugify from "@calcom/lib/slugify"; import { prisma } from "@calcom/prisma"; import { MembershipRole } from "@calcom/prisma/enums"; import { teamMetadataSchema } from "@calcom/prisma/zod-utils"; import { TRPCError } from "@trpc/server"; import type { TrpcSessionUser } from "../../../trpc"; import type { TCreateTeamsSchema } from "./createTeams.schema"; type CreateTeamsOptions = { ctx: { user: NonNullable; }; input: TCreateTeamsSchema; }; export const createTeamsHandler = async ({ ctx, input }: CreateTeamsOptions) => { const { teamNames, orgId } = input; const organization = await prisma.team.findFirst({ where: { id: orgId }, select: { metadata: true } }); const metadata = teamMetadataSchema.parse(organization?.metadata); if (!metadata?.requestedSlug) throw new TRPCError({ code: "BAD_REQUEST", message: "no_organization" }); const userMembership = await prisma.membership.findFirst({ where: { userId: ctx.user.id, teamId: orgId, }, select: { userId: true, role: true, }, }); // TODO test this check works if (!userMembership || userMembership.role !== MembershipRole.OWNER) throw new TRPCError({ code: "BAD_REQUEST", message: "not_authorized" }); const [teamSlugs, userSlugs] = await prisma.$transaction([ prisma.team.findMany({ where: { parentId: orgId }, select: { slug: true } }), prisma.user.findMany({ where: { organizationId: orgId }, select: { username: true } }), ]); const existingSlugs = teamSlugs .flatMap((ts) => ts.slug ?? []) .concat(userSlugs.flatMap((us) => us.username ?? [])); const duplicatedSlugs = existingSlugs.filter((slug) => teamNames.includes(slug)); await prisma.$transaction( teamNames.flatMap((name) => { if (!duplicatedSlugs.includes(name)) { return prisma.team.create({ data: { name, parentId: orgId, slug: slugify(name), members: { create: { userId: ctx.user.id, role: MembershipRole.OWNER, accepted: true }, }, }, }); } else { return []; } }) ); return { duplicatedSlugs }; };