177 lines
5.3 KiB
Go
177 lines
5.3 KiB
Go
package validator
|
|
|
|
import (
|
|
"apskel-pos-be/internal/contract"
|
|
"errors"
|
|
"strings"
|
|
|
|
"github.com/go-playground/validator/v10"
|
|
)
|
|
|
|
type CustomerValidator interface {
|
|
ValidateCreateCustomerRequest(req *contract.CreateCustomerRequest) (error, string)
|
|
ValidateUpdateCustomerRequest(req *contract.UpdateCustomerRequest) (error, string)
|
|
ValidateListCustomersRequest(req *contract.ListCustomersRequest) (error, string)
|
|
ValidateSetDefaultCustomerRequest(req *contract.SetDefaultCustomerRequest) (error, string)
|
|
}
|
|
|
|
type CustomerValidatorImpl struct {
|
|
validate *validator.Validate
|
|
}
|
|
|
|
func NewCustomerValidator() *CustomerValidatorImpl {
|
|
return &CustomerValidatorImpl{
|
|
validate: validator.New(),
|
|
}
|
|
}
|
|
|
|
// ValidateCreateCustomer validates create customer request
|
|
func (v *CustomerValidatorImpl) ValidateCreateCustomerRequest(req *contract.CreateCustomerRequest) (error, string) {
|
|
if err := v.validate.Struct(req); err != nil {
|
|
return err, "VALIDATION_ERROR"
|
|
}
|
|
|
|
// Additional custom validations
|
|
if req.Name != "" {
|
|
req.Name = strings.TrimSpace(req.Name)
|
|
if req.Name == "" {
|
|
return errors.New("name cannot be empty or whitespace only"), "INVALID_NAME"
|
|
}
|
|
if len(req.Name) > 255 {
|
|
return errors.New("name cannot exceed 255 characters"), "INVALID_NAME"
|
|
}
|
|
}
|
|
|
|
if req.Email != nil && *req.Email != "" {
|
|
*req.Email = strings.TrimSpace(strings.ToLower(*req.Email))
|
|
if *req.Email == "" {
|
|
return errors.New("email cannot be empty or whitespace only"), "INVALID_EMAIL"
|
|
}
|
|
if len(*req.Email) > 255 {
|
|
return errors.New("email cannot exceed 255 characters"), "INVALID_EMAIL"
|
|
}
|
|
}
|
|
|
|
if req.Phone != nil && *req.Phone != "" {
|
|
*req.Phone = strings.TrimSpace(*req.Phone)
|
|
if *req.Phone == "" {
|
|
return errors.New("phone cannot be empty or whitespace only"), "INVALID_PHONE"
|
|
}
|
|
if len(*req.Phone) > 20 {
|
|
return errors.New("phone cannot exceed 20 characters"), "INVALID_PHONE"
|
|
}
|
|
}
|
|
|
|
if req.Address != nil && *req.Address != "" {
|
|
*req.Address = strings.TrimSpace(*req.Address)
|
|
if *req.Address == "" {
|
|
return errors.New("address cannot be empty or whitespace only"), "INVALID_ADDRESS"
|
|
}
|
|
if len(*req.Address) > 500 {
|
|
return errors.New("address cannot exceed 500 characters"), "INVALID_ADDRESS"
|
|
}
|
|
}
|
|
|
|
return nil, ""
|
|
}
|
|
|
|
// ValidateUpdateCustomer validates update customer request
|
|
func (v *CustomerValidatorImpl) ValidateUpdateCustomerRequest(req *contract.UpdateCustomerRequest) (error, string) {
|
|
if err := v.validate.Struct(req); err != nil {
|
|
return err, "VALIDATION_ERROR"
|
|
}
|
|
|
|
// Check if at least one field is provided
|
|
if req.Name == nil && req.Email == nil && req.Phone == nil && req.Address == nil && req.IsActive == nil {
|
|
return errors.New("at least one field must be provided for update"), "MISSING_FIELDS"
|
|
}
|
|
|
|
// Additional custom validations
|
|
if req.Name != nil && *req.Name != "" {
|
|
*req.Name = strings.TrimSpace(*req.Name)
|
|
if *req.Name == "" {
|
|
return errors.New("name cannot be empty or whitespace only"), "INVALID_NAME"
|
|
}
|
|
if len(*req.Name) > 255 {
|
|
return errors.New("name cannot exceed 255 characters"), "INVALID_NAME"
|
|
}
|
|
}
|
|
|
|
if req.Email != nil && *req.Email != "" {
|
|
*req.Email = strings.TrimSpace(strings.ToLower(*req.Email))
|
|
if *req.Email == "" {
|
|
return errors.New("email cannot be empty or whitespace only"), "INVALID_EMAIL"
|
|
}
|
|
if len(*req.Email) > 255 {
|
|
return errors.New("email cannot exceed 255 characters"), "INVALID_EMAIL"
|
|
}
|
|
}
|
|
|
|
if req.Phone != nil && *req.Phone != "" {
|
|
*req.Phone = strings.TrimSpace(*req.Phone)
|
|
if *req.Phone == "" {
|
|
return errors.New("phone cannot be empty or whitespace only"), "INVALID_PHONE"
|
|
}
|
|
if len(*req.Phone) > 20 {
|
|
return errors.New("phone cannot exceed 20 characters"), "INVALID_PHONE"
|
|
}
|
|
}
|
|
|
|
if req.Address != nil && *req.Address != "" {
|
|
*req.Address = strings.TrimSpace(*req.Address)
|
|
if *req.Address == "" {
|
|
return errors.New("address cannot be empty or whitespace only"), "INVALID_ADDRESS"
|
|
}
|
|
if len(*req.Address) > 500 {
|
|
return errors.New("address cannot exceed 500 characters"), "INVALID_ADDRESS"
|
|
}
|
|
}
|
|
|
|
return nil, ""
|
|
}
|
|
|
|
// ValidateListCustomersRequest validates list customers request
|
|
func (v *CustomerValidatorImpl) ValidateListCustomersRequest(req *contract.ListCustomersRequest) (error, string) {
|
|
if err := v.validate.Struct(req); err != nil {
|
|
return err, "VALIDATION_ERROR"
|
|
}
|
|
|
|
// Additional custom validations
|
|
if req.Search != "" {
|
|
req.Search = strings.TrimSpace(req.Search)
|
|
if len(req.Search) > 100 {
|
|
return errors.New("search term cannot exceed 100 characters"), "INVALID_SEARCH"
|
|
}
|
|
}
|
|
|
|
if req.SortBy != "" {
|
|
req.SortBy = strings.ToLower(strings.TrimSpace(req.SortBy))
|
|
validSortFields := map[string]bool{
|
|
"name": true,
|
|
"email": true,
|
|
"created_at": true,
|
|
"updated_at": true,
|
|
}
|
|
if !validSortFields[req.SortBy] {
|
|
return errors.New("invalid sort field"), "INVALID_SORT_FIELD"
|
|
}
|
|
}
|
|
|
|
if req.SortOrder != "" {
|
|
req.SortOrder = strings.ToLower(strings.TrimSpace(req.SortOrder))
|
|
if req.SortOrder != "asc" && req.SortOrder != "desc" {
|
|
return errors.New("sort order must be 'asc' or 'desc'"), "INVALID_SORT_ORDER"
|
|
}
|
|
}
|
|
|
|
return nil, ""
|
|
}
|
|
|
|
// ValidateSetDefaultCustomer validates set default customer request
|
|
func (v *CustomerValidatorImpl) ValidateSetDefaultCustomerRequest(req *contract.SetDefaultCustomerRequest) (error, string) {
|
|
if err := v.validate.Struct(req); err != nil {
|
|
return err, "VALIDATION_ERROR"
|
|
}
|
|
return nil, ""
|
|
}
|