diff --git a/backend/src/controllers/user.go b/backend/src/controllers/user.go index 1b509bf3d..c6e7c71eb 100644 --- a/backend/src/controllers/user.go +++ b/backend/src/controllers/user.go @@ -137,3 +137,25 @@ func (u *UserController) DeleteUser(c *fiber.Ctx) error { return c.SendStatus(fiber.StatusNoContent) } + +func (u *UserController) GetUserTags(c *fiber.Ctx) error { + tags, err := u.userService.GetUserTags(c.Params("uid")) + if err != nil { + return err.FiberError(c) + } + return c.Status(fiber.StatusOK).JSON(&tags) +} + +func (u *UserController) CreateUserTags(c *fiber.Ctx) error { + var requestBody models.CreateUserTagsBody + if err := c.BodyParser(&requestBody); err != nil { + return errors.FailedToParseRequestBody.FiberError(c) + } + + tags, err := u.userService.CreateUserTags(c.Params("uid"), requestBody.Tags) + if err != nil { + return err.FiberError(c) + } + + return c.Status(fiber.StatusCreated).JSON(&tags) +} diff --git a/backend/src/models/user.go b/backend/src/models/user.go index 1f6b3aa7e..52f04308e 100644 --- a/backend/src/models/user.go +++ b/backend/src/models/user.go @@ -1,6 +1,8 @@ package models -import "github.com/GenerateNU/sac/backend/src/types" +import ( + "github.com/GenerateNU/sac/backend/src/types" +) type UserRole string @@ -76,3 +78,7 @@ type UpdateUserRequestBody struct { College College `json:"college" validate:"omitempty,oneof=CAMD DMSB KCCS CE BCHS SL CPS CS CSSH"` Year Year `json:"year" validate:"omitempty,min=1,max=6"` } + +type CreateUserTagsBody struct { + Tags []uint `json:"tags" validate:"required"` +} diff --git a/backend/src/server/server.go b/backend/src/server/server.go index 4d622d646..82c980ff7 100644 --- a/backend/src/server/server.go +++ b/backend/src/server/server.go @@ -73,6 +73,11 @@ func userRoutes(router fiber.Router, userService services.UserServiceInterface) users.Get("/:id", userController.GetUser) users.Patch("/:id", userController.UpdateUser) users.Delete("/:id", userController.DeleteUser) + + userTags := users.Group("/:uid/tags") + + userTags.Post("/", userController.CreateUserTags) + userTags.Get("/", userController.GetUserTags) } func categoryRoutes(router fiber.Router, categoryService services.CategoryServiceInterface) { diff --git a/backend/src/services/user.go b/backend/src/services/user.go index 324e37d56..e427c40e4 100644 --- a/backend/src/services/user.go +++ b/backend/src/services/user.go @@ -19,6 +19,8 @@ type UserServiceInterface interface { GetUser(id string) (*models.User, *errors.Error) UpdateUser(id string, userBody models.UpdateUserRequestBody) (*models.User, *errors.Error) DeleteUser(id string) *errors.Error + GetUserTags(id string) ([]models.Tag, *errors.Error) + CreateUserTags(id string, tagIDs []uint) ([]models.Tag, *errors.Error) } type UserService struct { @@ -107,3 +109,26 @@ func (u *UserService) DeleteUser(id string) *errors.Error { return transactions.DeleteUser(u.DB, *idAsInt) } + +func (u *UserService) GetUserTags(id string) ([]models.Tag, *errors.Error) { + idAsInt, err := utilities.ValidateID(id) + if err != nil { + return nil, err + } + + return transactions.GetUserTags(u.DB, *idAsInt) +} + +func (u *UserService) CreateUserTags(id string, tagIDs []uint) ([]models.Tag, *errors.Error) { + // Validate the id: + idAsInt, err := utilities.ValidateID(id) + if err != nil { + return nil, err + } + + // Retrieve a list of valid tags from the ids: + tags, err := transactions.GetTagsByIDs(u.DB, tagIDs) + + // Update the user to reflect the new tags: + return transactions.CreateUserTags(u.DB, *idAsInt, tags) +} diff --git a/backend/src/transactions/tag.go b/backend/src/transactions/tag.go index 9214ca683..da14ccdd0 100644 --- a/backend/src/transactions/tag.go +++ b/backend/src/transactions/tag.go @@ -55,3 +55,15 @@ func DeleteTag(db *gorm.DB, id uint) *errors.Error { return nil } + +func GetTagsByIDs(db *gorm.DB, selectedTagIDs []uint) ([]models.Tag, *errors.Error) { + if len(selectedTagIDs) != 0 { + var tags []models.Tag + if err := db.Model(models.Tag{}).Where("id IN ?", selectedTagIDs).Find(&tags).Error; err != nil { + return nil, &errors.FailedToGetTag + } + + return tags, nil + } + return []models.Tag{}, nil +} diff --git a/backend/src/transactions/user.go b/backend/src/transactions/user.go index 9fb868ee6..dc666b18b 100644 --- a/backend/src/transactions/user.go +++ b/backend/src/transactions/user.go @@ -74,3 +74,30 @@ func DeleteUser(db *gorm.DB, id uint) *errors.Error { } return nil } + +func GetUserTags(db *gorm.DB, id uint) ([]models.Tag, *errors.Error) { + var tags []models.Tag + + user, err := GetUser(db, id) + if err != nil { + return nil, &errors.UserNotFound + } + + if err := db.Model(&user).Association("Tag").Find(&tags) ; err != nil { + return nil, &errors.FailedToGetTag + } + return tags, nil +} + +func CreateUserTags(db *gorm.DB, id uint, tags []models.Tag) ([]models.Tag, *errors.Error) { + user, err := GetUser(db, id) + if err != nil { + return nil, &errors.UserNotFound + } + + if err := db.Model(&user).Association("Tag").Replace(tags); err != nil { + return nil, &errors.FailedToUpdateUser + } + + return tags, nil +}