UPDATE: Fix bug
All checks were successful
Build and Release / release (push) Successful in 1m8s

This commit is contained in:
2026-04-27 20:31:01 +07:00
parent eb08c16232
commit 17aafacbfd
36 changed files with 842 additions and 447 deletions

View File

@@ -32,14 +32,14 @@ import (
)
type AuthService interface {
Signin(ctx context.Context, dto *request.SignInDto) (*response.AuthResponse, error)
Signup(ctx context.Context, dto *request.SignUpDto) (*response.AuthResponse, error)
Logout(ctx context.Context, userId string) error
ForgotPassword(ctx context.Context, dto *request.ForgotPasswordDto) error
VerifyToken(ctx context.Context, dto *request.VerifyTokenDto) (*response.VerifyTokenResponse, error)
CreateToken(ctx context.Context, dto *request.CreateTokenDto) error
SigninWithGoogle(ctx context.Context, dto *request.SigninWithGoogleDto) (*response.AuthResponse, error)
RefreshToken(ctx context.Context, id string, refreshToken string) (*response.AuthResponse, error)
Signin(ctx context.Context, dto *request.SignInDto) (*response.AuthResponse, *fiber.Error)
Signup(ctx context.Context, dto *request.SignUpDto) (*response.AuthResponse, *fiber.Error)
Logout(ctx context.Context, userId string) *fiber.Error
ForgotPassword(ctx context.Context, dto *request.ForgotPasswordDto) *fiber.Error
VerifyToken(ctx context.Context, dto *request.VerifyTokenDto) (*response.VerifyTokenResponse, *fiber.Error)
CreateToken(ctx context.Context, dto *request.CreateTokenDto) *fiber.Error
SigninWithGoogle(ctx context.Context, dto *request.SigninWithGoogleDto) (*response.AuthResponse, *fiber.Error)
RefreshToken(ctx context.Context, id string, refreshToken string) (*response.AuthResponse, *fiber.Error)
}
type authService struct {
@@ -69,15 +69,15 @@ func NewAuthService(
func (a *authService) genToken(user *models.UserEntity) (*response.AuthResponse, error) {
jwtSecret, err := config.GetConfig("JWT_SECRET")
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "missing JWT_SECRET in environment")
return nil, err
}
jwtRefreshSecret, err := config.GetConfig("JWT_REFRESH_SECRET")
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "missing JWT_REFRESH_SECRET in environment")
return nil, err
}
if jwtSecret == "" || jwtRefreshSecret == "" {
return nil, fiber.NewError(fiber.StatusInternalServerError, "missing JWT secrets in environment")
return nil, errors.New("missing JWT secrets in environment")
}
claimsAccess := &response.JWTClaims{
@@ -117,9 +117,9 @@ func (a *authService) genToken(user *models.UserEntity) (*response.AuthResponse,
return &res, nil
}
func (a *authService) Signin(ctx context.Context, dto *request.SignInDto) (*response.AuthResponse, error) {
func (a *authService) Signin(ctx context.Context, dto *request.SignInDto) (*response.AuthResponse, *fiber.Error) {
if !constants.EMAIL_REGEX.MatchString(dto.Email) {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid email")
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid email format")
}
err := constants.ValidatePassword(dto.Password)
@@ -129,7 +129,7 @@ func (a *authService) Signin(ctx context.Context, dto *request.SignInDto) (*resp
user, err := a.userRepo.GetByEmail(ctx, dto.Email)
if err != nil || user == nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusUnauthorized, "Invalid email or password")
}
if user.AuthProvider != constants.ProviderTypeLocal.String() && user.PasswordHash == "" {
@@ -137,17 +137,17 @@ func (a *authService) Signin(ctx context.Context, dto *request.SignInDto) (*resp
}
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(dto.Password)); err != nil {
return nil, fiber.NewError(fiber.StatusUnauthorized, "Invalid identity or password!")
return nil, fiber.NewError(fiber.StatusUnauthorized, "Invalid email or password")
}
data, err := a.genToken(user)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to generate security tokens")
}
pgID, err := convert.StringToUUID(user.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID internal format")
}
err = a.userRepo.UpdateRefreshToken(
ctx,
@@ -160,14 +160,14 @@ func (a *authService) Signin(ctx context.Context, dto *request.SignInDto) (*resp
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update refresh token")
}
return data, nil
}
func (a *authService) Logout(ctx context.Context, userId string) error {
func (a *authService) Logout(ctx context.Context, userId string) *fiber.Error {
tx, err := a.db.Begin(ctx)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Failed to start transaction")
@@ -178,11 +178,11 @@ func (a *authService) Logout(ctx context.Context, userId string) error {
pgID, err := convert.StringToUUID(userId)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusBadRequest, "Invalid user ID format")
}
user, err := a.userRepo.GetByID(ctx, pgID)
if err != nil || user == nil {
return fiber.NewError(fiber.StatusInternalServerError, "Invalid user data")
return fiber.NewError(fiber.StatusNotFound, "User not found")
}
err = uRepoTx.UpdateTokenVersion(ctx, sqlc.UpdateTokenVersionParams{
@@ -190,7 +190,7 @@ func (a *authService) Logout(ctx context.Context, userId string) error {
TokenVersion: user.TokenVersion + 1,
})
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to revoke sessions")
}
err = uRepoTx.UpdateRefreshToken(ctx, sqlc.UpdateUserRefreshTokenParams{
@@ -201,39 +201,39 @@ func (a *authService) Logout(ctx context.Context, userId string) error {
},
})
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to clear refresh token")
}
err = tx.Commit(ctx)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to commit logout")
}
return nil
}
func (a *authService) RefreshToken(ctx context.Context, id string, refreshToken string) (*response.AuthResponse, error) {
func (a *authService) RefreshToken(ctx context.Context, id string, refreshToken string) (*response.AuthResponse, *fiber.Error) {
var pgID pgtype.UUID
err := pgID.Scan(id)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid user ID format")
}
user, err := a.userRepo.GetByID(ctx, pgID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user data")
return nil, fiber.NewError(fiber.StatusNotFound, "User not found")
}
if user.RefreshToken != refreshToken {
return nil, fiber.NewError(fiber.StatusUnauthorized, "Invalid refresh token")
return nil, fiber.NewError(fiber.StatusUnauthorized, "Invalid or expired refresh token")
}
roles := models.RolesEntityToRoleConstant(user.Roles)
if slices.Contains(roles, constants.RoleTypeBanned) {
return nil, fiber.NewError(fiber.StatusUnauthorized, "User is banned!")
return nil, fiber.NewError(fiber.StatusUnauthorized, "Your account has been banned")
}
data, err := a.genToken(user)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to generate new tokens")
}
err = a.userRepo.UpdateRefreshToken(
@@ -247,13 +247,13 @@ func (a *authService) RefreshToken(ctx context.Context, id string, refreshToken
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update refresh token")
}
return data, nil
}
func (a *authService) Signup(ctx context.Context, dto *request.SignUpDto) (*response.AuthResponse, error) {
func (a *authService) Signup(ctx context.Context, dto *request.SignUpDto) (*response.AuthResponse, *fiber.Error) {
tx, err := a.db.Begin(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to start transaction")
@@ -264,7 +264,7 @@ func (a *authService) Signup(ctx context.Context, dto *request.SignUpDto) (*resp
rRepoTx := a.roleRepo.WithTx(tx)
if !constants.EMAIL_REGEX.MatchString(dto.Email) {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid email")
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid email format")
}
err = constants.ValidatePassword(dto.Password)
if err != nil {
@@ -273,24 +273,24 @@ func (a *authService) Signup(ctx context.Context, dto *request.SignUpDto) (*resp
ok, err := a.tokenRepo.CheckVerified(ctx, dto.Email, constants.TokenTypeEmailVerify, dto.TokenID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to verify registration token")
}
if !ok {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid or expired token")
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid or expired verification token")
}
user, err := a.userRepo.GetByEmail(ctx, dto.Email)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to check existing user")
}
if user != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "User already exists")
return nil, fiber.NewError(fiber.StatusConflict, "Email is already registered")
}
hashed, err := bcrypt.GenerateFromPassword([]byte(dto.Password), bcrypt.DefaultCost)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to hash password")
}
user, err = uRepoTx.UpsertUser(
@@ -305,12 +305,12 @@ func (a *authService) Signup(ctx context.Context, dto *request.SignUpDto) (*resp
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create user account")
}
userId, err := convert.StringToUUID(user.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID internal format")
}
_, err = uRepoTx.CreateProfile(
ctx,
@@ -323,16 +323,16 @@ func (a *authService) Signup(ctx context.Context, dto *request.SignUpDto) (*resp
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create user profile")
}
role, err := a.roleRepo.GetByName(ctx, constants.RoleTypeUser.String())
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Default role not found")
}
roleId, err := convert.StringToUUID(role.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid role ID internal format")
}
err = rRepoTx.CreateUserRole(
@@ -343,12 +343,12 @@ func (a *authService) Signup(ctx context.Context, dto *request.SignUpDto) (*resp
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to assign user role")
}
data, err := a.genToken(user)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to generate security tokens")
}
err = uRepoTx.UpdateRefreshToken(
@@ -362,40 +362,40 @@ func (a *authService) Signup(ctx context.Context, dto *request.SignUpDto) (*resp
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update refresh token")
}
err = tx.Commit(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to commit signup")
}
return data, nil
}
func (a *authService) ForgotPassword(ctx context.Context, dto *request.ForgotPasswordDto) error {
func (a *authService) ForgotPassword(ctx context.Context, dto *request.ForgotPasswordDto) *fiber.Error {
ok, err := a.tokenRepo.CheckVerified(ctx, dto.Email, constants.TokenTypePasswordReset, dto.TokenID)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to verify reset token")
}
if !ok {
return fiber.NewError(fiber.StatusBadRequest, "Invalid or expired token")
return fiber.NewError(fiber.StatusBadRequest, "Invalid or expired reset token")
}
user, err := a.userRepo.GetByEmail(ctx, dto.Email)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusNotFound, "User not found")
}
if user == nil {
return fiber.NewError(fiber.StatusBadRequest, "User not found")
return fiber.NewError(fiber.StatusNotFound, "User not found")
}
hashed, err := bcrypt.GenerateFromPassword([]byte(dto.NewPassword), bcrypt.DefaultCost)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to hash new password")
}
userId, err := convert.StringToUUID(user.ID)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID format")
}
err = a.userRepo.UpdatePassword(ctx, sqlc.UpdateUserPasswordParams{
ID: userId,
@@ -405,12 +405,12 @@ func (a *authService) ForgotPassword(ctx context.Context, dto *request.ForgotPas
},
})
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update password")
}
return nil
}
func (a *authService) SigninWithGoogle(ctx context.Context, dto *request.SigninWithGoogleDto) (*response.AuthResponse, error) {
func (a *authService) SigninWithGoogle(ctx context.Context, dto *request.SigninWithGoogleDto) (*response.AuthResponse, *fiber.Error) {
tx, err := a.db.Begin(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to start transaction")
@@ -422,17 +422,17 @@ func (a *authService) SigninWithGoogle(ctx context.Context, dto *request.SigninW
user, err := a.userRepo.GetByEmail(ctx, dto.Email)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch user data")
}
if user != nil {
userId, err := convert.StringToUUID(user.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID format")
}
data, err := a.genToken(user)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to generate security tokens")
}
err = uRepoTx.UpdateRefreshToken(
ctx,
@@ -445,7 +445,7 @@ func (a *authService) SigninWithGoogle(ctx context.Context, dto *request.SigninW
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update refresh token")
}
return data, nil
}
@@ -462,11 +462,11 @@ func (a *authService) SigninWithGoogle(ctx context.Context, dto *request.SigninW
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create user account")
}
userId, err := convert.StringToUUID(user.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID format")
}
_, err = uRepoTx.CreateProfile(
ctx,
@@ -483,16 +483,16 @@ func (a *authService) SigninWithGoogle(ctx context.Context, dto *request.SigninW
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create user profile")
}
role, err := a.roleRepo.GetByName(ctx, constants.RoleTypeUser.String())
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Default role not found")
}
roleId, err := convert.StringToUUID(role.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid role ID format")
}
err = rRepoTx.CreateUserRole(
@@ -503,12 +503,12 @@ func (a *authService) SigninWithGoogle(ctx context.Context, dto *request.SigninW
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to assign user role")
}
data, err := a.genToken(user)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to generate security tokens")
}
err = uRepoTx.UpdateRefreshToken(
ctx,
@@ -521,11 +521,11 @@ func (a *authService) SigninWithGoogle(ctx context.Context, dto *request.SigninW
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update refresh token")
}
err = tx.Commit(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to commit Google signin")
}
return data, nil
}
@@ -540,19 +540,19 @@ func (a *authService) GenerateOTP() (string, error) {
return fmt.Sprintf("%06d", otp), nil
}
func (a *authService) CreateToken(ctx context.Context, dto *request.CreateTokenDto) error {
func (a *authService) CreateToken(ctx context.Context, dto *request.CreateTokenDto) *fiber.Error {
ok, err := a.tokenRepo.CheckCooldown(ctx, dto.Email, dto.TokenType)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Internal Server Error")
return fiber.NewError(fiber.StatusInternalServerError, "Failed to check request cooldown")
}
if ok {
return fiber.NewError(fiber.StatusBadRequest, "Too many requests. Please try again later.")
return fiber.NewError(fiber.StatusTooManyRequests, "Too many requests. Please try again later.")
}
user, err := a.userRepo.GetByEmail(ctx, dto.Email)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return fiber.NewError(fiber.StatusInternalServerError, "Internal Server Error")
return fiber.NewError(fiber.StatusInternalServerError, "Failed to check user existence")
}
shouldSend := true
@@ -564,7 +564,7 @@ func (a *authService) CreateToken(ctx context.Context, dto *request.CreateTokenD
if shouldSend {
otp, err := a.GenerateOTP()
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Internal Server Error")
return fiber.NewError(fiber.StatusInternalServerError, "Failed to generate OTP")
}
hash := sha256.Sum256([]byte(otp))
hashString := hex.EncodeToString(hash[:])
@@ -575,7 +575,7 @@ func (a *authService) CreateToken(ctx context.Context, dto *request.CreateTokenD
}
err = a.tokenRepo.Create(ctx, token)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Internal Server Error")
return fiber.NewError(fiber.StatusInternalServerError, "Failed to save verification token")
}
token.Token = otp
@@ -585,7 +585,7 @@ func (a *authService) CreateToken(ctx context.Context, dto *request.CreateTokenD
return nil
}
func (a *authService) VerifyToken(ctx context.Context, dto *request.VerifyTokenDto) (*response.VerifyTokenResponse, error) {
func (a *authService) VerifyToken(ctx context.Context, dto *request.VerifyTokenDto) (*response.VerifyTokenResponse, *fiber.Error) {
genericError := fiber.NewError(fiber.StatusBadRequest, "Invalid or expired token")
token, err := a.tokenRepo.Get(ctx, dto.Email, dto.TokenType)
if err != nil || token == nil {
@@ -607,7 +607,7 @@ func (a *authService) VerifyToken(ctx context.Context, dto *request.VerifyTokenD
user, err := a.userRepo.GetByEmail(ctx, dto.Email)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Internal Server Error")
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to check user existence")
}
if (dto.TokenType == constants.TokenTypeEmailVerify && user != nil) ||
@@ -618,7 +618,7 @@ func (a *authService) VerifyToken(ctx context.Context, dto *request.VerifyTokenD
tokenId := uuid.New().String()
err = a.tokenRepo.CreateVerified(ctx, dto.Email, dto.TokenType, tokenId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Internal Server Error")
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create verified token record")
}
_ = a.tokenRepo.Delete(ctx, dto.Email, dto.TokenType)

View File

@@ -16,9 +16,9 @@ import (
)
type CommitService interface {
CreateCommit(ctx context.Context, userID string, projectID string, dto *request.CreateCommitDto) (*response.CommitResponse, error)
RestoreCommit(ctx context.Context, userID string, projectID string, dto *request.RestoreCommitDto) error
GetProjectCommits(ctx context.Context, projectID string) ([]*response.CommitResponse, error)
CreateCommit(ctx context.Context, userID string, projectID string, dto *request.CreateCommitDto) (*response.CommitResponse, *fiber.Error)
RestoreCommit(ctx context.Context, userID string, projectID string, dto *request.RestoreCommitDto) *fiber.Error
GetProjectCommits(ctx context.Context, projectID string) ([]*response.CommitResponse, *fiber.Error)
}
type commitService struct {
@@ -38,7 +38,8 @@ func NewCommitService(
projectRepo: projectRepo,
}
}
func (s *commitService) checkWritePermission(ctx context.Context, userID string, projectUUID pgtype.UUID) error {
func (s *commitService) checkWritePermission(ctx context.Context, userID string, projectUUID pgtype.UUID) *fiber.Error {
project, err := s.projectRepo.GetByID(ctx, projectUUID)
if err != nil {
return fiber.NewError(fiber.StatusNotFound, "Project not found")
@@ -65,7 +66,7 @@ func (s *commitService) checkWritePermission(ctx context.Context, userID string,
return nil
}
func (s *commitService) CreateCommit(ctx context.Context, userID string, projectID string, dto *request.CreateCommitDto) (*response.CommitResponse, error) {
func (s *commitService) CreateCommit(ctx context.Context, userID string, projectID string, dto *request.CreateCommitDto) (*response.CommitResponse, *fiber.Error) {
tx, err := s.db.Begin(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to start transaction")
@@ -80,8 +81,8 @@ func (s *commitService) CreateCommit(ctx context.Context, userID string, project
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project ID")
}
if err := s.checkWritePermission(ctx, userID, projectUUID); err != nil {
return nil, err
if fErr := s.checkWritePermission(ctx, userID, projectUUID); fErr != nil {
return nil, fErr
}
userUUID, err := convert.StringToUUID(userID)
@@ -101,7 +102,7 @@ func (s *commitService) CreateCommit(ctx context.Context, userID string, project
commitUUID, err := convert.StringToUUID(commit.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid commit ID")
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to process commit ID")
}
err = pRepoTx.UpdateLatestCommit(ctx, sqlc.UpdateLatestCommitParams{
@@ -119,14 +120,14 @@ func (s *commitService) CreateCommit(ctx context.Context, userID string, project
return commit.ToResponse(), nil
}
func (s *commitService) RestoreCommit(ctx context.Context, userID string, projectID string, dto *request.RestoreCommitDto) error {
func (s *commitService) RestoreCommit(ctx context.Context, userID string, projectID string, dto *request.RestoreCommitDto) *fiber.Error {
projectUUID, err := convert.StringToUUID(projectID)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid project ID")
}
if err := s.checkWritePermission(ctx, userID, projectUUID); err != nil {
return err
if fErr := s.checkWritePermission(ctx, userID, projectUUID); fErr != nil {
return fErr
}
commitUUID, err := convert.StringToUUID(dto.CommitID)
@@ -153,7 +154,7 @@ func (s *commitService) RestoreCommit(ctx context.Context, userID string, projec
return nil
}
func (s *commitService) GetProjectCommits(ctx context.Context, projectID string) ([]*response.CommitResponse, error) {
func (s *commitService) GetProjectCommits(ctx context.Context, projectID string) ([]*response.CommitResponse, *fiber.Error) {
projectUUID, err := convert.StringToUUID(projectID)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project ID")

View File

@@ -13,8 +13,8 @@ import (
)
type EntityService interface {
GetEntityByID(ctx context.Context, id string) (*response.EntityResponse, error)
SearchEntities(ctx context.Context, req *request.SearchEntityDto) ([]*response.EntityResponse, error)
GetEntityByID(ctx context.Context, id string) (*response.EntityResponse, *fiber.Error)
SearchEntities(ctx context.Context, req *request.SearchEntityDto) ([]*response.EntityResponse, *fiber.Error)
}
type entityService struct {
@@ -27,10 +27,10 @@ func NewEntityService(entityRepo repositories.EntityRepository) EntityService {
}
}
func (s *entityService) GetEntityByID(ctx context.Context, id string) (*response.EntityResponse, error) {
func (s *entityService) GetEntityByID(ctx context.Context, id string) (*response.EntityResponse, *fiber.Error) {
entityId, err := convert.StringToUUID(id)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid entity ID format")
}
entity, err := s.entityRepo.GetByID(ctx, entityId)
if err != nil {
@@ -40,7 +40,7 @@ func (s *entityService) GetEntityByID(ctx context.Context, id string) (*response
return entity.ToResponse(), nil
}
func (s *entityService) SearchEntities(ctx context.Context, req *request.SearchEntityDto) ([]*response.EntityResponse, error) {
func (s *entityService) SearchEntities(ctx context.Context, req *request.SearchEntityDto) ([]*response.EntityResponse, *fiber.Error) {
limit := int32(25)
if req.Limit > 0 {
limit = int32(req.Limit)
@@ -61,7 +61,7 @@ func (s *entityService) SearchEntities(ctx context.Context, req *request.SearchE
entities, err := s.entityRepo.Search(ctx, params)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to search entities")
}
return models.EntitiesEntityToResponse(entities), nil

View File

@@ -14,8 +14,8 @@ import (
)
type GeometryService interface {
GetGeometryByID(ctx context.Context, id string) (*response.GeometryResponse, error)
SearchGeometries(ctx context.Context, req *request.SearchGeometryDto) ([]*response.GeometryResponse, error)
GetGeometryByID(ctx context.Context, id string) (*response.GeometryResponse, *fiber.Error)
SearchGeometries(ctx context.Context, req *request.SearchGeometryDto) ([]*response.GeometryResponse, *fiber.Error)
}
type geometryService struct {
@@ -28,10 +28,10 @@ func NewGeometryService(geometryRepo repositories.GeometryRepository) GeometrySe
}
}
func (s *geometryService) GetGeometryByID(ctx context.Context, id string) (*response.GeometryResponse, error) {
func (s *geometryService) GetGeometryByID(ctx context.Context, id string) (*response.GeometryResponse, *fiber.Error) {
geometryId, err := convert.StringToUUID(id)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid geometry ID format")
}
geometry, err := s.geometryRepo.GetByID(ctx, geometryId)
if err != nil {
@@ -41,24 +41,24 @@ func (s *geometryService) GetGeometryByID(ctx context.Context, id string) (*resp
return geometry.ToResponse(), nil
}
func (s *geometryService) SearchGeometries(ctx context.Context, req *request.SearchGeometryDto) ([]*response.GeometryResponse, error) {
func (s *geometryService) SearchGeometries(ctx context.Context, req *request.SearchGeometryDto) ([]*response.GeometryResponse, *fiber.Error) {
params := sqlc.SearchGeometriesParams{}
if req.MinLng != nil && req.MinLat != nil && req.MaxLng != nil && req.MaxLat != nil {
if *req.MaxLng < *req.MinLng || *req.MaxLat < *req.MinLat {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid bounding box")
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid bounding box coordinates")
}
params.SearchMinLng = pgtype.Float8{Float64: *req.MinLng, Valid: true}
params.SearchMinLat = pgtype.Float8{Float64: *req.MinLat, Valid: true}
params.SearchMaxLng = pgtype.Float8{Float64: *req.MaxLng, Valid: true}
params.SearchMaxLat = pgtype.Float8{Float64: *req.MaxLat, Valid: true}
} else {
return nil, fiber.NewError(fiber.StatusBadRequest, "Must provid Bounding box!")
return nil, fiber.NewError(fiber.StatusBadRequest, "Bounding box coordinates are required")
}
if req.TimePoint != nil {
if *req.TimePoint < 0 {
return nil, fiber.NewError(fiber.StatusBadRequest, "Time point must be non-negative!")
return nil, fiber.NewError(fiber.StatusBadRequest, "Time point must be non-negative")
}
params.TimePoint = pgtype.Int4{Int32: *req.TimePoint, Valid: true}
}
@@ -72,7 +72,7 @@ func (s *geometryService) SearchGeometries(ctx context.Context, req *request.Sea
geometries, err := s.geometryRepo.Search(ctx, params)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to search geometries")
}
return models.GeometriesEntityToResponse(geometries), nil

View File

@@ -28,14 +28,14 @@ import (
)
type MediaService interface {
GetMediaByID(ctx context.Context, mediaId string) (*response.MediaResponse, error)
GetMediaByUserID(ctx context.Context, userId string) ([]*response.MediaResponse, error)
SearchMedia(ctx context.Context, dto *request.SearchMediaDto) (*response.PaginatedResponse, error)
DeleteMedia(ctx context.Context, claims *response.JWTClaims, mediaId string) error
BulkDeleteMedia(ctx context.Context, claims *response.JWTClaims, dto *request.MediaBulkDeleteDto) error
UploadServerSide(ctx context.Context, userId string, fileHeader *multipart.FileHeader) (*response.MediaResponse, error)
GeneratePresignedURL(ctx context.Context, userId string, dto *request.PreSignedDto) (*response.PreSignedResponse, error)
PreSignedCompleted(ctx context.Context, userId string, dto *request.PreSignedCompleteDto) (*response.MediaResponse, error)
GetMediaByID(ctx context.Context, mediaId string) (*response.MediaResponse, *fiber.Error)
GetMediaByUserID(ctx context.Context, userId string) ([]*response.MediaResponse, *fiber.Error)
SearchMedia(ctx context.Context, dto *request.SearchMediaDto) (*response.PaginatedResponse, *fiber.Error)
DeleteMedia(ctx context.Context, claims *response.JWTClaims, mediaId string) *fiber.Error
BulkDeleteMedia(ctx context.Context, claims *response.JWTClaims, dto *request.MediaBulkDeleteDto) *fiber.Error
UploadServerSide(ctx context.Context, userId string, fileHeader *multipart.FileHeader) (*response.MediaResponse, *fiber.Error)
GeneratePresignedURL(ctx context.Context, userId string, dto *request.PreSignedDto) (*response.PreSignedResponse, *fiber.Error)
PreSignedCompleted(ctx context.Context, userId string, dto *request.PreSignedCompleteDto) (*response.MediaResponse, *fiber.Error)
}
type mediaService struct {
@@ -59,15 +59,15 @@ func NewMediaService(
}
}
func (m *mediaService) DeleteMedia(ctx context.Context, claims *response.JWTClaims, mediaId string) error {
func (m *mediaService) DeleteMedia(ctx context.Context, claims *response.JWTClaims, mediaId string) *fiber.Error {
mediaIdUUID, err := convert.StringToUUID(mediaId)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusBadRequest, "Invalid media ID format")
}
media, err := m.mediaRepo.GetByID(ctx, mediaIdUUID)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusNotFound, "Media not found")
}
shoudDelete := false
@@ -81,7 +81,7 @@ func (m *mediaService) DeleteMedia(ctx context.Context, claims *response.JWTClai
err = m.mediaRepo.Delete(ctx, mediaIdUUID)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to delete media from database")
}
m.c.PublishTask(ctx, constants.StreamStorageName, constants.TaskTypeDeleteMedia, media.ToStorageEntity())
@@ -89,24 +89,24 @@ func (m *mediaService) DeleteMedia(ctx context.Context, claims *response.JWTClai
return nil
}
func (m *mediaService) BulkDeleteMedia(ctx context.Context, claims *response.JWTClaims, dto *request.MediaBulkDeleteDto) error {
func (m *mediaService) BulkDeleteMedia(ctx context.Context, claims *response.JWTClaims, dto *request.MediaBulkDeleteDto) *fiber.Error {
listMedia, err := m.mediaRepo.GetByIDs(ctx, dto.MediaIDs)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch media list")
}
shoudDelete := false
if slices.Contains(claims.Roles, constants.RoleTypeAdmin) || slices.Contains(claims.Roles, constants.RoleTypeMod) {
shoudDelete = true
}
listMediaIds := make([]pgtype.UUID, len(listMedia))
listMediaStorageEntities := make([]*models.MediaStorageEntity, len(listMedia))
listMediaIds := make([]pgtype.UUID, 0)
listMediaStorageEntities := make([]*models.MediaStorageEntity, 0)
for _, media := range listMedia {
if media.UserID != claims.UId && !shoudDelete {
return fiber.NewError(fiber.StatusForbidden, "You don't have permission to delete this media")
return fiber.NewError(fiber.StatusForbidden, "You don't have permission to delete media "+media.ID)
}
id, err := convert.StringToUUID(media.ID)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
continue
}
listMediaIds = append(listMediaIds, id)
listMediaStorageEntities = append(listMediaStorageEntities, media.ToStorageEntity())
@@ -114,7 +114,7 @@ func (m *mediaService) BulkDeleteMedia(ctx context.Context, claims *response.JWT
err = m.mediaRepo.BulkDelete(ctx, listMediaIds)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to bulk delete media from database")
}
m.c.PublishTask(ctx, constants.StreamStorageName, constants.TaskTypeBulkDeleteMedia, listMediaStorageEntities)
@@ -122,26 +122,26 @@ func (m *mediaService) BulkDeleteMedia(ctx context.Context, claims *response.JWT
return nil
}
func (m *mediaService) GetMediaByID(ctx context.Context, id string) (*response.MediaResponse, error) {
func (m *mediaService) GetMediaByID(ctx context.Context, id string) (*response.MediaResponse, *fiber.Error) {
mediaId, err := convert.StringToUUID(id)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid media ID format")
}
media, err := m.mediaRepo.GetByID(ctx, mediaId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusNotFound, "Media not found")
}
return media.ToResponse(), nil
}
func (m *mediaService) GetMediaByUserID(ctx context.Context, id string) ([]*response.MediaResponse, error) {
func (m *mediaService) GetMediaByUserID(ctx context.Context, id string) ([]*response.MediaResponse, *fiber.Error) {
userId, err := convert.StringToUUID(id)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid user ID format")
}
medias, err := m.mediaRepo.GetByUserID(ctx, userId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch user media")
}
return models.MediaEntitiesToResponse(medias), nil
}
@@ -183,7 +183,7 @@ func (m *mediaService) fillSearchArgs(arg *sqlc.SearchMediasParams, dto *request
}
}
func (m *mediaService) SearchMedia(ctx context.Context, dto *request.SearchMediaDto) (*response.PaginatedResponse, error) {
func (m *mediaService) SearchMedia(ctx context.Context, dto *request.SearchMediaDto) (*response.PaginatedResponse, *fiber.Error) {
if dto.Page < 1 {
dto.Page = 1
}
@@ -224,17 +224,17 @@ func (m *mediaService) SearchMedia(ctx context.Context, dto *request.SearchMedia
})
if err := g.Wait(); err != nil {
return nil, err
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to search media")
}
media := models.MediaEntitiesToResponse(rows)
return response.BuildPaginatedResponse(media, totalRecords, dto.Page, dto.Limit), nil
}
func (m *mediaService) UploadServerSide(ctx context.Context, userId string, fileHeader *multipart.FileHeader) (*response.MediaResponse, error) {
func (m *mediaService) UploadServerSide(ctx context.Context, userId string, fileHeader *multipart.FileHeader) (*response.MediaResponse, *fiber.Error) {
userIdUUID, err := convert.StringToUUID(userId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid user ID format")
}
file, err := fileHeader.Open()
if err != nil {
@@ -279,7 +279,7 @@ func (m *mediaService) UploadServerSide(ctx context.Context, userId string, file
})
if err != nil {
log.Err(err).Msg("Failed to upload file to storage")
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to upload file")
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to upload file to storage")
}
media, err := m.mediaRepo.Create(ctx, sqlc.CreateMediaParams{
@@ -291,12 +291,12 @@ func (m *mediaService) UploadServerSide(ctx context.Context, userId string, file
FileMetadata: mdByte,
})
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create media record")
}
return media.ToResponse(), nil
}
func (m *mediaService) GeneratePresignedURL(ctx context.Context, userId string, dto *request.PreSignedDto) (*response.PreSignedResponse, error) {
func (m *mediaService) GeneratePresignedURL(ctx context.Context, userId string, dto *request.PreSignedDto) (*response.PreSignedResponse, *fiber.Error) {
fileExt := filepath.Ext(dto.FileName)
mid, err := uuid.NewV7()
if err != nil {
@@ -346,7 +346,7 @@ func (m *mediaService) GeneratePresignedURL(ctx context.Context, userId string,
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Internal Server Error")
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create upload token")
}
return &response.PreSignedResponse{
@@ -360,7 +360,7 @@ func (m *mediaService) GeneratePresignedURL(ctx context.Context, userId string,
}, nil
}
func (m *mediaService) PreSignedCompleted(ctx context.Context, userId string, dto *request.PreSignedCompleteDto) (*response.MediaResponse, error) {
func (m *mediaService) PreSignedCompleted(ctx context.Context, userId string, dto *request.PreSignedCompleteDto) (*response.MediaResponse, *fiber.Error) {
token, err := m.tokenRepo.GetUploadToken(ctx, userId, dto.TokenID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to get upload token")
@@ -370,7 +370,7 @@ func (m *mediaService) PreSignedCompleted(ctx context.Context, userId string, dt
}
userIdUUID, err := convert.StringToUUID(userId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid user ID format")
}
err = m.s.Move(
@@ -386,7 +386,7 @@ func (m *mediaService) PreSignedCompleted(ctx context.Context, userId string, dt
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to move file to main storage")
}
media, err := m.mediaRepo.Create(ctx, sqlc.CreateMediaParams{

View File

@@ -17,16 +17,16 @@ import (
)
type ProjectService interface {
GetProjectByID(ctx context.Context, id string) (*response.ProjectResponse, error)
GetProjectByUserID(ctx context.Context, userID string, dto *request.GetProjectsByUserDto) ([]*response.ProjectResponse, error)
SearchProject(ctx context.Context, dto *request.SearchProjectDto) (*response.PaginatedResponse, error)
DeleteProject(ctx context.Context, id string) error
CreateProject(ctx context.Context, userID string, dto *request.CreateProjectDto) (*response.ProjectResponse, error)
UpdateProject(ctx context.Context, id string, dto *request.UpdateProjectDto) (*response.ProjectResponse, error)
AddMember(ctx context.Context, callerID string, projectID string, dto *request.AddProjectMemberDto) (*response.ProjectResponse, error)
UpdateMemberRole(ctx context.Context, callerID string, projectID string, memberUserID string, dto *request.UpdateProjectMemberDto) (*response.ProjectResponse, error)
RemoveMember(ctx context.Context, callerID string, projectID string, memberUserID string) error
ChangeOwner(ctx context.Context, callerID string, projectID string, newOwnerID string) (*response.ProjectResponse, error)
GetProjectByID(ctx context.Context, id string) (*response.ProjectResponse, *fiber.Error)
GetProjectByUserID(ctx context.Context, userID string, dto *request.GetProjectsByUserDto) ([]*response.ProjectResponse, *fiber.Error)
SearchProject(ctx context.Context, dto *request.SearchProjectDto) (*response.PaginatedResponse, *fiber.Error)
DeleteProject(ctx context.Context, id string) *fiber.Error
CreateProject(ctx context.Context, userID string, dto *request.CreateProjectDto) (*response.ProjectResponse, *fiber.Error)
UpdateProject(ctx context.Context, id string, dto *request.UpdateProjectDto) (*response.ProjectResponse, *fiber.Error)
AddMember(ctx context.Context, callerID string, projectID string, dto *request.AddProjectMemberDto) (*response.ProjectResponse, *fiber.Error)
UpdateMemberRole(ctx context.Context, callerID string, projectID string, memberUserID string, dto *request.UpdateProjectMemberDto) (*response.ProjectResponse, *fiber.Error)
RemoveMember(ctx context.Context, callerID string, projectID string, memberUserID string) *fiber.Error
ChangeOwner(ctx context.Context, callerID string, projectID string, newOwnerID string) (*response.ProjectResponse, *fiber.Error)
}
type projectService struct {
@@ -39,7 +39,7 @@ func NewProjectService(projectRepo repositories.ProjectRepository) ProjectServic
}
}
func (s *projectService) checkCallerIsOwner(ctx context.Context, callerID string, projectUUID pgtype.UUID) error {
func (s *projectService) checkCallerIsOwner(ctx context.Context, callerID string, projectUUID pgtype.UUID) *fiber.Error {
project, err := s.projectRepo.GetByID(ctx, projectUUID)
if err != nil {
return fiber.NewError(fiber.StatusNotFound, "Project not found")
@@ -58,7 +58,7 @@ func (s *projectService) checkCallerIsOwner(ctx context.Context, callerID string
return nil
}
func (s *projectService) GetProjectByID(ctx context.Context, id string) (*response.ProjectResponse, error) {
func (s *projectService) GetProjectByID(ctx context.Context, id string) (*response.ProjectResponse, *fiber.Error) {
projectUUID, err := convert.StringToUUID(id)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project ID format")
@@ -72,7 +72,7 @@ func (s *projectService) GetProjectByID(ctx context.Context, id string) (*respon
return project.ToResponse(), nil
}
func (s *projectService) GetProjectByUserID(ctx context.Context, userID string, dto *request.GetProjectsByUserDto) ([]*response.ProjectResponse, error) {
func (s *projectService) GetProjectByUserID(ctx context.Context, userID string, dto *request.GetProjectsByUserDto) ([]*response.ProjectResponse, *fiber.Error) {
userUUID, err := convert.StringToUUID(userID)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid user ID format")
@@ -96,7 +96,7 @@ func (s *projectService) GetProjectByUserID(ctx context.Context, userID string,
projects, err := s.projectRepo.GetByUserID(ctx, arg)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch user projects")
}
return models.ProjectsEntityToResponse(projects), nil
@@ -143,7 +143,7 @@ func (s *projectService) fillSearchArgs(arg *sqlc.SearchProjectsParams, dto *req
}
}
func (s *projectService) SearchProject(ctx context.Context, dto *request.SearchProjectDto) (*response.PaginatedResponse, error) {
func (s *projectService) SearchProject(ctx context.Context, dto *request.SearchProjectDto) (*response.PaginatedResponse, *fiber.Error) {
if dto.Page < 1 {
dto.Page = 1
}
@@ -184,7 +184,7 @@ func (s *projectService) SearchProject(ctx context.Context, dto *request.SearchP
})
if err := g.Wait(); err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to search projects")
}
projects := models.ProjectsEntityToResponse(rows)
@@ -192,7 +192,7 @@ func (s *projectService) SearchProject(ctx context.Context, dto *request.SearchP
return response.BuildPaginatedResponse(projects, totalRecords, dto.Page, dto.Limit), nil
}
func (s *projectService) CreateProject(ctx context.Context, userID string, dto *request.CreateProjectDto) (*response.ProjectResponse, error) {
func (s *projectService) CreateProject(ctx context.Context, userID string, dto *request.CreateProjectDto) (*response.ProjectResponse, *fiber.Error) {
userUUID, err := convert.StringToUUID(userID)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid user ID format")
@@ -221,7 +221,7 @@ func (s *projectService) CreateProject(ctx context.Context, userID string, dto *
return project.ToResponse(), nil
}
func (s *projectService) UpdateProject(ctx context.Context, id string, dto *request.UpdateProjectDto) (*response.ProjectResponse, error) {
func (s *projectService) UpdateProject(ctx context.Context, id string, dto *request.UpdateProjectDto) (*response.ProjectResponse, *fiber.Error) {
projectUUID, err := convert.StringToUUID(id)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project ID format")
@@ -254,7 +254,7 @@ func (s *projectService) UpdateProject(ctx context.Context, id string, dto *requ
return project.ToResponse(), nil
}
func (s *projectService) DeleteProject(ctx context.Context, id string) error {
func (s *projectService) DeleteProject(ctx context.Context, id string) *fiber.Error {
projectUUID, err := convert.StringToUUID(id)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid project ID format")
@@ -273,14 +273,14 @@ func (s *projectService) DeleteProject(ctx context.Context, id string) error {
return nil
}
func (s *projectService) AddMember(ctx context.Context, callerID string, projectID string, dto *request.AddProjectMemberDto) (*response.ProjectResponse, error) {
func (s *projectService) AddMember(ctx context.Context, callerID string, projectID string, dto *request.AddProjectMemberDto) (*response.ProjectResponse, *fiber.Error) {
projectUUID, err := convert.StringToUUID(projectID)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project ID format")
}
if err := s.checkCallerIsOwner(ctx, callerID, projectUUID); err != nil {
return nil, err
if fErr := s.checkCallerIsOwner(ctx, callerID, projectUUID); fErr != nil {
return nil, fErr
}
memberUUID, err := convert.StringToUUID(dto.UserID)
@@ -314,14 +314,14 @@ func (s *projectService) AddMember(ctx context.Context, callerID string, project
return project.ToResponse(), nil
}
func (s *projectService) UpdateMemberRole(ctx context.Context, callerID string, projectID string, memberUserID string, dto *request.UpdateProjectMemberDto) (*response.ProjectResponse, error) {
func (s *projectService) UpdateMemberRole(ctx context.Context, callerID string, projectID string, memberUserID string, dto *request.UpdateProjectMemberDto) (*response.ProjectResponse, *fiber.Error) {
projectUUID, err := convert.StringToUUID(projectID)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project ID format")
}
if err := s.checkCallerIsOwner(ctx, callerID, projectUUID); err != nil {
return nil, err
if fErr := s.checkCallerIsOwner(ctx, callerID, projectUUID); fErr != nil {
return nil, fErr
}
memberUUID, err := convert.StringToUUID(memberUserID)
@@ -348,14 +348,14 @@ func (s *projectService) UpdateMemberRole(ctx context.Context, callerID string,
return project.ToResponse(), nil
}
func (s *projectService) RemoveMember(ctx context.Context, callerID string, projectID string, memberUserID string) error {
func (s *projectService) RemoveMember(ctx context.Context, callerID string, projectID string, memberUserID string) *fiber.Error {
projectUUID, err := convert.StringToUUID(projectID)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid project ID format")
}
if err := s.checkCallerIsOwner(ctx, callerID, projectUUID); err != nil {
return err
if fErr := s.checkCallerIsOwner(ctx, callerID, projectUUID); fErr != nil {
return fErr
}
memberUUID, err := convert.StringToUUID(memberUserID)
@@ -378,14 +378,14 @@ func (s *projectService) RemoveMember(ctx context.Context, callerID string, proj
return nil
}
func (s *projectService) ChangeOwner(ctx context.Context, callerID string, projectID string, newOwnerID string) (*response.ProjectResponse, error) {
func (s *projectService) ChangeOwner(ctx context.Context, callerID string, projectID string, newOwnerID string) (*response.ProjectResponse, *fiber.Error) {
projectUUID, err := convert.StringToUUID(projectID)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project ID format")
}
if err := s.checkCallerIsOwner(ctx, callerID, projectUUID); err != nil {
return nil, err
if fErr := s.checkCallerIsOwner(ctx, callerID, projectUUID); fErr != nil {
return nil, fErr
}
if callerID == newOwnerID {

View File

@@ -8,8 +8,8 @@ import (
)
type RasterTileService interface {
GetMetadata(ctx context.Context) (map[string]string, error)
GetTile(ctx context.Context, z, x, y int) ([]byte, map[string]string, error)
GetMetadata(ctx context.Context) (map[string]string, *fiber.Error)
GetTile(ctx context.Context, z, x, y int) ([]byte, map[string]string, *fiber.Error)
}
type rasterTileService struct {
@@ -24,21 +24,21 @@ func NewRasterTileService(
}
}
func (t *rasterTileService) GetMetadata(ctx context.Context) (map[string]string, error) {
func (t *rasterTileService) GetMetadata(ctx context.Context) (map[string]string, *fiber.Error) {
metaData, err := t.tileRepo.GetMetadata(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch map metadata")
}
return metaData, nil
}
func (t *rasterTileService) GetTile(ctx context.Context, z, x, y int) ([]byte, map[string]string, error) {
func (t *rasterTileService) GetTile(ctx context.Context, z, x, y int) ([]byte, map[string]string, *fiber.Error) {
contentType := make(map[string]string)
data, format, err := t.tileRepo.GetTile(ctx, z, x, y)
if err != nil {
return nil, contentType, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, contentType, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch tile data")
}
switch format {

View File

@@ -11,8 +11,8 @@ import (
)
type RoleService interface {
GetRoleByID(ctx context.Context, id string) (*response.RoleResponse, error)
GetAllRole(ctx context.Context) ([]*response.RoleResponse, error)
GetRoleByID(ctx context.Context, id string) (*response.RoleResponse, *fiber.Error)
GetAllRole(ctx context.Context) ([]*response.RoleResponse, *fiber.Error)
}
type roleService struct {
@@ -27,19 +27,19 @@ func NewRoleService(
}
}
func (r *roleService) GetAllRole(ctx context.Context) ([]*response.RoleResponse, error) {
func (r *roleService) GetAllRole(ctx context.Context) ([]*response.RoleResponse, *fiber.Error) {
roles, err := r.roleRepo.All(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch roles")
}
return models.RolesEntityToResponse(roles), nil
}
func (r *roleService) GetRoleByID(ctx context.Context, id string) (*response.RoleResponse, error) {
func (r *roleService) GetRoleByID(ctx context.Context, id string) (*response.RoleResponse, *fiber.Error) {
roleId, err := convert.StringToUUID(id)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid role ID format")
}
role, err := r.roleRepo.GetByID(ctx, roleId)
if err != nil {

View File

@@ -20,11 +20,11 @@ import (
)
type SubmissionService interface {
CreateSubmission(ctx context.Context, userID string, dto *request.CreateSubmissionDto) (*response.SubmissionResponse, error)
UpdateSubmissionStatus(ctx context.Context, reviewerID string, submissionID string, dto *request.UpdateSubmissionStatusDto) (*response.SubmissionResponse, error)
GetSubmissionByID(ctx context.Context, id string) (*response.SubmissionResponse, error)
SearchSubmissions(ctx context.Context, dto *request.SearchSubmissionDto) (*response.PaginatedResponse, error)
DeleteSubmission(ctx context.Context, userID string, id string, claims *response.JWTClaims) error
CreateSubmission(ctx context.Context, userID string, dto *request.CreateSubmissionDto) (*response.SubmissionResponse, *fiber.Error)
UpdateSubmissionStatus(ctx context.Context, reviewerID string, submissionID string, dto *request.UpdateSubmissionStatusDto) (*response.SubmissionResponse, *fiber.Error)
GetSubmissionByID(ctx context.Context, id string) (*response.SubmissionResponse, *fiber.Error)
SearchSubmissions(ctx context.Context, dto *request.SearchSubmissionDto) (*response.PaginatedResponse, *fiber.Error)
DeleteSubmission(ctx context.Context, userID string, id string, claims *response.JWTClaims) *fiber.Error
}
type submissionService struct {
@@ -54,7 +54,7 @@ func NewSubmissionService(
}
}
func (s *submissionService) CreateSubmission(ctx context.Context, userID string, dto *request.CreateSubmissionDto) (*response.SubmissionResponse, error) {
func (s *submissionService) CreateSubmission(ctx context.Context, userID string, dto *request.CreateSubmissionDto) (*response.SubmissionResponse, *fiber.Error) {
projectUUID, err := convert.StringToUUID(dto.ProjectID)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project ID")
@@ -94,7 +94,7 @@ func (s *submissionService) CreateSubmission(ctx context.Context, userID string,
return submission.ToResponse(), nil
}
func (s *submissionService) UpdateSubmissionStatus(ctx context.Context, reviewerID string, submissionID string, dto *request.UpdateSubmissionStatusDto) (*response.SubmissionResponse, error) {
func (s *submissionService) UpdateSubmissionStatus(ctx context.Context, reviewerID string, submissionID string, dto *request.UpdateSubmissionStatusDto) (*response.SubmissionResponse, *fiber.Error) {
submissionUUID, err := convert.StringToUUID(submissionID)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid submission ID")
@@ -110,7 +110,6 @@ func (s *submissionService) UpdateSubmissionStatus(ctx context.Context, reviewer
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid status")
}
submission, err := s.submissionRepo.GetByID(ctx, submissionUUID)
if err != nil {
return nil, fiber.NewError(fiber.StatusNotFound, "Submission not found")
@@ -132,8 +131,7 @@ func (s *submissionService) UpdateSubmissionStatus(ctx context.Context, reviewer
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update submission status")
}
_ = s.c.Del(ctx, fmt.Sprintf("proejct:id:%s", submission.ProjectID))
_ = s.c.Del(ctx, fmt.Sprintf("project:id:%s", submission.ProjectID))
return updatedSubmission.ToResponse(), nil
}
@@ -185,7 +183,7 @@ func (m *submissionService) fillSearchArgs(arg *sqlc.SearchSubmissionsParams, dt
}
}
func (s *submissionService) GetSubmissionByID(ctx context.Context, id string) (*response.SubmissionResponse, error) {
func (s *submissionService) GetSubmissionByID(ctx context.Context, id string) (*response.SubmissionResponse, *fiber.Error) {
submissionUUID, err := convert.StringToUUID(id)
if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid submission ID")
@@ -199,7 +197,7 @@ func (s *submissionService) GetSubmissionByID(ctx context.Context, id string) (*
return submission.ToResponse(), nil
}
func (s *submissionService) SearchSubmissions(ctx context.Context, dto *request.SearchSubmissionDto) (*response.PaginatedResponse, error) {
func (s *submissionService) SearchSubmissions(ctx context.Context, dto *request.SearchSubmissionDto) (*response.PaginatedResponse, *fiber.Error) {
if dto.Page < 1 {
dto.Page = 1
}
@@ -241,7 +239,7 @@ func (s *submissionService) SearchSubmissions(ctx context.Context, dto *request.
})
if err := g.Wait(); err != nil {
return nil, err
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to search submissions")
}
submissions := models.SubmissionsEntityToResponse(rows)
@@ -249,7 +247,7 @@ func (s *submissionService) SearchSubmissions(ctx context.Context, dto *request.
return response.BuildPaginatedResponse(submissions, totalRecords, dto.Page, dto.Limit), nil
}
func (s *submissionService) DeleteSubmission(ctx context.Context, userID string, id string, claims *response.JWTClaims) error {
func (s *submissionService) DeleteSubmission(ctx context.Context, userID string, id string, claims *response.JWTClaims) *fiber.Error {
submissionUUID, err := convert.StringToUUID(id)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid submission ID")

View File

@@ -8,8 +8,8 @@ import (
)
type TileService interface {
GetMetadata(ctx context.Context) (map[string]string, error)
GetTile(ctx context.Context, z, x, y int) ([]byte, map[string]string, error)
GetMetadata(ctx context.Context) (map[string]string, *fiber.Error)
GetTile(ctx context.Context, z, x, y int) ([]byte, map[string]string, *fiber.Error)
}
type tileService struct {
@@ -24,21 +24,21 @@ func NewTileService(
}
}
func (t *tileService) GetMetadata(ctx context.Context) (map[string]string, error) {
func (t *tileService) GetMetadata(ctx context.Context) (map[string]string, *fiber.Error) {
metaData, err := t.tileRepo.GetMetadata(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch map metadata")
}
return metaData, nil
}
func (t *tileService) GetTile(ctx context.Context, z, x, y int) ([]byte, map[string]string, error) {
func (t *tileService) GetTile(ctx context.Context, z, x, y int) ([]byte, map[string]string, *fiber.Error) {
contentType := make(map[string]string)
data, format, isPBF, err := t.tileRepo.GetTile(ctx, z, x, y)
if err != nil {
return nil, contentType, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, contentType, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch tile data")
}
switch format {
case "pbf":

View File

@@ -2,6 +2,8 @@ package services
import (
"context"
"database/sql"
"errors"
"fmt"
"history-api/internal/dtos/request"
"history-api/internal/dtos/response"
@@ -22,15 +24,16 @@ import (
type UserService interface {
//user
UpdateProfile(ctx context.Context, userId string, dto *request.UpdateProfileDto) (*response.UserResponse, error)
ChangePassword(ctx context.Context, userId string, dto *request.ChangePasswordDto) error
UpdateProfile(ctx context.Context, userId string, dto *request.UpdateProfileDto) (*response.UserResponse, *fiber.Error)
ChangePassword(ctx context.Context, userId string, dto *request.ChangePasswordDto) *fiber.Error
//admin
DeleteUser(ctx context.Context, userId string) error
ChangeRoleUser(ctx context.Context, userId string, claims *response.JWTClaims, dto *request.ChangeRoleDto) (*response.UserResponse, error)
RestoreUser(ctx context.Context, userId string) (*response.UserResponse, error)
GetUserByID(ctx context.Context, userId string) (*response.UserResponse, error)
SearchUser(ctx context.Context, dto *request.SearchUserDto) (*response.PaginatedResponse, error)
CreateUser(ctx context.Context, dto *request.CreateUserDto) (*response.UserResponse, *fiber.Error)
DeleteUser(ctx context.Context, userId string) *fiber.Error
ChangeRoleUser(ctx context.Context, userId string, claims *response.JWTClaims, dto *request.ChangeRoleDto) (*response.UserResponse, *fiber.Error)
RestoreUser(ctx context.Context, userId string) (*response.UserResponse, *fiber.Error)
GetUserByID(ctx context.Context, userId string) (*response.UserResponse, *fiber.Error)
SearchUser(ctx context.Context, dto *request.SearchUserDto) (*response.PaginatedResponse, *fiber.Error)
}
type userService struct {
@@ -45,7 +48,6 @@ func NewUserService(
roleRepo repositories.RoleRepository,
c cache.Cache,
db *pgxpool.Pool,
) UserService {
return &userService{
userRepo: userRepo,
@@ -55,7 +57,80 @@ func NewUserService(
}
}
func (u *userService) ChangePassword(ctx context.Context, userId string, dto *request.ChangePasswordDto) error {
func (u *userService) CreateUser(ctx context.Context, dto *request.CreateUserDto) (*response.UserResponse, *fiber.Error) {
tx, err := u.db.Begin(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to start transaction")
}
defer tx.Rollback(ctx)
uRepo := u.userRepo.WithTx(tx)
rRepo := u.roleRepo.WithTx(tx)
existingUser, err := u.userRepo.GetByEmail(ctx, dto.Email)
if err != nil && !errors.Is(err, sql.ErrNoRows) {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to check existing user")
}
if existingUser != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "User already exists")
}
hashed, err := bcrypt.GenerateFromPassword([]byte(dto.Password), bcrypt.DefaultCost)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to hash password")
}
user, err := uRepo.UpsertUser(ctx, sqlc.UpsertUserParams{
Email: dto.Email,
PasswordHash: pgtype.Text{String: string(hashed), Valid: true},
AuthProvider: constants.ProviderTypeLocal.String(),
})
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create user")
}
userUUID, err := convert.StringToUUID(user.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID")
}
_, err = uRepo.CreateProfile(ctx, sqlc.CreateUserProfileParams{
UserID: userUUID,
DisplayName: pgtype.Text{String: dto.DisplayName, Valid: true},
})
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create user profile")
}
var roleIdList []pgtype.UUID
for _, rId := range dto.Roles {
rid, err := convert.StringToUUID(rId)
if err == nil {
roleIdList = append(roleIdList, rid)
}
}
err = rRepo.CreateUserRole(ctx, sqlc.CreateUserRoleParams{
UserID: userUUID,
Column2: roleIdList,
})
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to assign roles")
}
if err := tx.Commit(ctx); err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to commit transaction")
}
finalUser, err := u.userRepo.GetByID(ctx, userUUID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch created user")
}
return finalUser.ToResponse(), nil
}
func (u *userService) ChangePassword(ctx context.Context, userId string, dto *request.ChangePasswordDto) *fiber.Error {
tx, err := u.db.Begin(ctx)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, "Failed to start transaction")
@@ -66,11 +141,11 @@ func (u *userService) ChangePassword(ctx context.Context, userId string, dto *re
pgID, err := convert.StringToUUID(userId)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID")
}
user, err := u.userRepo.GetByID(ctx, pgID)
if err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error())
return fiber.NewError(fiber.StatusNotFound, "Failed to fetch user")
}
if user == nil {
return fiber.NewError(fiber.StatusNotFound, "User not found")
@@ -81,15 +156,15 @@ func (u *userService) ChangePassword(ctx context.Context, userId string, dto *re
return fiber.NewError(fiber.StatusBadRequest, "Old password required")
}
if err := bcrypt.CompareHashAndPassword([]byte(user.PasswordHash), []byte(dto.OldPassword)); err != nil {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid password!")
return fiber.NewError(fiber.StatusUnauthorized, "Invalid old password")
}
} else if user.PasswordHash == "" && dto.OldPassword != "" {
return fiber.NewError(fiber.StatusBadRequest, "Invalid request")
return fiber.NewError(fiber.StatusBadRequest, "Invalid request: user has no password")
}
hashPassword, err := bcrypt.GenerateFromPassword([]byte(dto.NewPassword), bcrypt.DefaultCost)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to hash new password")
}
err = uRepo.UpdatePassword(ctx, sqlc.UpdateUserPasswordParams{
@@ -97,7 +172,7 @@ func (u *userService) ChangePassword(ctx context.Context, userId string, dto *re
PasswordHash: pgtype.Text{String: string(hashPassword), Valid: true},
})
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update password")
}
err = uRepo.UpdateTokenVersion(ctx, sqlc.UpdateTokenVersionParams{
@@ -105,7 +180,7 @@ func (u *userService) ChangePassword(ctx context.Context, userId string, dto *re
TokenVersion: user.TokenVersion + 1,
})
if err != nil {
return err
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update token version")
}
if err := tx.Commit(ctx); err != nil {
@@ -114,7 +189,7 @@ func (u *userService) ChangePassword(ctx context.Context, userId string, dto *re
return nil
}
func (u *userService) ChangeRoleUser(ctx context.Context, userId string, claims *response.JWTClaims, dto *request.ChangeRoleDto) (*response.UserResponse, error) {
func (u *userService) ChangeRoleUser(ctx context.Context, userId string, claims *response.JWTClaims, dto *request.ChangeRoleDto) (*response.UserResponse, *fiber.Error) {
tx, err := u.db.Begin(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to start transaction")
@@ -126,12 +201,12 @@ func (u *userService) ChangeRoleUser(ctx context.Context, userId string, claims
userUUID, err := convert.StringToUUID(userId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID")
}
user, err := u.userRepo.GetByID(ctx, userUUID)
if err != nil {
return nil, fiber.NewError(fiber.StatusNotFound, err.Error())
return nil, fiber.NewError(fiber.StatusNotFound, "Failed to fetch user")
}
if user == nil {
return nil, fiber.NewError(fiber.StatusNotFound, "User not found")
@@ -139,7 +214,7 @@ func (u *userService) ChangeRoleUser(ctx context.Context, userId string, claims
newListRole, err := u.roleRepo.GetByIDs(ctx, dto.Roles)
if err != nil {
return nil, err
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch roles")
}
hasUserRole := false
@@ -163,20 +238,20 @@ func (u *userService) ChangeRoleUser(ctx context.Context, userId string, claims
}
if !hasUserRole {
return nil, fiber.NewError(fiber.StatusNotFound, "User must have the USER role")
return nil, fiber.NewError(fiber.StatusForbidden, "User must have the USER role")
}
if slices.Contains(claims.Roles, constants.RoleTypeMod) && !slices.Contains(claims.Roles, constants.RoleTypeAdmin) {
if hasAdminRole {
return nil, fiber.NewError(fiber.StatusForbidden, "MOD cannot assign ADMIN role to any user")
return nil, fiber.NewError(fiber.StatusForbidden, "MOD cannot assign ADMIN role")
}
if userId == claims.UId && !hasModRole {
return nil, fiber.NewError(fiber.StatusForbidden, "You can't remove MOD role of yourself")
return nil, fiber.NewError(fiber.StatusForbidden, "You cannot remove your own MOD role")
}
if userId == claims.UId && hasBannedRole {
return nil, fiber.NewError(fiber.StatusForbidden, "You can't assign BANNED role to yourself")
return nil, fiber.NewError(fiber.StatusForbidden, "You cannot ban yourself")
}
isTargetAdminOrMod := false
for _, r := range user.Roles {
@@ -186,17 +261,17 @@ func (u *userService) ChangeRoleUser(ctx context.Context, userId string, claims
}
}
if isTargetAdminOrMod && hasBannedRole {
return nil, fiber.NewError(fiber.StatusForbidden, "MOD cannot assign BANNED role to an ADMIN or MOD user")
return nil, fiber.NewError(fiber.StatusForbidden, "MOD cannot ban an ADMIN or MOD")
}
}
if slices.Contains(claims.Roles, constants.RoleTypeAdmin) {
if userId == claims.UId && hasBannedRole {
return nil, fiber.NewError(fiber.StatusForbidden, "You can't assign BANNED role to yourself")
return nil, fiber.NewError(fiber.StatusForbidden, "You cannot ban yourself")
}
if userId == claims.UId && !hasAdminRole {
return nil, fiber.NewError(fiber.StatusForbidden, "You can't remove ADMIN role of yourself")
return nil, fiber.NewError(fiber.StatusForbidden, "You cannot remove your own ADMIN role")
}
}
@@ -213,7 +288,7 @@ func (u *userService) ChangeRoleUser(ctx context.Context, userId string, claims
err = rRepo.BulkDeleteRolesFromUser(ctx, userUUID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to clear old roles")
}
err = rRepo.CreateUserRole(ctx, sqlc.CreateUserRoleParams{
@@ -221,7 +296,7 @@ func (u *userService) ChangeRoleUser(ctx context.Context, userId string, claims
Column2: roleIdList,
})
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create new roles")
}
err = uRepo.UpdateTokenVersion(ctx, sqlc.UpdateTokenVersionParams{
@@ -229,13 +304,13 @@ func (u *userService) ChangeRoleUser(ctx context.Context, userId string, claims
TokenVersion: user.TokenVersion + 1,
})
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update token version")
}
user.TokenVersion += 1
err = tx.Commit(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to commit transaction")
}
mapCache := map[string]any{
@@ -247,33 +322,33 @@ func (u *userService) ChangeRoleUser(ctx context.Context, userId string, claims
return user.ToResponse(), nil
}
func (u *userService) DeleteUser(ctx context.Context, userId string) error {
func (u *userService) DeleteUser(ctx context.Context, userId string) *fiber.Error {
pgID, err := convert.StringToUUID(userId)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID")
}
user, err := u.userRepo.GetByID(ctx, pgID)
if err != nil {
return fiber.NewError(fiber.StatusNotFound, err.Error())
return fiber.NewError(fiber.StatusNotFound, "Failed to fetch user")
}
if user == nil {
return fiber.NewError(fiber.StatusNotFound, "User not found")
}
err = u.userRepo.Delete(ctx, pgID)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to delete user")
}
return nil
}
func (u *userService) UpdateProfile(ctx context.Context, userId string, dto *request.UpdateProfileDto) (*response.UserResponse, error) {
func (u *userService) UpdateProfile(ctx context.Context, userId string, dto *request.UpdateProfileDto) (*response.UserResponse, *fiber.Error) {
pgID, err := convert.StringToUUID(userId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID")
}
user, err := u.userRepo.GetByID(ctx, pgID)
if err != nil {
return nil, fiber.NewError(fiber.StatusNotFound, err.Error())
return nil, fiber.NewError(fiber.StatusNotFound, "Failed to fetch user")
}
if user == nil {
return nil, fiber.NewError(fiber.StatusNotFound, "User not found")
@@ -294,20 +369,20 @@ func (u *userService) UpdateProfile(ctx context.Context, userId string, dto *req
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update profile")
}
return newUser.ToResponse(), nil
}
func (u *userService) RestoreUser(ctx context.Context, userId string) (*response.UserResponse, error) {
func (u *userService) RestoreUser(ctx context.Context, userId string) (*response.UserResponse, *fiber.Error) {
pgID, err := convert.StringToUUID(userId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID")
}
user, err := u.userRepo.GetByIDWithoutDeleted(ctx, pgID)
if err != nil {
return nil, fiber.NewError(fiber.StatusNotFound, err.Error())
return nil, fiber.NewError(fiber.StatusNotFound, "Failed to fetch user")
}
if user == nil {
return nil, fiber.NewError(fiber.StatusNotFound, "User not found")
@@ -315,7 +390,7 @@ func (u *userService) RestoreUser(ctx context.Context, userId string) (*response
err = u.userRepo.Restore(ctx, pgID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to restore user")
}
user.IsDeleted = false
return user.ToResponse(), nil
@@ -362,7 +437,7 @@ func (m *userService) fillSearchArgs(arg *sqlc.SearchUsersParams, dto *request.S
}
}
func (u *userService) SearchUser(ctx context.Context, dto *request.SearchUserDto) (*response.PaginatedResponse, error) {
func (u *userService) SearchUser(ctx context.Context, dto *request.SearchUserDto) (*response.PaginatedResponse, *fiber.Error) {
if dto.Page < 1 {
dto.Page = 1
}
@@ -404,7 +479,7 @@ func (u *userService) SearchUser(ctx context.Context, dto *request.SearchUserDto
})
if err := g.Wait(); err != nil {
return nil, err
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to search users")
}
users := models.UsersEntityToResponse(rows)
@@ -412,14 +487,17 @@ func (u *userService) SearchUser(ctx context.Context, dto *request.SearchUserDto
return response.BuildPaginatedResponse(users, totalRecords, dto.Page, dto.Limit), nil
}
func (u *userService) GetUserByID(ctx context.Context, userId string) (*response.UserResponse, error) {
func (u *userService) GetUserByID(ctx context.Context, userId string) (*response.UserResponse, *fiber.Error) {
pgID, err := convert.StringToUUID(userId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID")
}
user, err := u.userRepo.GetByID(ctx, pgID)
if err != nil {
return nil, fiber.NewError(fiber.StatusNotFound, err.Error())
return nil, fiber.NewError(fiber.StatusNotFound, "Failed to fetch user")
}
if user == nil {
return nil, fiber.NewError(fiber.StatusNotFound, "User not found")
}
return user.ToResponse(), nil
}

View File

@@ -20,12 +20,12 @@ import (
)
type VerificationService interface {
GetVerificationByID(ctx context.Context, verificationId string) (*response.UserVerificationResponse, error)
GetVerificationByUserID(ctx context.Context, userId string) ([]*response.UserVerificationResponse, error)
SearchVerification(ctx context.Context, dto *request.SearchUserVerificationDto) (*response.PaginatedResponse, error)
DeleteVerification(ctx context.Context, claims *response.JWTClaims, verificationId string) error
CreateVerification(ctx context.Context, userId string, dto *request.CreateUserVerificationDto) (*response.UserVerificationResponse, error)
UpdateStatusVerification(ctx context.Context, userId string, verificationId string, dto *request.UpdateVerificationStatusDto) (*response.UserVerificationResponse, error)
GetVerificationByID(ctx context.Context, verificationId string) (*response.UserVerificationResponse, *fiber.Error)
GetVerificationByUserID(ctx context.Context, userId string) ([]*response.UserVerificationResponse, *fiber.Error)
SearchVerification(ctx context.Context, dto *request.SearchUserVerificationDto) (*response.PaginatedResponse, *fiber.Error)
DeleteVerification(ctx context.Context, claims *response.JWTClaims, verificationId string) *fiber.Error
CreateVerification(ctx context.Context, userId string, dto *request.CreateUserVerificationDto) (*response.UserVerificationResponse, *fiber.Error)
UpdateStatusVerification(ctx context.Context, userId string, verificationId string, dto *request.UpdateVerificationStatusDto) (*response.UserVerificationResponse, *fiber.Error)
}
type verificationService struct {
@@ -55,24 +55,24 @@ func NewVerificationService(
}
}
func (v *verificationService) CreateVerification(ctx context.Context, userId string, dto *request.CreateUserVerificationDto) (*response.UserVerificationResponse, error) {
func (v *verificationService) CreateVerification(ctx context.Context, userId string, dto *request.CreateUserVerificationDto) (*response.UserVerificationResponse, *fiber.Error) {
verifyType := constants.ParseVerifyTypeText(dto.VerifyType)
if verifyType == constants.VerifyTypeUnknown {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Unknown verify type!")
return nil, fiber.NewError(fiber.StatusBadRequest, "Unknown verify type!")
}
pgID, err := convert.StringToUUID(userId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid user ID format")
}
mediaList, err := v.mediaRepo.GetByIDs(ctx, dto.MediaIDs)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch media")
}
if len(mediaList) != len(dto.MediaIDs) {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Some media IDs are invalid!")
return nil, fiber.NewError(fiber.StatusBadRequest, "Some media IDs are invalid!")
}
item, err := v.verificationRepo.Create(
@@ -84,19 +84,19 @@ func (v *verificationService) CreateVerification(ctx context.Context, userId str
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create verification")
}
itemId, err := convert.StringToUUID(item.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid verification ID")
}
mediaIdList := make([]pgtype.UUID, 0)
for _, it := range mediaList {
mediaId, err := convert.StringToUUID(it.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
continue
}
mediaIdList = append(mediaIdList, mediaId)
item.Media = append(item.Media, it.ToSimpleEntity())
@@ -110,21 +110,21 @@ func (v *verificationService) CreateVerification(ctx context.Context, userId str
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to link media to verification")
}
return item.ToResponse(), nil
}
func (v *verificationService) DeleteVerification(ctx context.Context, claims *response.JWTClaims, verificationId string) error {
func (v *verificationService) DeleteVerification(ctx context.Context, claims *response.JWTClaims, verificationId string) *fiber.Error {
verificationIdUUID, err := convert.StringToUUID(verificationId)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusBadRequest, "Invalid verification ID format")
}
verification, err := v.verificationRepo.GetByID(ctx, verificationIdUUID)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusNotFound, "Verification not found")
}
shoudDelete := false
@@ -142,32 +142,32 @@ func (v *verificationService) DeleteVerification(ctx context.Context, claims *re
err = v.verificationRepo.Delete(ctx, verificationIdUUID)
if err != nil {
return fiber.NewError(fiber.StatusInternalServerError, err.Error())
return fiber.NewError(fiber.StatusInternalServerError, "Failed to delete verification")
}
return nil
}
func (v *verificationService) GetVerificationByID(ctx context.Context, verificationId string) (*response.UserVerificationResponse, error) {
func (v *verificationService) GetVerificationByID(ctx context.Context, verificationId string) (*response.UserVerificationResponse, *fiber.Error) {
verificationUUID, err := convert.StringToUUID(verificationId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid verification ID format")
}
verification, err := v.verificationRepo.GetByID(ctx, verificationUUID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusNotFound, "Verification not found")
}
return verification.ToResponse(), nil
}
func (v *verificationService) GetVerificationByUserID(ctx context.Context, userId string) ([]*response.UserVerificationResponse, error) {
func (v *verificationService) GetVerificationByUserID(ctx context.Context, userId string) ([]*response.UserVerificationResponse, *fiber.Error) {
userUUID, err := convert.StringToUUID(userId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid user ID format")
}
verifications, err := v.verificationRepo.GetByUserID(ctx, userUUID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch user verifications")
}
return models.UserVerificationsEntitiesToResponse(verifications), nil
}
@@ -227,7 +227,7 @@ func (m *verificationService) fillSearchArgs(arg *sqlc.SearchUserVerificationsPa
}
}
func (v *verificationService) SearchVerification(ctx context.Context, dto *request.SearchUserVerificationDto) (*response.PaginatedResponse, error) {
func (v *verificationService) SearchVerification(ctx context.Context, dto *request.SearchUserVerificationDto) (*response.PaginatedResponse, *fiber.Error) {
if dto.Page < 1 {
dto.Page = 1
}
@@ -270,7 +270,7 @@ func (v *verificationService) SearchVerification(ctx context.Context, dto *reque
})
if err := g.Wait(); err != nil {
return nil, err
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to search verifications")
}
verifications := models.UserVerificationsEntitiesToResponse(rows)
@@ -278,7 +278,7 @@ func (v *verificationService) SearchVerification(ctx context.Context, dto *reque
return response.BuildPaginatedResponse(verifications, totalRecords, dto.Page, dto.Limit), nil
}
func (v *verificationService) UpdateStatusVerification(ctx context.Context, userId string, verificationId string, dto *request.UpdateVerificationStatusDto) (*response.UserVerificationResponse, error) {
func (v *verificationService) UpdateStatusVerification(ctx context.Context, userId string, verificationId string, dto *request.UpdateVerificationStatusDto) (*response.UserVerificationResponse, *fiber.Error) {
tx, err := v.db.Begin(ctx)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to start transaction")
@@ -287,45 +287,45 @@ func (v *verificationService) UpdateStatusVerification(ctx context.Context, user
statusType := constants.ParseStatusTypeText(dto.Status)
if statusType == constants.StatusTypeUnknown {
return nil, fiber.NewError(fiber.StatusInternalServerError, "Unknown status type!")
return nil, fiber.NewError(fiber.StatusBadRequest, "Unknown status type!")
}
verificationUUID, err := convert.StringToUUID(verificationId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid verification ID format")
}
userAdminUUID, err := convert.StringToUUID(userId)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid reviewer ID format")
}
historianRole, err := v.roleRepo.GetByName(ctx, constants.RoleTypeHistorian.String())
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch historian role")
}
historianRoleID, err := convert.StringToUUID(historianRole.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid historian role ID")
}
verification, err := v.verificationRepo.GetByID(ctx, verificationUUID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusNotFound, "Verification not found")
}
if verification.Status != constants.StatusTypePending {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid status!")
return nil, fiber.NewError(fiber.StatusBadRequest, "Verification already processed!")
}
userVerificationUUID, err := convert.StringToUUID(verification.User.ID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Invalid user ID in verification")
}
userVerification, err := v.userRepo.GetByID(ctx, userVerificationUUID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch user data")
}
vRepoTx := v.verificationRepo.WithTx(tx)
@@ -342,7 +342,7 @@ func (v *verificationService) UpdateStatusVerification(ctx context.Context, user
},
)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update status")
}
verification.Status = statusType
@@ -370,7 +370,7 @@ func (v *verificationService) UpdateStatusVerification(ctx context.Context, user
err = rRepoTx.BulkDeleteRolesFromUser(ctx, userVerificationUUID)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to clear old roles")
}
err = rRepoTx.CreateUserRole(ctx, sqlc.CreateUserRoleParams{
@@ -378,7 +378,7 @@ func (v *verificationService) UpdateStatusVerification(ctx context.Context, user
Column2: roleIdList,
})
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create new roles")
}
err = uRepoTx.UpdateTokenVersion(ctx, sqlc.UpdateTokenVersionParams{
@@ -386,7 +386,7 @@ func (v *verificationService) UpdateStatusVerification(ctx context.Context, user
TokenVersion: userVerification.TokenVersion + 1,
})
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to update token version")
}
userVerification.TokenVersion += 1

View File

@@ -13,8 +13,8 @@ import (
)
type WikiService interface {
GetWikiByID(ctx context.Context, id string) (*response.WikiResponse, error)
SearchWikis(ctx context.Context, req *request.SearchWikiDto) ([]*response.WikiResponse, error)
GetWikiByID(ctx context.Context, id string) (*response.WikiResponse, *fiber.Error)
SearchWikis(ctx context.Context, req *request.SearchWikiDto) ([]*response.WikiResponse, *fiber.Error)
}
type wikiService struct {
@@ -27,10 +27,10 @@ func NewWikiService(wikiRepo repositories.WikiRepository) WikiService {
}
}
func (s *wikiService) GetWikiByID(ctx context.Context, id string) (*response.WikiResponse, error) {
func (s *wikiService) GetWikiByID(ctx context.Context, id string) (*response.WikiResponse, *fiber.Error) {
wikiId, err := convert.StringToUUID(id)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid wiki ID format")
}
wiki, err := s.wikiRepo.GetByID(ctx, wikiId)
if err != nil {
@@ -40,7 +40,7 @@ func (s *wikiService) GetWikiByID(ctx context.Context, id string) (*response.Wik
return wiki.ToResponse(), nil
}
func (s *wikiService) SearchWikis(ctx context.Context, req *request.SearchWikiDto) ([]*response.WikiResponse, error) {
func (s *wikiService) SearchWikis(ctx context.Context, req *request.SearchWikiDto) ([]*response.WikiResponse, *fiber.Error) {
limit := int32(25)
if req.Limit > 0 {
limit = int32(req.Limit)
@@ -67,7 +67,7 @@ func (s *wikiService) SearchWikis(ctx context.Context, req *request.SearchWikiDt
wikis, err := s.wikiRepo.Search(ctx, params)
if err != nil {
return nil, fiber.NewError(fiber.StatusInternalServerError, err.Error())
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to search wikis")
}
return models.WikisEntityToResponse(wikis), nil