Skip to content

Commit

Permalink
add post musicalinfo and fix
Browse files Browse the repository at this point in the history
  • Loading branch information
donaderoyan committed Jun 4, 2024
1 parent 7119973 commit be31f46
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 49 deletions.
10 changes: 10 additions & 0 deletions controllers/user/musicalinfo/entity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package musicalinfo

type MusicalInfoInput struct {
SkillLevel string `json:"skill_level" validate:"required" updateValidation:"omitempty"`
PrimaryInstrument string `json:"primary_instrument" validate:"required" updateValidation:"omitempty"`
SecondaryInstruments []string `json:"secondary_instruments,omitempty" validate:"omitempty" updateValidation:"omitempty"`
Genres []string `json:"genres" validate:"omitempty" updateValidation:"omitempty"`
FavoriteArtists []string `json:"favorite_artists,omitempty" validate:"omitempty" updateValidation:"omitempty"`
LearningGoals []string `json:"learning_goals,omitempty" validate:"omitempty" updateValidation:"omitempty"`
}
10 changes: 0 additions & 10 deletions controllers/user/musicalinfo/input.go

This file was deleted.

22 changes: 22 additions & 0 deletions controllers/user/musicalinfo/patch-service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package musicalinfo

import (
model "github.com/donaderoyan/talentgrowth-be/models"
"go.mongodb.org/mongo-driver/bson"
)

func (s *service) UpdateMusicalInfoService(userID string, input *MusicalInfoInput) (*model.MusicalInfo, error) {

fields := bson.M{
"skillLevel": input.SkillLevel,
"primaryInstrument": input.PrimaryInstrument,
"secondaryInstruments": input.SecondaryInstruments,
"genres": input.Genres,
"favoriteArtists": input.FavoriteArtists,
"learningGoals": input.LearningGoals,
}

result, err := s.repository.UpdateMusicalInfo(userID, fields)

return result, err
}
22 changes: 22 additions & 0 deletions controllers/user/musicalinfo/post-service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package musicalinfo

import (
model "github.com/donaderoyan/talentgrowth-be/models"
"go.mongodb.org/mongo-driver/bson"
)

func (s *service) CreateMusicalInfoService(userID string, input *MusicalInfoInput) (*model.MusicalInfo, error) {

fields := bson.M{
"skillLevel": input.SkillLevel,
"primaryInstrument": input.PrimaryInstrument,
"secondaryInstruments": input.SecondaryInstruments,
"genres": input.Genres,
"favoriteArtists": input.FavoriteArtists,
"learningGoals": input.LearningGoals,
}

result, err := s.repository.CreateMusicalInfo(userID, fields)

return result, err
}
90 changes: 80 additions & 10 deletions controllers/user/musicalinfo/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

type Repository interface {
UpdateMusicalInfo(userID string, updates bson.M) (*model.MusicalInfo, error)
CreateMusicalInfo(userID string, data bson.M) (*model.MusicalInfo, error)
}

