feat: add bulk user creation functionality with request handling and repository integration

This commit is contained in:
Habib Fatkhul Rohman 2025-11-21 13:55:42 +07:00
parent 4e9be2b87a
commit f7eab339b6
5 changed files with 79 additions and 0 deletions

View File

@ -37,6 +37,7 @@ type (
AddUserWarehouse(ctx *gin.Context) AddUserWarehouse(ctx *gin.Context)
ReplaceUserWarehouses(ctx *gin.Context) ReplaceUserWarehouses(ctx *gin.Context)
RemoveUserWarehouse(ctx *gin.Context) RemoveUserWarehouse(ctx *gin.Context)
BulkCreate(ctx *gin.Context)
} }
userController struct { userController struct {
@ -45,6 +46,24 @@ type (
} }
) )
// BulkCreate implements UserController.
func (c *userController) BulkCreate(ctx *gin.Context) {
var req dto.BulkCreateUserRequest
if err := ctx.ShouldBindJSON(&req); err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_GET_DATA_FROM_BODY, err.Error(), nil)
ctx.AbortWithStatusJSON(http.StatusBadRequest, res)
return
}
err := c.userService.BulkCreate(ctx.Request.Context(), req)
if err != nil {
res := utils.BuildResponseFailed(dto.MESSAGE_FAILED_PROSES_REQUEST, err.Error(), nil)
ctx.JSON(http.StatusBadRequest, res)
return
}
res := utils.BuildResponseSuccess(dto.MESSAGE_SUCCESS_PROSES_REQUEST, nil)
ctx.JSON(http.StatusOK, res)
}
// SwitchRole implements UserController. // SwitchRole implements UserController.
func (c *userController) SwitchRole(ctx *gin.Context) { func (c *userController) SwitchRole(ctx *gin.Context) {
userId := ctx.Param("id") userId := ctx.Param("id")

View File

@ -64,6 +64,10 @@ type (
LocationID uuid.UUID `json:"location_id" form:"location_id" binding:"omitempty,uuid4"` LocationID uuid.UUID `json:"location_id" form:"location_id" binding:"omitempty,uuid4"`
} }
BulkCreateUserRequest struct {
Users []UserCreateRequest `json:"users" binding:"required,dive"`
}
UserResponse struct { UserResponse struct {
ID string `json:"id"` ID string `json:"id"`
Name string `json:"name"` Name string `json:"name"`

View File

@ -28,6 +28,7 @@ type (
AddUserWarehouses(ctx context.Context, tx *gorm.DB, userId string, warehouseIds []string) error AddUserWarehouses(ctx context.Context, tx *gorm.DB, userId string, warehouseIds []string) error
AddUserWarehouse(ctx context.Context, tx *gorm.DB, userId string, warehouseId string) error AddUserWarehouse(ctx context.Context, tx *gorm.DB, userId string, warehouseId string) error
RemoveUserWarehouse(ctx context.Context, tx *gorm.DB, userId string, warehouseId string) error RemoveUserWarehouse(ctx context.Context, tx *gorm.DB, userId string, warehouseId string) error
BulkCreate(ctx context.Context, tx *gorm.DB, users []entities.M_User) error
} }
userRepository struct { userRepository struct {
@ -35,6 +36,17 @@ type (
} }
) )
// BulkCreate implements UserRepository.
func (r *userRepository) BulkCreate(ctx context.Context, tx *gorm.DB, users []entities.M_User) error {
if tx == nil {
tx = r.db
}
if err := tx.WithContext(ctx).Create(&users).Error; err != nil {
return err
}
return nil
}
// GetUserWarehouses implements UserRepository. // GetUserWarehouses implements UserRepository.
func (r *userRepository) GetUserWarehouses(ctx context.Context, tx *gorm.DB, userId string) ([]entities.MWarehouseEntity, error) { func (r *userRepository) GetUserWarehouses(ctx context.Context, tx *gorm.DB, userId string) ([]entities.MWarehouseEntity, error) {
if tx == nil { if tx == nil {

View File

@ -16,6 +16,7 @@ func RegisterRoutes(server *gin.Engine, injector *do.Injector) {
userRoutes := server.Group("/api/v1/users") userRoutes := server.Group("/api/v1/users")
{ {
userRoutes.POST("", middlewares.Authenticate(jwtService), userController.Create) userRoutes.POST("", middlewares.Authenticate(jwtService), userController.Create)
userRoutes.POST("/bulk-create", middlewares.Authenticate(jwtService), userController.BulkCreate)
// userRoutes.POST("/login", userController.Login) // userRoutes.POST("/login", userController.Login)
// userRoutes.POST("/verify-email", userController.VerifyEmail) // userRoutes.POST("/verify-email", userController.VerifyEmail)
userRoutes.GET("", middlewares.Authenticate(jwtService), userController.GetAllUser) userRoutes.GET("", middlewares.Authenticate(jwtService), userController.GetAllUser)

View File

@ -41,6 +41,7 @@ type UserService interface {
AssignWarehousesReplace(ctx context.Context, userId string, warehouseIds []string) error AssignWarehousesReplace(ctx context.Context, userId string, warehouseIds []string) error
AssignWarehouse(ctx context.Context, userId string, warehouseId string) error AssignWarehouse(ctx context.Context, userId string, warehouseId string) error
RemoveWarehouse(ctx context.Context, userId string, warehouseId string) error RemoveWarehouse(ctx context.Context, userId string, warehouseId string) error
BulkCreate(ctx context.Context, req dto.BulkCreateUserRequest) error
} }
type userService struct { type userService struct {
@ -52,6 +53,48 @@ type userService struct {
db *gorm.DB db *gorm.DB
} }
// BulkCreate implements UserService.
func (s *userService) BulkCreate(ctx context.Context, req dto.BulkCreateUserRequest) error {
users := make([]entities.M_User, len(req.Users))
for i, r := range req.Users {
hashedPassword, err := utils.HashPassword(r.Password)
if err != nil {
return err
}
users[i] = entities.M_User{
Username: r.Username,
Email: r.Email,
Password: hashedPassword,
Name: r.Name,
Gender: r.Gender,
Address: r.Address,
Phone: r.Phone,
PhotoUrl: r.PhotoUrl,
ClientID: r.ClientID,
MaintenanceGroupUserID: r.MaintenanceGroupUserID,
LocationID: r.LocationID,
}
}
tx := s.db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
err := s.userRepository.BulkCreate(ctx, tx, users)
if err != nil {
tx.Rollback()
return err
}
if err := tx.Commit().Error; err != nil {
return err
}
return nil
}
// GetUserWarehouses implements UserService. // GetUserWarehouses implements UserService.
func (s *userService) GetUserWarehouses(ctx context.Context, userId string) ([]dto.UserResponse, error) { func (s *userService) GetUserWarehouses(ctx context.Context, userId string) ([]dto.UserResponse, error) {
user, err := s.userRepository.GetUserById(ctx, s.db, userId) user, err := s.userRepository.GetUserById(ctx, s.db, userId)