3024998e7e
- Changed the approval status from "approved" to "submitted" in various locations, including entity definitions, forms, and service methods, to accurately reflect the tender approval process.
- Updated API documentation in Swagger JSON, YAML, and Go files to describe the new status options ("submitted" and "rejected") and their corresponding descriptions.
- Enhanced the tender approval statistics structures to include a count for submitted tenders, improving the overall data model for tender management.
- These changes ensure clarity in the tender approval workflow and enhance the usability of the API for clients interacting with tender approvals.
177 lines
4.1 KiB
Go
177 lines
4.1 KiB
Go
package tender_approval
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
// Validation functions for tender approval domain
|
|
|
|
// IsValidTenderID validates if the tender ID format is correct
|
|
func IsValidTenderID(tenderID string) bool {
|
|
if tenderID == "" {
|
|
return false
|
|
}
|
|
|
|
// Tender ID should be a non-empty string
|
|
// You can add more specific validation rules here based on your tender ID format
|
|
return len(tenderID) > 0 && len(tenderID) <= 100
|
|
}
|
|
|
|
// IsValidCompanyID validates if the company ID format is correct
|
|
func IsValidCompanyID(companyID string) bool {
|
|
if companyID == "" {
|
|
return false
|
|
}
|
|
|
|
// Company ID should be a non-empty string
|
|
// You can add more specific validation rules here based on your company ID format
|
|
return len(companyID) > 0 && len(companyID) <= 100
|
|
}
|
|
|
|
// IsValidSubmissionMode validates if the submission mode is valid
|
|
func IsValidSubmissionMode(mode string) bool {
|
|
validModes := []string{
|
|
string(SubmissionModeSelfApply),
|
|
string(SubmissionModePartnership),
|
|
}
|
|
|
|
for _, validMode := range validModes {
|
|
if strings.EqualFold(mode, validMode) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// IsValidStatus validates if the approval status is valid
|
|
func IsValidStatus(status string) bool {
|
|
validStatuses := []string{
|
|
string(ApprovalStatusSubmitted),
|
|
string(ApprovalStatusRejected),
|
|
}
|
|
|
|
for _, validStatus := range validStatuses {
|
|
if strings.EqualFold(status, validStatus) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// IsValidNotes validates if the notes field is valid
|
|
func IsValidNotes(notes *string) bool {
|
|
if notes == nil {
|
|
return true // Notes are optional
|
|
}
|
|
|
|
// Notes should be between 0 and 1000 characters
|
|
return len(*notes) <= 1000
|
|
}
|
|
|
|
// IsValidReason validates if the rejection reason is valid
|
|
func IsValidReason(reason string) bool {
|
|
// Reason should be between 10 and 500 characters
|
|
if len(reason) < 10 || len(reason) > 500 {
|
|
return false
|
|
}
|
|
|
|
// Reason should not contain only whitespace
|
|
if strings.TrimSpace(reason) == "" {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// IsValidTimestamp validates if the timestamp is within reasonable range
|
|
func IsValidTimestamp(timestamp int64) bool {
|
|
// Timestamp should be positive and not too far in the future
|
|
// You can adjust these limits based on your requirements
|
|
if timestamp <= 0 {
|
|
return false
|
|
}
|
|
|
|
// Check if timestamp is not too far in the future (e.g., 10 years from now)
|
|
maxFutureTimestamp := int64(10 * 365 * 24 * 60 * 60) // 10 years in seconds
|
|
return timestamp <= maxFutureTimestamp
|
|
}
|
|
|
|
// IsValidLimit validates if the limit parameter is valid
|
|
func IsValidLimit(limit int) bool {
|
|
return limit > 0 && limit <= 100
|
|
}
|
|
|
|
// IsValidOffset validates if the offset parameter is valid
|
|
func IsValidOffset(offset int) bool {
|
|
return offset >= 0
|
|
}
|
|
|
|
// IsValidSortBy validates if the sort by parameter is valid
|
|
func IsValidSortBy(sortBy string) bool {
|
|
validSortFields := []string{
|
|
"created_at",
|
|
"updated_at",
|
|
"status",
|
|
"submission_mode",
|
|
}
|
|
|
|
for _, validField := range validSortFields {
|
|
if strings.EqualFold(sortBy, validField) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// IsValidSortOrder validates if the sort order parameter is valid
|
|
func IsValidSortOrder(sortOrder string) bool {
|
|
validOrders := []string{"asc", "desc"}
|
|
|
|
for _, validOrder := range validOrders {
|
|
if strings.EqualFold(sortOrder, validOrder) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// SanitizeString removes potentially dangerous characters from input strings
|
|
func SanitizeString(input string) string {
|
|
// Remove HTML tags
|
|
htmlTagRegex := regexp.MustCompile(`<[^>]*>`)
|
|
sanitized := htmlTagRegex.ReplaceAllString(input, "")
|
|
|
|
// Remove script tags
|
|
scriptRegex := regexp.MustCompile(`(?i)<script[^>]*>.*?</script>`)
|
|
sanitized = scriptRegex.ReplaceAllString(sanitized, "")
|
|
|
|
// Trim whitespace
|
|
sanitized = strings.TrimSpace(sanitized)
|
|
|
|
return sanitized
|
|
}
|
|
|
|
// ValidateSearchQuery validates if the search query is valid
|
|
func ValidateSearchQuery(query string) bool {
|
|
if query == "" {
|
|
return true // Empty query is valid
|
|
}
|
|
|
|
// Query should not be too long
|
|
if len(query) > 200 {
|
|
return false
|
|
}
|
|
|
|
// Query should not contain only special characters
|
|
if regexp.MustCompile(`^[^a-zA-Z0-9\s]+$`).MatchString(query) {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|