diff --git a/apps/web/prisma/migrations/20250917120836_waitlist/migration.sql b/apps/web/prisma/migrations/20250917120836_waitlist/migration.sql
new file mode 100644
index 0000000..bc5eed8
--- /dev/null
+++ b/apps/web/prisma/migrations/20250917120836_waitlist/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "User" ADD COLUMN "isWaitlisted" BOOLEAN NOT NULL DEFAULT false;
diff --git a/apps/web/prisma/schema.prisma b/apps/web/prisma/schema.prisma
index a1a29d0..8e9e546 100644
--- a/apps/web/prisma/schema.prisma
+++ b/apps/web/prisma/schema.prisma
@@ -85,6 +85,7 @@ model User {
emailVerified DateTime?
image String?
isBetaUser Boolean @default(false)
+ isWaitlisted Boolean @default(false)
createdAt DateTime @default(now())
accounts Account[]
sessions Session[]
diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx
index 21d833d..574d65e 100644
--- a/apps/web/src/app/page.tsx
+++ b/apps/web/src/app/page.tsx
@@ -8,5 +8,9 @@ export default async function Home() {
redirect("/login");
}
- redirect("/dashboard");
+ if (session.user.isWaitlisted) {
+ redirect("/wait-list");
+ } else {
+ redirect("/dashboard");
+ }
}
diff --git a/apps/web/src/providers/next-auth.tsx b/apps/web/src/providers/next-auth.tsx
index 25a2d5b..d092fe3 100644
--- a/apps/web/src/providers/next-auth.tsx
+++ b/apps/web/src/providers/next-auth.tsx
@@ -35,5 +35,19 @@ const AppAuthProvider = ({ children }: { children: React.ReactNode }) => {
return ;
}
+ if (session.user.isWaitlisted) {
+ return (
+
+
+
+
You're on the Waitlist!
+
+ Hang tight, we'll get to you as soon as possible.
+
+
+
+ );
+ }
+
return <>{children}>;
};
diff --git a/apps/web/src/server/api/trpc.ts b/apps/web/src/server/api/trpc.ts
index 332d3ed..c86d4dc 100644
--- a/apps/web/src/server/api/trpc.ts
+++ b/apps/web/src/server/api/trpc.ts
@@ -99,7 +99,7 @@ export const publicProcedure = t.procedure;
* @see https://trpc.io/docs/procedures
*/
export const protectedProcedure = t.procedure.use(({ ctx, next }) => {
- if (!ctx.session || !ctx.session.user) {
+ if (!ctx.session || !ctx.session.user || ctx.session.user.isWaitlisted) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}
diff --git a/apps/web/src/server/auth.ts b/apps/web/src/server/auth.ts
index c2c7c33..1f53f4c 100644
--- a/apps/web/src/server/auth.ts
+++ b/apps/web/src/server/auth.ts
@@ -27,6 +27,7 @@ declare module "next-auth" {
id: number;
isBetaUser: boolean;
isAdmin: boolean;
+ isWaitlisted: boolean;
// ...other properties
// role: UserRole;
} & DefaultSession["user"];
@@ -37,6 +38,7 @@ declare module "next-auth" {
id: number;
isBetaUser: boolean;
isAdmin: boolean;
+ isWaitlisted: boolean;
}
}
@@ -107,6 +109,7 @@ export const authOptions: NextAuthOptions = {
id: user.id,
isBetaUser: user.isBetaUser,
isAdmin: user.email === env.ADMIN_EMAIL,
+ isWaitlisted: user.isWaitlisted,
},
}),
},
@@ -126,10 +129,21 @@ export const authOptions: NextAuthOptions = {
invitesAvailable = invites.length > 0;
}
- await db.user.update({
- where: { id: user.id },
- data: { isBetaUser: true },
- });
+ if (
+ !env.NEXT_PUBLIC_IS_CLOUD ||
+ env.NODE_ENV === "development" ||
+ invitesAvailable
+ ) {
+ await db.user.update({
+ where: { id: user.id },
+ data: { isBetaUser: true },
+ });
+ } else {
+ await db.user.update({
+ where: { id: user.id },
+ data: { isBetaUser: true, isWaitlisted: true },
+ });
+ }
},
},
providers: getProviders(),