diff --git a/app/(setup)/page.tsx b/app/(setup)/page.tsx
new file mode 100644
index 0000000..5534fa7
--- /dev/null
+++ b/app/(setup)/page.tsx
@@ -0,0 +1,26 @@
+import { redirect } from "next/navigation";
+
+import { db } from "@/lib/db";
+import { initialProfile } from "@/lib/initial-profile";
+
+const SetupPage = async () => {
+ const profile = await initialProfile();
+
+ const server = await db.server.findFirst({
+ where: {
+ members: {
+ some: {
+ profileId: profile.id,
+ },
+ },
+ }
+ });
+
+ if (server) {
+ return redirect(`/servers/${server.id}`);
+ }
+
+ return
Create a Server
;
+}
+
+export default SetupPage;
\ No newline at end of file
diff --git a/lib/db.ts b/lib/db.ts
new file mode 100644
index 0000000..f603f47
--- /dev/null
+++ b/lib/db.ts
@@ -0,0 +1,9 @@
+import { PrismaClient } from '@prisma/client'
+
+declare global {
+ var prisma: PrismaClient | undefined;
+};
+
+export const db = globalThis.prisma || new PrismaClient()
+
+if (process.env.NODE_ENV !== 'production') globalThis.prisma = db
\ No newline at end of file
diff --git a/lib/initial-profile.ts b/lib/initial-profile.ts
new file mode 100644
index 0000000..bea2097
--- /dev/null
+++ b/lib/initial-profile.ts
@@ -0,0 +1,32 @@
+import { currentUser, redirectToSignIn } from "@clerk/nextjs";
+
+import { db } from "@/lib/db";
+
+export const initialProfile = async () => {
+ const user = await currentUser();
+
+ if (!user) {
+ return redirectToSignIn();
+ }
+
+ const profile = await db.profile.findUnique({
+ where: {
+ userId: user.id,
+ },
+ });
+
+ if (profile) {
+ return profile;
+ }
+
+ const newProfile = await db.profile.create({
+ data: {
+ userId: user.id,
+ name: `${user.firstName} ${user.lastName}`,
+ imageUrl : user.imageUrl,
+ email: user.emailAddresses[0].emailAddress,
+ },
+ });
+
+ return newProfile;
+}
\ No newline at end of file
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
new file mode 100644
index 0000000..8779f36
--- /dev/null
+++ b/prisma/schema.prisma
@@ -0,0 +1,89 @@
+generator client {
+ provider = "prisma-client-js"
+}
+
+datasource db {
+ provider = "mysql"
+ url = env("DATABASE_URL")
+ relationMode = "prisma"
+}
+
+model Profile{
+ id String @id @default(uuid())
+ userId String @unique
+ name String
+ imageUrl String @db.Text
+ email String @db.Text
+
+ servers Server[]
+ members Member[]
+ channels Channel[]
+
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+}
+
+model Server{
+ id String @id @default(uuid())
+ name String
+ imageUrl String @db.Text
+ inviteCode String @db.Text
+
+ profileId String
+ profile Profile @relation(fields: [profileId], references: [id], onDelete: Cascade)
+
+ members Member[]
+ channels Channel[]
+
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ @@index([profileId])
+}
+
+enum MemberRole{
+ ADMIN
+ MODERATOR
+ GUEST
+}
+
+model Member{
+ id String @id @default(uuid())
+ role MemberRole @default(GUEST)
+
+ profileId String
+ profile Profile @relation(fields: [profileId], references: [id], onDelete: Cascade)
+
+ serverId String
+ server Server @relation(fields: [serverId], references: [id], onDelete: Cascade)
+
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ @@index([profileId])
+ @@index([serverId])
+}
+
+enum ChannelType{
+ TEXT
+ AUDIO
+ VIDEO
+}
+
+model Channel{
+ id String @id @default(uuid())
+ name String
+ type ChannelType @default(TEXT)
+
+ profileId String
+ profile Profile @relation(fields: [profileId], references: [id], onDelete: Cascade)
+
+ serverId String
+ server Server @relation(fields: [serverId], references: [id], onDelete: Cascade)
+
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+
+ @@index([profileId])
+ @@index([serverId])
+}
\ No newline at end of file