Add Tender Approval Management Functionality and API Enhancements
- Introduced a new tender approval management system, including the creation of tender approval entities, services, and repositories. - Implemented CRUD operations for tender approvals, allowing companies to approve or reject tenders. - Developed administrative and public API endpoints for listing, retrieving, and updating tender approvals with comprehensive filtering options. - Enhanced Swagger documentation to accurately reflect the new endpoints, including detailed descriptions, parameters, and response formats. - Updated existing routes to include tender approval management, ensuring adherence to Clean Architecture principles and maintaining a clear separation of concerns in the handler layer.
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
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(ApprovalStatusApproved),
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user