Skip to content

Commit

Permalink
SAC-25 Membership CRUD (#147)
Browse files Browse the repository at this point in the history
Co-authored-by: edwinliiiii <[email protected]>
Co-authored-by: Garrett Ladley <[email protected]>
Co-authored-by: garrettladley <[email protected]>
  • Loading branch information
4 people authored Feb 11, 2024
1 parent 6ca4f11 commit ccbbe09
Show file tree
Hide file tree
Showing 22 changed files with 876 additions and 115 deletions.
28 changes: 28 additions & 0 deletions backend/src/controllers/club_member.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 ClubMemberController struct {
clubMemberService services.ClubMemberServiceInterface
}

func NewClubMemberController(clubMemberService services.ClubMemberServiceInterface) *ClubMemberController {
return &ClubMemberController{clubMemberService: clubMemberService}
}

func (cm *ClubMemberController) GetClubMembers(c *fiber.Ctx) error {
defaultLimit := 10
defaultPage := 1

followers, err := cm.clubMemberService.GetClubMembers(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)
}
41 changes: 41 additions & 0 deletions backend/src/controllers/user_member.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package controllers

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

type UserMemberController struct {
clubMemberService services.UserMemberServiceInterface
}

func NewUserMemberController(clubMemberService services.UserMemberServiceInterface) *UserMemberController {
return &UserMemberController{clubMemberService: clubMemberService}
}

func (um *UserMemberController) CreateMembership(c *fiber.Ctx) error {
err := um.clubMemberService.CreateMembership(c.Params("userID"), c.Params("clubID"))
if err != nil {
return err.FiberError(c)
}

return c.SendStatus(fiber.StatusCreated)
}

func (um *UserMemberController) DeleteMembership(c *fiber.Ctx) error {
err := um.clubMemberService.DeleteMembership(c.Params("userID"), c.Params("clubID"))
if err != nil {
return err.FiberError(c)
}

return c.SendStatus(fiber.StatusNoContent)
}

func (um *UserMemberController) GetMembership(c *fiber.Ctx) error {
followers, err := um.clubMemberService.GetMembership(c.Params("clubID"))
if err != nil {
return err.FiberError(c)
}

return c.Status(fiber.StatusOK).JSON(followers)
}
9 changes: 8 additions & 1 deletion backend/src/errors/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ var (
StatusCode: fiber.StatusNotFound,
Message: "club not found",
}

FailedToGetMembers = Error{
StatusCode: fiber.StatusNotFound,
Message: "failed to get members",
}
FailedtoGetAdminIDs = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get admin ids",
Expand All @@ -44,4 +47,8 @@ var (
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get club followers",
}
FailedToGetClubMembers = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get club members",
}
)
8 changes: 8 additions & 0 deletions backend/src/errors/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ var (
StatusCode: fiber.StatusInternalServerError,
Message: "failed to compute password hash",
}
FailedToFindUsersByEmail = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get users by email",
}
FailedToGetUserMemberships = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get user memberships",
}
FailedToGetUserFollowing = Error{
StatusCode: fiber.StatusInternalServerError,
Message: "failed to get user following",
Expand Down
16 changes: 16 additions & 0 deletions backend/src/server/routes/club_member.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 ClubMember(clubsIDRouter fiber.Router, clubMemberService services.ClubMemberServiceInterface) {
clubMemberController := controllers.NewClubMemberController(clubMemberService)

clubMember := clubsIDRouter.Group("/member")

// api/v1/clubs/:clubID/member/*
clubMember.Get("/", clubMemberController.GetClubMembers)
}
18 changes: 18 additions & 0 deletions backend/src/server/routes/user_member.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 UserMember(usersRouter fiber.Router, userMembershipService services.UserMemberServiceInterface) {
userMemberController := controllers.NewUserMemberController(userMembershipService)

userMember := usersRouter.Group("/:userID/member")

// api/v1/users/:userID/member/*
userMember.Post("/", userMemberController.CreateMembership)
userMember.Delete("/", userMemberController.DeleteMembership)
userMember.Get("/", userMemberController.GetMembership)
}
8 changes: 5 additions & 3 deletions backend/src/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ 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.UserMember(userRouter, services.NewUserMemberService(db))

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))
clubsIDRouter := routes.Club(apiv1, services.NewClubService(db, validate), middlewareService)
routes.ClubFollower(clubsIDRouter, services.NewClubFollowerService(db))
routes.ClubMember(clubsIDRouter, services.NewClubMemberService(db, validate))
routes.ClubContact(clubsIDRouter, services.NewClubContactService(db, validate))

