# Architecture Documentation ## Overview This CV website is built following Go best practices with a focus on: - **Simplicity**: Clean, readable code - **Maintainability**: Well-structured packages - **Reliability**: Proper error handling and logging - **Performance**: Efficient template caching - **Security**: Multiple layers of protection ## Architecture Patterns ### 1. Package Structure (Internal Directory Pattern) ``` cv/ ├── main.go # Application entry point └── internal/ # Private packages (cannot be imported by other projects) ├── config/ # Configuration management ├── handlers/ # HTTP request handlers ├── middleware/ # HTTP middleware ├── models/ # Data models and business logic └── templates/ # Template management ``` **Benefits**: - Clear separation of concerns - Encapsulation (internal packages cannot be imported externally) - Easy to test and maintain - Scalable structure ### 2. Dependency Injection Handlers and services receive their dependencies through constructors: ```go // ✅ Good: Dependencies injected type CVHandler struct { templates *templates.Manager } func NewCVHandler(tmpl *templates.Manager) *CVHandler { return &CVHandler{templates: tmpl} } // ❌ Bad: Global state var globalTemplates *template.Template ``` **Benefits**: - Testability (easy to mock dependencies) - Flexibility (swap implementations) - Explicit dependencies ### 3. Error Handling Strategy Three-tier error handling: ```go // 1. Domain errors (AppError) type AppError struct { Err error // Original error Message string // User-friendly message StatusCode int // HTTP status Internal bool // Hide details from client } // 2. Error constructors for common cases NotFoundError("Resource not found") BadRequestError("Invalid input") InternalError(err) // 3. Centralized error handler HandleError(w, r, err) ``` **Benefits**: - Consistent error responses - Proper logging - Security (internal errors hidden) - Client-specific responses (JSON, HTML, HTMX) ### 4. Middleware Chain Onion-like middleware wrapping: ``` Request → Recovery → Logger → Security → Handler → Response ↑ ↑ ↑ ↑ Panics Logging Headers Business Logic ``` **Implementation**: ```go handler := middleware.Recovery( middleware.Logger( middleware.SecurityHeaders(mux), ), ) ``` **Benefits**: - Separation of cross-cutting concerns - Reusable components - Easy to add/remove middleware - Predictable request flow ## Component Details ### Configuration Management (`internal/config`) **Pattern**: Environment-based configuration with sensible defaults ```go cfg := config.Load() // Reads from env vars cfg.Server.Port // Defaults to "1999" cfg.Template.HotReload // Auto-detects development mode ``` **Features**: - Environment variable support - Type-safe configuration - Development/production modes - Sensible defaults ### Template Management (`internal/templates`) **Pattern**: Template manager with hot-reload support ```go manager := templates.NewManager(cfg) manager.Render("index.html") // Hot-reloads in dev mode ``` **Features**: - Centralized template loading - Custom template functions - Hot-reload in development - Thread-safe caching - Graceful error handling ### HTTP Handlers (`internal/handlers`) **Pattern**: Handler structs with methods ```go type CVHandler struct { templates *templates.Manager } func (h *CVHandler) Home(w http.ResponseWriter, r *http.Request) func (h *CVHandler) CVContent(w http.ResponseWriter, r *http.Request) ``` **Features**: - Clean separation of routes - Dependency injection - Consistent error handling - HTMX-aware responses ### Middleware (`internal/middleware`) **Components**: 1. **Recovery**: Catches panics, logs stack traces 2. **Logger**: Structured request/response logging 3. **SecurityHeaders**: CSP, XSS protection, clickjacking prevention ## Security Features ### 1. Security Headers ```go X-Frame-Options: SAMEORIGIN // Prevent clickjacking X-Content-Type-Options: nosniff // Prevent MIME sniffing X-XSS-Protection: 1; mode=block // XSS protection Content-Security-Policy: ... // Restrict resource loading Referrer-Policy: strict-origin-... // Control referrer info ``` ### 2. Request Timeouts ```go server := &http.Server{ ReadTimeout: 15 * time.Second, // Prevent slow clients WriteTimeout: 15 * time.Second, // Prevent slow responses IdleTimeout: 120 * time.Second, // Keep-alive timeout } ``` ### 3. Error Information Hiding ```go appErr := NewAppError(err, "Database error", 500, true) // Client sees: "Internal Server Error" // Logs show: actual error details ``` ## Performance Optimizations ### 1. Template Caching ```go // Templates parsed once at startup templates := template.New("").ParseGlob("*.html") // Hot-reload only in development if cfg.Template.HotReload { templates.ParseGlob("*.html") // Re-parse on each request } ``` ### 2. Static File Caching ```go // Development: 1 hour cache // Production: 1 day cache Cache-Control: public, max-age=86400 ``` ### 3. HTTP/2 Support Go's `http.Server` automatically supports HTTP/2 when using HTTPS. ## Graceful Shutdown ```go // 1. Listen for signals shutdown := make(chan os.Signal, 1) signal.Notify(shutdown, os.Interrupt, syscall.SIGTERM) // 2. Shutdown with timeout ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) server.Shutdown(ctx) ``` **Features**: - Finish in-flight requests - 30-second grace period - Forced shutdown if timeout exceeded ## HTMX Integration Patterns ### 1. Partial Content Rendering ```go // Full page: / // Partial: /cv?lang=es (returns only content div) if r.Header.Get("HX-Request") != "" { // HTMX request - return partial renderPartial() } else { // Regular request - return full page renderFull() } ``` ### 2. Language Switching ```html ``` **Benefits**: - No JavaScript frameworks needed - Progressive enhancement - Server-rendered content - Better SEO ## Testing Strategy ### Manual Testing ```bash # 1. Health check curl http://localhost:1999/health # 2. Happy path curl "http://localhost:1999/?lang=en" # 3. Error cases curl "http://localhost:1999/?lang=invalid" # 400 Bad Request # 4. HTMX requests curl -H "HX-Request: true" "http://localhost:1999/cv?lang=es" # 5. Security headers curl -I http://localhost:1999/ ``` ### Future: Automated Tests ```go func TestCVHandler_Home(t *testing.T) { // Setup cfg := &config.TemplateConfig{Dir: "../../templates"} tmpl, _ := templates.NewManager(cfg) handler := handlers.NewCVHandler(tmpl) // Execute req := httptest.NewRequest("GET", "/?lang=en", nil) w := httptest.NewRecorder() handler.Home(w, req) // Assert assert.Equal(t, 200, w.Code) } ``` ## Deployment Options ### 1. Standalone Binary ```bash go build -o cv-server -ldflags="-s -w" . ./cv-server ``` ### 2. Docker ```bash docker build -t cv-server . docker run -p 1999:1999 cv-server ``` ### 3. Cloud Platforms **Recommended**: - **Fly.io**: `fly launch` (auto-detects Dockerfile) - **Railway**: Connect GitHub, auto-deploy - **Google Cloud Run**: Serverless containers - **AWS ECS/Fargate**: Container orchestration ## Best Practices Applied 1. ✅ **Standard Project Layout**: Internal packages, clear structure 2. ✅ **Error Handling**: Custom error types, consistent handling 3. ✅ **Logging**: Structured, informative logs 4. ✅ **Configuration**: Environment-based with defaults 5. ✅ **Security**: Multiple layers of protection 6. ✅ **Graceful Shutdown**: Clean service termination 7. ✅ **Dependency Injection**: Testable, maintainable code 8. ✅ **Middleware Pattern**: Separation of concerns 9. ✅ **Template Management**: Efficient, cached rendering 10. ✅ **Production-Ready**: Timeouts, health checks, monitoring hooks ## Scaling Considerations ### Current State: Single Instance - Perfect for CV website (low traffic) - ~1000s of requests/second capability - Minimal resource usage ### Future: Multi-Instance (if needed) 1. **Load Balancer**: nginx, Caddy, or cloud LB 2. **Shared Storage**: For static files (S3, Cloud Storage) 3. **Health Checks**: `/health` endpoint already implemented 4. **Metrics**: Add Prometheus metrics 5. **Caching**: Redis for template cache (if very high traffic) ## Monitoring & Observability ### Current Implementation - **Structured Logging**: Request/response logging - **Health Check**: `/health` endpoint - **Error Tracking**: Detailed error logs with stack traces ### Future Enhancements ```go // Metrics prometheus.InstrumentHandler("/", handler) // Distributed Tracing opentelemetry.Trace(handler) // Error Monitoring sentry.CaptureException(err) ``` ## Conclusion This architecture provides: - ✅ Clean, maintainable code - ✅ Production-ready error handling - ✅ Security best practices - ✅ Performance optimizations - ✅ Easy deployment options - ✅ Room for future growth Perfect for a professional CV website with potential to scale.