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

Finished follower endpoints #142

Merged
merged 9 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
20 changes: 10 additions & 10 deletions backend/src/controllers/category.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ func NewCategoryController(categoryService services.CategoryServiceInterface) *C
// @Failure 400 {string} string "category with that name already exists"
// @Failure 500 {string} string "failed to create category"
// @Router /api/v1/category/ [post]
func (t *CategoryController) CreateCategory(c *fiber.Ctx) error {
func (cat *CategoryController) CreateCategory(c *fiber.Ctx) error {
var categoryBody models.CategoryRequestBody

if err := c.BodyParser(&categoryBody); err != nil {
return errors.FailedToParseRequestBody.FiberError(c)
}

newCategory, err := t.categoryService.CreateCategory(categoryBody)
newCategory, err := cat.categoryService.CreateCategory(categoryBody)
if err != nil {
return err.FiberError(c)
}
Expand All @@ -56,11 +56,11 @@ func (t *CategoryController) CreateCategory(c *fiber.Ctx) error {
// @Success 200 {object} []models.Category
// @Failure 500 {string} string "unable to retrieve categories"
// @Router /api/v1/category/ [get]
func (t *CategoryController) GetCategories(c *fiber.Ctx) error {
func (cat *CategoryController) GetCategories(c *fiber.Ctx) error {
defaultLimit := 10
defaultPage := 1

categories, err := t.categoryService.GetCategories(c.Query("limit", strconv.Itoa(defaultLimit)), c.Query("page", strconv.Itoa(defaultPage)))
categories, err := cat.categoryService.GetCategories(c.Query("limit", strconv.Itoa(defaultLimit)), c.Query("page", strconv.Itoa(defaultPage)))
if err != nil {
return err.FiberError(c)
}
Expand All @@ -80,8 +80,8 @@ func (t *CategoryController) GetCategories(c *fiber.Ctx) error {
// @Failure 404 {string} string "faied to find category"
// @Failure 500 {string} string "failed to retrieve category"
// @Router /api/v1/category/{id} [get]
func (t *CategoryController) GetCategory(c *fiber.Ctx) error {
category, err := t.categoryService.GetCategory(c.Params("categoryID"))
func (cat *CategoryController) GetCategory(c *fiber.Ctx) error {
category, err := cat.categoryService.GetCategory(c.Params("categoryID"))
if err != nil {
return err.FiberError(c)
}
Expand All @@ -101,8 +101,8 @@ func (t *CategoryController) GetCategory(c *fiber.Ctx) error {
// @Failure 404 {string} string "failed to find category"
// @Failure 500 {string} string "failed to delete category"
// @Router /api/v1/category/{id} [delete]
func (t *CategoryController) DeleteCategory(c *fiber.Ctx) error {
if err := t.categoryService.DeleteCategory(c.Params("categoryID")); err != nil {
func (cat *CategoryController) DeleteCategory(c *fiber.Ctx) error {
if err := cat.categoryService.DeleteCategory(c.Params("categoryID")); err != nil {
return err.FiberError(c)
}

Expand All @@ -121,14 +121,14 @@ func (t *CategoryController) DeleteCategory(c *fiber.Ctx) error {
// @Failure 404 {string} string "failed to find category"
// @Failure 500 {string} string "failed to update category"
// @Router /api/v1/category/{id} [patch]
func (t *CategoryController) UpdateCategory(c *fiber.Ctx) error {
func (cat *CategoryController) UpdateCategory(c *fiber.Ctx) error {
var category models.CategoryRequestBody

if err := c.BodyParser(&category); err != nil {
return errors.FailedToValidateCategory.FiberError(c)
}

updatedCategory, err := t.categoryService.UpdateCategory(c.Params("categoryID"), category)
updatedCategory, err := cat.categoryService.UpdateCategory(c.Params("categoryID"), category)
if err != nil {
return err.FiberError(c)
}
Expand Down
8 changes: 4 additions & 4 deletions backend/src/controllers/category_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@ func NewCategoryTagController(categoryTagService services.CategoryTagServiceInte
return &CategoryTagController{categoryTagService: categoryTagService}
}

func (t *CategoryTagController) GetTagsByCategory(c *fiber.Ctx) error {
func (ct *CategoryTagController) GetTagsByCategory(c *fiber.Ctx) error {
defaultLimit := 10
defaultPage := 1

tags, err := t.categoryTagService.GetTagsByCategory(c.Params("categoryID"), c.Query("limit", strconv.Itoa(defaultLimit)), c.Query("page", strconv.Itoa(defaultPage)))
tags, err := ct.categoryTagService.GetTagsByCategory(c.Params("categoryID"), c.Query("limit", strconv.Itoa(defaultLimit)), c.Query("page", strconv.Itoa(defaultPage)))
if err != nil {
return err.FiberError(c)
}

return c.Status(fiber.StatusOK).JSON(&tags)
}

func (t *CategoryTagController) GetTagByCategory(c *fiber.Ctx) error {
tag, err := t.categoryTagService.GetTagByCategory(c.Params("categoryID"), c.Params("tagID"))
func (ct *CategoryTagController) GetTagByCategory(c *fiber.Ctx) error {
tag, err := ct.categoryTagService.GetTagByCategory(c.Params("categoryID"), c.Params("tagID"))
if err != nil {
return err.FiberError(c)
}
Expand Down
28 changes: 28 additions & 0 deletions backend/src/controllers/club_follower.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package controllers

import (
"strconv"

"github.com/GenerateNU/sac/backend/src/services"
"github.com/gofiber/fiber/v2"
)

type ClubFollowerController struct {
clubFollowerService services.ClubFollowerServiceInterface
}

func NewClubFollowerController(clubFollowerService services.ClubFollowerServiceInterface) *ClubFollowerController {
return &ClubFollowerController{clubFollowerService: clubFollowerService}
}

func (cf *ClubFollowerController) GetClubFollowers(c *fiber.Ctx) error {
defaultLimit := 10
defaultPage := 1

followers, err := cf.clubFollowerService.GetClubFollowers(c.Params("clubID"), c.Query("limit", strconv.Itoa(defaultLimit)), c.Query("page", strconv.Itoa(defaultPage)))
if err != nil {
return err.FiberError(c)
}

return c.Status(fiber.StatusOK).JSON(followers)
}
38 changes: 38 additions & 0 deletions backend/src/controllers/user_follower.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package controllers

import (
"github.com/GenerateNU/sac/backend/src/services"
"github.com/gofiber/fiber/v2"
)

type UserFollowerController struct {
userFollowerService services.UserFollowerServiceInterface
}

func NewUserFollowerController(userFollowerService services.UserFollowerServiceInterface) *UserFollowerController {
return &UserFollowerController{userFollowerService: userFollowerService}
}

func (uf *UserFollowerController) CreateFollowing(c *fiber.Ctx) error {
err := uf.userFollowerService.CreateFollowing(c.Params("userID"), c.Params("clubID"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

if err != nil {
return err.FiberError(c)
}
return c.SendStatus(fiber.StatusCreated)
}

func (uf *UserFollowerController) DeleteFollowing(c *fiber.Ctx) error {
err := uf.userFollowerService.DeleteFollowing(c.Params("userID"), c.Params("clubID"))
if err != nil {
return err.FiberError(c)
}
return c.SendStatus(fiber.StatusNoContent)
}

func (uf *UserFollowerController) GetAllFollowing(c *fiber.Ctx) error {
clubs, err := uf.userFollowerService.GetFollowing(c.Params("userID"))
if err != nil {
return err.FiberError(c)
}
return c.Status(fiber.StatusOK).JSON(clubs)
}
8 changes: 4 additions & 4 deletions backend/src/controllers/user_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,21 @@ func NewUserTagController(userTagService services.UserTagServiceInterface) *User
return &UserTagController{userTagService: userTagService}
}

func (u *UserTagController) GetUserTags(c *fiber.Ctx) error {
tags, err := u.userTagService.GetUserTags(c.Params("userID"))
func (ut *UserTagController) GetUserTags(c *fiber.Ctx) error {
tags, err := ut.userTagService.GetUserTags(c.Params("userID"))
if err != nil {
return err.FiberError(c)
}
return c.Status(fiber.StatusOK).JSON(&tags)
}

func (u *UserTagController) CreateUserTags(c *fiber.Ctx) error {
func (ut *UserTagController) CreateUserTags(c *fiber.Ctx) error {
var requestBody models.CreateUserTagsBody
if err := c.BodyParser(&requestBody); err != nil {
return errors.FailedToParseRequestBody.FiberError(c)
}

tags, err := u.userTagService.CreateUserTags(c.Params("userID"), requestBody)
tags, err := ut.userTagService.CreateUserTags(c.Params("userID"), requestBody)
if err != nil {
return err.FiberError(c)
}
Expand Down
4 changes: 4 additions & 0 deletions backend/src/errors/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@ var (
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get admin ids",
}
FailedToGetClubFollowers = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get club followers",
}
)
4 changes: 4 additions & 0 deletions backend/src/errors/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,8 @@ var (
StatusCode: fiber.StatusInternalServerError,
Message: "failed to compute password hash",
}
FailedToGetUserFollowing = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get user following",
}
)
2 changes: 1 addition & 1 deletion backend/src/middleware/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (m *MiddlewareService) ClubAuthorizeById(c *fiber.Ctx) error {
return errors.FailedToParseAccessToken.FiberError(c)
}

// use club_id to get the list of admin for a certain club
// use clubID to get the list of admin for a certain club
clubAdmin, clubErr := transactions.GetAdminIDs(m.DB, *clubUUID)
if clubErr != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion backend/src/models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type User struct {
Tag []Tag `gorm:"many2many:user_tags;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
Admin []Club `gorm:"many2many:user_club_admins;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
Member []Club `gorm:"many2many:user_club_members;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
Follower []Club `gorm:"many2many:user_club_followers;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
Follower []Club `gorm:"many2many:user_club_followers;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"clubs_followed,omitempty" validate:"-"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to send a list of followers? or should it only be passed when requested? might be unnecessary information

IntendedApplicant []Club `gorm:"many2many:user_club_intended_applicants;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-" validate:"-"`
Asked []Comment `gorm:"foreignKey:AskedByID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" json:"-" validate:"-"`
Answered []Comment `gorm:"foreignKey:AnsweredByID;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" json:"-" validate:"-"`
Expand Down
16 changes: 16 additions & 0 deletions backend/src/server/routes/club_follower.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package routes

import (
"github.com/GenerateNU/sac/backend/src/controllers"
"github.com/GenerateNU/sac/backend/src/services"
"github.com/gofiber/fiber/v2"
)

func ClubFollower(clubsIDRouter fiber.Router, clubFollowerService services.ClubFollowerServiceInterface) {
clubFollowerController := controllers.NewClubFollowerController(clubFollowerService)

clubFollower := clubsIDRouter.Group("/followers")

// api/clubs/:clubID/followers/*
clubFollower.Get("/", clubFollowerController.GetClubFollowers)
}
18 changes: 18 additions & 0 deletions backend/src/server/routes/user_follower.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package routes

import (
"github.com/GenerateNU/sac/backend/src/controllers"
"github.com/GenerateNU/sac/backend/src/services"
"github.com/gofiber/fiber/v2"
)

func UserFollower(usersIDRouter fiber.Router, userFollowerService services.UserFollowerServiceInterface) {
userFollowerController := controllers.NewUserFollowerController(userFollowerService)

userFollower := usersIDRouter.Group("/:userID/follower")

// api/v1/users/:userID/follower/*
userFollower.Post("/:clubID", userFollowerController.CreateFollowing)
userFollower.Delete("/:clubID", userFollowerController.DeleteFollowing)
userFollower.Get("/", userFollowerController.GetAllFollowing)
}
2 changes: 2 additions & 0 deletions backend/src/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,12 @@ func Init(db *gorm.DB, settings config.Settings) *fiber.App {

userRouter := routes.User(apiv1, services.NewUserService(db, validate), middlewareService)
routes.UserTag(userRouter, services.NewUserTagService(db, validate))
routes.UserFollower(userRouter, services.NewUserFollowerService(db, validate))

routes.Contact(apiv1, services.NewContactService(db, validate))

clubsRouter := routes.Club(apiv1, services.NewClubService(db, validate), middlewareService)
routes.ClubFollower(clubsRouter, services.NewClubFollowerService(db, validate))
routes.ClubContact(clubsRouter, services.NewClubContactService(db, validate))

routes.Tag(apiv1, services.NewTagService(db, validate))
Expand Down
9 changes: 9 additions & 0 deletions backend/src/services/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type ClubServiceInterface interface {
CreateClub(clubBody models.CreateClubRequestBody) (*models.Club, *errors.Error)
UpdateClub(id string, clubBody models.UpdateClubRequestBody) (*models.Club, *errors.Error)
DeleteClub(id string) *errors.Error
GetUserFollowersForClub(id string) ([]models.User, *errors.Error)
}

type ClubService struct {
Expand Down Expand Up @@ -91,3 +92,11 @@ func (c *ClubService) DeleteClub(id string) *errors.Error {

return transactions.DeleteClub(c.DB, *idAsUUID)
}

func (c *ClubService) GetUserFollowersForClub(id string) ([]models.User, *errors.Error) {
idAsUUID, err := utilities.ValidateID(id)
if err != nil {
return nil, &errors.FailedToValidateID
}
return transactions.GetUserFollowersForClub(c.DB, *idAsUUID)
}
42 changes: 42 additions & 0 deletions backend/src/services/club_follower.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package services

import (
"github.com/GenerateNU/sac/backend/src/errors"
"github.com/GenerateNU/sac/backend/src/models"
"github.com/GenerateNU/sac/backend/src/transactions"
"github.com/GenerateNU/sac/backend/src/utilities"
"github.com/go-playground/validator/v10"
"gorm.io/gorm"
)

type ClubFollowerServiceInterface interface {
GetClubFollowers(clubID string, limit string, page string) ([]models.User, *errors.Error)
}

type ClubFollowerService struct {
DB *gorm.DB
Validate *validator.Validate
}

func NewClubFollowerService(db *gorm.DB, validate *validator.Validate) *ClubFollowerService {
return &ClubFollowerService{DB: db, Validate: validate}
}

func (cf *ClubFollowerService) GetClubFollowers(clubID string, limit string, page string) ([]models.User, *errors.Error) {
idAsUUID, err := utilities.ValidateID(clubID)
if err != nil {
return nil, &errors.FailedToValidateID
}

limitAsInt, err := utilities.ValidateNonNegative(limit)
if err != nil {
return nil, &errors.FailedToValidateLimit
}

pageAsInt, err := utilities.ValidateNonNegative(page)
if err != nil {
return nil, &errors.FailedToValidatePage
}

return transactions.GetClubFollowers(cf.DB, *idAsUUID, *limitAsInt, *pageAsInt)
}
32 changes: 32 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 @@ -102,3 +104,33 @@ 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)
if err != nil {
return nil, err
}

// Update the user to reflect the new tags:
return transactions.CreateUserTags(u.DB, *idAsUUID, tags)
}
Loading
Loading