go build- Build the binarygo run .- Run the applicationgo test ./...- Run all testsgo test -v ./pkg/...- Run package tests with verbose outputgo test -v ./pkg/auth/- Run authentication testsgo test -v ./pkg/web/- Run web handler testsgo test -run TestName- Run specific test./staticsend --port 3000 --db ./data/app.db- Run with custom port and databasego mod tidy- Clean up dependenciesgo fmt ./...- Format all Go codego vet ./...- Run static analysis
- Use Go 1.21+ features
- Follow standard Go formatting (gofmt)
- Use
camelCasefor variables and functions - Use
PascalCasefor exported identifiers - Prefer short, descriptive names
- Group imports: stdlib, third-party, local
- Use absolute import paths for local packages
- Avoid dot imports
- Always handle errors explicitly
- Use
fmt.Errorf("context: %w", err)for wrapped errors - Return early on errors
- Use sentinel errors for expected error conditions
- Use meaningful type names
- Add JSON tags for API structs
- Include comments for exported types
- Use
time.Timefor timestamps
- Use chi router for HTTP routing
- JSON responses should use consistent structure
- Validate all incoming requests
- Use middleware for common functionality (auth, logging, rate limiting)
- API Design: Only submission endpoints needed (no management API)
- Test-Driven Development: Write tests before or alongside feature implementation
- Package Coverage: Every package should have corresponding *_test.go files
- Table-driven tests for complex logic with multiple scenarios
- Integration Tests: Test complete workflows from HTTP request to database/email
- Mock external dependencies (Turnstile, SMTP, database) for reliable testing
- Test both success and error cases comprehensively
- Concurrency testing for email worker pool and concurrent submissions
- Benchmark tests for performance-critical components
- Test coverage goal: 80%+ for all packages
- Run tests frequently:
go test ./...after every significant change - Test data: Use test fixtures and setup/teardown functions for consistent test environment
- Use sqlc for type-safe SQL queries
- SQLite for development and production
- Use transactions for write operations
- Handle database migrations with goose
- Asynchronous processing with worker pool
- Configurable queue size and worker count
- Automatic retries with exponential backoff
- Graceful shutdown support
- Synchronous fallback option available
cmd/
staticsend/ # Main application
pkg/
api/ # HTTP handlers and routing
auth/ # Authentication logic
database/ # Database operations
email/ # Email sending service
middleware/ # HTTP middleware
models/ # Data models
turnstile/ # Cloudflare Turnstile integration
utils/ # Utility functions
internal/
# Private application code
templates/ # HTML templates for HTMX UI
migrations/ # Database migrations
- chi: HTTP router
- sqlc: SQL code generation
- testify: Testing utilities
- go-sqlite3: SQLite driver
- jwt-go: JWT authentication
- mail: SMTP email sending
Simple project tracking with checkable tasks and clear current focus.
# PLAN.md - staticSend Development Plan
**Current Task:** [Brief description of what's being worked on now]
**Last Task:** [Brief description of the most recently completed task]
## Stage 1: Core Foundation
- [ ] Initialize Go module structure
- [ ] Set up basic HTTP server with chi router
- [ ] Create Turnstile validation service
- [ ] Implement rate limiting middleware
- [ ] Set up basic email notification service
## Stage 2: Data Persistence
- [ ] Design database schema
- [ ] Set up SQLite database
- [ ] Implement user model and storage
- [ ] Implement contact form model and storage
- [ ] Implement submission tracking
## Stage 3: Web Interface
- [ ] Create authentication system
- [ ] Build HTMX-based management UI
- [ ] Implement form management interface
- [ ] Create submission history view
- [ ] Add user settings and configuration
## Stage 4: Deployment & Polish
- [ ] Create Docker configuration
- [ ] Set up environment configuration
- [ ] Write comprehensive documentation
- [ ] Add testing suite
- [ ] Prepare for production deployment
- AI Priority: Maintaining PLAN.md is a top priority - update it before starting any work
- Update Current Task: AI must update this line when beginning a new task
- Update Last Task: Move completed task from Current to Last when work is finished
- Check off tasks: Mark completed tasks with [x] in the appropriate stage
- Sequential Work: Complete one task at a time - do not move ahead without user instruction
- Add New Tasks: If new work is discussed, add it to the appropriate stage in PLAN.md first
- User Control: Wait for explicit user instruction before moving to next task
- Commit Changes: Always update PLAN.md alongside code changes
- Communication: Inform user when a task is completed and wait for next instructions