refactor: centralize constants and reorganize documentation
- Create internal/constants package with all hardcoded values (environment, cookies, themes, headers, routes, cache) - Create internal/httputil package for HTTP helper functions - Update all handlers and middleware to use centralized constants - Reorganize documentation with numbered prefixes (00-26) - Remove duplicate docs from validation folder and docs/ - Delete handlers/constants.go (moved to internal/constants)
This commit is contained in:
@@ -0,0 +1,477 @@
|
||||
# CV Site Go Documentation
|
||||
|
||||
Comprehensive documentation for the Go implementation of the CV site.
|
||||
|
||||
## Documentation Overview
|
||||
|
||||
This documentation covers the core Go systems that power the CV site, with a focus on architecture, implementation details, and practical usage examples.
|
||||
|
||||
### 📚 Documentation Files
|
||||
|
||||
1. **[Go Validation System](24-GO-VALIDATION-SYSTEM.md)** (739 lines)
|
||||
- Tag-based validation with reflection caching
|
||||
- Built-in validation rules (required, email, pattern, etc.)
|
||||
- Security validation (injection prevention, honeypot, timing)
|
||||
- Custom rule extension guide
|
||||
- Complete ContactFormRequest example
|
||||
|
||||
2. **[Go Template System](25-GO-TEMPLATE-SYSTEM.md)** (894 lines)
|
||||
- Thread-safe template manager
|
||||
- Hot reload mechanism for development
|
||||
- Custom template functions (iterate, eq, safeHTML, dict)
|
||||
- Template organization and patterns
|
||||
- Performance optimizations
|
||||
|
||||
3. **[Go Routes and API](26-GO-ROUTES-API.md)** (1,203 lines)
|
||||
- Complete route table with descriptions
|
||||
- Middleware chain architecture
|
||||
- Security features (CSP, HSTS, rate limiting)
|
||||
- Protected endpoints and authentication
|
||||
- API request/response formats
|
||||
|
||||
## Quick Navigation
|
||||
|
||||
### By Feature
|
||||
|
||||
**Validation:**
|
||||
- [Tag Syntax](24-GO-VALIDATION-SYSTEM.md#tag-syntax)
|
||||
- [Available Rules](24-GO-VALIDATION-SYSTEM.md#available-validation-rules)
|
||||
- [ContactFormRequest Example](24-GO-VALIDATION-SYSTEM.md#complete-example-contactformrequest)
|
||||
- [Error Handling](24-GO-VALIDATION-SYSTEM.md#error-handling)
|
||||
- [Security Rules](24-GO-VALIDATION-SYSTEM.md#5-security-validation)
|
||||
|
||||
**Templates:**
|
||||
- [Custom Functions](25-GO-TEMPLATE-SYSTEM.md#custom-template-functions)
|
||||
- [Hot Reload](25-GO-TEMPLATE-SYSTEM.md#hot-reload-mechanism)
|
||||
- [Thread Safety](25-GO-TEMPLATE-SYSTEM.md#thread-safety)
|
||||
- [Template Patterns](25-GO-TEMPLATE-SYSTEM.md#template-patterns)
|
||||
- [Security Best Practices](25-GO-TEMPLATE-SYSTEM.md#security-best-practices)
|
||||
|
||||
**Routes:**
|
||||
- [Route Table](26-GO-ROUTES-API.md#route-table)
|
||||
- [Middleware Stack](26-GO-ROUTES-API.md#middleware-stack)
|
||||
- [Contact Form API](26-GO-ROUTES-API.md#apicontact---contact-form-submission)
|
||||
- [PDF Export](26-GO-ROUTES-API.md#exportpdf---pdf-export)
|
||||
- [Security Features](26-GO-ROUTES-API.md#security-features)
|
||||
|
||||
### By Use Case
|
||||
|
||||
**Setting Up Validation:**
|
||||
1. [Define struct with tags](24-GO-VALIDATION-SYSTEM.md#struct-definition)
|
||||
2. [Call validator](24-GO-VALIDATION-SYSTEM.md#validation-execution)
|
||||
3. [Handle errors](24-GO-VALIDATION-SYSTEM.md#error-handling-example)
|
||||
|
||||
**Creating Templates:**
|
||||
1. [Initialize manager](25-GO-TEMPLATE-SYSTEM.md#initialization)
|
||||
2. [Use custom functions](25-GO-TEMPLATE-SYSTEM.md#custom-template-functions)
|
||||
3. [Render in handlers](25-GO-TEMPLATE-SYSTEM.md#usage-in-handlers)
|
||||
|
||||
**Adding Routes:**
|
||||
1. [Configure middleware](26-GO-ROUTES-API.md#middleware-stack)
|
||||
2. [Register handlers](26-GO-ROUTES-API.md#route-table)
|
||||
3. [Apply security](26-GO-ROUTES-API.md#route-specific-middleware)
|
||||
|
||||
## System Architecture
|
||||
|
||||
### Overall Flow
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ HTTP Request │
|
||||
└──────────────────────┬───────────────────────────────────────┘
|
||||
│
|
||||
v
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Middleware Chain │
|
||||
│ Recovery → Logger → SecurityHeaders → DynamicCache → │
|
||||
│ Preferences → Router │
|
||||
└──────────────────────┬───────────────────────────────────────┘
|
||||
│
|
||||
v
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Route Handler │
|
||||
│ 1. Parse request │
|
||||
│ 2. Get preferences from context │
|
||||
│ 3. Load data (CV, config) │
|
||||
│ 4. Validate input (if needed) │
|
||||
│ 5. Render template │
|
||||
└──────────────────────┬───────────────────────────────────────┘
|
||||
│
|
||||
v
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Template Rendering │
|
||||
│ 1. Load template (hot reload in dev) │
|
||||
│ 2. Execute with data │
|
||||
│ 3. Apply custom functions │
|
||||
│ 4. Output HTML │
|
||||
└──────────────────────┬───────────────────────────────────────┘
|
||||
│
|
||||
v
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ HTTP Response │
|
||||
│ - Security headers │
|
||||
│ - Cache headers │
|
||||
│ - Content-Type │
|
||||
│ - HTML/JSON/PDF body │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Contact Form Flow
|
||||
|
||||
```
|
||||
POST /api/contact
|
||||
│
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ BrowserOnly │ Check User-Agent, Referer, Headers
|
||||
│ Middleware │ → 403 if not browser
|
||||
└─────────┬───────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ RateLimiter │ 5 requests/hour per IP
|
||||
│ (5/hour) │ → 429 if exceeded
|
||||
└─────────┬───────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ Parse JSON │ Decode ContactFormRequest
|
||||
│ Request Body │
|
||||
└─────────┬───────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ Validate with │ Tag-based validation:
|
||||
│ ValidateV2() │ - required, trim, max
|
||||
│ │ - email, pattern
|
||||
│ │ - no_injection, honeypot
|
||||
│ │ - timing (2s-24h)
|
||||
└─────────┬───────────┘
|
||||
│
|
||||
├─> Validation Failed → 400 + errors
|
||||
│
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ Send Email │ SMTP or email service
|
||||
└─────────┬───────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ 200 OK │ Success response
|
||||
│ {success: true} │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. Validation System
|
||||
|
||||
**Highlights:**
|
||||
- Reflection-based with `sync.Map` caching for performance
|
||||
- Declarative tag syntax: `validate:"required,email,max=254"`
|
||||
- 11+ built-in rules including security rules
|
||||
- Extensible with custom rules
|
||||
- Thread-safe concurrent validation
|
||||
|
||||
**Performance:**
|
||||
- First validation: ~2000 ns/op
|
||||
- Cached validations: ~1500 ns/op
|
||||
- Pre-compiled regex patterns
|
||||
|
||||
**Security:**
|
||||
- Email header injection prevention
|
||||
- Honeypot bot detection
|
||||
- Timing-based bot detection
|
||||
- HTML sanitization
|
||||
- UTF-8 aware length validation
|
||||
|
||||
### 2. Template System
|
||||
|
||||
**Highlights:**
|
||||
- Thread-safe with `sync.RWMutex`
|
||||
- Hot reload in development (edit without restart)
|
||||
- 4 custom template functions
|
||||
- Recursive partial loading
|
||||
- Production caching
|
||||
|
||||
**Custom Functions:**
|
||||
- `iterate(count)` - Generate integer ranges
|
||||
- `eq(a, b)` - String equality
|
||||
- `safeHTML(s)` - Safe HTML (trusted content only)
|
||||
- `dict(k1, v1, ...)` - Create maps for sub-templates
|
||||
|
||||
**Thread Safety:**
|
||||
- Development: Full lock during reload
|
||||
- Production: Read-only lock (concurrent)
|
||||
|
||||
### 3. Routes and Middleware
|
||||
|
||||
**Highlights:**
|
||||
- 15+ routes (public, HTMX, API, protected)
|
||||
- 8 middleware layers
|
||||
- Comprehensive security headers
|
||||
- Rate limiting (contact: 5/hour, PDF: 3/min)
|
||||
- Origin checking for PDF exports
|
||||
|
||||
**Security Features:**
|
||||
- Content Security Policy (CSP)
|
||||
- HTTP Strict Transport Security (HSTS)
|
||||
- BrowserOnly middleware (blocks curl/Postman)
|
||||
- Email header injection prevention
|
||||
- Rate limiting per IP
|
||||
- Origin/Referer validation
|
||||
|
||||
## Code Examples
|
||||
|
||||
### Validation Example
|
||||
|
||||
```go
|
||||
// Define struct with validation tags
|
||||
type ContactFormRequest struct {
|
||||
Name string `json:"name" validate:"required,trim,max=100,pattern=name"`
|
||||
Email string `json:"email" validate:"required,email,no_injection"`
|
||||
Message string `json:"message" validate:"required,trim,max=5000,sanitize"`
|
||||
}
|
||||
|
||||
// Validate
|
||||
if err := validation.ValidateContactFormV2(req); err != nil {
|
||||
// Handle validation errors
|
||||
validationErrors := err.(validation.ValidationErrors)
|
||||
return c.JSON(400, map[string]interface{}{
|
||||
"errors": validationErrors,
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### Template Example
|
||||
|
||||
```go
|
||||
// Initialize template manager
|
||||
cfg := &config.TemplateConfig{
|
||||
Dir: "templates",
|
||||
PartialsDir: "templates/partials",
|
||||
HotReload: true, // Development
|
||||
}
|
||||
manager, _ := templates.NewManager(cfg)
|
||||
|
||||
// Render in handler
|
||||
tmpl, _ := manager.Render("home.html")
|
||||
tmpl.Execute(w, map[string]interface{}{
|
||||
"Title": "CV",
|
||||
"CV": cvData,
|
||||
})
|
||||
```
|
||||
|
||||
### Route Example
|
||||
|
||||
```go
|
||||
// Protected contact endpoint
|
||||
contactRateLimiter := middleware.NewRateLimiter(5, 1*time.Hour)
|
||||
protectedHandler := middleware.BrowserOnly(
|
||||
contactRateLimiter.Middleware(
|
||||
http.HandlerFunc(cvHandler.HandleContact),
|
||||
),
|
||||
)
|
||||
mux.Handle("/api/contact", protectedHandler)
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Run All Tests
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
go test ./...
|
||||
|
||||
# Run with coverage
|
||||
go test -cover ./...
|
||||
|
||||
# Run specific package
|
||||
go test ./internal/validation/...
|
||||
|
||||
# Run with verbose output
|
||||
go test -v ./internal/routes/...
|
||||
```
|
||||
|
||||
### Test Examples
|
||||
|
||||
```bash
|
||||
# Validation tests
|
||||
go test ./internal/validation/ -v
|
||||
|
||||
# Template tests
|
||||
go test ./internal/templates/ -v
|
||||
|
||||
# Middleware tests
|
||||
go test ./internal/middleware/ -v
|
||||
|
||||
# Handler tests
|
||||
go test ./internal/handlers/ -v
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
### Benchmarks
|
||||
|
||||
```bash
|
||||
# Run benchmarks
|
||||
go test -bench=. ./...
|
||||
|
||||
# Validation benchmarks
|
||||
go test -bench=Validate ./internal/validation/
|
||||
|
||||
# Template benchmarks
|
||||
go test -bench=Render ./internal/templates/
|
||||
```
|
||||
|
||||
### Typical Performance
|
||||
|
||||
**Validation:**
|
||||
- Contact form validation: ~1.5 µs
|
||||
- Email validation: ~500 ns
|
||||
- Pattern matching: ~300 ns (pre-compiled)
|
||||
|
||||
**Templates:**
|
||||
- Template render (cached): ~50-100 µs
|
||||
- Hot reload: ~1-2 ms (development only)
|
||||
|
||||
**Routes:**
|
||||
- Middleware overhead: ~10-20 µs per request
|
||||
- Rate limiter check: ~100-200 ns
|
||||
- Total request latency: <5 ms (p50), <20 ms (p99)
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
### Development
|
||||
|
||||
```bash
|
||||
export GO_ENV=development
|
||||
export TEMPLATE_HOT_RELOAD=true
|
||||
export PORT=8080
|
||||
```
|
||||
|
||||
### Production
|
||||
|
||||
```bash
|
||||
export GO_ENV=production
|
||||
export TEMPLATE_HOT_RELOAD=false
|
||||
export ALLOWED_ORIGINS="juan.andres.morenorub.io"
|
||||
export PORT=8080
|
||||
```
|
||||
|
||||
## File Organization
|
||||
|
||||
```
|
||||
cv/
|
||||
├── doc/
|
||||
│ ├── 24-GO-VALIDATION-SYSTEM.md # Validation docs
|
||||
│ ├── 25-GO-TEMPLATE-SYSTEM.md # Template docs
|
||||
│ ├── 26-GO-ROUTES-API.md # Routes/API docs
|
||||
│ └── 00-GO-DOCUMENTATION-INDEX.md # This file
|
||||
│
|
||||
├── internal/
|
||||
│ ├── validation/
|
||||
│ │ ├── validator.go # Core validator
|
||||
│ │ ├── rules.go # Validation rules
|
||||
│ │ ├── errors.go # Error types
|
||||
│ │ └── contact.go # ContactFormRequest
|
||||
│ │
|
||||
│ ├── templates/
|
||||
│ │ └── template.go # Template manager
|
||||
│ │
|
||||
│ ├── routes/
|
||||
│ │ └── routes.go # Route setup
|
||||
│ │
|
||||
│ ├── middleware/
|
||||
│ │ ├── security.go # Security middleware
|
||||
│ │ ├── browser_only.go # BrowserOnly middleware
|
||||
│ │ ├── contact_rate_limit.go # Rate limiting
|
||||
│ │ ├── logger.go # Request logging
|
||||
│ │ ├── recovery.go # Panic recovery
|
||||
│ │ └── preferences.go # User preferences
|
||||
│ │
|
||||
│ └── handlers/
|
||||
│ ├── cv.go # CV handlers
|
||||
│ ├── cv_contact.go # Contact handler
|
||||
│ ├── cv_pdf.go # PDF handler
|
||||
│ └── health.go # Health check
|
||||
│
|
||||
└── templates/
|
||||
├── *.html # Main templates
|
||||
└── partials/ # Partial templates
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Validation
|
||||
|
||||
1. **Use tag-based validation** for all struct validation
|
||||
2. **Order rules correctly**: transformations first (trim, sanitize), then validations
|
||||
3. **Use global validator** instance to benefit from caching
|
||||
4. **Combine security rules** for defense in depth
|
||||
5. **UTF-8 aware**: Use max/min for character count, not byte count
|
||||
|
||||
### Templates
|
||||
|
||||
1. **Disable hot reload** in production for performance
|
||||
2. **Use safeHTML only** with trusted content (YAML/config)
|
||||
3. **Organize templates** logically (main, partials, HTMX)
|
||||
4. **Leverage custom functions** for reusable logic
|
||||
5. **Test template execution** to catch errors early
|
||||
|
||||
### Routes
|
||||
|
||||
1. **Register specific routes first** to avoid conflicts
|
||||
2. **Apply security middleware** to sensitive endpoints
|
||||
3. **Use rate limiting** for resource-intensive operations
|
||||
4. **Log all requests** for monitoring
|
||||
5. **Implement health checks** for load balancers
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
**Validation not working:**
|
||||
- Check tag syntax: `validate:"rule1,rule2=param"`
|
||||
- Ensure field is exported (capitalized)
|
||||
- Verify validator instance is created
|
||||
|
||||
**Template not found:**
|
||||
- Check file exists in templates directory
|
||||
- Verify filename matches `Render("name")`
|
||||
- Check template loading logs
|
||||
|
||||
**Rate limit too strict:**
|
||||
- Adjust limit in middleware initialization
|
||||
- Clear rate limiter state (restart or implement clear endpoint)
|
||||
|
||||
**CORS errors:**
|
||||
- Add domain to `ALLOWED_ORIGINS` environment variable
|
||||
- Check `OriginChecker` middleware configuration
|
||||
|
||||
## Contributing
|
||||
|
||||
When adding new features:
|
||||
|
||||
1. **Update documentation** in relevant .md file
|
||||
2. **Add tests** for new functionality
|
||||
3. **Update route table** if adding endpoints
|
||||
4. **Document security implications** if applicable
|
||||
5. **Add examples** for complex features
|
||||
|
||||
## Version History
|
||||
|
||||
- **v1.0** (2025-12-06) - Initial comprehensive documentation
|
||||
- Validation system with tag-based approach
|
||||
- Template system with hot reload
|
||||
- Complete route and middleware documentation
|
||||
|
||||
## License
|
||||
|
||||
This documentation is part of the CV site project.
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** December 6, 2025
|
||||
**Total Documentation:** 2,836+ lines across 3 files
|
||||
**Coverage:** Validation, Templates, Routes, Middleware, Security
|
||||
Reference in New Issue
Block a user