package validator import ( "errors" "strings" "apskel-pos-be/internal/constants" "apskel-pos-be/internal/contract" "apskel-pos-be/internal/entities" ) type UserDeviceValidator interface { ValidateRegisterDeviceRequest(req *contract.RegisterUserDeviceRequest) (error, string) ValidateUpdateDeviceRequest(req *contract.UpdateUserDeviceRequest) (error, string) ValidateListDevicesRequest(req *contract.ListUserDevicesRequest) (error, string) } type UserDeviceValidatorImpl struct{} func NewUserDeviceValidator() *UserDeviceValidatorImpl { return &UserDeviceValidatorImpl{} } var validDeviceTypes = map[entities.DeviceType]bool{ entities.DeviceTypeMobile: true, entities.DeviceTypeTablet: true, entities.DeviceTypeDesktop: true, } var validPlatforms = map[entities.DevicePlatform]bool{ entities.DevicePlatformAndroid: true, entities.DevicePlatformIOS: true, entities.DevicePlatformWeb: true, } func (v *UserDeviceValidatorImpl) ValidateRegisterDeviceRequest(req *contract.RegisterUserDeviceRequest) (error, string) { if req == nil { return errors.New("request body is required"), constants.MissingFieldErrorCode } if strings.TrimSpace(req.DeviceID) == "" { return errors.New("device_id is required"), constants.MissingFieldErrorCode } if len(req.DeviceID) > 255 { return errors.New("device_id must be at most 255 characters"), constants.MalformedFieldErrorCode } if req.DeviceName != "" && len(req.DeviceName) > 255 { return errors.New("device_name must be at most 255 characters"), constants.MalformedFieldErrorCode } if req.DeviceType != "" && !validDeviceTypes[req.DeviceType] { return errors.New("device_type must be one of: mobile, tablet, desktop"), constants.MalformedFieldErrorCode } if req.Platform != "" && !validPlatforms[req.Platform] { return errors.New("platform must be one of: android, ios, web"), constants.MalformedFieldErrorCode } if req.FCMToken != "" && len(req.FCMToken) > 512 { return errors.New("fcm_token must be at most 512 characters"), constants.MalformedFieldErrorCode } if req.AppVersion != "" && len(req.AppVersion) > 50 { return errors.New("app_version must be at most 50 characters"), constants.MalformedFieldErrorCode } if req.OsVersion != "" && len(req.OsVersion) > 50 { return errors.New("os_version must be at most 50 characters"), constants.MalformedFieldErrorCode } return nil, "" } func (v *UserDeviceValidatorImpl) ValidateUpdateDeviceRequest(req *contract.UpdateUserDeviceRequest) (error, string) { if req == nil { return errors.New("request body is required"), constants.MissingFieldErrorCode } if req.DeviceName != "" && len(req.DeviceName) > 255 { return errors.New("device_name must be at most 255 characters"), constants.MalformedFieldErrorCode } if req.DeviceType != "" && !validDeviceTypes[req.DeviceType] { return errors.New("device_type must be one of: mobile, tablet, desktop"), constants.MalformedFieldErrorCode } if req.Platform != "" && !validPlatforms[req.Platform] { return errors.New("platform must be one of: android, ios, web"), constants.MalformedFieldErrorCode } if req.FCMToken != "" && len(req.FCMToken) > 512 { return errors.New("fcm_token must be at most 512 characters"), constants.MalformedFieldErrorCode } if req.AppVersion != "" && len(req.AppVersion) > 50 { return errors.New("app_version must be at most 50 characters"), constants.MalformedFieldErrorCode } if req.OsVersion != "" && len(req.OsVersion) > 50 { return errors.New("os_version must be at most 50 characters"), constants.MalformedFieldErrorCode } return nil, "" } func (v *UserDeviceValidatorImpl) ValidateListDevicesRequest(req *contract.ListUserDevicesRequest) (error, string) { if req == nil { return errors.New("request body is required"), constants.MissingFieldErrorCode } if req.Page < 1 { return errors.New("page must be at least 1"), constants.MalformedFieldErrorCode } if req.Limit < 1 || req.Limit > 100 { return errors.New("limit must be between 1 and 100"), constants.MalformedFieldErrorCode } if req.Platform != "" && !validPlatforms[entities.DevicePlatform(req.Platform)] { return errors.New("platform must be one of: android, ios, web"), constants.MalformedFieldErrorCode } return nil, "" }