From 2a462a674bca064c37b9720a4c11230e4d4fc178 Mon Sep 17 00:00:00 2001 From: MAXOUXAX <24844231+MAXOUXAX@users.noreply.github.com> Date: Sun, 28 Jan 2024 21:25:42 +0100 Subject: [PATCH] refactor/db-changes (#73) * refactor(db): room status handling is now updated to work with new database schema * refactor(backend): adding host as participant when creating the room and improved code * chore(backend): removed useless import * fix: import correct Alert component and fixed eslint issues * refactor(backend): removed useless array in insert method of supabase client --- backend/src/room.ts | 114 ++++++++++++++----------------- backend/src/route/RoomPOST.ts | 5 +- commons/database-types-utils.ts | 2 - commons/database-types.ts | 66 +++--------------- expo/app/(tabs)/rooms/[id].tsx | 3 +- expo/app/(tabs)/rooms/create.tsx | 41 ++++++----- expo/app/join/[roomCode].tsx | 3 +- 7 files changed, 92 insertions(+), 142 deletions(-) diff --git a/backend/src/room.ts b/backend/src/room.ts index 1aec0fa1..c24f9d6a 100644 --- a/backend/src/room.ts +++ b/backend/src/room.ts @@ -1,11 +1,10 @@ import { FastifyReply, FastifyRequest } from "fastify"; import { adminSupabase } from "./server"; import createClient from "./lib/supabase"; -import { PostgrestError } from "@supabase/supabase-js"; export async function getUserFromRequest( request: FastifyRequest, - response: FastifyReply, + response: FastifyReply ) { const supabase = createClient({ request, response }); @@ -23,6 +22,10 @@ export async function getUserProfileIdFromAccountId(accId: string) { return { data: data.user_profile_id, error: null }; } +function unauthorizedResponse(response: FastifyReply) { + return response.code(401).send("User not logged in"); +} + export async function createRoom( name: string, code: string, @@ -32,16 +35,19 @@ export async function createRoom( maxMusicPerUserDuration: number, serviceId: string, req: FastifyRequest, - rep: FastifyReply, + rep: FastifyReply ) { const supabase = adminSupabase; - const user = await getUserFromRequest(req, rep); - if (!user.data.user) { - return rep.code(401).send("User not logged in"); - } - const hostUserProfileId = - (await getUserProfileIdFromAccountId(user.data.user.id)).data || null; + + // If the user is not logged in + if (!user.data.user) return unauthorizedResponse(rep); + + // If we didn't manage to get the user profile id from the account id + const { data: hostUserProfileId } = await getUserProfileIdFromAccountId( + user.data.user.id + ); + if (!hostUserProfileId) return unauthorizedResponse(rep); const roomConfigRes = await supabase .from("room_configurations") @@ -54,63 +60,47 @@ export async function createRoom( .select("id") .single(); - if (roomConfigRes.error) { + // If we didn't manage to create the room configuration + if (roomConfigRes.error) return rep.code(roomConfigRes.status).send(roomConfigRes.error); - } + const configurationId = roomConfigRes.data.id; - const roomRes = await supabase - .from("active_rooms") - .insert([ - { - name: name, - code: code, - configuration_id: configurationId, - host_user_profile_id: hostUserProfileId, - service_id: serviceId, - }, - ]) - .select("id"); - - if (roomRes.error) { - return rep.code(roomRes.status).send(roomRes.error); - } else { - // TODO use roomid here (send) - return rep.code(201).send("Room created"); - } + const { error, data, status } = await supabase + .from("rooms") + .insert({ + name: name, + code: code, + configuration_id: configurationId, + host_user_profile_id: hostUserProfileId, + service_id: serviceId, + }) + .select("id") + .single(); + + // If we didn't manage to create the room + if (error || !data) return rep.code(status).send(error); + + const { error: roomUserError } = await supabase.from("room_users").insert({ + room_id: data.id, + profile_id: hostUserProfileId, + }); + + // If we didn't manage to add the host to the participants + if (error) return rep.code(500).send(roomUserError); + + const response = { + error: null, + data: { + room_id: data.id, + }, + }; + + // If we managed to create the room + return rep.code(201).send(response); } export function endRoom(roomId: string) { - let room: any = null; - const supabase = adminSupabase; - - supabase - .from("active_rooms") - .delete() - .eq("id", roomId) - .select("*") - .then((res) => { - if (res.error) { - return res.error; - } else { - room = res.data[0]; - console.log("Room ended"); - } - }); - - supabase - .from("rooms") - .insert([ - { - ...room, - ended_at: new Date(), - }, - ]) - .then((res) => { - if (res.error) { - return res.error; - } else { - console.log("Room added to rooms"); - } - }); + // TODO: Properly end room + // This will set the join code of this room to null, and set is_active to false } diff --git a/backend/src/route/RoomPOST.ts b/backend/src/route/RoomPOST.ts index 5eb1a538..9c61b43f 100644 --- a/backend/src/route/RoomPOST.ts +++ b/backend/src/route/RoomPOST.ts @@ -1,6 +1,5 @@ import { FastifyReply, FastifyRequest } from "fastify"; import { createRoom } from "../room"; -import * as repl from "repl"; interface BodyParams { name: string; @@ -34,7 +33,7 @@ function extractFromRequest(req: FastifyRequest): BodyParams { export default async function RoomPOST( req: FastifyRequest, - reply: FastifyReply, + reply: FastifyReply ) { const roomOptions = extractFromRequest(req); @@ -47,6 +46,6 @@ export default async function RoomPOST( roomOptions.maxMusicDuration, roomOptions.service, req, - reply, + reply ); } diff --git a/commons/database-types-utils.ts b/commons/database-types-utils.ts index 90e444b3..e0da8020 100644 --- a/commons/database-types-utils.ts +++ b/commons/database-types-utils.ts @@ -1,7 +1,5 @@ import { Database } from "./database-types"; // prettier-ignore -export type ActiveRoom = Database["public"]["Tables"]["active_rooms"]["Row"]; -// prettier-ignore export type BoundService = Database["public"]["Tables"]["bound_services"]["Row"]; // prettier-ignore export type FriendList = Database["public"]["Tables"]["friends_list"]["Row"]; diff --git a/commons/database-types.ts b/commons/database-types.ts index ab94d932..947dc1f0 100644 --- a/commons/database-types.ts +++ b/commons/database-types.ts @@ -9,58 +9,6 @@ export type Json = export interface Database { public: { Tables: { - active_rooms: { - Row: { - code: string; - configuration_id: string | null; - created_at: string; - host_user_profile_id: string | null; - id: string; - name: string; - service_id: string | null; - }; - Insert: { - code: string; - configuration_id?: string | null; - created_at?: string; - host_user_profile_id?: string | null; - id?: string; - name: string; - service_id?: string | null; - }; - Update: { - code?: string; - configuration_id?: string | null; - created_at?: string; - host_user_profile_id?: string | null; - id?: string; - name?: string; - service_id?: string | null; - }; - Relationships: [ - { - foreignKeyName: "active_rooms_configuration_id_fkey"; - columns: ["configuration_id"]; - isOneToOne: false; - referencedRelation: "room_configurations"; - referencedColumns: ["id"]; - }, - { - foreignKeyName: "active_rooms_host_user_profile_id_fkey"; - columns: ["host_user_profile_id"]; - isOneToOne: false; - referencedRelation: "user_profile"; - referencedColumns: ["user_profile_id"]; - }, - { - foreignKeyName: "active_rooms_service_id_fkey"; - columns: ["service_id"]; - isOneToOne: false; - referencedRelation: "streaming_services"; - referencedColumns: ["service_id"]; - } - ]; - }; bound_services: { Row: { access_token: string | null; @@ -280,7 +228,7 @@ export interface Database { { foreignKeyName: "room_users_room_id_fkey"; columns: ["room_id"]; - isOneToOne: true; + isOneToOne: false; referencedRelation: "rooms"; referencedColumns: ["id"]; } @@ -288,29 +236,32 @@ export interface Database { }; rooms: { Row: { + code: string; configuration_id: string | null; created_at: string; - ended_at: string | null; host_user_profile_id: string | null; id: string; + is_active: boolean; name: string; service_id: string | null; }; Insert: { + code: string; configuration_id?: string | null; - created_at: string; - ended_at?: string | null; + created_at?: string; host_user_profile_id?: string | null; id?: string; + is_active?: boolean; name: string; service_id?: string | null; }; Update: { + code?: string; configuration_id?: string | null; created_at?: string; - ended_at?: string | null; host_user_profile_id?: string | null; id?: string; + is_active?: boolean; name?: string; service_id?: string | null; }; @@ -506,3 +457,4 @@ export type Enums< : PublicEnumNameOrOptions extends keyof Database["public"]["Enums"] ? Database["public"]["Enums"][PublicEnumNameOrOptions] : never; + diff --git a/expo/app/(tabs)/rooms/[id].tsx b/expo/app/(tabs)/rooms/[id].tsx index cefb2931..eb116f72 100644 --- a/expo/app/(tabs)/rooms/[id].tsx +++ b/expo/app/(tabs)/rooms/[id].tsx @@ -35,9 +35,10 @@ export default function RoomPage() { useEffect(() => { const fetchData = async () => { const { data, error } = await supabase - .from("active_rooms") + .from("rooms") .select("*") .eq("id", id) + .eq("is_active", true) .single(); if (error) { Alert.alert( diff --git a/expo/app/(tabs)/rooms/create.tsx b/expo/app/(tabs)/rooms/create.tsx index a7e41a94..5a9849d8 100644 --- a/expo/app/(tabs)/rooms/create.tsx +++ b/expo/app/(tabs)/rooms/create.tsx @@ -2,13 +2,14 @@ import { makeRedirectUri } from "expo-auth-session"; import { router } from "expo-router"; import React, { useEffect, useState } from "react"; import { - Alert, ScrollView, StyleSheet, Text, TouchableOpacity, View, } from "react-native"; + +import Alert from "../../../components/Alert"; import CustomTextInput from "../../../components/CustomTextInput"; import ParametersList from "../../../components/ParametersList"; import ServiceList from "../../../components/ServicesList"; @@ -53,7 +54,7 @@ export default function CreateRoom() { const response = await fetch(baseUrl + ":3000/streaming-services"); const data = await response.json(); - const services: Array = []; + const services: StreamingService[] = []; data.forEach((service: StreamingService) => { services.push(service); @@ -75,24 +76,21 @@ export default function CreateRoom() { function checkConstraints(body: CreateRoomFormBody): { error: true | null } { if (body.voteSkippingNeeded > 100 || body.voteSkippingNeeded < 0) { Alert.alert( - "Mauvais pourcentage", - "Le pourcentage doit être entre 0 et 100", + "Mauvais pourcentage: Le pourcentage doit être entre 0 et 100" ); return { error: true }; } if (body.maxMusicPerUser <= 0) { Alert.alert( - "Mauvais nombre de musique", - "Le nombre maximum de musique par utilisateur doit être positif ou au moins supérieur à 1", + "Mauvais nombre de musique: Le nombre maximum de musique par utilisateur doit être positif ou au moins supérieur à 1" ); return { error: true }; } if (body.maxMusicDuration <= 0) { Alert.alert( - "Mauvaise durée de musique", - "La durée maximale d'une musique doit être positive ou au moins supérieur à 1 seconde", + "Mauvaise durée de musique: La durée maximale d'une musique doit être positive ou au moins supérieur à 1 seconde" ); return { error: true }; } @@ -107,9 +105,9 @@ export default function CreateRoom() { code: roomCode, service: selectedService, voteSkipping: canVote, - voteSkippingNeeded: parseInt(percentageVoteToSkipAMusic), - maxMusicPerUser: parseInt(maxMusicPerUser), - maxMusicDuration: parseInt(maxMusicDuration), + voteSkippingNeeded: parseInt(percentageVoteToSkipAMusic, 10), + maxMusicPerUser: parseInt(maxMusicPerUser, 10), + maxMusicDuration: parseInt(maxMusicDuration, 10), }; const { error } = checkConstraints(body); @@ -126,11 +124,22 @@ export default function CreateRoom() { body: JSON.stringify(body), credentials: "include", }); - if (response.ok) { - router.push("/rooms"); + console.log(response); + + if (!response.ok) { + if (response.status === 409) + return Alert.alert("Ce code de salle est déjà utilisé"); + + return Alert.alert(response.statusText); } + + const jsonResponse = await response.json(); + + const roomId = jsonResponse.data.room_id; + router.push(`/rooms/${roomId}`); } catch (error) { - return error; + console.error(error); + Alert.alert("Une erreur est survenue lors de la création de la salle"); } }; @@ -139,13 +148,13 @@ export default function CreateRoom() { Nom de la salle Code de la salle diff --git a/expo/app/join/[roomCode].tsx b/expo/app/join/[roomCode].tsx index 96633934..e16b01a7 100644 --- a/expo/app/join/[roomCode].tsx +++ b/expo/app/join/[roomCode].tsx @@ -32,9 +32,10 @@ export default function JoinPage() { }; const fetchRoomId = async () => { const { data } = await supabase - .from("active_rooms") + .from("rooms") .select("id") .eq("code", roomCode) + .eq("is_active", true) .single(); if (!data) {