Files
cv-site/internal/routes/routes.go
T
juanatsap ae89d84e07 refactor: Integrate PreferencesMiddleware and update handlers
Complete middleware integration with comprehensive testing:

1. Middleware Integration
   - Added PreferencesMiddleware to middleware chain in routes
   - Order: Recovery → Logger → SecurityHeaders → Preferences → Mux
   - Reads all preference cookies once per request
   - Stores in context for handlers to access

2. Handler Updates
   - cv_pages.go: Home handler uses middleware.GetPreferences()
   - cv_htmx.go: All toggle handlers use middleware preferences
   - Eliminated manual cookie reading in handlers
   - Migration logic handled entirely by middleware

3. Comprehensive Middleware Tests
   - Created preferences_test.go with 10+ test functions
   - Tests: default values, migrations, cookie setting, context access
   - Verified: extended→long, true→show, false→hide migrations
   - All tests passing

Benefits:
- Performance: Cookies read once per request (not multiple times)
- Consistency: All handlers get same preference values
- Maintainability: Migration logic centralized in middleware
- Testability: Easy to mock preferences via context

Testing:
- All unit tests pass (handlers + middleware)
- Build succeeds
- No breaking changes
2025-11-20 17:56:47 +00:00

55 lines
1.7 KiB
Go

package routes
import (
"net/http"
"time"
"github.com/juanatsap/cv-site/internal/handlers"
"github.com/juanatsap/cv-site/internal/middleware"
)
// Setup configures all application routes and middleware
func Setup(cvHandler *handlers.CVHandler, healthHandler *handlers.HealthHandler) http.Handler {
mux := http.NewServeMux()
// Shortcut routes for default CV (year-aware) - MUST be before "/" route
// Pattern: /cv-jamr-{year}-{lang}.pdf (e.g., /cv-jamr-2025-en.pdf)
mux.HandleFunc("/cv-jamr-", cvHandler.DefaultCVShortcut)
// Public routes
mux.HandleFunc("/", cvHandler.Home)
mux.HandleFunc("/cv", cvHandler.CVContent)
mux.HandleFunc("/health", healthHandler.Check)
// HTMX endpoints for interactive controls
mux.HandleFunc("/switch-language", cvHandler.SwitchLanguage)
mux.HandleFunc("/toggle/length", cvHandler.ToggleLength)
mux.HandleFunc("/toggle/icons", cvHandler.ToggleIcons)
mux.HandleFunc("/toggle/theme", cvHandler.ToggleTheme)
// Protected PDF endpoint with rate limiting (3 requests/minute per IP)
pdfRateLimiter := middleware.NewRateLimiter(3, 1*time.Minute)
protectedPDFHandler := middleware.OriginChecker(
pdfRateLimiter.Middleware(
http.HandlerFunc(cvHandler.ExportPDF),
),
)
mux.Handle("/export/pdf", protectedPDFHandler)
// Static files with cache control
staticHandler := http.StripPrefix("/static/", http.FileServer(http.Dir("static")))
mux.Handle("/static/", middleware.CacheControl(staticHandler))
// Apply comprehensive middleware chain
// Order: Recovery → Logger → SecurityHeaders → Preferences → Mux
handler := middleware.Recovery(
middleware.Logger(
middleware.SecurityHeaders(
middleware.PreferencesMiddleware(mux),
),
),
)
return handler
}