Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SAC-19 User Tag CRUD #67

Merged
merged 20 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions backend/src/controllers/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
if err != nil {
return err.FiberError(c)
}

return c.Status(fiber.StatusCreated).JSON(&tags)
}
4 changes: 4 additions & 0 deletions backend/src/errors/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ var (
StatusCode: fiber.StatusBadRequest,
Message: "failed to validate user",
}
FailedToValidateUserTags = Error {
StatusCode: fiber.StatusBadRequest,
Message: "failed to validate user tags",
}
FailedToCreateUser = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to create user",
Expand Down
2 changes: 1 addition & 1 deletion backend/src/models/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ type Tag struct {

Name string `gorm:"type:varchar(255)" json:"name" validate:"required,max=255"`

CategoryID uuid.UUID `gorm:"foreignKey:CategoryID" json:"category_id" validate:"required,uuid4"`
CategoryID uuid.UUID `json:"category_id" validate:"required,uuid4"`

User []User `gorm:"many2many:user_tags;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
Club []Club `gorm:"many2many:club_tags;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
Expand Down
6 changes: 6 additions & 0 deletions backend/src/models/user.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package models

import "github.com/google/uuid"

type UserRole string

const (
Expand Down Expand Up @@ -74,3 +76,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 []uuid.UUID `json:"tags" validate:"required"`
}
5 changes: 5 additions & 0 deletions backend/src/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,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 clubRoutes(router fiber.Router, clubService services.ClubServiceInterface) {
Expand Down
29 changes: 29 additions & 0 deletions backend/src/services/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 models.CreateUserTagsBody) ([]models.Tag, *errors.Error)
}

type UserService struct {
Expand Down Expand Up @@ -107,3 +109,30 @@ func (u *UserService) DeleteUser(id string) *errors.Error {

return transactions.DeleteUser(u.DB, *idAsUUID)
}

func (u *UserService) GetUserTags(id string) ([]models.Tag, *errors.Error) {
idAsUUID, err := utilities.ValidateID(id)
if err != nil {
return nil, err
}

return transactions.GetUserTags(u.DB, *idAsUUID)
}

func (u *UserService) CreateUserTags(id string, tagIDs models.CreateUserTagsBody) ([]models.Tag, *errors.Error) {
// Validate the id:
idAsUUID, err := utilities.ValidateID(id)
if err != nil {
return nil, err
}

if err := u.Validate.Struct(tagIDs); err != nil {
return nil, &errors.FailedToValidateUserTags
}

// Retrieve a list of valid tags from the ids:
tags, err := transactions.GetTagsByIDs(u.DB, tagIDs.Tags)

// Update the user to reflect the new tags:
return transactions.CreateUserTags(u.DB, *idAsUUID, tags)
}
13 changes: 12 additions & 1 deletion backend/src/transactions/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package transactions

import (
stdliberrors "errors"

"github.com/GenerateNU/sac/backend/src/errors"
"github.com/google/uuid"

Expand Down Expand Up @@ -56,3 +55,15 @@ func DeleteTag(db *gorm.DB, id uuid.UUID) *errors.Error {

return nil
}

func GetTagsByIDs(db *gorm.DB, selectedTagIDs []uuid.UUID) ([]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
}
27 changes: 27 additions & 0 deletions backend/src/transactions/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,30 @@ func DeleteUser(db *gorm.DB, id uuid.UUID) *errors.Error {
}
return nil
}

func GetUserTags(db *gorm.DB, id uuid.UUID) ([]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 uuid.UUID, 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
}
Loading
Loading