docs: Rename all documentation with numbered prefixes for clarity
RENAMING: - README.md → 0-README.md (start here) - ARCHITECTURE.md → 1-ARCHITECTURE.md (backend overview) - MODERN-WEB-TECHNIQUES.md → 2-MODERN-WEB-TECHNIQUES.md (frontend architecture) - API.md → 3-API.md (API reference) - HYPERSCRIPT-RULES.md → 4-HYPERSCRIPT-RULES.md (conventions) - ZOOM_IMPLEMENTATION.md → 5-ZOOM-IMPLEMENTATION.md (zoom feature) - USER_GUIDE.md → 6-USER-GUIDE.md (user docs) - CUSTOMIZATION.md → 7-CUSTOMIZATION.md (customization guide) - DEPLOYMENT.md → 8-DEPLOYMENT.md (deployment) - SECURITY.md → 9-SECURITY.md (security) - PRIVACY.md → 10-PRIVACY.md (privacy policy) CROSS-REFERENCE UPDATES: - Updated all internal links in all documentation files - Updated README navigation with numbered references - Added # column to documentation tables - Made all links use numbered filenames BENEFITS: ✅ Clear reading order (0-10) ✅ Logical progression (overview → technical → user → ops → compliance) ✅ Easy sorting and navigation ✅ Professional organization ✅ Zero broken links
This commit is contained in:
@@ -0,0 +1,395 @@
|
||||
# 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
|
||||
<button hx-get="/cv?lang=es"
|
||||
hx-target="#cv-content"
|
||||
hx-swap="innerHTML">
|
||||
🇪🇸 Español
|
||||
</button>
|
||||
```
|
||||
|
||||
**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.
|
||||
Reference in New Issue
Block a user