diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 30be62df..226822eb 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -28,12 +28,12 @@ model Match { } model AppUser { - uid String @id + uid String @id displayName String? photoUrl String? matchDifficulty Int? matchProgrammingLanguage String? - attempts Attempts[] + attempts Attempt[] } model Room { @@ -43,6 +43,8 @@ model Room { text String saved_text String? question_id String? + attempt Attempt? @relation(fields: [attempt_id], references: [id]) + attempt_id String? @unique } enum EnumRoomStatus { @@ -50,11 +52,14 @@ enum EnumRoomStatus { inactive } -model Attempts { +model Attempt { id String @id @default(uuid()) users AppUser[] question_id String answer String? solved Boolean @default(false) - time_saved_at DateTime @default(now()) + time_saved_at DateTime @default(now()) // when answers are updated + time_updated DateTime @updatedAt // any field change + room_id String // may be inactive + room Room? } diff --git a/services/collaboration-service/src/db/prisma-db.ts b/services/collaboration-service/src/db/prisma-db.ts index a4c84013..f85ef4b2 100644 --- a/services/collaboration-service/src/db/prisma-db.ts +++ b/services/collaboration-service/src/db/prisma-db.ts @@ -1,4 +1,4 @@ -import { PrismaClient, Room } from "@prisma/client"; +import { AppUser, PrismaClient, Room } from "@prisma/client"; const prisma = new PrismaClient(); @@ -58,15 +58,83 @@ export async function updateRoomStatus(room_id: string): Promise { if (room.users.length === 0) { room.status = "inactive"; + saveAttempt(room_id); } else { room.status = "active"; } } +export async function saveAttempt(room_id: string): Promise { + const room = await prisma.room.findUnique({ + where: { + room_id: room_id, + }, + }); + + const attempt_id = room!.attempt_id; + const answer = room!.text; + + if (attempt_id) { + await prisma.attempt.update({ + where: { + id: attempt_id, + }, + data: { + answer: answer, + time_saved_at: new Date(), + }, + }); + } + + const users: AppUser[] = await prisma.appUser.findMany({ + where: { + uid: { + in: room!.users, + }, + }, + }); + + const question_id = room!.question_id!; + + await prisma.attempt.create({ + data: { + users: { + connect: users.map((user) => ({ + uid: user.uid as string, + })), + }, + question_id: question_id, + answer: answer, + room_id: room_id, + room: { + connect: { + room_id: room_id, + }, + }, + }, + }); +} + export async function createOrUpdateRoomWithUser( room_id: string, user_id: string ): Promise { + let users: string[] = []; + const room = await prisma.room.findUnique({ + where: { + room_id: room_id, + }, + select: { + users: true, + }, + }); + if (room) { + users = room.users; + if (users.indexOf(user_id) === -1) { + users.push(user_id); + } + } + await prisma.room.upsert({ where: { room_id: room_id, @@ -74,7 +142,7 @@ export async function createOrUpdateRoomWithUser( update: { status: "active", users: { - push: user_id, + set: users, }, }, create: { diff --git a/services/collaboration-service/src/routes/room.ts b/services/collaboration-service/src/routes/room.ts index f45bd895..3e2fa74f 100644 --- a/services/collaboration-service/src/routes/room.ts +++ b/services/collaboration-service/src/routes/room.ts @@ -12,6 +12,7 @@ import { isRoomExists, getRoom, getSavedRoomText, + saveAttempt, } from "../db/prisma-db"; import { @@ -190,7 +191,7 @@ function initSocketListeners(io: Server, socket: Socket, room_id: string) { ); socket.on(SocketEvents.ROOM_SAVE, (text: string) => - saveRoomText(room_id, text) + saveRoomText(room_id, text).then(() => saveAttempt(room_id)) ); socket.on(SocketEvents.ROOM_LOAD, () => loadTextFromDb(io, socket, room_id)); @@ -199,7 +200,7 @@ function initSocketListeners(io: Server, socket: Socket, room_id: string) { export const roomRouter = (io: Server) => { const router = express.Router(); - router.get("/:room_id", (req: Request, res: Response) => { + router.get("/:room_id", async (req: Request, res: Response) => { const room_id = req.params.room_id as string; if (!isRoomExists(room_id)) { @@ -209,11 +210,11 @@ export const roomRouter = (io: Server) => { return res.status(200).json({ message: "Room exists", room_id: room_id, - info: getRoom(room_id), + info: await getRoom(room_id), }); }); - router.post("/save", (req: Request, res: Response) => { + router.post("/save", async (req: Request, res: Response) => { try { const room_id = req.body.room_id as string; const text = req.body.text as string; @@ -222,12 +223,14 @@ export const roomRouter = (io: Server) => { return res.status(400).json({ error: "Invalid roomId provided" }); } - saveRoomText(room_id, text); - - res.status(201).json({ - message: "Room saved successfully", - info: getRoom(room_id), - }); + await saveRoomText(room_id, text) + .then(async () => await saveAttempt(room_id)) + .then(async () => { + res.status(201).json({ + message: "Room saved successfully", + info: await getRoom(room_id), + }); + }); } catch (error) { console.error(error); res.status(500).json({ message: "Error saving room" });