Skip to content

Commit

Permalink
add musical information endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
donaderoyan committed May 30, 2024
1 parent 34cb045 commit d49efea
Show file tree
Hide file tree
Showing 21 changed files with 799 additions and 60 deletions.
10 changes: 10 additions & 0 deletions controllers/user/musicalinfo/input.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" updateValidation:"omitempty"`
PrimaryInstrument string `json:"primary_instrument" updateValidation:"omitempty"`
SecondaryInstruments []string `json:"secondary_instruments,omitempty" updateValidation:"omitempty"`
Genres []string `json:"genres" updateValidation:"omitempty"`
FavoriteArtists []string `json:"favorite_artists,omitempty" updateValidation:"omitempty"`
LearningGoals []string `json:"learning_goals,omitempty" updateValidation:"omitempty"`
}
95 changes: 95 additions & 0 deletions controllers/user/musicalinfo/repository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package musicalinfo

import (
"context"
"fmt"

model "github.com/donaderoyan/talentgrowth-be/models"
util "github.com/donaderoyan/talentgrowth-be/utils"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
)

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

type repository struct {
db *mongo.Database
}

func NewMusicalInfoRepository(db *mongo.Database) *repository {
return &repository{db: db}
}

type MusicalInfoUpdateError struct {
*util.BaseError
}

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

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")}
}
var updatedMusicalInfo model.MusicalInfo

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
}

updates["userID"] = userIDPrimitive
// Insert musical information
result, errInsert := r.db.Collection("musicalinfo").InsertOne(sc, updates)
if errInsert != nil {
return &MusicalInfoUpdateError{util.NewBaseError("ADD_MUSICALINFO_ERROR", "Update 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),
},
}

_, err = r.db.Collection("users").UpdateOne(sc, filter, userUpdate)
if err != nil {
return &MusicalInfoUpdateError{util.NewBaseError("ADD_MUSICALINFO_ERROR", "Update 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 nil
})

if transactionErr != nil {
return nil, transactionErr
}

return &updatedMusicalInfo, nil
}
34 changes: 34 additions & 0 deletions controllers/user/musicalinfo/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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)
}

type service struct {
repository Repository
}

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
}
6 changes: 3 additions & 3 deletions controllers/user/profile/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ type UpdateProfileInput struct {
FirstName string `json:"firstName" validate:"required,alpha" updateValidation:"omitempty,alpha"`
LastName string `json:"lastName" validate:"required,alpha" updateValidation:"omitempty,alpha"`
Phone string `json:"phone" validate:"required,e164" updateValidation:"omitempty,e164"`
Address Address `json:"address" validate:"omitempty" updateValidation:"omitempty"`
Birthday string `json:"birthday" validate:"omitempty,customdate,datebeforetoday" updateValidation:"omitempty,customdate,datebeforetoday"`
Gender string `json:"gender" validate:"omitempty,oneof=male female" updateValidation:"omitempty,oneof=male female"`
Address Address `json:"address" validate:"required" updateValidation:"omitempty"`
Birthday string `json:"birthday" validate:"required,customdate,datebeforetoday" updateValidation:"omitempty,customdate,datebeforetoday"`
Gender string `json:"gender" validate:"required,oneof=male female" updateValidation:"omitempty,oneof=male female"`
Nationality string `json:"nationality" validate:"omitempty" updateValidation:"omitempty"`
Bio string `json:"bio" validate:"omitempty" updateValidation:"omitempty"`
ProfilePicture string `json:"profilePicture" validate:"omitempty,url" updateValidation:"omitempty,url"`
Expand Down
File renamed without changes.
57 changes: 57 additions & 0 deletions controllers/user/profile/put-service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package profile

import (
"time"

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

type PutService interface {
PutProfileService(userID string, input *UpdateProfileInput) (*model.User, error)
}

type putservice struct {
repository Repository
}

func NewPutProfileService(repository Repository) *putservice {
return &putservice{repository: repository}
}

func (s *putservice) PutProfileService(userID string, input *UpdateProfileInput) (*model.User, error) {
// Update user profile
// Ensure correct field names are used for MongoDB document
var parsedBirthday time.Time
if input.Birthday != "" {
var err error
parsedBirthday, err = time.Parse("02-01-2006", input.Birthday)
if err != nil {
return nil, err
}
}

correctFieldNames := bson.M{
"firstName": input.FirstName,
"lastName": input.LastName,
"birthday": parsedBirthday,
"phone": input.Phone,
"gender": input.Gender,
"nationality": input.Nationality,
"bio": input.Bio,
"updatedAt": time.Now(),
"profilePicture": input.ProfilePicture,
}

// Handle address update if present
if input.Address != (Address{}) {
correctFieldNames["address.street"] = input.Address.Street
correctFieldNames["address.city"] = input.Address.City
correctFieldNames["address.state"] = input.Address.State
correctFieldNames["address.postalCode"] = input.Address.PostalCode
correctFieldNames["address.country"] = input.Address.Country
}

result, err := s.repository.UpdateProfile(userID, correctFieldNames)
return result, err
}
Loading

0 comments on commit d49efea

Please sign in to comment.