mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-16 22:35:34 +00:00
add stripe subscription id to org
This commit is contained in:
parent
9665f149cd
commit
33ae585327
8 changed files with 15498 additions and 15122 deletions
120
package-lock.json
generated
120
package-lock.json
generated
|
|
@ -14710,6 +14710,126 @@
|
||||||
"optional": true
|
"optional": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-darwin-x64": {
|
||||||
|
"version": "14.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.21.tgz",
|
||||||
|
"integrity": "sha512-TSAA2ROgNzm4FhKbTbyJOBrsREOMVdDIltZ6aZiKvCi/v0UwFmwigBGeqXDA97TFMpR3LNNpw52CbVelkoQBxA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||||
|
"version": "14.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.21.tgz",
|
||||||
|
"integrity": "sha512-0Dqjn0pEUz3JG+AImpnMMW/m8hRtl1GQCNbO66V1yp6RswSTiKmnHf3pTX6xMdJYSemf3O4Q9ykiL0jymu0TuA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-arm64-musl": {
|
||||||
|
"version": "14.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.21.tgz",
|
||||||
|
"integrity": "sha512-Ggfw5qnMXldscVntwnjfaQs5GbBbjioV4B4loP+bjqNEb42fzZlAaK+ldL0jm2CTJga9LynBMhekNfV8W4+HBw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-x64-gnu": {
|
||||||
|
"version": "14.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.21.tgz",
|
||||||
|
"integrity": "sha512-uokj0lubN1WoSa5KKdThVPRffGyiWlm/vCc/cMkWOQHw69Qt0X1o3b2PyLLx8ANqlefILZh1EdfLRz9gVpG6tg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-linux-x64-musl": {
|
||||||
|
"version": "14.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.21.tgz",
|
||||||
|
"integrity": "sha512-iAEBPzWNbciah4+0yI4s7Pce6BIoxTQ0AGCkxn/UBuzJFkYyJt71MadYQkjPqCQCJAFQ26sYh7MOKdU+VQFgPg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||||
|
"version": "14.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.21.tgz",
|
||||||
|
"integrity": "sha512-plykgB3vL2hB4Z32W3ktsfqyuyGAPxqwiyrAi2Mr8LlEUhNn9VgkiAl5hODSBpzIfWweX3er1f5uNpGDygfQVQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-ia32-msvc": {
|
||||||
|
"version": "14.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.21.tgz",
|
||||||
|
"integrity": "sha512-w5bacz4Vxqrh06BjWgua3Yf7EMDb8iMcVhNrNx8KnJXt8t+Uu0Zg4JHLDL/T7DkTCEEfKXO/Er1fcfWxn2xfPA==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@next/swc-win32-x64-msvc": {
|
||||||
|
"version": "14.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.21.tgz",
|
||||||
|
"integrity": "sha512-sT6+llIkzpsexGYZq8cjjthRyRGe5cJVhqh12FmlbxHqna6zsDDK8UNaV7g41T6atFHCJUPeLb3uyAwrBwy0NA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 10"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Org" ADD COLUMN "subscriptionId" TEXT;
|
||||||
|
|
@ -115,6 +115,8 @@ model Org {
|
||||||
repos Repo[]
|
repos Repo[]
|
||||||
secrets Secret[]
|
secrets Secret[]
|
||||||
|
|
||||||
|
subscriptionId String?
|
||||||
|
|
||||||
/// List of pending invites to this organization
|
/// List of pending invites to this organization
|
||||||
invites Invite[]
|
invites Invite[]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
'use server';
|
'use server';
|
||||||
|
|
||||||
import Ajv from "ajv";
|
import Ajv from "ajv";
|
||||||
import { Stripe } from "stripe";
|
|
||||||
import { auth, getCurrentUserOrg } from "./auth";
|
import { auth, getCurrentUserOrg } from "./auth";
|
||||||
import { notAuthenticated, notFound, ServiceError, unexpectedError, orgDomainExists } from "@/lib/serviceError";
|
import { notAuthenticated, notFound, ServiceError, unexpectedError, orgDomainExists } from "@/lib/serviceError";
|
||||||
import { prisma } from "@/prisma";
|
import { prisma } from "@/prisma";
|
||||||
|
|
@ -99,7 +98,7 @@ export const checkIfOrgDomainExists = async (domain: string): Promise<boolean> =
|
||||||
return !!org;
|
return !!org;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createOrg = async (name: string, domain: string): Promise<{ id: number } | ServiceError> => {
|
export const createOrg = async (name: string, domain: string, subscriptionId?: string): Promise<{ id: number } | ServiceError> => {
|
||||||
const session = await auth();
|
const session = await auth();
|
||||||
if (!session) {
|
if (!session) {
|
||||||
return notAuthenticated();
|
return notAuthenticated();
|
||||||
|
|
@ -120,6 +119,7 @@ export const createOrg = async (name: string, domain: string): Promise<{ id: num
|
||||||
data: {
|
data: {
|
||||||
name,
|
name,
|
||||||
domain,
|
domain,
|
||||||
|
subscriptionId,
|
||||||
members: {
|
members: {
|
||||||
create: {
|
create: {
|
||||||
userId: session.user.id,
|
userId: session.user.id,
|
||||||
|
|
|
||||||
|
|
@ -30,21 +30,27 @@ export default async function OnboardComplete({ searchParams }: OnboardCompleteP
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sessionId || !orgName || !orgDomain) {
|
if (!sessionId || !orgName || !orgDomain) {
|
||||||
|
console.error("Missing required parameters");
|
||||||
return <ErrorPage />;
|
return <ErrorPage />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stripeSession = await fetchStripeSession(sessionId);
|
const stripeSession = await fetchStripeSession(sessionId);
|
||||||
if(stripeSession.payment_status !== "paid") {
|
const stripeSubscription = stripeSession.subscription;
|
||||||
|
if(stripeSession.payment_status !== "paid" || !stripeSubscription) {
|
||||||
|
console.error("Invalid stripe session");
|
||||||
return <ErrorPage />;
|
return <ErrorPage />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await createOrg(orgName, orgDomain);
|
const subscriptionId = stripeSubscription as string;
|
||||||
|
const res = await createOrg(orgName, orgDomain, subscriptionId);
|
||||||
if (isServiceError(res)) {
|
if (isServiceError(res)) {
|
||||||
|
console.error("Failed to create org");
|
||||||
return <ErrorPage />;
|
return <ErrorPage />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const orgSwitchRes = await switchActiveOrg(res.id);
|
const orgSwitchRes = await switchActiveOrg(res.id);
|
||||||
if (isServiceError(orgSwitchRes)) {
|
if (isServiceError(orgSwitchRes)) {
|
||||||
|
console.error("Failed to switch active org");
|
||||||
return <ErrorPage />;
|
return <ErrorPage />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,9 @@ const onboardingFormSchema = z.object({
|
||||||
.max(30, { message: "Organization name must be at most 30 characters long." }),
|
.max(30, { message: "Organization name must be at most 30 characters long." }),
|
||||||
domain: z.string()
|
domain: z.string()
|
||||||
.min(2, { message: "Organization domain must be at least 3 characters long." })
|
.min(2, { message: "Organization domain must be at least 3 characters long." })
|
||||||
.max(20, { message: "Organization domain must be at most 20 characters long." }),
|
.max(20, { message: "Organization domain must be at most 20 characters long." })
|
||||||
|
.regex(/^[a-zA-Z-]+$/, { message: "Organization domain must contain only letters and hyphens." })
|
||||||
|
.regex(/^[^-].*[^-]$/, { message: "Organization domain must not start or end with a hyphen." }),
|
||||||
})
|
})
|
||||||
|
|
||||||
export type OnboardingFormValues = z.infer<typeof onboardingFormSchema>
|
export type OnboardingFormValues = z.infer<typeof onboardingFormSchema>
|
||||||
|
|
|
||||||
|
|
@ -61,10 +61,11 @@ export function TrialCard({ orgCreateInfo }: { orgCreateInfo: OnboardingFormValu
|
||||||
<CardContent className="pt-2">
|
<CardContent className="pt-2">
|
||||||
<ul className="space-y-4 mb-6">
|
<ul className="space-y-4 mb-6">
|
||||||
{[
|
{[
|
||||||
"Index hundreds of repos from multiple code hosts (GitHub, GitLab, Gerrit, Gitea, etc.)",
|
|
||||||
"Powerful regex and symbol search",
|
|
||||||
"Blazingly fast code search",
|
"Blazingly fast code search",
|
||||||
|
"Index hundreds of repos from multiple code hosts (GitHub, GitLab, Gerrit, Gitea, etc.). Self-hosted code sources supported.",
|
||||||
|
"Public and private repos supported.",
|
||||||
"Create sharable links to code snippets.",
|
"Create sharable links to code snippets.",
|
||||||
|
"Powerful regex and symbol search",
|
||||||
].map((feature, index) => (
|
].map((feature, index) => (
|
||||||
<li key={index} className="flex items-center">
|
<li key={index} className="flex items-center">
|
||||||
<div className="mr-3 flex-shrink-0">
|
<div className="mr-3 flex-shrink-0">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue