feat: add tag-based validation system with reflection caching

Implement a declarative struct tag validation system for Go:

- Add validator.go with sync.Map caching for reflection metadata
- Add rules.go with 11 built-in validation rules (required, email,
  pattern, honeypot, timing, etc.)
- Add errors.go with FieldError and ValidationErrors types
- Update ContactFormRequest with validate tags
- Add ValidateContactFormV2() using the new tag-based validator

Rules implemented:
- required/optional: field presence validation
- trim/sanitize: automatic value transformations
- min/max: UTF-8 aware length validation
- email: RFC 5322 email format validation
- pattern: predefined regex patterns (name, subject, company)
- no_injection: email header injection prevention
- honeypot: bot trap (must be empty)
- timing: timestamp validation for bot detection

Documentation:
- docs/go-validation-system.md: complete validation guide
- docs/go-template-system.md: template manager documentation
- docs/go-routes-api.md: routes and API reference
- docs/README.md: documentation index
This commit is contained in:
juanatsap
2025-12-06 15:20:45 +00:00
parent 6172ada527
commit 6c7595b041
12 changed files with 5338 additions and 7 deletions
+16 -7
View File
@@ -11,13 +11,13 @@ import (
// ContactFormRequest represents a validated contact form submission
type ContactFormRequest struct {
Name string `json:"name"`
Email string `json:"email"`
Company string `json:"company"`
Subject string `json:"subject"`
Message string `json:"message"`
Honeypot string `json:"website"` // Should always be empty (bot trap)
Timestamp int64 `json:"timestamp"` // Form load time (set by server)
Name string `json:"name" validate:"required,trim,max=100,pattern=name,no_injection"`
Email string `json:"email" validate:"required,trim,max=254,email,no_injection"`
Company string `json:"company" validate:"optional,trim,max=100,pattern=company"`
Subject string `json:"subject" validate:"required,trim,max=200,pattern=subject,no_injection"`
Message string `json:"message" validate:"required,trim,max=5000,sanitize"`
Honeypot string `json:"website" validate:"honeypot"` // Should always be empty (bot trap)
Timestamp int64 `json:"timestamp" validate:"timing=2:86400"` // Form load time (set by server)
}
// ValidationError represents a validation error with field context
@@ -350,3 +350,12 @@ var (
ErrFieldTooLong = errors.New("field exceeds maximum length")
ErrSubmittedTooFast = errors.New("form submitted too quickly")
)
// Global validator instance for reusing cached struct metadata
var globalValidator = NewValidator()
// ValidateContactFormV2 validates a contact form using struct tags
// This is the new validation method that uses the tag-based validator
func ValidateContactFormV2(req *ContactFormRequest) error {
return globalValidator.Validate(req)
}