routes.Tag(apiv1, services.NewTagService(db, validate))

Expand Down
9 changes: 0 additions & 9 deletions backend/src/services/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ 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 @@ -92,11 +91,3 @@ 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)
}
8 changes: 3 additions & 5 deletions backend/src/services/club_follower.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"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"
)

Expand All @@ -14,12 +13,11 @@ type ClubFollowerServiceInterface interface {
}

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

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

func (cf *ClubFollowerService) GetClubFollowers(clubID string, limit string, page string) ([]models.User, *errors.Error) {
Expand Down
41 changes: 41 additions & 0 deletions backend/src/services/club_member.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
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 ClubMemberServiceInterface interface {
GetClubMembers(clubID string, limit string, page string) ([]models.User, *errors.Error)
}

type ClubMemberService struct {
DB *gorm.DB
}

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

func (cms *ClubMemberService) GetClubMembers(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.GetClubMembers(cms.DB, *idAsUUID, *limitAsInt, *pageAsInt)
}
32 changes: 0 additions & 32 deletions backend/src/services/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ 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 @@ -104,33 +102,3 @@ 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)
}
59 changes: 59 additions & 0 deletions backend/src/services/user_member.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
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"
"gorm.io/gorm"
)

type UserMemberServiceInterface interface {
CreateMembership(userID string, clubID string) *errors.Error
DeleteMembership(userID string, clubID string) *errors.Error
GetMembership(userID string) ([]models.Club, *errors.Error)
}

type UserMemberService struct {
DB *gorm.DB
}

func NewUserMemberService(db *gorm.DB) *UserMemberService {
return &UserMemberService{DB: db}
}

func (u *UserMemberService) CreateMembership(userID string, clubID string) *errors.Error {
userIdAsUUID, err := utilities.ValidateID(userID)
if err != nil {
return err
}

clubIdAsUUID, err := utilities.ValidateID(clubID)
if err != nil {
return err
}

return transactions.CreateMember(u.DB, *userIdAsUUID, *clubIdAsUUID)
}

func (u *UserMemberService) DeleteMembership(userID string, clubID string) *errors.Error {
userIdAsUUID, err := utilities.ValidateID(userID)
if err != nil {
return err
}

clubIdAsUUID, err := utilities.ValidateID(clubID)
if err != nil {
return err
}
return transactions.DeleteMember(u.DB, *userIdAsUUID, *clubIdAsUUID)
}

func (u *UserMemberService) GetMembership(userID string) ([]models.Club, *errors.Error) {
userIdAsUUID, err := utilities.ValidateID(userID)
if err != nil {
return nil, err
}

return transactions.GetClubMembership(u.DB, *userIdAsUUID)
}
13 changes: 0 additions & 13 deletions backend/src/transactions/club.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,3 @@ func DeleteClub(db *gorm.DB, id uuid.UUID) *errors.Error {
}
return nil
}

func GetUserFollowersForClub(db *gorm.DB, club_id uuid.UUID) ([]models.User, *errors.Error) {
var users []models.User
club, err := GetClub(db, club_id)
if err != nil {
return nil, &errors.ClubNotFound
}

if err := db.Model(&club).Association("Follower").Find(&users); err != nil {
return nil, &errors.FailedToGetClubFollowers
}
return users, nil
}
9 changes: 9 additions & 0 deletions backend/src/transactions/club_follower.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@ import (
)

func GetClubFollowers(db *gorm.DB, clubID uuid.UUID, limit int, page int) ([]models.User, *errors.Error) {
club, err := GetClub(db, clubID)
if err != nil {
return nil, &errors.ClubNotFound
}

var users []models.User

if err := db.Model(&club).Association("Followers").Find(&users); err != nil {
return nil, &errors.FailedToGetClubFollowers
}

return users, nil
}
Loading

0 comments on commit ccbbe09

Please sign in to comment.