type repository struct {
Expand All @@ -28,10 +29,18 @@ type MusicalInfoUpdateError struct {
}

func (e *MusicalInfoUpdateError) Error() string {
return fmt.Sprintf("Profile update error: %s - %s", e.Code, e.Message)
return fmt.Sprintf("Musical Information update error: %s - %s", e.Code, e.Message)
}

func (r *repository) UpdateMusicalInfo(userID string, updates bson.M) (*model.MusicalInfo, error) {
type MusicalInfoCreateError struct {
*util.BaseError
}

func (e *MusicalInfoCreateError) Error() string {
return fmt.Sprintf("Musical Information update error: %s - %s", e.Code, e.Message)
}

func (r *repository) CreateMusicalInfo(userID string, data bson.M) (*model.MusicalInfo, error) {
// Start a session for transaction
session, err := r.db.Client().StartSession()
if err != nil {
Expand All @@ -42,7 +51,7 @@ func (r *repository) UpdateMusicalInfo(userID string, updates bson.M) (*model.Mu
// Convert userID to primitive.ObjectID
userIDPrimitive, err := primitive.ObjectIDFromHex(userID)
if err != nil {
return nil, &MusicalInfoUpdateError{util.NewBaseError("INVALID_USER_ID", "Invalid user ID format")}
return nil, &MusicalInfoCreateError{util.NewBaseError("INVALID_USER_ID", "Invalid user ID format")}
}
var updatedMusicalInfo model.MusicalInfo

Expand All @@ -53,35 +62,89 @@ func (r *repository) UpdateMusicalInfo(userID string, updates bson.M) (*model.Mu
err = r.db.Collection("users").FindOne(sc, bson.M{"_id": userIDPrimitive}).Decode(&existingUser)
if err != nil {
if err == mongo.ErrNoDocuments {
return &MusicalInfoUpdateError{util.NewBaseError("USER_NOT_FOUND", "User not found")}
return &MusicalInfoCreateError{util.NewBaseError("USER_NOT_FOUND", "User not found")}
}
return err
}

updates["userID"] = userIDPrimitive
var existingMusicalInfo *model.MusicalInfo
err := r.db.Collection("musicalinfo").FindOne(sc, bson.M{"userID": userIDPrimitive}).Decode(&existingMusicalInfo)
if err == mongo.ErrNoDocuments {
// userID does not exist in musicalinfo, continue with creation
data["userID"] = userIDPrimitive
} else if err != nil {
return err
} else {
// Musical info already exists, return error
return &MusicalInfoCreateError{util.NewBaseError("MUSICAL_INFO_EXIST", "Musical information already exists")}
}

// Insert musical information
result, errInsert := r.db.Collection("musicalinfo").InsertOne(sc, updates)
result, errInsert := r.db.Collection("musicalinfo").InsertOne(sc, data)
if errInsert != nil {
return &MusicalInfoUpdateError{util.NewBaseError("ADD_MUSICALINFO_ERROR", "Update musical information failed")}
return &MusicalInfoCreateError{util.NewBaseError("ADD_MUSICALINFO_ERROR", "Create musical information failed")}
}

// Update the User document with the MusicalInfoID
filter := bson.M{"_id": userIDPrimitive}
userUpdate := bson.M{
"$set": bson.M{
"musical_info_id": result.InsertedID.(primitive.ObjectID),
"musicalInfoId": result.InsertedID.(primitive.ObjectID),
},
}

_, err = r.db.Collection("users").UpdateOne(sc, filter, userUpdate)
if err != nil {
return &MusicalInfoUpdateError{util.NewBaseError("ADD_MUSICALINFO_ERROR", "Update musical information failed")}
return &MusicalInfoCreateError{util.NewBaseError("ADD_MUSICALINFO_ERROR", "Create musical information failed")}
}

// Retrieve the updated MusicalInfo
err = r.db.Collection("musicalinfo").FindOne(context.Background(), bson.M{"userID": userIDPrimitive}).Decode(&updatedMusicalInfo)
if err != nil {
return &MusicalInfoUpdateError{util.NewBaseError("MUSICAL_INFO_RETRIEVE_ERROR", "Failed to retrieve updated musical information")}
return &MusicalInfoCreateError{util.NewBaseError("MUSICAL_INFO_RETRIEVE_ERROR", "Failed to retrieve updated musical information")}
}

return nil
})

if transactionErr != nil {
return nil, transactionErr
}

return &updatedMusicalInfo, nil
}

func (r *repository) UpdateMusicalInfo(userID string, updates bson.M) (*model.MusicalInfo, error) {
// Start a session for transaction
session, err := r.db.Client().StartSession()
if err != nil {
return nil, err
}
defer session.EndSession(context.Background())

// Convert userID to primitive.ObjectID
userIDPrimitive, err := primitive.ObjectIDFromHex(userID)
if err != nil {
return nil, &MusicalInfoUpdateError{util.NewBaseError("INVALID_USER_ID", "Invalid user ID format")}
}

transactionErr := mongo.WithSession(context.Background(), session, func(sc mongo.SessionContext) error {

// Check if user exists and retrieve current user data
var existingUser model.User
err = r.db.Collection("users").FindOne(sc, bson.M{"_id": userIDPrimitive}).Decode(&existingUser)
if err != nil {
if err == mongo.ErrNoDocuments {
return &MusicalInfoUpdateError{util.NewBaseError("USER_NOT_FOUND", "User not found")}
}
return err
}

// Insert musical information
_, errInsert := r.db.Collection("musicalinfo").UpdateOne(sc, bson.M{"userID": userIDPrimitive}, bson.M{"$set": updates})
if errInsert != nil {
fmt.Printf("INSERT MUSICAL INFORMATION ERRORR >>>>>>>>>>> %v", errInsert)
return &MusicalInfoUpdateError{util.NewBaseError("ADD_MUSICALINFO_ERROR", "Update musical information failed")}
}

return nil
Expand All @@ -91,5 +154,12 @@ func (r *repository) UpdateMusicalInfo(userID string, updates bson.M) (*model.Mu
return nil, transactionErr
}

// Retrieve the updated MusicalInfo
var updatedMusicalInfo model.MusicalInfo
err = r.db.Collection("musicalinfo").FindOne(context.Background(), bson.M{"userID": userIDPrimitive}).Decode(&updatedMusicalInfo)
if err != nil {
return nil, &MusicalInfoUpdateError{util.NewBaseError("MUSICAL_INFO_RETRIEVE_ERROR", "Failed to retrieve updated musical information")}
}

return &updatedMusicalInfo, nil
}
18 changes: 1 addition & 17 deletions controllers/user/musicalinfo/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package musicalinfo

import (
model "github.com/donaderoyan/talentgrowth-be/models"
"go.mongodb.org/mongo-driver/bson"
)

type Service interface {
UpdateMusicalInfoService(userID string, input *MusicalInfoInput) (*model.MusicalInfo, error)
CreateMusicalInfoService(userID string, input *MusicalInfoInput) (*model.MusicalInfo, error)
}

type service struct {
Expand All @@ -16,19 +16,3 @@ type service struct {
func NewMusicalInfoService(repository Repository) *service {
return &service{repository: repository}
}

func (s *service) UpdateMusicalInfoService(userID string, input *MusicalInfoInput) (*model.MusicalInfo, error) {

fields := bson.M{
"skillLevel": input.SkillLevel,
"primaryInstrument": input.PrimaryInstrument,
"secondaryInstruments": input.SecondaryInstruments,
"genres": input.Genres,
"favoriteArtists": input.FavoriteArtists,
"learningGoals": input.LearningGoals,
}

result, err := s.repository.UpdateMusicalInfo(userID, fields)

return result, err
}
11 changes: 11 additions & 0 deletions handlers/user/musicalinfo/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package musicalinfohandler

import musicalinfo "github.com/donaderoyan/talentgrowth-be/controllers/user/musicalinfo"

type handler struct {
service musicalinfo.Service
}

func NewMusicalInfohandler(service musicalinfo.Service) *handler {
return &handler{service: service}
}
8 changes: 0 additions & 8 deletions handlers/user/musicalinfo/patch.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,6 @@ import (
"github.com/gin-gonic/gin"
)

type handler struct {
service musicalinfo.Service
}

func NewMusicalInfohandler(service musicalinfo.Service) *handler {
return &handler{service: service}
}

// Swagger documentation for UpdateMusicalInfoHandler
// @Summary Update musical information (partial update)
// @Description Update musical information for a user
Expand Down
38 changes: 38 additions & 0 deletions handlers/user/musicalinfo/post.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package musicalinfohandler

import (
"net/http"

musicalinfo "github.com/donaderoyan/talentgrowth-be/controllers/user/musicalinfo"
util "github.com/donaderoyan/talentgrowth-be/utils"
"github.com/gin-gonic/gin"
)

func (h *handler) CreateMusicalInfoHandler(ctx *gin.Context) {
userID := ctx.Param("id")
var input musicalinfo.MusicalInfoInput

if err := ctx.ShouldBindJSON(&input); err != nil {
util.ErrorResponse(ctx, "Create musical information failed", http.StatusBadRequest, http.MethodPost, err.Error())
}

if errValidator := util.Validator(input, "validate"); errValidator != nil {
util.ErrorResponse(ctx, "The input value is invalid", http.StatusBadRequest, http.MethodPost, errValidator.Error())
return
}

updateMusicalInfo, errUpdate := h.service.CreateMusicalInfoService(userID, &input)
if errUpdate != nil {
switch errUpdate.(type) {
case *musicalinfo.MusicalInfoCreateError:
util.ErrorResponse(ctx, "Create musical information failed", http.StatusBadRequest, http.MethodPost, errUpdate.Error())
return
default:
// Handle other unexpected errors
util.ErrorResponse(ctx, "Internal server error", http.StatusInternalServerError, http.MethodPost, errUpdate.Error())
return
}
}

util.APIResponse(ctx, "Musical information created successfully", http.StatusOK, http.MethodPost, updateMusicalInfo)
}
8 changes: 4 additions & 4 deletions handlers/user/profile/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ import (
func (h *handler) GetProfileHandler(ctx *gin.Context) {
userID := ctx.Param("id")
if userID == "" {
util.ErrorResponse(ctx, "Update profile failed", http.StatusBadRequest, http.MethodPut, "ID is required")
util.ErrorResponse(ctx, "Update profile failed", http.StatusBadRequest, http.MethodGet, "ID is required")
return
}

dataUser, errData := h.service.GetProfileService(userID)
if errData != nil {
switch errData.(type) {
case *profile.GetUserProfileError:
util.ErrorResponse(ctx, "Get user profile failed", http.StatusBadRequest, http.MethodPatch, errData.Error())
util.ErrorResponse(ctx, "Get user profile failed", http.StatusBadRequest, http.MethodGet, errData.Error())
return
default:
// Handle other unexpected errors
util.ErrorResponse(ctx, "Internal server error", http.StatusInternalServerError, http.MethodPatch, nil)
util.ErrorResponse(ctx, "Internal server error", http.StatusInternalServerError, http.MethodGet, nil)
return
}
}
Expand All @@ -51,5 +51,5 @@ func (h *handler) GetProfileHandler(ctx *gin.Context) {
"bio": dataUser.Bio,
}

util.APIResponse(ctx, "Get user profile successfully", http.StatusOK, http.MethodPatch, responseData)
util.APIResponse(ctx, "Get user profile successfully", http.StatusOK, http.MethodGet, responseData)
}
1 change: 1 addition & 0 deletions routes/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ func InitUserRoutes(db *mongo.Database, route *gin.Engine) {
userGroup.GET("/profile/:id", profileHandler.GetProfileHandler)
// musical information
userGroup.PATCH("/musicalinfo/:id", musicalInfoHandler.UpdateMusicalInfoHandler)
userGroup.POST("/musicalinfo/:id", musicalInfoHandler.CreateMusicalInfoHandler)
}

0 comments on commit be31f46

Please sign in to comment.