diff --git a/apps/client/src/components/account-content.tsx b/apps/client/src/components/account-content.tsx index 85cbf00c..51105c4b 100644 --- a/apps/client/src/components/account-content.tsx +++ b/apps/client/src/components/account-content.tsx @@ -1,25 +1,33 @@ /* eslint-disable @next/next/no-img-element */ "use client"; -import Button from "./button"; -// import { useRef } from "react"; -// import { FiX } from "react-icons/fi"; +import Button, { SecondaryButton } from "./button"; +import { useRef } from "react"; +import { FiX } from "react-icons/fi"; import { Session } from "next-auth"; import { signOut } from "next-auth/react"; import * as Sentry from "@sentry/nextjs"; +import { deleteUser } from "@ai/utils/queries"; +import toast from "react-hot-toast"; export default function AccountContent({ session }: { session: Session }) { - // const dialogRef = useRef(null); + const dialogRef = useRef(null); const handleSignOut = () => { Sentry.setUser(null); signOut(); }; - // const handleDeleteAccount = () => { - // Sentry.setUser(null); - // signOut(); - // }; + const handleDeleteAccount = async () => { + try { + await deleteUser(session.user.id); + Sentry.setUser(null); + signOut(); + } catch (error) { + toast.error("Unable to delete your account"); + Sentry.captureException(error); + } + }; return ( <> @@ -41,13 +49,11 @@ export default function AccountContent({ session }: { session: Session }) { - {/* TODO: finish ability to delete account */} - {/* dialogRef.current?.showModal()}> + dialogRef.current?.showModal()}> Delete Account - */} + - {/* TODO: finish ability to delete account */} - {/* @@ -65,7 +71,7 @@ export default function AccountContent({ session }: { session: Session }) { - */} + ); } diff --git a/apps/client/src/utils/queries.ts b/apps/client/src/utils/queries.ts index 664d98d2..c2f80201 100644 --- a/apps/client/src/utils/queries.ts +++ b/apps/client/src/utils/queries.ts @@ -117,6 +117,25 @@ export async function existingHost({ return data; } +export type DeleteUserResponse = { + user: User; +}; + +export async function deleteUser(userId: string) { + const response = await fetch(`${URL}/user/${userId}`, { + method: "DELETE", + credentials: "include", + }); + + if (!response.ok) { + throw new Error("Failed to delete user"); + } + + const data: DeleteUserResponse = await response.json(); + + return data; +} + // ! ----------> ROOMS <---------- export type JoinRoomResponse = { diff --git a/apps/server/src/controllers/user.controller.ts b/apps/server/src/controllers/user.controller.ts index a31f36cb..0c561eaa 100644 --- a/apps/server/src/controllers/user.controller.ts +++ b/apps/server/src/controllers/user.controller.ts @@ -1,7 +1,7 @@ import type { NextFunction, Request, Response } from "express"; import { createRoom, joinRoom } from "../services/room.service"; -import { updateUserNickname } from "../services/user.service"; +import { deleteUser, updateUserNickname } from "../services/user.service"; export async function existingHostController( req: Request<{}, {}, { userId: string; nickname: string }>, @@ -28,3 +28,22 @@ export async function existingHostController( next(error); } } + +export async function deleteUserController( + req: Request<{ id: string }>, + res: Response, + next: NextFunction +) { + try { + const { id } = req.params; + + console.log("HEREEEE????"); + + const deletedUser = await deleteUser({ userId: id }); + console.log("DELETED USER", deletedUser); + + res.status(200).json({ user: deletedUser }); + } catch (error) { + next(error); + } +} diff --git a/apps/server/src/routes/user.route.ts b/apps/server/src/routes/user.route.ts index 21b87a9d..fe4e302f 100644 --- a/apps/server/src/routes/user.route.ts +++ b/apps/server/src/routes/user.route.ts @@ -1,6 +1,10 @@ import type { Express } from "express"; -import { existingHostController } from "../controllers/user.controller"; +import { + deleteUserController, + existingHostController, +} from "../controllers/user.controller"; export function userRoutes(app: Express) { app.post("/user/existingHost", existingHostController); + app.delete("/user/:id", deleteUserController); } diff --git a/apps/server/src/server.ts b/apps/server/src/server.ts index 8c2fb6bd..537d94eb 100644 --- a/apps/server/src/server.ts +++ b/apps/server/src/server.ts @@ -55,7 +55,7 @@ export function buildServer() { app.use(express.json()); app.use( cors({ - methods: ["GET", "POST"], + methods: ["GET", "POST", "DELETE"], origin: process.env.APP_URL ?? "https://www.artificialunintelligence.gg", credentials: true, }) diff --git a/apps/server/src/services/user.service.ts b/apps/server/src/services/user.service.ts index c6302873..29623c49 100644 --- a/apps/server/src/services/user.service.ts +++ b/apps/server/src/services/user.service.ts @@ -43,3 +43,12 @@ export async function checkUserSession({ return checkDBForSession[0]; } + +export async function deleteUser({ userId }: { userId: string }) { + const deletedUser = await db + .delete(users) + .where(eq(users.id, userId)) + .returning(); + + return deletedUser[0]; +} diff --git a/packages/database/drizzle/0002_romantic_meltdown.sql b/packages/database/drizzle/0002_romantic_meltdown.sql new file mode 100644 index 00000000..ea37ebb6 --- /dev/null +++ b/packages/database/drizzle/0002_romantic_meltdown.sql @@ -0,0 +1,47 @@ +ALTER TABLE "generations" DROP CONSTRAINT "generations_user_id_users_id_fk"; +--> statement-breakpoint +ALTER TABLE "questions_to_games" DROP CONSTRAINT "questions_to_games_question_id_questions_id_fk"; +--> statement-breakpoint +ALTER TABLE "rooms" DROP CONSTRAINT "rooms_host_id_users_id_fk"; +--> statement-breakpoint +ALTER TABLE "users_to_games" DROP CONSTRAINT "users_to_games_user_id_users_id_fk"; +--> statement-breakpoint +ALTER TABLE "users_to_rooms" DROP CONSTRAINT "users_to_rooms_user_id_users_id_fk"; +--> statement-breakpoint +ALTER TABLE "votes" DROP CONSTRAINT "votes_user_id_users_id_fk"; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "generations" ADD CONSTRAINT "generations_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "questions_to_games" ADD CONSTRAINT "questions_to_games_question_id_questions_id_fk" FOREIGN KEY ("question_id") REFERENCES "questions"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "rooms" ADD CONSTRAINT "rooms_host_id_users_id_fk" FOREIGN KEY ("host_id") REFERENCES "users"("id") ON DELETE set null ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "users_to_games" ADD CONSTRAINT "users_to_games_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "users_to_rooms" ADD CONSTRAINT "users_to_rooms_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "votes" ADD CONSTRAINT "votes_user_id_users_id_fk" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE cascade ON UPDATE no action; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; diff --git a/packages/database/drizzle/meta/0002_snapshot.json b/packages/database/drizzle/meta/0002_snapshot.json new file mode 100644 index 00000000..625edd70 --- /dev/null +++ b/packages/database/drizzle/meta/0002_snapshot.json @@ -0,0 +1,775 @@ +{ + "version": "5", + "dialect": "pg", + "id": "c0c4bb7a-da41-4daf-a8ca-d84db9fa9adf", + "prevId": "2f7d8dac-6c1b-415e-b13c-eaeeaacbc81d", + "tables": { + "accounts": { + "name": "accounts", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_account_id": { + "name": "provider_account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "token_type": { + "name": "token_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "session_state": { + "name": "session_state", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "accounts_user_id_users_id_fk": { + "name": "accounts_user_id_users_id_fk", + "tableFrom": "accounts", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "accounts_provider_provider_account_id": { + "name": "accounts_provider_provider_account_id", + "columns": [ + "provider", + "provider_account_id" + ] + } + }, + "uniqueConstraints": {} + }, + "games": { + "name": "games", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "room_code": { + "name": "room_code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "round": { + "name": "round", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "games_room_code_rooms_code_fk": { + "name": "games_room_code_rooms_code_fk", + "tableFrom": "games", + "tableTo": "rooms", + "columnsFrom": [ + "room_code" + ], + "columnsTo": [ + "code" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "generations": { + "name": "generations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "game_id": { + "name": "game_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "question_id": { + "name": "question_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image_url": { + "name": "image_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "selected": { + "name": "selected", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "generations_user_id_users_id_fk": { + "name": "generations_user_id_users_id_fk", + "tableFrom": "generations", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generations_game_id_games_id_fk": { + "name": "generations_game_id_games_id_fk", + "tableFrom": "generations", + "tableTo": "games", + "columnsFrom": [ + "game_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "generations_question_id_questions_id_fk": { + "name": "generations_question_id_questions_id_fk", + "tableFrom": "generations", + "tableTo": "questions", + "columnsFrom": [ + "question_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "questions": { + "name": "questions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "questions_to_games": { + "name": "questions_to_games", + "schema": "", + "columns": { + "question_id": { + "name": "question_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "game_id": { + "name": "game_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "round": { + "name": "round", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "player_1": { + "name": "player_1", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "player_2": { + "name": "player_2", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "questions_to_games_question_id_questions_id_fk": { + "name": "questions_to_games_question_id_questions_id_fk", + "tableFrom": "questions_to_games", + "tableTo": "questions", + "columnsFrom": [ + "question_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "questions_to_games_game_id_games_id_fk": { + "name": "questions_to_games_game_id_games_id_fk", + "tableFrom": "questions_to_games", + "tableTo": "games", + "columnsFrom": [ + "game_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "questions_to_games_player_1_users_id_fk": { + "name": "questions_to_games_player_1_users_id_fk", + "tableFrom": "questions_to_games", + "tableTo": "users", + "columnsFrom": [ + "player_1" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "questions_to_games_player_2_users_id_fk": { + "name": "questions_to_games_player_2_users_id_fk", + "tableFrom": "questions_to_games", + "tableTo": "users", + "columnsFrom": [ + "player_2" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "questions_to_games_game_id_question_id": { + "name": "questions_to_games_game_id_question_id", + "columns": [ + "game_id", + "question_id" + ] + } + }, + "uniqueConstraints": {} + }, + "rooms": { + "name": "rooms", + "schema": "", + "columns": { + "code": { + "name": "code", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "rooms_host_id_users_id_fk": { + "name": "rooms_host_id_users_id_fk", + "tableFrom": "rooms", + "tableTo": "users", + "columnsFrom": [ + "host_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "sessions": { + "name": "sessions", + "schema": "", + "columns": { + "session_token": { + "name": "session_token", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "nickname": { + "name": "nickname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + }, + "users_to_games": { + "name": "users_to_games", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "game_id": { + "name": "game_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "points": { + "name": "points", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "users_to_games_user_id_users_id_fk": { + "name": "users_to_games_user_id_users_id_fk", + "tableFrom": "users_to_games", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "users_to_games_game_id_games_id_fk": { + "name": "users_to_games_game_id_games_id_fk", + "tableFrom": "users_to_games", + "tableTo": "games", + "columnsFrom": [ + "game_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "users_to_games_user_id_game_id": { + "name": "users_to_games_user_id_game_id", + "columns": [ + "user_id", + "game_id" + ] + } + }, + "uniqueConstraints": {} + }, + "users_to_rooms": { + "name": "users_to_rooms", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "room_code": { + "name": "room_code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "users_to_rooms_user_id_users_id_fk": { + "name": "users_to_rooms_user_id_users_id_fk", + "tableFrom": "users_to_rooms", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "users_to_rooms_room_code_rooms_code_fk": { + "name": "users_to_rooms_room_code_rooms_code_fk", + "tableFrom": "users_to_rooms", + "tableTo": "rooms", + "columnsFrom": [ + "room_code" + ], + "columnsTo": [ + "code" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "users_to_rooms_user_id_room_code": { + "name": "users_to_rooms_user_id_room_code", + "columns": [ + "user_id", + "room_code" + ] + } + }, + "uniqueConstraints": {} + }, + "verification_tokens": { + "name": "verification_tokens", + "schema": "", + "columns": { + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires": { + "name": "expires", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "verification_tokens_identifier_token": { + "name": "verification_tokens_identifier_token", + "columns": [ + "identifier", + "token" + ] + } + }, + "uniqueConstraints": {} + }, + "votes": { + "name": "votes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "serial", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "generation_id": { + "name": "generation_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "votes_user_id_users_id_fk": { + "name": "votes_user_id_users_id_fk", + "tableFrom": "votes", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "votes_generation_id_generations_id_fk": { + "name": "votes_generation_id_generations_id_fk", + "tableFrom": "votes", + "tableTo": "generations", + "columnsFrom": [ + "generation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {} + } + }, + "enums": {}, + "schemas": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + } +} \ No newline at end of file diff --git a/packages/database/drizzle/meta/_journal.json b/packages/database/drizzle/meta/_journal.json index f30bb2d2..bda6c2dd 100644 --- a/packages/database/drizzle/meta/_journal.json +++ b/packages/database/drizzle/meta/_journal.json @@ -15,6 +15,13 @@ "when": 1694300360287, "tag": "0001_shallow_moonstone", "breakpoints": true + }, + { + "idx": 2, + "version": "5", + "when": 1696551373425, + "tag": "0002_romantic_meltdown", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/database/schema.ts b/packages/database/schema.ts index f4c802e0..248caa0b 100644 --- a/packages/database/schema.ts +++ b/packages/database/schema.ts @@ -63,7 +63,7 @@ export const verificationTokens = pgTable( export const rooms = pgTable("rooms", { code: text("code").primaryKey(), - hostId: text("host_id").references(() => users.id), + hostId: text("host_id").references(() => users.id, { onDelete: "set null" }), createdAt: timestamp("created_at").defaultNow().notNull(), }); @@ -71,10 +71,10 @@ export const usersToRooms = pgTable( "users_to_rooms", { userId: text("user_id") - .references(() => users.id) + .references(() => users.id, { onDelete: "cascade" }) .notNull(), roomCode: text("room_code") - .references(() => rooms.code) + .references(() => rooms.code, { onDelete: "cascade" }) .notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), }, @@ -104,17 +104,17 @@ export const questionsToGames = pgTable( "questions_to_games", { questionId: integer("question_id") - .references(() => questions.id) + .references(() => questions.id, { onDelete: "cascade" }) .notNull(), gameId: integer("game_id") - .references(() => games.id) + .references(() => games.id, { onDelete: "cascade" }) .notNull(), round: integer("round").notNull(), player1: text("player_1") - .references(() => users.id) + .references(() => users.id, { onDelete: "cascade" }) .notNull(), player2: text("player_2") - .references(() => users.id) + .references(() => users.id, { onDelete: "cascade" }) .notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), }, @@ -126,13 +126,13 @@ export const questionsToGames = pgTable( export const generations = pgTable("generations", { id: serial("id").primaryKey(), userId: text("user_id") - .references(() => users.id) + .references(() => users.id, { onDelete: "cascade" }) .notNull(), gameId: integer("game_id") - .references(() => games.id) + .references(() => games.id, { onDelete: "cascade" }) .notNull(), questionId: integer("question_id") - .references(() => questions.id) + .references(() => questions.id, { onDelete: "cascade" }) .notNull(), text: text("text").notNull(), imageUrl: text("image_url").notNull(), @@ -143,10 +143,10 @@ export const generations = pgTable("generations", { export const votes = pgTable("votes", { id: serial("id").primaryKey(), userId: text("user_id") - .references(() => users.id) + .references(() => users.id, { onDelete: "cascade" }) .notNull(), generationId: integer("generation_id") - .references(() => generations.id) + .references(() => generations.id, { onDelete: "cascade" }) .notNull(), createdAt: timestamp("created_at").defaultNow().notNull(), }); @@ -155,10 +155,10 @@ export const usersToGames = pgTable( "users_to_games", { userId: text("user_id") - .references(() => users.id) + .references(() => users.id, { onDelete: "cascade" }) .notNull(), gameId: integer("game_id") - .references(() => games.id) + .references(() => games.id, { onDelete: "cascade" }) .notNull(), points: integer("points").default(0).notNull(), },