feat: create workspace on successful activation

This commit is contained in:
Henry
2026-04-10 15:28:27 +01:00
parent 6dfee580f7
commit cb76926041
6 changed files with 96 additions and 38 deletions

View File

@@ -113,18 +113,23 @@ export default withRateLimit(
resolvedWorkspacePublicId = generateUID();
}
const priceId =
billing === "annual"
? (process.env.STRIPE_PRO_PLAN_ANNUAL_PRICE_ID ??
process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID)
: process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID;
const isTeam = body.plan === "team";
const annualPriceId = isTeam
? (process.env.STRIPE_TEAM_PLAN_ANNUAL_PRICE_ID ??
process.env.STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID)
: (process.env.STRIPE_PRO_PLAN_ANNUAL_PRICE_ID ??
process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID);
const monthlyPriceId = isTeam
? process.env.STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID
: process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID;
const priceId = billing === "annual" ? annualPriceId : monthlyPriceId;
const session = await stripe.checkout.sessions.create({
mode: "subscription",
payment_method_collection: "always",
line_items: [{ price: priceId, quantity: 1 }],
subscription_data: { trial_period_days: 14 },
success_url: `${env("NEXT_PUBLIC_BASE_URL")}${successUrl}`,
success_url: `${env("NEXT_PUBLIC_BASE_URL")}${successUrl}?workspacePublicId=${resolvedWorkspacePublicId}`,
cancel_url: `${env("NEXT_PUBLIC_BASE_URL")}${cancelUrl}`,
client_reference_id: resolvedWorkspacePublicId,
customer: user.stripeCustomerId ?? undefined,

View File

@@ -3,6 +3,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
import type { Readable } from "node:stream";
import { createNextApiContext } from "@kan/api/trpc";
import * as subscriptionRepo from "@kan/db/repository/subscription.repo";
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
import { createLogger } from "@kan/logger";
import { createStripeClient } from "@kan/stripe";
@@ -55,34 +56,47 @@ export default async function handler(
if (!meta?.workspacePublicId) break;
const plan = meta.plan === "team" ? "team" : ("pro" as const);
if (
meta.isNewWorkspace === "true" &&
meta.workspaceName &&
meta.userId &&
meta.userEmail
) {
const slug = meta.workspaceSlug ?? meta.workspacePublicId;
const existing = await workspaceRepo.getByPublicId(db, meta.workspacePublicId);
await workspaceRepo.create(db, {
publicId: meta.workspacePublicId,
name: meta.workspaceName,
slug,
createdBy: meta.userId,
createdByEmail: meta.userEmail,
...(meta.workspaceDescription && {
description: meta.workspaceDescription,
}),
if (!existing) {
const slug = meta.workspaceSlug ?? meta.workspacePublicId;
await workspaceRepo.create(db, {
publicId: meta.workspacePublicId,
name: meta.workspaceName,
slug,
plan,
createdBy: meta.userId,
createdByEmail: meta.userEmail,
...(meta.workspaceDescription && {
description: meta.workspaceDescription,
}),
});
await subscriptionRepo.create(db, {
plan,
referenceId: meta.workspacePublicId,
userId: meta.userId,
stripeCustomerId: checkoutSession.customer as string,
status: "active",
});
}
} else {
// Existing workspace upgrade — update plan (and slug for pro)
await workspaceRepo.update(db, meta.workspacePublicId, {
plan,
...(plan === "pro" && meta.workspaceSlug && { slug: meta.workspaceSlug }),
});
}
const plan = meta.plan === "team" ? "team" : "pro";
await workspaceRepo.update(db, meta.workspacePublicId, {
plan,
...(plan === "pro" &&
meta.workspaceSlug &&
meta.isNewWorkspace !== "true" && { slug: meta.workspaceSlug }),
});
break;
}
default: