Commit dd58b9f

bryfry <bryon@fryer.io>
2025-07-24 09:15:33
Plan Chapter 3 tasks: Configuration and Error Handling
Add comprehensive task definitions for Let's Go Chapter 3: **Task 3.1: Managing Configuration Settings** - Command-line flags and environment variables - Configurable ports, paths, and environment modes - Configuration struct and validation - Replace hardcoded values with flexible config system **Task 3.2: Structured Logging** - Separate info/error loggers with proper formatting - Request logging and contextual error logging - Configurable log levels and output destinations - Replace ad-hoc logging with structured system **Task 3.3: Dependency Injection** - Formalize application struct as dependency container - Clean dependency injection patterns throughout app - Interfaces for future external services (DB, email) - Remove global variables and improve testability **Task 3.4: Centralized Error Handling** - Consistent HTTP error responses and user-friendly error pages - Proper error logging with context and stack traces - Error categorization (client vs server errors) - Helper methods for common error scenarios **Task 3.5: Isolating the Application Routes** - Extract route definitions from main.go to routes.go - Clean route organization and documentation - Prepare structure for middleware integration - Improve code maintainability and separation of concerns All tasks build on each other and will be implemented in stacked branches. Each task includes comprehensive acceptance criteria, testing strategy, and success metrics. See: docs/project_plan.md for task overview
1 parent 63f739a
docs/todo/task_3.1.md
@@ -0,0 +1,130 @@
+---
+task_id: "3.1"
+title: "Managing Configuration Settings"
+status: "pending"
+priority: "high"
+estimated_effort: "medium"
+created: "2025-07-24"
+assigned_to: "pair"
+related_rfds: "RFD 004"
+---
+
+# Task 3.1: Managing Configuration Settings
+
+## Summary
+
+Implement configuration management for buylater.email using command-line flags, environment variables, and sensible defaults to make the application more flexible and production-ready.
+
+## Motivation
+
+Following Let's Go Chapter 3.1, we need to move away from hardcoded configuration values (like port 4000) to a flexible configuration system. This will allow easy deployment across different environments and better operational control.
+
+## Acceptance Criteria
+
+- [ ] Add command-line flag support for server address/port configuration
+- [ ] Implement environment variable fallbacks for configuration
+- [ ] Create configuration struct to hold all application settings
+- [ ] Add configuration for template directory paths
+- [ ] Add configuration for static file directory paths
+- [ ] Support debug/production mode configuration
+- [ ] Provide sensible defaults for all configuration options
+- [ ] Update application struct to use configuration
+- [ ] Document all available configuration options
+
+## Technical Requirements
+
+### Configuration Structure
+```go
+type config struct {
+    port      int
+    env       string
+    staticDir string
+    htmlDir   string
+}
+```
+
+### Implementation Details
+- Use Go's `flag` package for command-line arguments
+- Support environment variable overrides
+- Implement configuration validation
+- Update main.go to parse and use configuration
+- Make template and static file paths configurable
+- Add help text for all configuration options
+
+### Dependencies
+- [ ] Task 1.10 completed (HTTP handler interface foundation)
+
+## Testing Strategy
+
+### Unit Tests
+- [ ] Test configuration parsing with various inputs
+- [ ] Verify default values are applied correctly
+- [ ] Test environment variable precedence
+
+### Integration Tests  
+- [ ] Application starts with default configuration
+- [ ] Command-line flags override defaults correctly
+- [ ] Environment variables work as expected
+
+### Manual Testing
+- [ ] Start server with default settings
+- [ ] Test custom port: `go run ./cmd/web -port=8080`
+- [ ] Test environment variables: `PORT=3000 go run ./cmd/web`
+- [ ] Verify help output: `go run ./cmd/web -help`
+- [ ] Test different environment modes (development/production)
+
+## Definition of Done
+
+- [ ] All acceptance criteria met
+- [ ] All specified tests pass
+- [ ] Code follows project conventions (go fmt, go vet)
+- [ ] Configuration system is well-documented
+- [ ] No hardcoded values remain in application
+- [ ] Environment-specific behavior works correctly
+- [ ] Human verification completed successfully
+- [ ] Git commit created with proper message format
+
+## Implementation Notes
+
+### Approach
+Replace hardcoded values with a flexible configuration system that supports multiple sources (flags, environment, defaults) with proper precedence.
+
+### Key Files to Modify
+- `cmd/web/main.go` - Add configuration parsing and usage
+- `cmd/web/handlers.go` - Update to use configurable paths
+
+### Configuration Options
+- `port`: Server port (default: 4000)
+- `env`: Environment mode (default: "development")
+- `static-dir`: Static files directory (default: "./ui/static")
+- `html-dir`: HTML templates directory (default: "./ui/html")
+
+### Potential Risks
+- Configuration parsing errors could prevent startup
+- Path resolution issues in different environments
+- Environment variable naming conflicts
+
+## Success Metrics
+
+Flexible, configurable buylater.email application that can be easily deployed and managed across different environments with proper configuration management.
+
+## Related Tasks
+
+- **Blocks**: Future deployment and environment-specific configurations
+- **Blocked by**: Task 1.10 (needs application struct foundation)
+- **Related**: Production deployment and operational management
+
+---
+
+## Implementation Log
+
+_Implementation details will be recorded here during development._
+
+---
+
+## Final Verification
+
+**Human Tester**: [Name]  
+**Date Completed**: [YYYY-MM-DD]  
+**Verification Result**: [Pass/Fail]  
+**Notes**: [Any issues found or additional observations]
\ No newline at end of file
docs/todo/task_3.2.md
@@ -0,0 +1,139 @@
+---
+task_id: "3.2"
+title: "Structured Logging"
+status: "pending"
+priority: "high"
+estimated_effort: "medium"
+created: "2025-07-24"
+assigned_to: "pair"
+related_rfds: "RFD 004"
+---
+
+# Task 3.2: Structured Logging
+
+## Summary
+
+Implement structured logging system for buylater.email with different log levels, proper formatting, and configurable output to improve debugging and operational monitoring.
+
+## Motivation
+
+Following Let's Go Chapter 3.2, we need to replace basic log.Println() calls with a structured logging system that provides better visibility into application behavior and makes debugging easier in production.
+
+## Acceptance Criteria
+
+- [ ] Create separate loggers for different types of messages (info, error)
+- [ ] Implement structured log message formatting with timestamps
+- [ ] Add log levels (INFO, ERROR, WARN) with proper filtering
+- [ ] Configure log output destinations (stdout, stderr, files)
+- [ ] Add contextual logging throughout the application
+- [ ] Implement request logging for HTTP requests
+- [ ] Add configuration for log level and output format
+- [ ] Update all existing logging to use structured format
+- [ ] Add operational logging for key application events
+
+## Technical Requirements
+
+### Logger Structure
+```go
+type application struct {
+    config config
+    logger struct {
+        info  *log.Logger
+        error *log.Logger
+    }
+    serviceName string
+}
+```
+
+### Implementation Details
+- Use Go's standard `log` package with custom configuration
+- Create separate loggers for different message types
+- Implement consistent log message formatting
+- Add request ID tracking for better traceability
+- Include relevant context in all log messages
+- Configure log prefixes and formatting flags
+
+### Dependencies  
+- [ ] Task 3.1 completed (configuration management foundation)
+
+## Testing Strategy
+
+### Unit Tests
+- [ ] Test logger initialization and configuration
+- [ ] Verify log message formatting and output
+- [ ] Test different log levels and filtering
+
+### Integration Tests
+- [ ] Log messages appear in correct output streams
+- [ ] Request logging captures all HTTP requests
+- [ ] Error logging works for all error conditions
+
+### Manual Testing
+- [ ] Start application and verify startup logging
+- [ ] Make HTTP requests and check request logs
+- [ ] Trigger errors and verify error logging format
+- [ ] Test different log level configurations
+- [ ] Verify log output goes to correct destinations
+
+## Definition of Done
+
+- [ ] All acceptance criteria met
+- [ ] All specified tests pass
+- [ ] Code follows project conventions (go fmt, go vet)
+- [ ] Logging system is consistent throughout application
+- [ ] Log messages are informative and properly formatted
+- [ ] No remaining uses of basic log.Println()
+- [ ] Human verification completed successfully
+- [ ] Git commit created with proper message format
+
+## Implementation Notes
+
+### Approach
+Replace ad-hoc logging with a structured system that provides clear, consistent, and useful log messages for both development and production operations.
+
+### Key Files to Modify
+- `cmd/web/main.go` - Initialize structured loggers
+- `cmd/web/handlers.go` - Update all logging calls
+- Add request logging middleware (prepare for future middleware)
+
+### Log Message Categories
+- **INFO**: Application startup, configuration, normal operations
+- **ERROR**: Application errors, HTTP errors, template errors
+- **REQUEST**: HTTP request details (method, path, response code, duration)
+
+### Log Message Format
+```
+2025/07/24 10:30:45 INFO  Starting server on http://localhost:4000
+2025/07/24 10:30:46 ERROR Template parsing failed: template not found
+2025/07/24 10:30:47 INFO  Request: GET / -> 200 OK (15ms)
+```
+
+### Potential Risks
+- Log volume could impact performance
+- Log formatting changes might break log parsing tools
+- Missing error context could reduce debugging effectiveness
+
+## Success Metrics
+
+Professional logging system that provides clear visibility into buylater.email application behavior with structured, consistent, and useful log messages for operations and debugging.
+
+## Related Tasks
+
+- **Blocks**: Future monitoring, alerting, and operational tools
+- **Blocked by**: Task 3.1 (needs configuration system)
+- **Related**: Error handling, monitoring, and debugging
+
+---
+
+## Implementation Log
+
+_Implementation details will be recorded here during development._
+
+---
+
+## Final Verification
+
+**Human Tester**: [Name]  
+**Date Completed**: [YYYY-MM-DD]  
+**Verification Result**: [Pass/Fail]  
+**Notes**: [Any issues found or additional observations]
\ No newline at end of file
docs/todo/task_3.3.md
@@ -0,0 +1,139 @@
+---
+task_id: "3.3"
+title: "Dependency Injection"
+status: "pending"
+priority: "high"
+estimated_effort: "medium"
+created: "2025-07-24"
+assigned_to: "pair"
+related_rfds: "RFD 004"
+---
+
+# Task 3.3: Dependency Injection
+
+## Summary
+
+Implement proper dependency injection pattern for buylater.email to improve testability, maintainability, and separation of concerns by cleanly managing application dependencies.
+
+## Motivation
+
+Following Let's Go Chapter 3.3, we need to formalize our dependency injection approach to make the application more modular, testable, and maintainable. This builds on our application struct pattern to properly inject dependencies throughout the system.
+
+## Acceptance Criteria
+
+- [ ] Refactor application struct to be the central dependency container
+- [ ] Implement dependency injection for all handlers
+- [ ] Create interfaces for external dependencies (future database, email service)
+- [ ] Update handler methods to receive dependencies through application struct
+- [ ] Remove global variables and direct dependency access
+- [ ] Implement clean dependency initialization in main.go
+- [ ] Prepare structure for future database and email service injection
+- [ ] Add dependency validation and initialization checks
+- [ ] Document dependency injection patterns used
+
+## Technical Requirements
+
+### Application Structure
+```go
+type application struct {
+    config config
+    logger struct {
+        info  *log.Logger
+        error *log.Logger
+    }
+    // Future dependencies will be added here:
+    // db     database.DB
+    // mailer mailer.Service
+}
+```
+
+### Implementation Details
+- Make application struct the single source of dependencies
+- Pass application instance to all handlers that need dependencies
+- Create initialization functions for complex dependencies
+- Implement clean separation between dependency creation and usage
+- Add validation for required dependencies
+- Prepare interfaces for future external services
+
+### Dependencies
+- [ ] Task 3.2 completed (structured logging system)
+
+## Testing Strategy
+
+### Unit Tests
+- [ ] Test dependency initialization and validation
+- [ ] Verify proper dependency injection throughout handlers
+- [ ] Test application struct methods
+
+### Integration Tests
+- [ ] All handlers work with injected dependencies
+- [ ] Dependency initialization is robust
+- [ ] Application starts correctly with all dependencies
+
+### Manual Testing
+- [ ] Application starts without dependency errors
+- [ ] All handlers function correctly with injected dependencies
+- [ ] Logging works through injected loggers
+- [ ] Configuration is properly available throughout app
+
+## Definition of Done
+
+- [ ] All acceptance criteria met
+- [ ] All specified tests pass
+- [ ] Code follows project conventions (go fmt, go vet)
+- [ ] Clean dependency injection pattern implemented
+- [ ] No global variables or direct dependency access
+- [ ] Dependencies are properly initialized and validated
+- [ ] Human verification completed successfully
+- [ ] Git commit created with proper message format
+
+## Implementation Notes
+
+### Approach
+Formalize the dependency injection pattern started in Task 1.10 by making the application struct a proper dependency container and ensuring all dependencies flow cleanly through the application.
+
+### Key Files to Modify
+- `cmd/web/main.go` - Dependency initialization and injection
+- `cmd/web/handlers.go` - Update to use injected dependencies
+- Future: Add interfaces for external services (database, email)
+
+### Dependency Injection Patterns
+1. **Constructor Pattern**: Initialize dependencies in main()
+2. **Method Injection**: Pass application struct to handler methods
+3. **Interface Segregation**: Define interfaces for external services
+4. **Dependency Container**: Application struct holds all dependencies
+
+### Current Dependencies to Inject
+- Configuration settings
+- Structured loggers (info, error)
+- Future: Database connection, email service, template cache
+
+### Potential Risks
+- Over-engineering simple dependency needs
+- Circular dependency issues
+- Complex initialization order requirements
+
+## Success Metrics
+
+Clean, maintainable dependency injection system that makes buylater.email more testable and modular while preparing for future service integrations.
+
+## Related Tasks
+
+- **Blocks**: Database integration, email service, testing improvements
+- **Blocked by**: Task 3.2 (needs structured logging)
+- **Related**: Testing, modularity, and future service integrations
+
+---
+
+## Implementation Log
+
+_Implementation details will be recorded here during development._
+
+---
+
+## Final Verification
+
+**Human Tester**: [Name]  
+**Date Completed**: [YYYY-MM-DD]  
+**Verification Result**: [Pass/Fail]  
+**Notes**: [Any issues found or additional observations]
\ No newline at end of file
docs/todo/task_3.4.md
@@ -0,0 +1,145 @@
+---
+task_id: "3.4"
+title: "Centralized Error Handling"
+status: "pending"
+priority: "high"
+estimated_effort: "medium"
+created: "2025-07-24"
+assigned_to: "pair"
+related_rfds: "RFD 004"
+---
+
+# Task 3.4: Centralized Error Handling
+
+## Summary
+
+Implement centralized error handling system for buylater.email with consistent error responses, proper logging, and user-friendly error pages to improve reliability and user experience.
+
+## Motivation
+
+Following Let's Go Chapter 3.4, we need to replace scattered error handling with a centralized system that provides consistent error responses, proper logging, and graceful error recovery throughout the application.
+
+## Acceptance Criteria
+
+- [ ] Create centralized error handling helper methods
+- [ ] Implement consistent HTTP error response format
+- [ ] Add proper error logging with context and stack traces
+- [ ] Create user-friendly error pages (404, 500, etc.)
+- [ ] Implement error recovery mechanisms
+- [ ] Add error categorization (client errors vs server errors)
+- [ ] Update all handlers to use centralized error handling
+- [ ] Add error monitoring and alerting preparation
+- [ ] Implement graceful degradation for non-critical errors
+
+## Technical Requirements
+
+### Error Handler Structure
+```go
+func (app *application) serverError(w http.ResponseWriter, err error) {
+    // Log error with stack trace
+    // Return 500 error page
+}
+
+func (app *application) clientError(w http.ResponseWriter, status int) {
+    // Log client error
+    // Return appropriate error page
+}
+
+func (app *application) notFound(w http.ResponseWriter) {
+    // Return 404 error page
+}
+```
+
+### Implementation Details
+- Create error helper methods on application struct
+- Implement proper error logging with context
+- Create HTML templates for error pages
+- Add error categorization and handling logic
+- Update all handlers to use centralized error methods
+- Implement consistent error response format
+
+### Dependencies
+- [ ] Task 3.3 completed (dependency injection for clean error handler access)
+
+## Testing Strategy
+
+### Unit Tests
+- [ ] Test error handler methods with various error types
+- [ ] Verify error logging includes proper context
+- [ ] Test error response formatting
+
+### Integration Tests
+- [ ] 404 errors return proper not found page
+- [ ] 500 errors return proper server error page
+- [ ] Error logging works for all error conditions
+
+### Manual Testing
+- [ ] Visit non-existent routes to test 404 handling
+- [ ] Trigger server errors to test 500 handling
+- [ ] Verify error pages are user-friendly and branded
+- [ ] Check error logs contain useful debugging information
+- [ ] Test error handling in all existing handlers
+
+## Definition of Done
+
+- [ ] All acceptance criteria met
+- [ ] All specified tests pass
+- [ ] Code follows project conventions (go fmt, go vet)
+- [ ] Consistent error handling throughout application
+- [ ] User-friendly error pages with proper branding
+- [ ] Comprehensive error logging for debugging
+- [ ] Human verification completed successfully
+- [ ] Git commit created with proper message format
+
+## Implementation Notes
+
+### Approach
+Replace ad-hoc error handling with a centralized system that provides consistent, user-friendly error responses while maintaining comprehensive error logging for operations.
+
+### Key Files to Create/Modify
+- `cmd/web/helpers.go` - New file for error handling helpers
+- `ui/html/pages/error.tmpl` - Generic error page template
+- `ui/html/pages/404.tmpl` - Not found page template
+- `cmd/web/handlers.go` - Update all handlers to use centralized errors
+
+### Error Page Design
+- Consistent with buylater.email branding
+- User-friendly error messages
+- Helpful navigation options
+- No technical details exposed to users
+- Professional appearance
+
+### Error Categories
+- **Client Errors (4xx)**: Bad requests, not found, method not allowed
+- **Server Errors (5xx)**: Template errors, database errors, internal failures
+- **Recovery**: Graceful handling of non-critical errors
+
+### Potential Risks
+- Error handling overhead could impact performance
+- Over-generic error messages might reduce debugging info
+- Error page template failures could cause recursive errors
+
+## Success Metrics
+
+Professional error handling system that provides excellent user experience during errors while maintaining comprehensive error logging and monitoring capabilities for operations.
+
+## Related Tasks
+
+- **Blocks**: Production deployment, monitoring, and reliability improvements
+- **Blocked by**: Task 3.3 (needs dependency injection)
+- **Related**: User experience, logging, and operational monitoring
+
+---
+
+## Implementation Log
+
+_Implementation details will be recorded here during development._
+
+---
+
+## Final Verification
+
+**Human Tester**: [Name]  
+**Date Completed**: [YYYY-MM-DD]  
+**Verification Result**: [Pass/Fail]  
+**Notes**: [Any issues found or additional observations]
\ No newline at end of file
docs/todo/task_3.5.md
@@ -0,0 +1,149 @@
+---
+task_id: "3.5"
+title: "Isolating the Application Routes"
+status: "pending"
+priority: "medium"
+estimated_effort: "small"
+created: "2025-07-24"
+assigned_to: "pair"
+related_rfds: "RFD 004"
+---
+
+# Task 3.5: Isolating the Application Routes
+
+## Summary
+
+Refactor buylater.email route definitions into a separate routes file to improve code organization, maintainability, and prepare for more complex routing patterns and middleware.
+
+## Motivation
+
+Following Let's Go Chapter 3.5, we need to separate route definitions from main.go to improve code organization and make route management more maintainable as the application grows.
+
+## Acceptance Criteria
+
+- [ ] Create dedicated routes.go file for route definitions
+- [ ] Move all route registration logic from main.go to routes function
+- [ ] Implement clean routes() function that returns configured mux
+- [ ] Maintain all existing route functionality
+- [ ] Group related routes logically with clear comments
+- [ ] Prepare structure for future middleware integration
+- [ ] Update main.go to use routes function
+- [ ] Document route organization and patterns
+- [ ] Ensure route definitions are easy to understand and modify
+
+## Technical Requirements
+
+### Routes Structure
+```go
+// routes.go
+func (app *application) routes() *http.ServeMux {
+    mux := http.NewServeMux()
+    
+    // Static files
+    // Application routes
+    // API routes (future)
+    
+    return mux
+}
+```
+
+### Implementation Details
+- Create new `cmd/web/routes.go` file
+- Move all mux.Handle() and mux.HandleFunc() calls to routes function
+- Organize routes by category (static, pages, API, etc.)
+- Add clear comments explaining route patterns
+- Return configured mux from routes function
+- Update main.go to call routes function
+
+### Dependencies
+- [ ] Task 3.4 completed (centralized error handling system)
+
+## Testing Strategy
+
+### Unit Tests
+- [ ] Test routes function returns properly configured mux
+- [ ] Verify all routes are registered correctly
+
+### Integration Tests
+- [ ] All existing routes continue to work
+- [ ] Route patterns match correctly
+- [ ] Handler assignments are correct
+
+### Manual Testing
+- [ ] Test all existing routes: /, /submit, /about, /confirm/{token}
+- [ ] Verify static file serving still works
+- [ ] Check that POST /submit still functions
+- [ ] Confirm no routes were lost in refactoring
+
+## Definition of Done
+
+- [ ] All acceptance criteria met
+- [ ] All specified tests pass
+- [ ] Code follows project conventions (go fmt, go vet)
+- [ ] Clean separation of concerns achieved
+- [ ] All routes properly organized and documented
+- [ ] No functional regressions in route handling
+- [ ] Human verification completed successfully
+- [ ] Git commit created with proper message format
+
+## Implementation Notes
+
+### Approach
+Extract route definitions from main.go into a dedicated, well-organized routes function that makes route management cleaner and more maintainable.
+
+### Key Files to Create/Modify
+- `cmd/web/routes.go` - New file with routes function
+- `cmd/web/main.go` - Update to use routes function
+
+### Route Organization
+```go
+// Static files
+mux.Handle("GET /static/", ...)
+
+// Page routes
+mux.Handle("GET /{$}", ...)
+mux.Handle("GET /submit", ...)
+mux.Handle("GET /about", ...)
+
+// Form processing
+mux.Handle("POST /submit", ...)
+
+// API routes (future)
+mux.Handle("GET /confirm/{token}", ...)
+```
+
+### Benefits
+- Cleaner main.go focused on application startup
+- Easier route management and modification
+- Better organization for growing route complexity
+- Preparation for middleware integration
+- Clearer separation of concerns
+
+### Potential Risks
+- Route function could become unwieldy as application grows
+- Need to maintain proper route organization as features are added
+
+## Success Metrics
+
+Clean, well-organized route definitions that are easy to understand, modify, and maintain while preserving all existing functionality.
+
+## Related Tasks
+
+- **Blocks**: Future middleware implementation and complex routing
+- **Blocked by**: Task 3.4 (needs error handling foundation)
+- **Related**: Code organization, maintainability, and middleware preparation
+
+---
+
+## Implementation Log
+
+_Implementation details will be recorded here during development._
+
+---
+
+## Final Verification
+
+**Human Tester**: [Name]  
+**Date Completed**: [YYYY-MM-DD]  
+**Verification Result**: [Pass/Fail]  
+**Notes**: [Any issues found or additional observations]
\ No newline at end of file
docs/project_plan.md
@@ -18,6 +18,11 @@ Phase 1 lays the groundwork by methodically working through the Let's Go book, c
 | 1.8  | HTML Templating and Inheritance         | Completed | Medium | 2.8     | [task_1.8.md](todo/task_1.8.md) |
 | 1.9  | Serving Static Files                    | Completed | Small  | 2.9     | [task_1.9.md](todo/task_1.9.md) |
 | 1.10 | The HTTP Handler Interface              | Completed | Medium | 2.10    | [task_1.10.md](todo/task_1.10.md) |
+| 3.1  | Managing Configuration Settings         | Pending   | Medium | 3.1     | [task_3.1.md](todo/task_3.1.md) |
+| 3.2  | Structured Logging                      | Pending   | Medium | 3.2     | [task_3.2.md](todo/task_3.2.md) |
+| 3.3  | Dependency Injection                    | Pending   | Medium | 3.3     | [task_3.3.md](todo/task_3.3.md) |
+| 3.4  | Centralized Error Handling             | Pending   | Medium | 3.4     | [task_3.4.md](todo/task_3.4.md) |
+| 3.5  | Isolating the Application Routes        | Pending   | Small  | 3.5     | [task_3.5.md](todo/task_3.5.md) |
 
 ## Status Legend
 - **Completed** - Implemented and verified