From 326a005673125dbbbbc8e7955a86479e57056435 Mon Sep 17 00:00:00 2001 From: Abyan Nawaz Date: Tue, 15 Oct 2024 19:58:46 -0400 Subject: [PATCH 1/4] Refactored profile folder into profiles --- .../internal/handlers/profile/preferences.go | 27 ------------------- backend/internal/handlers/profile/routes.go | 21 --------------- backend/internal/handlers/profile/service.go | 11 -------- .../internal/handlers/profiles/profiles.go | 20 ++++++++++++++ backend/internal/handlers/profiles/routes.go | 1 + 5 files changed, 21 insertions(+), 59 deletions(-) delete mode 100644 backend/internal/handlers/profile/preferences.go delete mode 100644 backend/internal/handlers/profile/routes.go delete mode 100644 backend/internal/handlers/profile/service.go diff --git a/backend/internal/handlers/profile/preferences.go b/backend/internal/handlers/profile/preferences.go deleted file mode 100644 index 2619ba5..0000000 --- a/backend/internal/handlers/profile/preferences.go +++ /dev/null @@ -1,27 +0,0 @@ -package profile - -import ( - "github.com/GenerateNU/nightlife/internal/errs" - "github.com/GenerateNU/nightlife/internal/models" - "github.com/gofiber/fiber/v2" -) - -// POST Endpoint -> allows users to add their preferences to the db -func (s *Service) CreatePreferences(c *fiber.Ctx) error { - var p models.Preferences - if err := c.BodyParser(&p); err != nil { - return errs.BadRequest(err) - } - - if verrs := p.Validate(); verrs != nil { - return errs.InvalidRequestData(verrs) - } - - if err := s.store.CreatePreferences(c.Context(), p); err != nil { - return err - } - - // close out with success status - return c.Status(fiber.StatusCreated).JSON(p) - -} diff --git a/backend/internal/handlers/profile/routes.go b/backend/internal/handlers/profile/routes.go deleted file mode 100644 index 16ebc1e..0000000 --- a/backend/internal/handlers/profile/routes.go +++ /dev/null @@ -1,21 +0,0 @@ -package profile - -import ( - "github.com/GenerateNU/nightlife/internal/auth" - "github.com/GenerateNU/nightlife/internal/types" - "github.com/gofiber/fiber/v2" -) - -// Create Profile fiber route group (no unprotected routes) -func Routes(app *fiber.App, params types.Params) { - service := newService(params.Store) - - // Create Protected Grouping - protected := app.Group("/profile") - - // Register Middleware - protected.Use(auth.Protected(¶ms.Supabase)) - - //Endpoints - protected.Post("/preferences", service.CreatePreferences) -} diff --git a/backend/internal/handlers/profile/service.go b/backend/internal/handlers/profile/service.go deleted file mode 100644 index 92c0687..0000000 --- a/backend/internal/handlers/profile/service.go +++ /dev/null @@ -1,11 +0,0 @@ -package profile - -import "github.com/GenerateNU/nightlife/internal/storage" - -type Service struct { - store storage.Storage -} - -func newService(store storage.Storage) *Service { - return &Service{store: store} -} diff --git a/backend/internal/handlers/profiles/profiles.go b/backend/internal/handlers/profiles/profiles.go index 9a7c63b..eb30bf8 100644 --- a/backend/internal/handlers/profiles/profiles.go +++ b/backend/internal/handlers/profiles/profiles.go @@ -10,6 +10,26 @@ import ( "github.com/google/uuid" ) +// POST Endpoint -> allows users to add their preferences to the db +func (s *Service) CreatePreferences(c *fiber.Ctx) error { + var p models.Preferences + if err := c.BodyParser(&p); err != nil { + return errs.BadRequest(err) + } + + if verrs := p.Validate(); verrs != nil { + return errs.InvalidRequestData(verrs) + } + + if err := s.store.CreatePreferences(c.Context(), p); err != nil { + return err + } + + // close out with success status + return c.Status(fiber.StatusCreated).JSON(p) + +} + func (s *Service) UpdateProfilePreferences(c *fiber.Ctx) error { // Parse the request body diff --git a/backend/internal/handlers/profiles/routes.go b/backend/internal/handlers/profiles/routes.go index a5671b2..05e2b30 100644 --- a/backend/internal/handlers/profiles/routes.go +++ b/backend/internal/handlers/profiles/routes.go @@ -18,6 +18,7 @@ func Routes(app *fiber.App, params types.Params) { //Endpoints protected.Get("/:username", service.GetProfile) + protected.Post("/preferences", service.CreatePreferences) protected.Patch("/preferences", service.UpdateProfilePreferences) protected.Delete("/:userId", service.DeleteUser) protected.Delete("/friends/:username", service.RemoveFriend) From bf519123524637f654929f572049eab1d6e32915 Mon Sep 17 00:00:00 2001 From: Abyan Nawaz Date: Tue, 15 Oct 2024 21:43:12 -0400 Subject: [PATCH 2/4] Added get user endpoints for id, email and username. Also added a getAllUsers --- .../internal/handlers/profiles/profiles.go | 50 +++++++-- backend/internal/handlers/profiles/routes.go | 12 +- backend/internal/server/server.go | 13 ++- backend/internal/storage/postgres/profile.go | 16 --- backend/internal/storage/postgres/profiles.go | 106 ++++++++++++++++++ backend/internal/storage/storage.go | 13 ++- backend/internal/utils/validators.go | 18 +++ 7 files changed, 192 insertions(+), 36 deletions(-) delete mode 100644 backend/internal/storage/postgres/profile.go create mode 100644 backend/internal/utils/validators.go diff --git a/backend/internal/handlers/profiles/profiles.go b/backend/internal/handlers/profiles/profiles.go index eb30bf8..fd8a48d 100644 --- a/backend/internal/handlers/profiles/profiles.go +++ b/backend/internal/handlers/profiles/profiles.go @@ -2,6 +2,7 @@ package profiles import ( "github.com/GenerateNU/nightlife/internal/errs" + "github.com/GenerateNU/nightlife/internal/utils" "log" "net/http" @@ -105,21 +106,52 @@ func (s *Service) RemoveFriend(c *fiber.Ctx) error { return c.Status(http.StatusOK).JSON(fiber.Map{"message": "Friend removed successfully"}) } +/* +GetProfile retrieves a user's profile information by the user's username, email, or ID. +*/ func (s *Service) GetProfile(c *fiber.Ctx) error { - username := c.Params("username") + userIdentifier := c.Params("userIdentifier") - if username == "" { - c.Status(http.StatusBadRequest) - return errs.APIError{StatusCode: fiber.StatusBadRequest, Message: "username is required"} - } + var profile models.Profile + var err error - profile, err := s.store.GetProfileByUsername(c.Context(), username) + if utils.IsEmail(userIdentifier) { + profile, err = s.store.GetProfileByEmail(c.Context(), userIdentifier) + } else if utils.IsUUID(userIdentifier) { + profile, err = s.store.GetProfileByID(c.Context(), userIdentifier) + } else { + profile, err = s.store.GetProfileByUsername(c.Context(), userIdentifier) + } + + if err != nil { + return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "profile not found"}) + } + + return c.Status(fiber.StatusOK).JSON(profile) +} +/* +Get All Users +*/ +func (s *Service) GetAllUsers(c *fiber.Ctx) error { + // Fetch all users from the store + users, err := s.store.GetAllUsers(c.Context()) if err != nil { - c.Status(http.StatusInternalServerError) - return errs.APIError{StatusCode: fiber.StatusNotFound, Message: "profile not found"} + + return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to retrieve users", + "details": err.Error(), + }) + } + + // If no users are found, we can return a 404 + if len(users) == 0 { + return c.Status(fiber.StatusNotFound).JSON(fiber.Map{ + "message": "No users found", + }) } - return c.Status(http.StatusOK).JSON(profile) + // Return the list of users with a 200 OK status + return c.Status(fiber.StatusOK).JSON(users) } diff --git a/backend/internal/handlers/profiles/routes.go b/backend/internal/handlers/profiles/routes.go index 05e2b30..2db08a9 100644 --- a/backend/internal/handlers/profiles/routes.go +++ b/backend/internal/handlers/profiles/routes.go @@ -17,9 +17,11 @@ func Routes(app *fiber.App, params types.Params) { protected.Use(auth.Protected(¶ms.Supabase)) //Endpoints - protected.Get("/:username", service.GetProfile) - protected.Post("/preferences", service.CreatePreferences) - protected.Patch("/preferences", service.UpdateProfilePreferences) - protected.Delete("/:userId", service.DeleteUser) - protected.Delete("/friends/:username", service.RemoveFriend) + protected.Get("/", service.GetAllUsers) + protected.Get("/:userIdentifier", service.GetProfile) + protected.Post("/preferences", service.CreatePreferences) + protected.Patch("/preferences", service.UpdateProfilePreferences) + protected.Delete("/:userId", service.DeleteUser) + protected.Delete("/friends/:username", service.RemoveFriend) + } diff --git a/backend/internal/server/server.go b/backend/internal/server/server.go index 911c68d..9f664d9 100644 --- a/backend/internal/server/server.go +++ b/backend/internal/server/server.go @@ -26,11 +26,22 @@ func New(params types.Params) *fiber.App { useMiddlewares(app) - health.Routes(app, params) + // Hellp route group hello.Routes(app, params) + + // Test route group test.Routes(app, params) + + // Health route group + health.Routes(app, params) + + // Auth route group auth.Routes(app, params) + + // Venues route group venues.Routes(app, params) + + // Profile (User) route group profiles.Routes(app, params) //User Ratings route group diff --git a/backend/internal/storage/postgres/profile.go b/backend/internal/storage/postgres/profile.go deleted file mode 100644 index 462fd42..0000000 --- a/backend/internal/storage/postgres/profile.go +++ /dev/null @@ -1,16 +0,0 @@ -package postgres - -import ( - "context" - - "github.com/GenerateNU/nightlife/internal/models" -) - -func (db *DB) CreatePreferences(ctx context.Context, p models.Preferences) error { - // query to save user data to db - query := `INSERT INTO preferences (userID, location, age, music, ambiance, notifs) - VALUES ($1, $2, $3, $4, $5, $6)` - - _, err := db.conn.Query(ctx, query, p.UserID, p.Location, p.Age, p.Music, p.Ambiance, p.Notifs) - return err -} diff --git a/backend/internal/storage/postgres/profiles.go b/backend/internal/storage/postgres/profiles.go index 4385a72..8f7d76c 100644 --- a/backend/internal/storage/postgres/profiles.go +++ b/backend/internal/storage/postgres/profiles.go @@ -50,6 +50,73 @@ func (db *DB) GetProfileByUsername(ctx context.Context, username string) (models return profile, nil } +func (db *DB) GetProfileByEmail(ctx context.Context, email string) (models.Profile, error) { + var profile models.Profile + var query = ` + SELECT user_id, first_name, username, email, age, location, profile_picture_url, created_at + FROM "User" + WHERE email = $1 + ` + row := db.conn.QueryRow(ctx, query, email) + err := row.Scan( + &profile.UserID, + &profile.FirstName, + &profile.Username, + &profile.Email, + &profile.Age, + &profile.Location, + &profile.ProfilePictureURL, + &profile.CreatedAt, + ) + + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return models.Profile{}, fmt.Errorf("no profile found for email: %s", email) + } + return models.Profile{}, err + } + + return profile, nil +} + +func (db *DB) GetProfileByID(ctx context.Context, id string) (models.Profile, error) { + var profile models.Profile + var query = ` + SELECT user_id, first_name, username, email, age, location, profile_picture_url, created_at + FROM "User" + WHERE user_id = $1 + ` + row := db.conn.QueryRow(ctx, query, id) + err := row.Scan( + &profile.UserID, + &profile.FirstName, + &profile.Username, + &profile.Email, + &profile.Age, + &profile.Location, + &profile.ProfilePictureURL, + &profile.CreatedAt, + ) + + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return models.Profile{}, fmt.Errorf("no profile found for ID: %s", id) + } + return models.Profile{}, err + } + + return profile, nil +} + +func (db *DB) CreatePreferences(ctx context.Context, p models.Preferences) error { + // query to save user data to db + query := `INSERT INTO preferences (userID, location, age, music, ambiance, notifs) + VALUES ($1, $2, $3, $4, $5, $6)` + + _, err := db.conn.Query(ctx, query, p.UserID, p.Location, p.Age, p.Music, p.Ambiance, p.Notifs) + return err +} + func (db *DB) UpdateProfilePreferences(ctx context.Context, userID uuid.UUID, preferencetypeto string, preferencevalueto string, preferenceType string, preferenceValue string) error { // SQL query execution @@ -100,3 +167,42 @@ func (db *DB) RemoveFriend(ctx context.Context, userID uuid.UUID, friendUsername } return nil } + +/* +Get All Users +*/ +func (db *DB) GetAllUsers(ctx context.Context) ([]models.Profile, error) { + + rows, err := db.conn.Query(ctx, `SELECT user_id, first_name, username, email, age, location, profile_picture_url, created_at FROM "User"`) + if err != nil { + return nil, err + } + defer rows.Close() + + var profiles []models.Profile + + // Iterate through the result rows + for rows.Next() { + var profile models.Profile + if err := rows.Scan( + &profile.UserID, + &profile.FirstName, + &profile.Username, + &profile.Email, + &profile.Age, + &profile.Location, + &profile.ProfilePictureURL, + &profile.CreatedAt, + ); err != nil { + return nil, err + } + profiles = append(profiles, profile) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return profiles, nil +} + diff --git a/backend/internal/storage/storage.go b/backend/internal/storage/storage.go index 811151b..ebcb2e3 100644 --- a/backend/internal/storage/storage.go +++ b/backend/internal/storage/storage.go @@ -21,11 +21,14 @@ type Test interface { } type Profile interface { - CreatePreferences(context.Context, models.Preferences) error - UpdateProfilePreferences(context.Context, uuid.UUID, string, string, string, string) error - DeleteAccount(context.Context, uuid.UUID) error - RemoveFriend(context.Context, uuid.UUID, string) error - GetProfileByUsername(context.Context, string) (models.Profile, error) + CreatePreferences(context.Context, models.Preferences) error + UpdateProfilePreferences(context.Context, uuid.UUID, string, string, string, string) error + DeleteAccount(context.Context, uuid.UUID) error + RemoveFriend(context.Context, uuid.UUID, string) error + GetProfileByUsername(context.Context, string) (models.Profile, error) + GetProfileByEmail(context.Context, string) (models.Profile, error) + GetProfileByID(context.Context, string) (models.Profile, error) + GetAllUsers(context.Context) ([]models.Profile, error) } type UserRating interface { diff --git a/backend/internal/utils/validators.go b/backend/internal/utils/validators.go new file mode 100644 index 0000000..80dcfdf --- /dev/null +++ b/backend/internal/utils/validators.go @@ -0,0 +1,18 @@ +// internal/utils/validators.go +package utils + +import ( + "regexp" + "strings" +) + +// Check if the string is a valid email address +func IsEmail(input string) bool { + return strings.Contains(input, "@") +} + +// Check if the string is a valid UUID +func IsUUID(input string) bool { + uuidRegex := regexp.MustCompile(`^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`) + return uuidRegex.MatchString(input) +} From 80f2a467837ce88827743b5835600d8107fdd416 Mon Sep 17 00:00:00 2001 From: Abyan Nawaz <77990944+abyan-n@users.noreply.github.com> Date: Wed, 16 Oct 2024 09:42:40 -0400 Subject: [PATCH 3/4] Db/rename all tables (#50) * dropping all tables migration file * Database migrations, deleted old tables and created new ones with proper names * renamed user table to users. Fixed all sql queries to use new tables names. * Small sql fix --- .../internal/handlers/profiles/profiles.go | 3 +- .../internal/storage/postgres/friendship.go | 2 +- backend/internal/storage/postgres/profiles.go | 12 +- .../internal/storage/postgres/userrating.go | 6 +- .../internal/storage/postgres/venueratings.go | 4 +- backend/internal/storage/postgres/venues.go | 4 +- .../20241015222413_drop_all_tables.sql | 13 + ...015224216_remake_tables_with_lowercase.sql | 171 ++++ ...41015231021_rename_user_table_to_users.sql | 49 + .../20241016000000_drop_all_tables_2.sql | 13 + .../20241016023520_remote_schema.sql | 835 ++++++++++++++++++ backend/supabase/seed.sql | 111 +++ 12 files changed, 1208 insertions(+), 15 deletions(-) create mode 100644 backend/supabase/migrations/20241015222413_drop_all_tables.sql create mode 100644 backend/supabase/migrations/20241015224216_remake_tables_with_lowercase.sql create mode 100644 backend/supabase/migrations/20241015231021_rename_user_table_to_users.sql create mode 100644 backend/supabase/migrations/20241016000000_drop_all_tables_2.sql create mode 100644 backend/supabase/migrations/20241016023520_remote_schema.sql diff --git a/backend/internal/handlers/profiles/profiles.go b/backend/internal/handlers/profiles/profiles.go index fd8a48d..354b5b9 100644 --- a/backend/internal/handlers/profiles/profiles.go +++ b/backend/internal/handlers/profiles/profiles.go @@ -1,11 +1,12 @@ package profiles import ( - "github.com/GenerateNU/nightlife/internal/errs" "github.com/GenerateNU/nightlife/internal/utils" "log" "net/http" + "github.com/GenerateNU/nightlife/internal/errs" + "github.com/GenerateNU/nightlife/internal/models" "github.com/gofiber/fiber/v2" "github.com/google/uuid" diff --git a/backend/internal/storage/postgres/friendship.go b/backend/internal/storage/postgres/friendship.go index acedaeb..075f9c9 100644 --- a/backend/internal/storage/postgres/friendship.go +++ b/backend/internal/storage/postgres/friendship.go @@ -8,7 +8,7 @@ import ( func (db *DB) CreateFriendship(ctx context.Context, friendship models.Friendship) error { var query = ` - INSERT INTO "Friendship" (user_id1, user_id2, friendship_status, created_at) + INSERT INTO friendship (user_id1, user_id2, friendship_status, created_at) VALUES ($1, $2, $3, $4); ` _, err := db.conn.Exec(ctx, query, friendship.UserID1, friendship.UserID2, friendship.FriendshipStatus, friendship.CreatedAt) diff --git a/backend/internal/storage/postgres/profiles.go b/backend/internal/storage/postgres/profiles.go index 8f7d76c..b65222e 100644 --- a/backend/internal/storage/postgres/profiles.go +++ b/backend/internal/storage/postgres/profiles.go @@ -23,7 +23,7 @@ func (db *DB) GetProfileByUsername(ctx context.Context, username string) (models location, profile_picture_url, created_at - FROM "User" + FROM users WHERE username = $1 ` @@ -121,7 +121,7 @@ func (db *DB) UpdateProfilePreferences(ctx context.Context, userID uuid.UUID, pr // SQL query execution _, err := db.conn.Exec(ctx, ` - UPDATE "UserPreference" up + UPDATE user_preference up SET user_id = $1, preference_type = $2, @@ -143,7 +143,7 @@ func (db *DB) UpdateProfilePreferences(ctx context.Context, userID uuid.UUID, pr Delete an account */ func (db *DB) DeleteAccount(ctx context.Context, userID uuid.UUID) error { - _, err := db.conn.Exec(ctx, `DELETE FROM "User" WHERE user_id = $1`, userID) + _, err := db.conn.Exec(ctx, `DELETE FROM users WHERE user_id = $1`, userID) if err != nil { return err @@ -157,9 +157,9 @@ RemoveFriend removes a friend from the user's friend list based on the friend's */ func (db *DB) RemoveFriend(ctx context.Context, userID uuid.UUID, friendUsername string) error { _, err := db.conn.Exec(ctx, ` - DELETE FROM "Friendship" - WHERE user_id1 = $1 AND user_id2 = (SELECT user_id FROM "User" WHERE username = $2) - OR user_id2 = $1 AND user_id1 = (SELECT user_id FROM "User" WHERE username = $2) + DELETE FROM friendship + WHERE user_id1 = $1 AND user_id2 = (SELECT user_id FROM users WHERE username = $2) + OR user_id2 = $1 AND user_id1 = (SELECT user_id FROM users WHERE username = $2) `, userID, friendUsername) if err != nil { diff --git a/backend/internal/storage/postgres/userrating.go b/backend/internal/storage/postgres/userrating.go index 3e5b639..b7e262e 100644 --- a/backend/internal/storage/postgres/userrating.go +++ b/backend/internal/storage/postgres/userrating.go @@ -18,11 +18,11 @@ SELECT v.name AS venue_name, r.overall_rating FROM - "Review" r + review r JOIN - "User" u ON r.user_id = u.user_id + users u ON r.user_id = u.user_id JOIN - "Venue" v ON r.venue_id = v.venue_id + venue v ON r.venue_id = v.venue_id WHERE u.user_id = $1; ` diff --git a/backend/internal/storage/postgres/venueratings.go b/backend/internal/storage/postgres/venueratings.go index 46f590b..53f0ba6 100644 --- a/backend/internal/storage/postgres/venueratings.go +++ b/backend/internal/storage/postgres/venueratings.go @@ -21,9 +21,9 @@ SELECT r.crowd_rating, r.service_rating FROM - "Review" r + review r JOIN - "Venue" v ON r.venue_id = v.venue_id + venue v ON r.venue_id = v.venue_id WHERE v.venue_id = $1; ` diff --git a/backend/internal/storage/postgres/venues.go b/backend/internal/storage/postgres/venues.go index 0271f17..03cf796 100644 --- a/backend/internal/storage/postgres/venues.go +++ b/backend/internal/storage/postgres/venues.go @@ -8,7 +8,7 @@ import ( ) func (db *DB) DeleteVenue(ctx context.Context, id uuid.UUID) error { - _, err := db.conn.Exec(ctx, `DELETE FROM "Venue" v WHERE venue_id = $1`, id) + _, err := db.conn.Exec(ctx, `DELETE FROM venue v WHERE venue_id = $1`, id) if err != nil { return err } @@ -19,7 +19,7 @@ func (db *DB) DeleteVenue(ctx context.Context, id uuid.UUID) error { Deletes a review for a venue. */ func (db *DB) DeleteReviewForVenue(ctx context.Context, reviewID int8) error { - result, err := db.conn.Exec(ctx, `DELETE FROM "Review" WHERE review_id = $1`, reviewID) + result, err := db.conn.Exec(ctx, `DELETE FROM review WHERE review_id = $1`, reviewID) if err != nil { return err } diff --git a/backend/supabase/migrations/20241015222413_drop_all_tables.sql b/backend/supabase/migrations/20241015222413_drop_all_tables.sql new file mode 100644 index 0000000..8d5a53a --- /dev/null +++ b/backend/supabase/migrations/20241015222413_drop_all_tables.sql @@ -0,0 +1,13 @@ +-- Drop tables with capitalized names +DROP TABLE IF EXISTS public."Friendship" CASCADE; +DROP TABLE IF EXISTS public."Notification" CASCADE; +DROP TABLE IF EXISTS public."Review" CASCADE; +DROP TABLE IF EXISTS public."SearchHistory" CASCADE; +DROP TABLE IF EXISTS public."UserPreference" CASCADE; +DROP TABLE IF EXISTS public."VenueAttribute" CASCADE; +DROP TABLE IF EXISTS public."VenuePhoto" CASCADE; +DROP TABLE IF EXISTS public."Venue" CASCADE; +DROP TABLE IF EXISTS public."User" CASCADE; + +DROP TYPE IF EXISTS public."FriendshipStatus"; +DROP TYPE IF EXISTS public."VenueType"; \ No newline at end of file diff --git a/backend/supabase/migrations/20241015224216_remake_tables_with_lowercase.sql b/backend/supabase/migrations/20241015224216_remake_tables_with_lowercase.sql new file mode 100644 index 0000000..ee2c896 --- /dev/null +++ b/backend/supabase/migrations/20241015224216_remake_tables_with_lowercase.sql @@ -0,0 +1,171 @@ +-- Keep enums as is +CREATE TYPE "public"."FriendshipStatus" AS ENUM ('PENDING', 'ACCEPTED', 'DECLINED', 'BLOCKED'); +CREATE TYPE "public"."VenueType" AS ENUM ('BAR', 'CLUB', 'LOUNGE'); + +-- Create tables with underscored two-word table names +CREATE TABLE "public"."friendship" ( + "user_id1" uuid NOT NULL DEFAULT gen_random_uuid(), + "user_id2" uuid NOT NULL DEFAULT gen_random_uuid(), + "friendship_status" "FriendshipStatus" NOT NULL, + "created_at" timestamp without time zone NOT NULL DEFAULT now() +); + +ALTER TABLE "public"."friendship" ENABLE ROW LEVEL SECURITY; + +CREATE TABLE "public"."notification" ( + "notification_id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + "user_id" UUID NOT NULL DEFAULT gen_random_uuid(), + "message" TEXT, + "is_read" BOOLEAN NOT NULL DEFAULT FALSE, + "created_at" timestamp without time zone NOT NULL DEFAULT now() +); + +ALTER TABLE "public"."notification" ENABLE ROW LEVEL SECURITY; + +CREATE TABLE "public"."review" ( + "review_id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + "user_id" UUID NOT NULL DEFAULT gen_random_uuid(), + "venue_id" UUID DEFAULT gen_random_uuid(), + "overall_rating" BIGINT, + "ambiance_rating" BIGINT, + "music_rating" BIGINT, + "crowd_rating" BIGINT, + "service_rating" BIGINT, + "review_text" TEXT, + "created_at" TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT NOW(), + "updated_at" TIMESTAMP WITHOUT TIME ZONE +); + +ALTER TABLE "public"."review" ENABLE ROW LEVEL SECURITY; + +CREATE TABLE "public"."search_history" ( + "search_id" BIGINT GENERATED BY DEFAULT AS IDENTITY NOT NULL, + "user_id" UUID DEFAULT gen_random_uuid(), + "search_term" TIMESTAMP WITHOUT TIME ZONE NOT NULL, + "search_time" TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now() +); + +ALTER TABLE "public"."search_history" ENABLE ROW LEVEL SECURITY; + +CREATE TABLE "public"."user" ( + "user_id" UUID NOT NULL DEFAULT gen_random_uuid(), + "first_name" VARCHAR NOT NULL, + "username" VARCHAR NOT NULL, + "email" VARCHAR NOT NULL, + "age" BIGINT NOT NULL, + "location" geography NOT NULL, + "profile_picture_url" VARCHAR, + "created_at" TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now(), + "updated_at" TIMESTAMP WITHOUT TIME ZONE +); + +ALTER TABLE "public"."user" ENABLE ROW LEVEL SECURITY; + +CREATE TABLE "public"."user_preference" ( + "user_id" UUID NOT NULL, + "preference_type" VARCHAR NOT NULL, + "preference_value" VARCHAR NOT NULL +); + +ALTER TABLE "public"."user_preference" ENABLE ROW LEVEL SECURITY; + +CREATE TABLE "public"."venue" ( + "venue_id" UUID NOT NULL DEFAULT gen_random_uuid(), + "name" VARCHAR NOT NULL, + "address" VARCHAR NOT NULL, + "city" VARCHAR, + "state" VARCHAR, + "zip_code" VARCHAR, + "location" geography NOT NULL, + "venue_type" "VenueType" NOT NULL, + "created_at" TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now(), + "updated_at" TIMESTAMP WITHOUT TIME ZONE +); + +ALTER TABLE "public"."venue" ENABLE ROW LEVEL SECURITY; + +CREATE TABLE "public"."venue_attribute" ( + "venue_id" UUID NOT NULL, + "attribute_type" VARCHAR NOT NULL, + "attribute_value" VARCHAR NOT NULL +); + +ALTER TABLE "public"."venue_attribute" ENABLE ROW LEVEL SECURITY; + +CREATE TABLE "public"."venue_photo" ( + "photo_id" UUID NOT NULL DEFAULT gen_random_uuid(), + "review_id" UUID NOT NULL, + "user_id" UUID NOT NULL, + "photo_url" VARCHAR NOT NULL, + "caption" TEXT, + "uploaded_at" TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT now() +); + +ALTER TABLE "public"."venue_photo" ENABLE ROW LEVEL SECURITY; + +-- Create indexes with updated table names +CREATE UNIQUE INDEX "friendship_pkey" ON public."friendship" USING btree (user_id1, user_id2); +CREATE UNIQUE INDEX "notification_notification_id_key" ON public."notification" USING btree (notification_id); +CREATE UNIQUE INDEX "notification_pkey" ON public."notification" USING btree (notification_id); +CREATE UNIQUE INDEX "review_pkey" ON public."review" USING btree (review_id); +CREATE UNIQUE INDEX "review_review_id_key" ON public."review" USING btree (review_id); +CREATE UNIQUE INDEX "search_history_pkey" ON public."search_history" USING btree (search_id); +CREATE UNIQUE INDEX "search_history_search_id_key" ON public."search_history" USING btree (search_id); +CREATE UNIQUE INDEX "user_preference_pkey" ON public."user_preference" USING btree (user_id, preference_type, preference_value); +CREATE UNIQUE INDEX "user_email_key" ON public."user" USING btree (email); +CREATE UNIQUE INDEX "user_pkey" ON public."user" USING btree (user_id); +CREATE UNIQUE INDEX "user_username_key" ON public."user" USING btree (username); +CREATE UNIQUE INDEX "venue_attribute_pkey" ON public."venue_attribute" USING btree (venue_id, attribute_type, attribute_value); +CREATE UNIQUE INDEX "venue_photo_pkey" ON public."venue_photo" USING btree (photo_id); +CREATE UNIQUE INDEX "venue_pkey" ON public."venue" USING btree (venue_id); + +-- Add primary key constraints +ALTER TABLE "public"."friendship" ADD CONSTRAINT "friendship_pkey" PRIMARY KEY USING INDEX "friendship_pkey"; +ALTER TABLE "public"."notification" ADD CONSTRAINT "notification_pkey" PRIMARY KEY USING INDEX "notification_pkey"; +ALTER TABLE "public"."review" ADD CONSTRAINT "review_pkey" PRIMARY KEY USING INDEX "review_pkey"; +ALTER TABLE "public"."search_history" ADD CONSTRAINT "search_history_pkey" PRIMARY KEY USING INDEX "search_history_pkey"; +ALTER TABLE "public"."user" ADD CONSTRAINT "user_pkey" PRIMARY KEY USING INDEX "user_pkey"; +ALTER TABLE "public"."user_preference" ADD CONSTRAINT "user_preference_pkey" PRIMARY KEY USING INDEX "user_preference_pkey"; +ALTER TABLE "public"."venue" ADD CONSTRAINT "venue_pkey" PRIMARY KEY USING INDEX "venue_pkey"; +ALTER TABLE "public"."venue_attribute" ADD CONSTRAINT "venue_attribute_pkey" PRIMARY KEY USING INDEX "venue_attribute_pkey"; +ALTER TABLE "public"."venue_photo" ADD CONSTRAINT "venue_photo_pkey" PRIMARY KEY USING INDEX "venue_photo_pkey"; + +-- Add foreign key constraints +ALTER TABLE "public"."friendship" ADD CONSTRAINT "friendship_user_id1_fkey" FOREIGN KEY (user_id1) REFERENCES "public"."user" (user_id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; +ALTER TABLE "public"."friendship" VALIDATE CONSTRAINT "friendship_user_id1_fkey"; +ALTER TABLE "public"."friendship" ADD CONSTRAINT "friendship_user_id2_fkey" FOREIGN KEY (user_id2) REFERENCES "public"."user" (user_id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; +ALTER TABLE "public"."friendship" VALIDATE CONSTRAINT "friendship_user_id2_fkey"; + +ALTER TABLE "public"."notification" ADD CONSTRAINT "notification_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "public"."user" (user_id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; +ALTER TABLE "public"."notification" VALIDATE CONSTRAINT "notification_user_id_fkey"; + +ALTER TABLE "public"."review" ADD CONSTRAINT "review_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "public"."user" (user_id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; +ALTER TABLE "public"."review" VALIDATE CONSTRAINT "review_user_id_fkey"; +ALTER TABLE "public"."review" ADD CONSTRAINT "review_venue_id_fkey" FOREIGN KEY (venue_id) REFERENCES "public"."venue" (venue_id) ON UPDATE CASCADE ON DELETE SET NULL NOT VALID; +ALTER TABLE "public"."review" VALIDATE CONSTRAINT "review_venue_id_fkey"; + +ALTER TABLE "public"."search_history" ADD CONSTRAINT "search_history_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "public"."user" (user_id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; +ALTER TABLE "public"."search_history" VALIDATE CONSTRAINT "search_history_user_id_fkey"; + +ALTER TABLE "public"."user_preference" ADD CONSTRAINT "user_preference_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "public"."user" (user_id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; +ALTER TABLE "public"."user_preference" VALIDATE CONSTRAINT "user_preference_user_id_fkey"; + +ALTER TABLE "public"."venue_attribute" ADD CONSTRAINT "venue_attribute_venue_id_fkey" FOREIGN KEY (venue_id) REFERENCES "public"."venue" (venue_id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID; +ALTER TABLE "public"."venue_attribute" VALIDATE CONSTRAINT "venue_attribute_venue_id_fkey"; + +ALTER TABLE "public"."venue_photo" ADD CONSTRAINT "venue_photo_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "public"."user" (user_id) ON UPDATE CASCADE ON DELETE SET NULL NOT VALID; +ALTER TABLE "public"."venue_photo" VALIDATE CONSTRAINT "venue_photo_user_id_fkey"; + +-- Grant permissions for lowercase table names +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.friendship TO anon, authenticated, service_role; +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.notification TO anon, authenticated, service_role; +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.review TO anon, authenticated, service_role; +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.search_history TO anon, authenticated, service_role; +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.user TO anon, authenticated, service_role; +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.user_preference TO anon, authenticated, service_role; +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.venue TO anon, authenticated, service_role; +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.venue_attribute TO anon, authenticated, service_role; +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.venue_photo TO anon, authenticated, service_role; + +-- Create extension +CREATE EXTENSION IF NOT EXISTS "postgis" WITH SCHEMA "public" VERSION '3.3.2'; diff --git a/backend/supabase/migrations/20241015231021_rename_user_table_to_users.sql b/backend/supabase/migrations/20241015231021_rename_user_table_to_users.sql new file mode 100644 index 0000000..75b8c4e --- /dev/null +++ b/backend/supabase/migrations/20241015231021_rename_user_table_to_users.sql @@ -0,0 +1,49 @@ +-- Rename "user" table to "users" +ALTER TABLE "public"."user" RENAME TO "users"; + +-- Friendship table +ALTER TABLE "public"."friendship" DROP CONSTRAINT "friendship_user_id1_fkey"; +ALTER TABLE "public"."friendship" ADD CONSTRAINT "friendship_user_id1_fkey" +FOREIGN KEY (user_id1) REFERENCES "public"."users" (user_id) ON UPDATE CASCADE ON DELETE CASCADE; + +ALTER TABLE "public"."friendship" DROP CONSTRAINT "friendship_user_id2_fkey"; +ALTER TABLE "public"."friendship" ADD CONSTRAINT "friendship_user_id2_fkey" +FOREIGN KEY (user_id2) REFERENCES "public"."users" (user_id) ON UPDATE CASCADE ON DELETE CASCADE; + +-- Notification table +ALTER TABLE "public"."notification" DROP CONSTRAINT "notification_user_id_fkey"; +ALTER TABLE "public"."notification" ADD CONSTRAINT "notification_user_id_fkey" +FOREIGN KEY (user_id) REFERENCES "public"."users" (user_id) ON UPDATE CASCADE ON DELETE CASCADE; + +-- Review table +ALTER TABLE "public"."review" DROP CONSTRAINT "review_user_id_fkey"; +ALTER TABLE "public"."review" ADD CONSTRAINT "review_user_id_fkey" +FOREIGN KEY (user_id) REFERENCES "public"."users" (user_id) ON UPDATE CASCADE ON DELETE CASCADE; + +-- Search History table +ALTER TABLE "public"."search_history" DROP CONSTRAINT "search_history_user_id_fkey"; +ALTER TABLE "public"."search_history" ADD CONSTRAINT "search_history_user_id_fkey" +FOREIGN KEY (user_id) REFERENCES "public"."users" (user_id) ON UPDATE CASCADE ON DELETE CASCADE; + +-- User Preference table +ALTER TABLE "public"."user_preference" DROP CONSTRAINT "user_preference_user_id_fkey"; +ALTER TABLE "public"."user_preference" ADD CONSTRAINT "user_preference_user_id_fkey" +FOREIGN KEY (user_id) REFERENCES "public"."users" (user_id) ON UPDATE CASCADE ON DELETE CASCADE; + +-- Venue Photo table +ALTER TABLE "public"."venue_photo" DROP CONSTRAINT "venue_photo_user_id_fkey"; +ALTER TABLE "public"."venue_photo" ADD CONSTRAINT "venue_photo_user_id_fkey" +FOREIGN KEY (user_id) REFERENCES "public"."users" (user_id) ON UPDATE CASCADE ON DELETE SET NULL; + +-- Update any permissions related to the table "users" +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.users TO anon, authenticated, service_role; +GRANT DELETE, INSERT, REFERENCES, SELECT, TRIGGER, TRUNCATE, UPDATE ON public.user_preference TO anon, authenticated, service_role; + +-- Optional: Validate all the foreign key constraints +ALTER TABLE "public"."friendship" VALIDATE CONSTRAINT "friendship_user_id1_fkey"; +ALTER TABLE "public"."friendship" VALIDATE CONSTRAINT "friendship_user_id2_fkey"; +ALTER TABLE "public"."notification" VALIDATE CONSTRAINT "notification_user_id_fkey"; +ALTER TABLE "public"."review" VALIDATE CONSTRAINT "review_user_id_fkey"; +ALTER TABLE "public"."search_history" VALIDATE CONSTRAINT "search_history_user_id_fkey"; +ALTER TABLE "public"."user_preference" VALIDATE CONSTRAINT "user_preference_user_id_fkey"; +ALTER TABLE "public"."venue_photo" VALIDATE CONSTRAINT "venue_photo_user_id_fkey"; diff --git a/backend/supabase/migrations/20241016000000_drop_all_tables_2.sql b/backend/supabase/migrations/20241016000000_drop_all_tables_2.sql new file mode 100644 index 0000000..8d5a53a --- /dev/null +++ b/backend/supabase/migrations/20241016000000_drop_all_tables_2.sql @@ -0,0 +1,13 @@ +-- Drop tables with capitalized names +DROP TABLE IF EXISTS public."Friendship" CASCADE; +DROP TABLE IF EXISTS public."Notification" CASCADE; +DROP TABLE IF EXISTS public."Review" CASCADE; +DROP TABLE IF EXISTS public."SearchHistory" CASCADE; +DROP TABLE IF EXISTS public."UserPreference" CASCADE; +DROP TABLE IF EXISTS public."VenueAttribute" CASCADE; +DROP TABLE IF EXISTS public."VenuePhoto" CASCADE; +DROP TABLE IF EXISTS public."Venue" CASCADE; +DROP TABLE IF EXISTS public."User" CASCADE; + +DROP TYPE IF EXISTS public."FriendshipStatus"; +DROP TYPE IF EXISTS public."VenueType"; \ No newline at end of file diff --git a/backend/supabase/migrations/20241016023520_remote_schema.sql b/backend/supabase/migrations/20241016023520_remote_schema.sql new file mode 100644 index 0000000..6d9a173 --- /dev/null +++ b/backend/supabase/migrations/20241016023520_remote_schema.sql @@ -0,0 +1,835 @@ +create extension if not exists "postgis" with schema "public" version '3.3.2'; + +create type "public"."FriendshipStatus" as enum ('PENDING', 'ACCEPTED', 'DECLINED', 'BLOCKED'); + +create type "public"."VenueType" as enum ('BAR', 'CLUB', 'LOUNGE'); + +create table "public"."Friendship" ( + "user_id1" uuid not null default gen_random_uuid(), + "user_id2" uuid not null default gen_random_uuid(), + "friendship_status" "FriendshipStatus" not null, + "created_at" timestamp without time zone not null default now() +); + + +alter table "public"."Friendship" enable row level security; + +create table "public"."Notification" ( + "notification_id" bigint generated by default as identity not null, + "user_id" uuid not null default gen_random_uuid(), + "message" text, + "is_read" boolean not null default false, + "created_at" timestamp without time zone not null default now() +); + + +alter table "public"."Notification" enable row level security; + +create table "public"."Review" ( + "review_id" bigint generated by default as identity not null, + "user_id" uuid not null default gen_random_uuid(), + "venue_id" uuid default gen_random_uuid(), + "overall_rating" bigint, + "ambiance_rating" bigint, + "music_rating" bigint, + "crowd_rating" bigint, + "service_rating" bigint, + "review_text" text, + "created_at" timestamp without time zone not null default now(), + "udpated_at" timestamp without time zone +); + + +alter table "public"."Review" enable row level security; + +create table "public"."SearchHistory" ( + "search_id" bigint generated by default as identity not null, + "user_id" uuid default gen_random_uuid(), + "search_term" timestamp without time zone not null, + "search_time" timestamp without time zone not null default now() +); + + +alter table "public"."SearchHistory" enable row level security; + +create table "public"."User" ( + "user_id" uuid not null default gen_random_uuid(), + "first_name" character varying not null, + "username" character varying not null, + "email" character varying not null, + "age" bigint not null, + "location" geography not null, + "profile_picture_url" character varying, + "created_at" timestamp without time zone not null default now(), + "updated_at" timestamp without time zone +); + + +alter table "public"."User" enable row level security; + +create table "public"."UserPreference" ( + "user_id" uuid not null default gen_random_uuid(), + "preference_type" character varying not null, + "preference_value" character varying not null +); + + +alter table "public"."UserPreference" enable row level security; + +create table "public"."Venue" ( + "venue_id" uuid not null default gen_random_uuid(), + "name" character varying not null, + "address" character varying not null, + "city" character varying, + "state" character varying, + "zip_code" character varying, + "location" geography not null, + "venue_type" "VenueType" not null, + "created_at" timestamp without time zone not null default now(), + "updated_at" timestamp without time zone +); + + +alter table "public"."Venue" enable row level security; + +create table "public"."VenueAttribute" ( + "venue_id" uuid not null default gen_random_uuid(), + "attribute_type" character varying not null, + "attribute_value" character varying not null +); + + +alter table "public"."VenueAttribute" enable row level security; + +create table "public"."VenuePhoto" ( + "photo_id" uuid not null default gen_random_uuid(), + "review_id" uuid not null default gen_random_uuid(), + "user_id" uuid not null default gen_random_uuid(), + "photo_url" character varying not null, + "caption" text, + "uploaded_at" timestamp without time zone not null default now() +); + + +alter table "public"."VenuePhoto" enable row level security; + +create table "public"."temp_rating" ( + "rating_id" uuid not null default gen_random_uuid(), + "user_id" uuid not null, + "review" integer +); + + +create table "public"."temp_user" ( + "user_id" uuid not null default gen_random_uuid(), + "name" character varying not null +); + + +create table "public"."testMigrationTable" ( + "id" uuid not null default gen_random_uuid(), + "name" character varying not null, + "created_at" timestamp without time zone not null default now(), + "updated_at" timestamp without time zone +); + + +alter table "public"."testMigrationTable" enable row level security; + +CREATE UNIQUE INDEX "Friendship_pkey" ON public."Friendship" USING btree (user_id1, user_id2); + +CREATE UNIQUE INDEX "Notification_notification_id_key" ON public."Notification" USING btree (notification_id); + +CREATE UNIQUE INDEX "Notification_pkey" ON public."Notification" USING btree (notification_id); + +CREATE UNIQUE INDEX "Review_pkey" ON public."Review" USING btree (review_id); + +CREATE UNIQUE INDEX "Review_review_id_key" ON public."Review" USING btree (review_id); + +CREATE UNIQUE INDEX "SearchHistory_pkey" ON public."SearchHistory" USING btree (search_id); + +CREATE UNIQUE INDEX "SearchHistory_search_id_key" ON public."SearchHistory" USING btree (search_id); + +CREATE UNIQUE INDEX "UserPreference_pkey" ON public."UserPreference" USING btree (user_id, preference_type, preference_value); + +CREATE UNIQUE INDEX "User_email_key" ON public."User" USING btree (email); + +CREATE UNIQUE INDEX "User_pkey" ON public."User" USING btree (user_id); + +CREATE UNIQUE INDEX "User_username_key" ON public."User" USING btree (username); + +CREATE UNIQUE INDEX "VenueAttribute_pkey" ON public."VenueAttribute" USING btree (venue_id, attribute_type, attribute_value); + +CREATE UNIQUE INDEX "VenuePhoto_pkey" ON public."VenuePhoto" USING btree (photo_id); + +CREATE UNIQUE INDEX "Venue_pkey" ON public."Venue" USING btree (venue_id); + +CREATE UNIQUE INDEX temp_rating_pkey ON public.temp_rating USING btree (rating_id); + +CREATE UNIQUE INDEX temp_user_pkey ON public.temp_user USING btree (user_id); + +CREATE UNIQUE INDEX "testMigrationTable_pkey" ON public."testMigrationTable" USING btree (id); + +alter table "public"."Friendship" add constraint "Friendship_pkey" PRIMARY KEY using index "Friendship_pkey"; + +alter table "public"."Notification" add constraint "Notification_pkey" PRIMARY KEY using index "Notification_pkey"; + +alter table "public"."Review" add constraint "Review_pkey" PRIMARY KEY using index "Review_pkey"; + +alter table "public"."SearchHistory" add constraint "SearchHistory_pkey" PRIMARY KEY using index "SearchHistory_pkey"; + +alter table "public"."User" add constraint "User_pkey" PRIMARY KEY using index "User_pkey"; + +alter table "public"."UserPreference" add constraint "UserPreference_pkey" PRIMARY KEY using index "UserPreference_pkey"; + +alter table "public"."Venue" add constraint "Venue_pkey" PRIMARY KEY using index "Venue_pkey"; + +alter table "public"."VenueAttribute" add constraint "VenueAttribute_pkey" PRIMARY KEY using index "VenueAttribute_pkey"; + +alter table "public"."VenuePhoto" add constraint "VenuePhoto_pkey" PRIMARY KEY using index "VenuePhoto_pkey"; + +alter table "public"."temp_rating" add constraint "temp_rating_pkey" PRIMARY KEY using index "temp_rating_pkey"; + +alter table "public"."temp_user" add constraint "temp_user_pkey" PRIMARY KEY using index "temp_user_pkey"; + +alter table "public"."testMigrationTable" add constraint "testMigrationTable_pkey" PRIMARY KEY using index "testMigrationTable_pkey"; + +alter table "public"."Friendship" add constraint "Friendship_user_id1_fkey" FOREIGN KEY (user_id1) REFERENCES "User"(user_id) ON UPDATE CASCADE ON DELETE CASCADE not valid; + +alter table "public"."Friendship" validate constraint "Friendship_user_id1_fkey"; + +alter table "public"."Friendship" add constraint "Friendship_user_id2_fkey" FOREIGN KEY (user_id2) REFERENCES "User"(user_id) ON UPDATE CASCADE ON DELETE CASCADE not valid; + +alter table "public"."Friendship" validate constraint "Friendship_user_id2_fkey"; + +alter table "public"."Notification" add constraint "Notification_notification_id_key" UNIQUE using index "Notification_notification_id_key"; + +alter table "public"."Notification" add constraint "Notification_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "User"(user_id) ON UPDATE CASCADE ON DELETE CASCADE not valid; + +alter table "public"."Notification" validate constraint "Notification_user_id_fkey"; + +alter table "public"."Review" add constraint "Review_ambiance_rating_check" CHECK (((ambiance_rating >= 1) AND (ambiance_rating <= 10))) not valid; + +alter table "public"."Review" validate constraint "Review_ambiance_rating_check"; + +alter table "public"."Review" add constraint "Review_crowd_rating_check" CHECK (((crowd_rating >= 1) AND (crowd_rating <= 10))) not valid; + +alter table "public"."Review" validate constraint "Review_crowd_rating_check"; + +alter table "public"."Review" add constraint "Review_music_rating_check" CHECK (((music_rating >= 1) AND (music_rating <= 10))) not valid; + +alter table "public"."Review" validate constraint "Review_music_rating_check"; + +alter table "public"."Review" add constraint "Review_overall_rating_check" CHECK (((overall_rating >= 1) AND (overall_rating <= 5))) not valid; + +alter table "public"."Review" validate constraint "Review_overall_rating_check"; + +alter table "public"."Review" add constraint "Review_review_id_key" UNIQUE using index "Review_review_id_key"; + +alter table "public"."Review" add constraint "Review_service_rating_check" CHECK (((service_rating >= 1) AND (service_rating <= 10))) not valid; + +alter table "public"."Review" validate constraint "Review_service_rating_check"; + +alter table "public"."Review" add constraint "Review_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "User"(user_id) ON UPDATE CASCADE ON DELETE CASCADE not valid; + +alter table "public"."Review" validate constraint "Review_user_id_fkey"; + +alter table "public"."Review" add constraint "Review_venue_id_fkey" FOREIGN KEY (venue_id) REFERENCES "Venue"(venue_id) ON UPDATE CASCADE ON DELETE SET NULL not valid; + +alter table "public"."Review" validate constraint "Review_venue_id_fkey"; + +alter table "public"."SearchHistory" add constraint "SearchHistory_search_id_key" UNIQUE using index "SearchHistory_search_id_key"; + +alter table "public"."SearchHistory" add constraint "SearchHistory_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "User"(user_id) ON UPDATE CASCADE ON DELETE CASCADE not valid; + +alter table "public"."SearchHistory" validate constraint "SearchHistory_user_id_fkey"; + +alter table "public"."User" add constraint "User_email_key" UNIQUE using index "User_email_key"; + +alter table "public"."User" add constraint "User_username_key" UNIQUE using index "User_username_key"; + +alter table "public"."UserPreference" add constraint "UserPreference_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "User"(user_id) ON UPDATE CASCADE ON DELETE CASCADE not valid; + +alter table "public"."UserPreference" validate constraint "UserPreference_user_id_fkey"; + +alter table "public"."VenueAttribute" add constraint "VenueAttribute_venue_id_fkey" FOREIGN KEY (venue_id) REFERENCES "Venue"(venue_id) ON UPDATE CASCADE ON DELETE CASCADE not valid; + +alter table "public"."VenueAttribute" validate constraint "VenueAttribute_venue_id_fkey"; + +alter table "public"."VenuePhoto" add constraint "VenuePhoto_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "User"(user_id) ON UPDATE CASCADE ON DELETE SET NULL not valid; + +alter table "public"."VenuePhoto" validate constraint "VenuePhoto_user_id_fkey"; + +alter table "public"."temp_rating" add constraint "fk_user" FOREIGN KEY (user_id) REFERENCES temp_user(user_id) not valid; + +alter table "public"."temp_rating" validate constraint "fk_user"; + +alter table "public"."temp_rating" add constraint "temp_rating_review_check" CHECK (((review >= 0) AND (review <= 5))) not valid; + +alter table "public"."temp_rating" validate constraint "temp_rating_review_check"; + +create type "public"."geometry_dump" as ("path" integer[], "geom" geometry); + +create type "public"."valid_detail" as ("valid" boolean, "reason" character varying, "location" geometry); + +grant delete on table "public"."Friendship" to "anon"; + +grant insert on table "public"."Friendship" to "anon"; + +grant references on table "public"."Friendship" to "anon"; + +grant select on table "public"."Friendship" to "anon"; + +grant trigger on table "public"."Friendship" to "anon"; + +grant truncate on table "public"."Friendship" to "anon"; + +grant update on table "public"."Friendship" to "anon"; + +grant delete on table "public"."Friendship" to "authenticated"; + +grant insert on table "public"."Friendship" to "authenticated"; + +grant references on table "public"."Friendship" to "authenticated"; + +grant select on table "public"."Friendship" to "authenticated"; + +grant trigger on table "public"."Friendship" to "authenticated"; + +grant truncate on table "public"."Friendship" to "authenticated"; + +grant update on table "public"."Friendship" to "authenticated"; + +grant delete on table "public"."Friendship" to "service_role"; + +grant insert on table "public"."Friendship" to "service_role"; + +grant references on table "public"."Friendship" to "service_role"; + +grant select on table "public"."Friendship" to "service_role"; + +grant trigger on table "public"."Friendship" to "service_role"; + +grant truncate on table "public"."Friendship" to "service_role"; + +grant update on table "public"."Friendship" to "service_role"; + +grant delete on table "public"."Notification" to "anon"; + +grant insert on table "public"."Notification" to "anon"; + +grant references on table "public"."Notification" to "anon"; + +grant select on table "public"."Notification" to "anon"; + +grant trigger on table "public"."Notification" to "anon"; + +grant truncate on table "public"."Notification" to "anon"; + +grant update on table "public"."Notification" to "anon"; + +grant delete on table "public"."Notification" to "authenticated"; + +grant insert on table "public"."Notification" to "authenticated"; + +grant references on table "public"."Notification" to "authenticated"; + +grant select on table "public"."Notification" to "authenticated"; + +grant trigger on table "public"."Notification" to "authenticated"; + +grant truncate on table "public"."Notification" to "authenticated"; + +grant update on table "public"."Notification" to "authenticated"; + +grant delete on table "public"."Notification" to "service_role"; + +grant insert on table "public"."Notification" to "service_role"; + +grant references on table "public"."Notification" to "service_role"; + +grant select on table "public"."Notification" to "service_role"; + +grant trigger on table "public"."Notification" to "service_role"; + +grant truncate on table "public"."Notification" to "service_role"; + +grant update on table "public"."Notification" to "service_role"; + +grant delete on table "public"."Review" to "anon"; + +grant insert on table "public"."Review" to "anon"; + +grant references on table "public"."Review" to "anon"; + +grant select on table "public"."Review" to "anon"; + +grant trigger on table "public"."Review" to "anon"; + +grant truncate on table "public"."Review" to "anon"; + +grant update on table "public"."Review" to "anon"; + +grant delete on table "public"."Review" to "authenticated"; + +grant insert on table "public"."Review" to "authenticated"; + +grant references on table "public"."Review" to "authenticated"; + +grant select on table "public"."Review" to "authenticated"; + +grant trigger on table "public"."Review" to "authenticated"; + +grant truncate on table "public"."Review" to "authenticated"; + +grant update on table "public"."Review" to "authenticated"; + +grant delete on table "public"."Review" to "service_role"; + +grant insert on table "public"."Review" to "service_role"; + +grant references on table "public"."Review" to "service_role"; + +grant select on table "public"."Review" to "service_role"; + +grant trigger on table "public"."Review" to "service_role"; + +grant truncate on table "public"."Review" to "service_role"; + +grant update on table "public"."Review" to "service_role"; + +grant delete on table "public"."SearchHistory" to "anon"; + +grant insert on table "public"."SearchHistory" to "anon"; + +grant references on table "public"."SearchHistory" to "anon"; + +grant select on table "public"."SearchHistory" to "anon"; + +grant trigger on table "public"."SearchHistory" to "anon"; + +grant truncate on table "public"."SearchHistory" to "anon"; + +grant update on table "public"."SearchHistory" to "anon"; + +grant delete on table "public"."SearchHistory" to "authenticated"; + +grant insert on table "public"."SearchHistory" to "authenticated"; + +grant references on table "public"."SearchHistory" to "authenticated"; + +grant select on table "public"."SearchHistory" to "authenticated"; + +grant trigger on table "public"."SearchHistory" to "authenticated"; + +grant truncate on table "public"."SearchHistory" to "authenticated"; + +grant update on table "public"."SearchHistory" to "authenticated"; + +grant delete on table "public"."SearchHistory" to "service_role"; + +grant insert on table "public"."SearchHistory" to "service_role"; + +grant references on table "public"."SearchHistory" to "service_role"; + +grant select on table "public"."SearchHistory" to "service_role"; + +grant trigger on table "public"."SearchHistory" to "service_role"; + +grant truncate on table "public"."SearchHistory" to "service_role"; + +grant update on table "public"."SearchHistory" to "service_role"; + +grant delete on table "public"."User" to "anon"; + +grant insert on table "public"."User" to "anon"; + +grant references on table "public"."User" to "anon"; + +grant select on table "public"."User" to "anon"; + +grant trigger on table "public"."User" to "anon"; + +grant truncate on table "public"."User" to "anon"; + +grant update on table "public"."User" to "anon"; + +grant delete on table "public"."User" to "authenticated"; + +grant insert on table "public"."User" to "authenticated"; + +grant references on table "public"."User" to "authenticated"; + +grant select on table "public"."User" to "authenticated"; + +grant trigger on table "public"."User" to "authenticated"; + +grant truncate on table "public"."User" to "authenticated"; + +grant update on table "public"."User" to "authenticated"; + +grant delete on table "public"."User" to "service_role"; + +grant insert on table "public"."User" to "service_role"; + +grant references on table "public"."User" to "service_role"; + +grant select on table "public"."User" to "service_role"; + +grant trigger on table "public"."User" to "service_role"; + +grant truncate on table "public"."User" to "service_role"; + +grant update on table "public"."User" to "service_role"; + +grant delete on table "public"."UserPreference" to "anon"; + +grant insert on table "public"."UserPreference" to "anon"; + +grant references on table "public"."UserPreference" to "anon"; + +grant select on table "public"."UserPreference" to "anon"; + +grant trigger on table "public"."UserPreference" to "anon"; + +grant truncate on table "public"."UserPreference" to "anon"; + +grant update on table "public"."UserPreference" to "anon"; + +grant delete on table "public"."UserPreference" to "authenticated"; + +grant insert on table "public"."UserPreference" to "authenticated"; + +grant references on table "public"."UserPreference" to "authenticated"; + +grant select on table "public"."UserPreference" to "authenticated"; + +grant trigger on table "public"."UserPreference" to "authenticated"; + +grant truncate on table "public"."UserPreference" to "authenticated"; + +grant update on table "public"."UserPreference" to "authenticated"; + +grant delete on table "public"."UserPreference" to "service_role"; + +grant insert on table "public"."UserPreference" to "service_role"; + +grant references on table "public"."UserPreference" to "service_role"; + +grant select on table "public"."UserPreference" to "service_role"; + +grant trigger on table "public"."UserPreference" to "service_role"; + +grant truncate on table "public"."UserPreference" to "service_role"; + +grant update on table "public"."UserPreference" to "service_role"; + +grant delete on table "public"."Venue" to "anon"; + +grant insert on table "public"."Venue" to "anon"; + +grant references on table "public"."Venue" to "anon"; + +grant select on table "public"."Venue" to "anon"; + +grant trigger on table "public"."Venue" to "anon"; + +grant truncate on table "public"."Venue" to "anon"; + +grant update on table "public"."Venue" to "anon"; + +grant delete on table "public"."Venue" to "authenticated"; + +grant insert on table "public"."Venue" to "authenticated"; + +grant references on table "public"."Venue" to "authenticated"; + +grant select on table "public"."Venue" to "authenticated"; + +grant trigger on table "public"."Venue" to "authenticated"; + +grant truncate on table "public"."Venue" to "authenticated"; + +grant update on table "public"."Venue" to "authenticated"; + +grant delete on table "public"."Venue" to "service_role"; + +grant insert on table "public"."Venue" to "service_role"; + +grant references on table "public"."Venue" to "service_role"; + +grant select on table "public"."Venue" to "service_role"; + +grant trigger on table "public"."Venue" to "service_role"; + +grant truncate on table "public"."Venue" to "service_role"; + +grant update on table "public"."Venue" to "service_role"; + +grant delete on table "public"."VenueAttribute" to "anon"; + +grant insert on table "public"."VenueAttribute" to "anon"; + +grant references on table "public"."VenueAttribute" to "anon"; + +grant select on table "public"."VenueAttribute" to "anon"; + +grant trigger on table "public"."VenueAttribute" to "anon"; + +grant truncate on table "public"."VenueAttribute" to "anon"; + +grant update on table "public"."VenueAttribute" to "anon"; + +grant delete on table "public"."VenueAttribute" to "authenticated"; + +grant insert on table "public"."VenueAttribute" to "authenticated"; + +grant references on table "public"."VenueAttribute" to "authenticated"; + +grant select on table "public"."VenueAttribute" to "authenticated"; + +grant trigger on table "public"."VenueAttribute" to "authenticated"; + +grant truncate on table "public"."VenueAttribute" to "authenticated"; + +grant update on table "public"."VenueAttribute" to "authenticated"; + +grant delete on table "public"."VenueAttribute" to "service_role"; + +grant insert on table "public"."VenueAttribute" to "service_role"; + +grant references on table "public"."VenueAttribute" to "service_role"; + +grant select on table "public"."VenueAttribute" to "service_role"; + +grant trigger on table "public"."VenueAttribute" to "service_role"; + +grant truncate on table "public"."VenueAttribute" to "service_role"; + +grant update on table "public"."VenueAttribute" to "service_role"; + +grant delete on table "public"."VenuePhoto" to "anon"; + +grant insert on table "public"."VenuePhoto" to "anon"; + +grant references on table "public"."VenuePhoto" to "anon"; + +grant select on table "public"."VenuePhoto" to "anon"; + +grant trigger on table "public"."VenuePhoto" to "anon"; + +grant truncate on table "public"."VenuePhoto" to "anon"; + +grant update on table "public"."VenuePhoto" to "anon"; + +grant delete on table "public"."VenuePhoto" to "authenticated"; + +grant insert on table "public"."VenuePhoto" to "authenticated"; + +grant references on table "public"."VenuePhoto" to "authenticated"; + +grant select on table "public"."VenuePhoto" to "authenticated"; + +grant trigger on table "public"."VenuePhoto" to "authenticated"; + +grant truncate on table "public"."VenuePhoto" to "authenticated"; + +grant update on table "public"."VenuePhoto" to "authenticated"; + +grant delete on table "public"."VenuePhoto" to "service_role"; + +grant insert on table "public"."VenuePhoto" to "service_role"; + +grant references on table "public"."VenuePhoto" to "service_role"; + +grant select on table "public"."VenuePhoto" to "service_role"; + +grant trigger on table "public"."VenuePhoto" to "service_role"; + +grant truncate on table "public"."VenuePhoto" to "service_role"; + +grant update on table "public"."VenuePhoto" to "service_role"; + +grant delete on table "public"."spatial_ref_sys" to "anon"; + +grant insert on table "public"."spatial_ref_sys" to "anon"; + +grant references on table "public"."spatial_ref_sys" to "anon"; + +grant select on table "public"."spatial_ref_sys" to "anon"; + +grant trigger on table "public"."spatial_ref_sys" to "anon"; + +grant truncate on table "public"."spatial_ref_sys" to "anon"; + +grant update on table "public"."spatial_ref_sys" to "anon"; + +grant delete on table "public"."spatial_ref_sys" to "authenticated"; + +grant insert on table "public"."spatial_ref_sys" to "authenticated"; + +grant references on table "public"."spatial_ref_sys" to "authenticated"; + +grant select on table "public"."spatial_ref_sys" to "authenticated"; + +grant trigger on table "public"."spatial_ref_sys" to "authenticated"; + +grant truncate on table "public"."spatial_ref_sys" to "authenticated"; + +grant update on table "public"."spatial_ref_sys" to "authenticated"; + +grant delete on table "public"."spatial_ref_sys" to "postgres"; + +grant insert on table "public"."spatial_ref_sys" to "postgres"; + +grant references on table "public"."spatial_ref_sys" to "postgres"; + +grant select on table "public"."spatial_ref_sys" to "postgres"; + +grant trigger on table "public"."spatial_ref_sys" to "postgres"; + +grant truncate on table "public"."spatial_ref_sys" to "postgres"; + +grant update on table "public"."spatial_ref_sys" to "postgres"; + +grant delete on table "public"."spatial_ref_sys" to "service_role"; + +grant insert on table "public"."spatial_ref_sys" to "service_role"; + +grant references on table "public"."spatial_ref_sys" to "service_role"; + +grant select on table "public"."spatial_ref_sys" to "service_role"; + +grant trigger on table "public"."spatial_ref_sys" to "service_role"; + +grant truncate on table "public"."spatial_ref_sys" to "service_role"; + +grant update on table "public"."spatial_ref_sys" to "service_role"; + +grant delete on table "public"."temp_rating" to "anon"; + +grant insert on table "public"."temp_rating" to "anon"; + +grant references on table "public"."temp_rating" to "anon"; + +grant select on table "public"."temp_rating" to "anon"; + +grant trigger on table "public"."temp_rating" to "anon"; + +grant truncate on table "public"."temp_rating" to "anon"; + +grant update on table "public"."temp_rating" to "anon"; + +grant delete on table "public"."temp_rating" to "authenticated"; + +grant insert on table "public"."temp_rating" to "authenticated"; + +grant references on table "public"."temp_rating" to "authenticated"; + +grant select on table "public"."temp_rating" to "authenticated"; + +grant trigger on table "public"."temp_rating" to "authenticated"; + +grant truncate on table "public"."temp_rating" to "authenticated"; + +grant update on table "public"."temp_rating" to "authenticated"; + +grant delete on table "public"."temp_rating" to "service_role"; + +grant insert on table "public"."temp_rating" to "service_role"; + +grant references on table "public"."temp_rating" to "service_role"; + +grant select on table "public"."temp_rating" to "service_role"; + +grant trigger on table "public"."temp_rating" to "service_role"; + +grant truncate on table "public"."temp_rating" to "service_role"; + +grant update on table "public"."temp_rating" to "service_role"; + +grant delete on table "public"."temp_user" to "anon"; + +grant insert on table "public"."temp_user" to "anon"; + +grant references on table "public"."temp_user" to "anon"; + +grant select on table "public"."temp_user" to "anon"; + +grant trigger on table "public"."temp_user" to "anon"; + +grant truncate on table "public"."temp_user" to "anon"; + +grant update on table "public"."temp_user" to "anon"; + +grant delete on table "public"."temp_user" to "authenticated"; + +grant insert on table "public"."temp_user" to "authenticated"; + +grant references on table "public"."temp_user" to "authenticated"; + +grant select on table "public"."temp_user" to "authenticated"; + +grant trigger on table "public"."temp_user" to "authenticated"; + +grant truncate on table "public"."temp_user" to "authenticated"; + +grant update on table "public"."temp_user" to "authenticated"; + +grant delete on table "public"."temp_user" to "service_role"; + +grant insert on table "public"."temp_user" to "service_role"; + +grant references on table "public"."temp_user" to "service_role"; + +grant select on table "public"."temp_user" to "service_role"; + +grant trigger on table "public"."temp_user" to "service_role"; + +grant truncate on table "public"."temp_user" to "service_role"; + +grant update on table "public"."temp_user" to "service_role"; + +grant delete on table "public"."testMigrationTable" to "anon"; + +grant insert on table "public"."testMigrationTable" to "anon"; + +grant references on table "public"."testMigrationTable" to "anon"; + +grant select on table "public"."testMigrationTable" to "anon"; + +grant trigger on table "public"."testMigrationTable" to "anon"; + +grant truncate on table "public"."testMigrationTable" to "anon"; + +grant update on table "public"."testMigrationTable" to "anon"; + +grant delete on table "public"."testMigrationTable" to "authenticated"; + +grant insert on table "public"."testMigrationTable" to "authenticated"; + +grant references on table "public"."testMigrationTable" to "authenticated"; + +grant select on table "public"."testMigrationTable" to "authenticated"; + +grant trigger on table "public"."testMigrationTable" to "authenticated"; + +grant truncate on table "public"."testMigrationTable" to "authenticated"; + +grant update on table "public"."testMigrationTable" to "authenticated"; + +grant delete on table "public"."testMigrationTable" to "service_role"; + +grant insert on table "public"."testMigrationTable" to "service_role"; + +grant references on table "public"."testMigrationTable" to "service_role"; + +grant select on table "public"."testMigrationTable" to "service_role"; + +grant trigger on table "public"."testMigrationTable" to "service_role"; + +grant truncate on table "public"."testMigrationTable" to "service_role"; + +grant update on table "public"."testMigrationTable" to "service_role"; + + diff --git a/backend/supabase/seed.sql b/backend/supabase/seed.sql index e69de29..6f08331 100644 --- a/backend/supabase/seed.sql +++ b/backend/supabase/seed.sql @@ -0,0 +1,111 @@ +-- Insert test data into "user" table +INSERT INTO public."user" (first_name, username, email, age, location, profile_picture_url) +VALUES + ('Alice', 'alice1', 'alice1@test.com', 25, ST_GeogFromText('POINT(40.748817 -73.985428)'), 'https://example.com/alice.jpg'), + ('Bob', 'bob2', 'bob2@test.com', 30, ST_GeogFromText('POINT(34.052235 -118.243683)'), 'https://example.com/bob.jpg'), + ('Charlie', 'charlie3', 'charlie3@test.com', 27, ST_GeogFromText('POINT(37.774929 -122.419418)'), 'https://example.com/charlie.jpg'), + ('David', 'david4', 'david4@test.com', 22, ST_GeogFromText('POINT(51.507351 -0.127758)'), 'https://example.com/david.jpg'), + ('Eve', 'eve5', 'eve5@test.com', 35, ST_GeogFromText('POINT(48.856614 2.352222)'), 'https://example.com/eve.jpg'), + ('Frank', 'frank6', 'frank6@test.com', 29, ST_GeogFromText('POINT(40.730610 -73.935242)'), 'https://example.com/frank.jpg'), + ('Grace', 'grace7', 'grace7@test.com', 28, ST_GeogFromText('POINT(34.052235 -118.243683)'), 'https://example.com/grace.jpg'), + ('Hank', 'hank8', 'hank8@test.com', 31, ST_GeogFromText('POINT(37.774929 -122.419418)'), 'https://example.com/hank.jpg'), + ('Ivy', 'ivy9', 'ivy9@test.com', 33, ST_GeogFromText('POINT(51.507351 -0.127758)'), 'https://example.com/ivy.jpg'), + ('Jack', 'jack10', 'jack10@test.com', 26, ST_GeogFromText('POINT(48.856614 2.352222)'), 'https://example.com/jack.jpg'); + +-- Insert test data into "user_preference" table +INSERT INTO public."user_preference" (user_id, preference_type, preference_value) +VALUES + ((SELECT user_id FROM public."user" WHERE username='alice1'), 'Music', 'Jazz'), + ((SELECT user_id FROM public."user" WHERE username='bob2'), 'Music', 'Rock'), + ((SELECT user_id FROM public."user" WHERE username='charlie3'), 'Drink', 'Cocktail'), + ((SELECT user_id FROM public."user" WHERE username='david4'), 'Ambiance', 'Quiet'), + ((SELECT user_id FROM public."user" WHERE username='eve5'), 'Music', 'Pop'), + ((SELECT user_id FROM public."user" WHERE username='frank6'), 'Ambiance', 'Lively'), + ((SELECT user_id FROM public."user" WHERE username='grace7'), 'Drink', 'Beer'), + ((SELECT user_id FROM public."user" WHERE username='hank8'), 'Ambiance', 'Classy'), + ((SELECT user_id FROM public."user" WHERE username='ivy9'), 'Music', 'Classical'), + ((SELECT user_id FROM public."user" WHERE username='jack10'), 'Drink', 'Wine'); + +-- Insert test data into "venue" table +INSERT INTO public."venue" (name, address, city, state, zip_code, location, venue_type) +VALUES + ('Blue Bar', '123 Main St', 'New York', 'NY', '10001', ST_GeogFromText('POINT(40.748817 -73.985428)'), 'BAR'), + ('The Night Club', '456 Sunset Blvd', 'Los Angeles', 'CA', '90028', ST_GeogFromText('POINT(34.052235 -118.243683)'), 'CLUB'), + ('Smooth Lounge', '789 Market St', 'San Francisco', 'CA', '94103', ST_GeogFromText('POINT(37.774929 -122.419418)'), 'LOUNGE'), + ('Vibe Bar', '101 Oxford St', 'London', '', 'W1D 2HS', ST_GeogFromText('POINT(51.507351 -0.127758)'), 'BAR'), + ('Parisian Lounge', '202 Champs-Elysees', 'Paris', '', '75008', ST_GeogFromText('POINT(48.856614 2.352222)'), 'LOUNGE'), + ('The High Club', '303 King St', 'New York', 'NY', '10012', ST_GeogFromText('POINT(40.730610 -73.935242)'), 'CLUB'), + ('The Jazz Spot', '404 Central Ave', 'Los Angeles', 'CA', '90012', ST_GeogFromText('POINT(34.052235 -118.243683)'), 'BAR'), + ('Chill Lounge', '505 Broadway', 'San Francisco', 'CA', '94133', ST_GeogFromText('POINT(37.774929 -122.419418)'), 'LOUNGE'), + ('Club Infinity', '606 Times Square', 'New York', 'NY', '10036', ST_GeogFromText('POINT(40.758896 -73.985130)'), 'CLUB'), + ('Elegant Bar', '707 Rue de Rivoli', 'Paris', '', '75001', ST_GeogFromText('POINT(48.860611 2.337644)'), 'BAR'); + +-- Insert test data into "venue_attribute" table +INSERT INTO public."venue_attribute" (venue_id, attribute_type, attribute_value) +VALUES + ((SELECT venue_id FROM public."venue" WHERE name='Blue Bar'), 'Drink Special', 'Happy Hour'), + ((SELECT venue_id FROM public."venue" WHERE name='The Night Club'), 'Music', 'Electronic'), + ((SELECT venue_id FROM public."venue" WHERE name='Smooth Lounge'), 'Ambiance', 'Relaxed'), + ((SELECT venue_id FROM public."venue" WHERE name='Vibe Bar'), 'Music', 'Live Band'), + ((SELECT venue_id FROM public."venue" WHERE name='Parisian Lounge'), 'Drink Special', 'Champagne'), + ((SELECT venue_id FROM public."venue" WHERE name='The High Club'), 'Ambiance', 'High Energy'), + ((SELECT venue_id FROM public."venue" WHERE name='The Jazz Spot'), 'Music', 'Jazz'), + ((SELECT venue_id FROM public."venue" WHERE name='Chill Lounge'), 'Ambiance', 'Chill'), + ((SELECT venue_id FROM public."venue" WHERE name='Club Infinity'), 'Music', 'Pop'), + ((SELECT venue_id FROM public."venue" WHERE name='Elegant Bar'), 'Ambiance', 'Elegant'); + +-- Insert test data into "friendship" table +INSERT INTO public."friendship" (user_id1, user_id2, friendship_status) +VALUES + ((SELECT user_id FROM public."user" WHERE username='alice1'), (SELECT user_id FROM public."user" WHERE username='bob2'), 'ACCEPTED'), + ((SELECT user_id FROM public."user" WHERE username='charlie3'), (SELECT user_id FROM public."user" WHERE username='david4'), 'PENDING'), + ((SELECT user_id FROM public."user" WHERE username='eve5'), (SELECT user_id FROM public."user" WHERE username='frank6'), 'ACCEPTED'), + ((SELECT user_id FROM public."user" WHERE username='grace7'), (SELECT user_id FROM public."user" WHERE username='hank8'), 'BLOCKED'), + ((SELECT user_id FROM public."user" WHERE username='ivy9'), (SELECT user_id FROM public."user" WHERE username='jack10'), 'DECLINED'), + ((SELECT user_id FROM public."user" WHERE username='alice1'), (SELECT user_id FROM public."user" WHERE username='charlie3'), 'ACCEPTED'), + ((SELECT user_id FROM public."user" WHERE username='bob2'), (SELECT user_id FROM public."user" WHERE username='eve5'), 'PENDING'), + ((SELECT user_id FROM public."user" WHERE username='david4'), (SELECT user_id FROM public."user" WHERE username='grace7'), 'ACCEPTED'), + ((SELECT user_id FROM public."user" WHERE username='frank6'), (SELECT user_id FROM public."user" WHERE username='ivy9'), 'ACCEPTED'), + ((SELECT user_id FROM public."user" WHERE username='hank8'), (SELECT user_id FROM public."user" WHERE username='jack10'), 'PENDING'); + +-- Insert test data into "notification" table +INSERT INTO public."notification" (user_id, message) +VALUES + ((SELECT user_id FROM public."user" WHERE username='alice1'), 'You have a new friend request from Bob.'), + ((SELECT user_id FROM public."user" WHERE username='bob2'), 'Your review has been approved.'), + ((SELECT user_id FROM public."user" WHERE username='charlie3'), 'You have a new message.'), + ((SELECT user_id FROM public."user" WHERE username='david4'), 'Your profile has been updated.'), + ((SELECT user_id FROM public."user" WHERE username='eve5'), 'You have a new friend request from Grace.'), + ((SELECT user_id FROM public."user" WHERE username='frank6'), 'Your notification settings have been changed.'), + ((SELECT user_id FROM public."user" WHERE username='grace7'), 'New venues near you have been added.'), + ((SELECT user_id FROM public."user" WHERE username='hank8'), 'Your review for Club Infinity has been published.'), + ((SELECT user_id FROM public."user" WHERE username='ivy9'), 'You have a new friend request from Jack.'), + ((SELECT user_id FROM public."user" WHERE username='jack10'), 'Your review has been flagged.'); + +-- Insert test data into "review" table +INSERT INTO public."review" (user_id, venue_id, overall_rating, ambiance_rating, music_rating, crowd_rating, service_rating, review_text) +VALUES + ((SELECT user_id FROM public."user" WHERE username='alice1'), (SELECT venue_id FROM public."venue" WHERE name='Blue Bar'), 5, 9, 8, 7, 10, 'Great atmosphere, excellent service.'), + ((SELECT user_id FROM public."user" WHERE username='bob2'), (SELECT venue_id FROM public."venue" WHERE name='The Night Club'), 4, 7, 9, 8, 7, 'Loved the music, but it was too crowded.'), + ((SELECT user_id FROM public."user" WHERE username='charlie3'), (SELECT venue_id FROM public."venue" WHERE name='Smooth Lounge'), 4, 8, 7, 6, 8, 'Nice and relaxing spot.'), + ((SELECT user_id FROM public."user" WHERE username='david4'), (SELECT venue_id FROM public."venue" WHERE name='Vibe Bar'), 5, 9, 9, 8, 9, 'Live band was fantastic!'), + ((SELECT user_id FROM public."user" WHERE username='eve5'), (SELECT venue_id FROM public."venue" WHERE name='Parisian Lounge'), 4, 8, 7, 6, 8, 'Classy ambiance, good drinks.'), + ((SELECT user_id FROM public."user" WHERE username='frank6'), (SELECT venue_id FROM public."venue" WHERE name='The High Club'), 5, 8, 9, 9, 7, 'High energy, awesome music.'), + ((SELECT user_id FROM public."user" WHERE username='grace7'), (SELECT venue_id FROM public."venue" WHERE name='The Jazz Spot'), 5, 9, 10, 7, 8, 'Jazz night was amazing!'), + ((SELECT user_id FROM public."user" WHERE username='hank8'), (SELECT venue_id FROM public."venue" WHERE name='Chill Lounge'), 3, 7, 6, 6, 6, 'Good place but average experience.'), + ((SELECT user_id FROM public."user" WHERE username='ivy9'), (SELECT venue_id FROM public."venue" WHERE name='Club Infinity'), 5, 10, 9, 8, 9, 'Loved everything about it!'), + ((SELECT user_id FROM public."user" WHERE username='jack10'), (SELECT venue_id FROM public."venue" WHERE name='Elegant Bar'), 4, 8, 7, 7, 8, 'Sophisticated and nice.'); + +-- Insert test data into "search_history" table +INSERT INTO public."search_history" (user_id, search_term) +VALUES + ((SELECT user_id FROM public."user" WHERE username='alice1'), now()), + ((SELECT user_id FROM public."user" WHERE username='bob2'), now()), + ((SELECT user_id FROM public."user" WHERE username='charlie3'), now()), + ((SELECT user_id FROM public."user" WHERE username='david4'), now()), + ((SELECT user_id FROM public."user" WHERE username='eve5'), now()), + ((SELECT user_id FROM public."user" WHERE username='frank6'), now()), + ((SELECT user_id FROM public."user" WHERE username='grace7'), now()), + ((SELECT user_id FROM public."user" WHERE username='hank8'), now()), + ((SELECT user_id FROM public."user" WHERE username='ivy9'), now()), + ((SELECT user_id FROM public."user" WHERE username='jack10'), now()); From 4ecbe6211a3178c8bceff4c132d47efb8998205b Mon Sep 17 00:00:00 2001 From: Abyan Nawaz Date: Wed, 16 Oct 2024 10:07:40 -0400 Subject: [PATCH 4/4] Abstracted + email regex --- .../internal/handlers/profiles/profiles.go | 10 +- backend/internal/storage/postgres/profiles.go | 150 +++++------------- backend/internal/storage/storage.go | 4 +- backend/internal/utils/validators.go | 11 +- 4 files changed, 57 insertions(+), 118 deletions(-) diff --git a/backend/internal/handlers/profiles/profiles.go b/backend/internal/handlers/profiles/profiles.go index 354b5b9..948ec6f 100644 --- a/backend/internal/handlers/profiles/profiles.go +++ b/backend/internal/handlers/profiles/profiles.go @@ -118,11 +118,14 @@ func (s *Service) GetProfile(c *fiber.Ctx) error { var err error if utils.IsEmail(userIdentifier) { - profile, err = s.store.GetProfileByEmail(c.Context(), userIdentifier) + // Query by email + profile, err = s.store.GetProfileByColumn(c.Context(), "email", userIdentifier) } else if utils.IsUUID(userIdentifier) { - profile, err = s.store.GetProfileByID(c.Context(), userIdentifier) + // Query by ID + profile, err = s.store.GetProfileByColumn(c.Context(), "user_id", userIdentifier) } else { - profile, err = s.store.GetProfileByUsername(c.Context(), userIdentifier) + // Query by username + profile, err = s.store.GetProfileByColumn(c.Context(), "username", userIdentifier) } if err != nil { @@ -132,6 +135,7 @@ func (s *Service) GetProfile(c *fiber.Ctx) error { return c.Status(fiber.StatusOK).JSON(profile) } + /* Get All Users */ diff --git a/backend/internal/storage/postgres/profiles.go b/backend/internal/storage/postgres/profiles.go index b65222e..fcad93b 100644 --- a/backend/internal/storage/postgres/profiles.go +++ b/backend/internal/storage/postgres/profiles.go @@ -5,29 +5,24 @@ import ( "database/sql" "errors" "fmt" - "github.com/GenerateNU/nightlife/internal/models" "log" + "github.com/GenerateNU/nightlife/internal/models" + "github.com/google/uuid" ) -func (db *DB) GetProfileByUsername(ctx context.Context, username string) (models.Profile, error) { +/* +Gets a user profile by a column, (username, id, or email). +*/ +func (db *DB) GetProfileByColumn(ctx context.Context, column string, value string) (models.Profile, error) { var profile models.Profile + var query = fmt.Sprintf(` + SELECT user_id, first_name, username, email, age, location, profile_picture_url, created_at + FROM users + WHERE %s = $1`, column) - var query = ` - SELECT user_id, - first_name, - username, - email, - age, - location, - profile_picture_url, - created_at - FROM users - WHERE username = $1 - ` - - row := db.conn.QueryRow(ctx, query, username) + row := db.conn.QueryRow(ctx, query, value) err := row.Scan( &profile.UserID, @@ -42,7 +37,7 @@ func (db *DB) GetProfileByUsername(ctx context.Context, username string) (models if err != nil { if errors.Is(err, sql.ErrNoRows) { - return models.Profile{}, fmt.Errorf("no profile found for username: %s", username) + return models.Profile{}, fmt.Errorf("no profile found for %s: %s", column, value) } return models.Profile{}, err } @@ -50,64 +45,6 @@ func (db *DB) GetProfileByUsername(ctx context.Context, username string) (models return profile, nil } -func (db *DB) GetProfileByEmail(ctx context.Context, email string) (models.Profile, error) { - var profile models.Profile - var query = ` - SELECT user_id, first_name, username, email, age, location, profile_picture_url, created_at - FROM "User" - WHERE email = $1 - ` - row := db.conn.QueryRow(ctx, query, email) - err := row.Scan( - &profile.UserID, - &profile.FirstName, - &profile.Username, - &profile.Email, - &profile.Age, - &profile.Location, - &profile.ProfilePictureURL, - &profile.CreatedAt, - ) - - if err != nil { - if errors.Is(err, sql.ErrNoRows) { - return models.Profile{}, fmt.Errorf("no profile found for email: %s", email) - } - return models.Profile{}, err - } - - return profile, nil -} - -func (db *DB) GetProfileByID(ctx context.Context, id string) (models.Profile, error) { - var profile models.Profile - var query = ` - SELECT user_id, first_name, username, email, age, location, profile_picture_url, created_at - FROM "User" - WHERE user_id = $1 - ` - row := db.conn.QueryRow(ctx, query, id) - err := row.Scan( - &profile.UserID, - &profile.FirstName, - &profile.Username, - &profile.Email, - &profile.Age, - &profile.Location, - &profile.ProfilePictureURL, - &profile.CreatedAt, - ) - - if err != nil { - if errors.Is(err, sql.ErrNoRows) { - return models.Profile{}, fmt.Errorf("no profile found for ID: %s", id) - } - return models.Profile{}, err - } - - return profile, nil -} - func (db *DB) CreatePreferences(ctx context.Context, p models.Preferences) error { // query to save user data to db query := `INSERT INTO preferences (userID, location, age, music, ambiance, notifs) @@ -173,36 +110,35 @@ Get All Users */ func (db *DB) GetAllUsers(ctx context.Context) ([]models.Profile, error) { - rows, err := db.conn.Query(ctx, `SELECT user_id, first_name, username, email, age, location, profile_picture_url, created_at FROM "User"`) - if err != nil { - return nil, err - } - defer rows.Close() - - var profiles []models.Profile - - // Iterate through the result rows - for rows.Next() { - var profile models.Profile - if err := rows.Scan( - &profile.UserID, - &profile.FirstName, - &profile.Username, - &profile.Email, - &profile.Age, - &profile.Location, - &profile.ProfilePictureURL, - &profile.CreatedAt, - ); err != nil { - return nil, err - } - profiles = append(profiles, profile) - } - - if err := rows.Err(); err != nil { - return nil, err - } - - return profiles, nil -} + rows, err := db.conn.Query(ctx, `SELECT user_id, first_name, username, email, age, location, profile_picture_url, created_at FROM users`) + if err != nil { + return nil, err + } + defer rows.Close() + + var profiles []models.Profile + + // Iterate through the result rows + for rows.Next() { + var profile models.Profile + if err := rows.Scan( + &profile.UserID, + &profile.FirstName, + &profile.Username, + &profile.Email, + &profile.Age, + &profile.Location, + &profile.ProfilePictureURL, + &profile.CreatedAt, + ); err != nil { + return nil, err + } + profiles = append(profiles, profile) + } + + if err := rows.Err(); err != nil { + return nil, err + } + return profiles, nil +} diff --git a/backend/internal/storage/storage.go b/backend/internal/storage/storage.go index ebcb2e3..9e23a00 100644 --- a/backend/internal/storage/storage.go +++ b/backend/internal/storage/storage.go @@ -25,9 +25,7 @@ type Profile interface { UpdateProfilePreferences(context.Context, uuid.UUID, string, string, string, string) error DeleteAccount(context.Context, uuid.UUID) error RemoveFriend(context.Context, uuid.UUID, string) error - GetProfileByUsername(context.Context, string) (models.Profile, error) - GetProfileByEmail(context.Context, string) (models.Profile, error) - GetProfileByID(context.Context, string) (models.Profile, error) + GetProfileByColumn(context.Context, string, string) (models.Profile, error) GetAllUsers(context.Context) ([]models.Profile, error) } diff --git a/backend/internal/utils/validators.go b/backend/internal/utils/validators.go index 80dcfdf..5e4c04f 100644 --- a/backend/internal/utils/validators.go +++ b/backend/internal/utils/validators.go @@ -2,17 +2,18 @@ package utils import ( - "regexp" - "strings" + "regexp" ) // Check if the string is a valid email address func IsEmail(input string) bool { - return strings.Contains(input, "@") + // Define the regular expression for validating an email address + var emailRegex = regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`) + return emailRegex.MatchString(input) } // Check if the string is a valid UUID func IsUUID(input string) bool { - uuidRegex := regexp.MustCompile(`^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`) - return uuidRegex.MatchString(input) + uuidRegex := regexp.MustCompile(`^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$`) + return uuidRegex.MatchString(input) }