diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..1326925f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,189 @@ +name: Release + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + tag: + description: 'Release tag (e.g., v1.0.0)' + required: true + type: string + +permissions: + contents: write + +jobs: + build: + name: Build ${{ matrix.os }}/${{ matrix.arch }} + runs-on: ubuntu-latest + strategy: + matrix: + include: + - os: linux + arch: amd64 + goos: linux + goarch: amd64 + - os: linux + arch: arm64 + goos: linux + goarch: arm64 + - os: darwin + arch: amd64 + goos: darwin + goarch: amd64 + - os: darwin + arch: arm64 + goos: darwin + goarch: arm64 + - os: windows + arch: amd64 + goos: windows + goarch: amd64 + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.25' + cache: true + + - name: Determine version + id: version + run: | + if [ "${{ github.ref_type }}" = "tag" ]; then + echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + else + echo "version=dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + fi + + - name: Build binary + env: + GOOS: ${{ matrix.goos }} + GOARCH: ${{ matrix.goarch }} + CGO_ENABLED: 0 + run: | + EXT="" + if [ "${{ matrix.goos }}" = "windows" ]; then + EXT=".exe" + fi + + BINARY_NAME="hatch-${{ matrix.os }}-${{ matrix.arch }}${EXT}" + + go build \ + -ldflags="-s -w -X main.version=${{ steps.version.outputs.version }}" \ + -o "${BINARY_NAME}" \ + ./cmd/hatch + + echo "BINARY_NAME=${BINARY_NAME}" >> $GITHUB_ENV + + - name: Generate checksum + run: | + sha256sum "${BINARY_NAME}" > "${BINARY_NAME}.sha256" + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.os }}-${{ matrix.arch }} + path: | + ${{ env.BINARY_NAME }} + ${{ env.BINARY_NAME }}.sha256 + retention-days: 1 + + release: + name: Create Release + needs: build + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Determine version + id: version + run: | + if [ "${{ github.ref_type }}" = "tag" ]; then + echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + else + echo "version=dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + fi + + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: artifacts + merge-multiple: true + + - name: List artifacts + run: | + ls -la artifacts/ + echo "---" + for f in artifacts/*; do + echo "$f: $(du -h "$f" | cut -f1)" + done + + - name: Create release notes + id: notes + run: | + # Extract changelog for this version if exists + VERSION="${{ steps.version.outputs.version }}" + NOTES="" + + if [ -f CHANGELOG.md ]; then + # Extract notes for this version + NOTES=$(awk "/^## ${VERSION}/,/^## [0-9]/" CHANGELOG.md | head -n -1) + fi + + if [ -z "$NOTES" ]; then + NOTES="## Changes in ${VERSION} + + - Standalone binary releases for Linux, macOS, and Windows + - Updated CLI documentation + - See [CLI Reference](https://github.com/elfoundation/hatch/blob/main/docs/engineering/cli.md) for usage" + fi + + echo "notes<> $GITHUB_OUTPUT + echo "$NOTES" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + name: "Hatch ${{ steps.version.outputs.version }}" + body: ${{ steps.notes.outputs.notes }} + draft: false + prerelease: ${{ contains(steps.version.outputs.version, '-') }} + files: | + artifacts/* + fail_on_unmatched_files: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate SBOM + run: | + # Create a simple SBOM with version info + cat > sbom.json << EOF + { + "name": "hatch", + "version": "${{ steps.version.outputs.version }}", + "buildDate": "$(date -u +%Y-%m-%dT%H:%M:%SZ)", + "goVersion": "$(go version | awk '{print $3}')", + "platforms": [ + "linux/amd64", + "linux/arm64", + "darwin/amd64", + "darwin/arm64", + "windows/amd64" + ] + } + EOF + + # Upload SBOM as release asset + gh release upload "${{ steps.version.outputs.version }}" sbom.json --clobber || true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..b5bd84d8 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,120 @@ +# Changelog + +All notable changes to Hatch will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- CLI documentation with comprehensive command reference +- GitHub Actions release workflow for binary builds +- Standalone binaries for Linux, macOS, and Windows +- SHA256 checksums for all binaries +- SBOM generation for releases + +### Changed +- Updated README with CLI installation instructions + +### Fixed +- N/A + +## [0.1.0] - 2024-01-15 + +### Added +- Initial release of Hatch +- HTTP request capture and storage +- Request inspection and search +- Request replay functionality +- Mock response configuration +- OpenAPI documentation generation +- Web UI for visual inspection +- Docker support with Caddy reverse proxy +- SQLite storage backend +- REST API v1 + +### Changed +- N/A + +### Fixed +- N/A + +## [0.0.1] - 2024-01-01 + +### Added +- Project scaffolding +- Basic architecture design +- Development environment setup + +### Changed +- N/A + +### Fixed +- N/A + +--- + +## Release Process + +### Creating a Release + +1. **Update CHANGELOG.md** with the new version and changes +2. **Create a git tag** for the version: + ```bash + git tag -a v1.0.0 -m "Release v1.0.0" + git push origin v1.0.0 + ``` +3. **GitHub Actions will automatically**: + - Build binaries for all platforms + - Create SHA256 checksums + - Generate SBOM + - Create GitHub Release with assets + +### Manual Release + +For manual releases or testing: + +```bash +# Trigger workflow manually +gh workflow run release.yml -f tag=v1.0.0 + +# Or create tag and push +git tag -a v1.0.0 -m "Release v1.0.0" +git push origin v1.0.0 +``` + +### Platform Support + +| Platform | Architecture | Binary Name | +|----------|--------------|-------------| +| Linux | x86_64 | `hatch-linux-amd64` | +| Linux | ARM64 | `hatch-linux-arm64` | +| macOS | Intel | `hatch-darwin-amd64` | +| macOS | Apple Silicon | `hatch-darwin-arm64` | +| Windows | x86_64 | `hatch-windows-amd64.exe` | + +### Binary Installation + +After downloading: + +```bash +# Linux/macOS +chmod +x hatch-* +sudo mv hatch-* /usr/local/bin/hatch + +# Windows (PowerShell) +Rename-Item hatch-windows-amd64.exe hatch.exe +``` + +### Verification + +Verify binary integrity using SHA256 checksums: + +```bash +# Linux/macOS +sha256sum -c hatch-linux-amd64.sha256 + +# Windows (PowerShell) +Get-FileHash hatch-windows-amd64.exe -Algorithm SHA256 +``` \ No newline at end of file diff --git a/README.md b/README.md index 0cbe6a47..b28ce97e 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,41 @@ El Foundation builds institutions that outlast their founders. We create technol 4. Read [docs/engineering/local-dev.md](docs/engineering/local-dev.md) for the day-to-day workflow. 5. Read [docs/engineering/hatch-architecture.md](docs/engineering/hatch-architecture.md) for the component map. +## Installation + +### Pre-built Binaries (Recommended) + +Download the latest binary for your platform from the [Releases page](https://github.com/elfoundation/hatch/releases): + +- **Linux (x64)**: `hatch-linux-amd64` +- **Linux (ARM64)**: `hatch-linux-arm64` +- **macOS (Intel)**: `hatch-darwin-amd64` +- **macOS (Apple Silicon)**: `hatch-darwin-arm64` +- **Windows (x64)**: `hatch-windows-amd64.exe` + +After downloading: + +```bash +# Linux/macOS +chmod +x hatch-* +sudo mv hatch-* /usr/local/bin/hatch + +# Windows (PowerShell) +Rename-Item hatch-windows-amd64.exe hatch.exe +# Move to a directory in your PATH +``` + +### Build from Source + +Requires Go 1.25 or later: + +```bash +git clone https://github.com/elfoundation/hatch.git +cd hatch +CGO_ENABLED=0 go build -o hatch ./cmd/hatch +sudo mv hatch /usr/local/bin/ +``` + ## Repository Layout ``` @@ -23,6 +58,7 @@ El Foundation builds institutions that outlast their founders. We create technol │ ├── company/ # Founding documents (charter, org, etc.) │ ├── engineering/ # Engineering standards, architecture, local dev │ └── adrs/ # Architecture Decision Records +├── examples/ # Usage examples and integration guides ├── internal/ # Go packages (handler, store, ...) ├── Dockerfile # Multi-stage static binary build (golang → scratch) ├── docker-compose.yml # Local stack with optional Caddy sidecar @@ -76,6 +112,32 @@ Internet → :443 (Caddy) → hatch:8080 (Go binary, internal network) Caddy terminates TLS and reverse-proxies to the Hatch Go binary. The Hatch container only listens on `127.0.0.1:8080` — it's never directly exposed to the internet. +## CLI Reference + +Hatch includes a powerful CLI for interacting with the server from the command line: + +```bash +# Capture requests +hatch capture https://api.example.com/webhook + +# Inspect captured traffic +hatch inspect my-webhook + +# Search for specific requests +hatch search my-webhook -query 'status:500' + +# Replay requests to other services +hatch replay -endpoint my-webhook -target https://httpbin.org/post + +# Configure mock responses +hatch mock set my-webhook -status 200 -body '{"ok":true}' + +# Generate OpenAPI documentation +hatch doc generate my-webhook > openapi.json +``` + +For detailed CLI documentation, see [docs/engineering/cli.md](docs/engineering/cli.md). + ## Technology Stack See [docs/engineering/tech-stack.md](docs/engineering/tech-stack.md) for current choices and rationale, and [docs/adrs/](docs/adrs/) for the decision records that produced them. diff --git a/docs/engineering/cli-quick-reference.md b/docs/engineering/cli-quick-reference.md new file mode 100644 index 00000000..8255a4b9 --- /dev/null +++ b/docs/engineering/cli-quick-reference.md @@ -0,0 +1,118 @@ +# Hatch CLI Quick Reference + +## Installation + +```bash +# Download binary (Linux example) +curl -L https://github.com/elfoundation/hatch/releases/latest/download/hatch-linux-amd64 -o hatch +chmod +x hatch +sudo mv hatch /usr/local/bin/ +``` + +## Commands + +| Command | Description | Example | +|---------|-------------|---------| +| `hatch serve` | Start server | `hatch serve` | +| `hatch capture ` | Capture request | `hatch capture /api/webhook` | +| `hatch inspect ` | View requests | `hatch inspect my-webhook` | +| `hatch search ` | Search traffic | `hatch search my-webhook -query 'status:500'` | +| `hatch replay ` | Replay request | `hatch replay abc123 -endpoint api -target http://localhost:3000` | +| `hatch mock set ` | Configure mock | `hatch mock set api -status 200 -body '{}'` | +| `hatch doc generate ` | Generate OpenAPI | `hatch doc generate api > openapi.json` | +| `hatch version` | Print version | `hatch version` | + +## Common Flags + +| Flag | Description | Example | +|------|-------------|---------| +| `-method METHOD` | HTTP method | `hatch capture /api -method PUT` | +| `-body BODY` | Request body | `hatch capture /api -body '{"key":"value"}'` | +| `-header KEY:VALUE` | Add header | `hatch capture /api -header 'Auth:token'` | +| `-limit N` | Limit results | `hatch inspect api -limit 10` | +| `-query QUERY` | Search query | `hatch search api -query 'status:500'` | +| `-endpoint ENDPOINT` | Source endpoint | `hatch replay abc -endpoint api` | +| `-target URL` | Target URL | `hatch replay abc -target http://localhost:3000` | +| `-status CODE` | HTTP status | `hatch mock set api -status 200` | + +## Environment Variables + +| Variable | Description | Default | +|----------|-------------|---------| +| `HATCH_URL` | Server URL | `http://localhost:8080` | +| `PORT` | Server port | `8080` | + +## Quick Examples + +### Capture a Webhook + +```bash +hatch capture /webhooks/stripe \ + -method POST \ + -header 'Stripe-Signature:whsec_test' \ + -body '{"type":"payment_intent.succeeded"}' +``` + +### Debug Failed Requests + +```bash +# Find 500 errors +hatch search api -query 'status:500' + +# Get details +hatch inspect api -limit 5 + +# Replay to debug +hatch replay -endpoint api -target http://localhost:8080/debug +``` + +### Mock API for Frontend + +```bash +hatch mock set api/users \ + -status 200 \ + -header 'Content-Type:application/json' \ + -body '[{"id":1,"name":"John"}]' +``` + +### Generate API Docs + +```bash +hatch doc generate api/users > users-api.json +hatch doc generate api/posts > posts-api.json +``` + +## Query Syntax + +| Query | Description | +|-------|-------------| +| `status:500` | Filter by status code | +| `POST` | Filter by HTTP method | +| `user.created` | Search in body | +| `Content-Type:application/json` | Filter by header | + +## Exit Codes + +| Code | Meaning | +|------|---------| +| 0 | Success | +| 1 | General error | +| 2 | Invalid arguments | +| 3 | Network error | +| 4 | Auth error | +| 5 | Not found | + +## Troubleshooting + +```bash +# Check server health +curl http://localhost:8080/healthz + +# Verify binary works +hatch version + +# Test connection +hatch inspect default -limit 1 +``` + +For detailed troubleshooting, see [cli-troubleshooting.md](cli-troubleshooting.md). \ No newline at end of file diff --git a/docs/engineering/cli-troubleshooting.md b/docs/engineering/cli-troubleshooting.md new file mode 100644 index 00000000..c2d80206 --- /dev/null +++ b/docs/engineering/cli-troubleshooting.md @@ -0,0 +1,670 @@ +# CLI Troubleshooting Guide + +Comprehensive troubleshooting guide for Hatch CLI issues. + +## Quick Diagnostics + +### Health Check + +First, verify the Hatch server is running and accessible: + +```bash +# Check if server is responding +curl -s http://localhost:8080/healthz + +# Expected output: ok + +# If using custom URL +curl -s $HATCH_URL/healthz +``` + +### Version Check + +Verify you're using the correct version: + +```bash +hatch version +# Expected output: hatch v0.1.0 + +# Check if binary is working +hatch --help +``` + +### Connectivity Test + +Test network connectivity to the server: + +```bash +# Test with verbose output +curl -v http://localhost:8080/healthz + +# Test with specific timeout +curl --connect-timeout 5 http://localhost:8080/healthz +``` + +## Common Error Messages + +### Connection Issues + +#### `Error: request failed: connection refused` + +**Cause:** The Hatch server is not running or not accessible. + +**Solutions:** + +1. Start the Hatch server: + ```bash + hatch serve + ``` + +2. Check if the server is listening on the expected port: + ```bash + # Linux/macOS + netstat -tlnp | grep 8080 + # or + lsof -i :8080 + + # Windows + netstat -ano | findstr :8080 + ``` + +3. Verify the HATCH_URL environment variable: + ```bash + echo $HATCH_URL + # Should be http://localhost:8080 or your server URL + ``` + +4. Check firewall settings: + ```bash + # Linux + sudo iptables -L -n | grep 8080 + + # macOS + sudo pfctl -sr | grep 8080 + ``` + +#### `Error: request failed: dial tcp: lookup localhost: no such host` + +**Cause:** DNS resolution failure. + +**Solutions:** + +1. Use IP address instead of hostname: + ```bash + export HATCH_URL=http://127.0.0.1:8080 + ``` + +2. Check `/etc/hosts` file: + ```bash + grep localhost /etc/hosts + # Should contain: 127.0.0.1 localhost + ``` + +#### `Error: request failed: context deadline exceeded` + +**Cause:** Request timeout. + +**Solutions:** + +1. Check server load: + ```bash + top -bn1 | grep hatch + ``` + +2. Increase timeout (if using curl): + ```bash + curl --max-time 30 http://localhost:8080/healthz + ``` + +3. Check network latency: + ```bash + ping localhost + ``` + +### Authentication Errors + +#### `Error (HTTP 401): unauthorized` + +**Cause:** Authentication required but not provided. + +**Solutions:** + +1. Check if authentication is enabled: + ```bash + # Check server configuration + docker exec hatch-container env | grep AUTH + ``` + +2. Provide authentication token: + ```bash + # For API requests + curl -H "Authorization: Bearer $HATCH_AUTH_TOKEN" http://localhost:8080/v1/endpoints + ``` + +3. For development, disable authentication: + ```bash + # Start server without auth + HATCH_AUTH_ENABLED=false hatch serve + ``` + +#### `Error (HTTP 403): forbidden` + +**Cause:** Insufficient permissions. + +**Solutions:** + +1. Check user roles and permissions +2. Verify API token has required scopes +3. Contact administrator for access + +### Request/Response Errors + +#### `Error (HTTP 400): bad request` + +**Cause:** Invalid request format. + +**Solutions:** + +1. Validate JSON format: + ```bash + echo '{"invalid":json}' | jq . + # Should show parse error + ``` + +2. Check Content-Type header: + ```bash + curl -H "Content-Type: application/json" -d '{"valid":"json"}' ... + ``` + +3. Verify request body size: + ```bash + # Check body size + echo -n '{"data":"..."}' | wc -c + ``` + +#### `Error (HTTP 404): endpoint not found` + +**Cause:** Requested resource doesn't exist. + +**Solutions:** + +1. List available endpoints: + ```bash + curl http://localhost:8080/v1/endpoints + ``` + +2. Check endpoint ID spelling: + ```bash + # Case-sensitive + hatch inspect MyEndpoint # Wrong + hatch inspect myendpoint # Correct + ``` + +3. Verify endpoint has captured requests: + ```bash + hatch inspect myendpoint -limit 1 + ``` + +#### `Error (HTTP 413): payload too large` + +**Cause:** Request body exceeds size limit. + +**Solutions:** + +1. Reduce request body size +2. Compress data before sending +3. Split into smaller chunks + +#### `Error (HTTP 429): too many requests` + +**Cause:** Rate limiting. + +**Solutions:** + +1. Implement backoff: + ```bash + # Exponential backoff script + for i in {1..5}; do + sleep $((2**i)) + hatch capture /api -body '{"retry":'$i'}' && break + done + ``` + +2. Check rate limit headers: + ```bash + curl -I http://localhost:8080/v1/endpoints + # Look for X-RateLimit-* headers + ``` + +### Data Errors + +#### `Error: invalid character '}' looking for beginning of value` + +**Cause:** Malformed JSON in request body. + +**Solutions:** + +1. Validate JSON: + ```bash + echo '{"key":"value"}' | jq . + ``` + +2. Use proper escaping: + ```bash + # Bash + hatch capture /api -body '{"key":"value with \"quotes\""}' + + # Use file input + echo '{"key":"value"}' > request.json + hatch capture /api -body @request.json + ``` + +3. Check for invisible characters: + ```bash + cat -A request.json + ``` + +#### `Error: unexpected end of JSON input` + +**Cause:** Incomplete JSON response. + +**Solutions:** + +1. Check server logs for errors +2. Verify network connection wasn't interrupted +3. Try with smaller payload + +### Storage Errors + +#### `Error: database is locked` + +**Cause:** SQLite database contention. + +**Solutions:** + +1. Reduce concurrent operations +2. Check for long-running transactions: + ```bash + # Monitor database locks + sqlite3 hatch.db "PRAGMA journal_mode=WAL;" + ``` + +3. Consider using PostgreSQL for production + +#### `Error: no space left on device` + +**Cause:** Disk space exhausted. + +**Solutions:** + +1. Check disk space: + ```bash + df -h + du -sh /var/lib/hatch + ``` + +2. Clean old data: + ```bash + # Remove requests older than 7 days + curl -X DELETE "http://localhost:8080/v1/endpoints/myendpoint/requests?older_than=7d" + ``` + +3. Configure data retention: + ```bash + # Set retention policy + HATCH_RETENTION_DAYS=30 hatch serve + ``` + +## Platform-Specific Issues + +### Linux + +#### Permission Denied + +```bash +# Fix binary permissions +chmod +x /usr/local/bin/hatch + +# Or install to user directory +mkdir -p ~/.local/bin +mv hatch ~/.local/bin/ +export PATH="$HOME/.local/bin:$PATH" +``` + +#### SELinux Issues + +```bash +# Check SELinux status +getenforce + +# If enabled, add context +sudo semanage fcontext -a -t bin_t /usr/local/bin/hatch +sudo restorecon -v /usr/local/bin/hatch +``` + +### macOS + +#### Gatekeeper Blocked + +```bash +# Remove quarantine attribute +xattr -d com.apple.quarantine /usr/local/bin/hatch + +# Or allow in System Preferences > Security & Privacy +``` + +#### Homebrew Path Issues + +```bash +# Ensure Homebrew bin is in PATH +export PATH="/usr/local/bin:$PATH" + +# Or create symlink +ln -s /usr/local/bin/hatch /opt/homebrew/bin/hatch +``` + +### Windows + +#### Windows Defender Blocked + +1. Open Windows Security +2. Go to Virus & threat protection +3. Allow app through firewall + +#### PowerShell Execution Policy + +```bash +# Run as Administrator +Set-ExecutionPolicy RemoteSigned + +# Or bypass for current session +powershell -ExecutionPolicy Bypass -File script.ps1 +``` + +#### PATH Not Updated + +```bash +# Add to PATH permanently +$env:PATH += ";C:\path\to\hatch" + +# Or use System Properties > Environment Variables +``` + +## Performance Issues + +### Slow Response Times + +#### Diagnose + +```bash +# Measure response time +time curl -s http://localhost:8080/v1/endpoints > /dev/null + +# Check server resources +top -bn1 | grep hatch + +# Monitor network +iftop -i eth0 +``` + +#### Solutions + +1. **Increase server resources:** + ```bash + # Docker + docker update --cpus="2.0" --memory="2g" hatch-container + ``` + +2. **Optimize database:** + ```bash + # Vacuum SQLite database + sqlite3 hatch.db "VACUUM;" + ``` + +3. **Enable caching:** + ```bash + HATCH_CACHE_TTL=300 hatch serve + ``` + +### High Memory Usage + +#### Diagnose + +```bash +# Check memory usage +ps aux | grep hatch +pmap -x $(pgrep hatch) | tail -1 + +# Monitor over time +while true; do + echo "$(date): $(ps -o rss= -p $(pgrep hatch))KB" + sleep 60 +done +``` + +#### Solutions + +1. **Limit request history:** + ```bash + HATCH_MAX_REQUESTS=10000 hatch serve + ``` + +2. **Enable pagination:** + ```bash + hatch inspect myendpoint -limit 100 + ``` + +3. **Restart periodically:** + ```bash + # Cron job + 0 0 * * * systemctl restart hatch + ``` + +### High CPU Usage + +#### Diagnose + +```bash +# Check CPU usage +top -bn1 | grep hatch + +# Profile if needed +go tool pprof http://localhost:6060/debug/pprof/profile +``` + +#### Solutions + +1. **Reduce logging:** + ```bash + HATCH_LOG_LEVEL=warn hatch serve + ``` + +2. **Limit concurrent connections:** + ```bash + HATCH_MAX_CONNECTIONS=100 hatch serve + ``` + +## Network Issues + +### Proxy Configuration + +```bash +# Set proxy environment variables +export HTTP_PROXY=http://proxy.example.com:8080 +export HTTPS_PROXY=http://proxy.example.com:8080 +export NO_PROXY=localhost,127.0.0.1 + +# Or configure in hatch +HATCH_PROXY=$HTTP_PROXY hatch serve +``` + +### SSL/TLS Issues + +```bash +# Skip SSL verification (development only) +curl -k https://hatch.example.com/healthz + +# Or add certificate +curl --cacert /path/to/ca.crt https://hatch.example.com/healthz + +# For self-signed certificates +export CURL_CA_BUNDLE=/path/to/cert.pem +``` + +### DNS Resolution + +```bash +# Test DNS resolution +nslookup localhost +dig localhost + +# Use IP address +export HATCH_URL=http://127.0.0.1:8080 +``` + +## Docker Issues + +### Container Won't Start + +```bash +# Check container logs +docker logs hatch-container + +# Check container status +docker ps -a | grep hatch + +# Inspect container +docker inspect hatch-container +``` + +### Port Conflicts + +```bash +# Find what's using port 8080 +lsof -i :8080 +netstat -tlnp | grep 8080 + +# Use different port +docker run -p 9090:8080 hatch:latest +``` + +### Volume Mount Issues + +```bash +# Check volume permissions +ls -la /path/to/volume + +# Fix permissions +sudo chown -R 1000:1000 /path/to/volume + +# Test mount +docker run -v /path/to/volume:/data busybox ls -la /data +``` + +## Debugging Techniques + +### Enable Debug Logging + +```bash +# Set debug level +DEBUG=true hatch serve + +# Or use environment variable +HATCH_LOG_LEVEL=debug hatch serve +``` + +### Verbose Output + +```bash +# Use curl verbose mode +curl -v http://localhost:8080/v1/endpoints + +# Capture full request/response +curl -v -w '\n' http://localhost:8080/v1/endpoints > debug.txt 2>&1 +``` + +### Network Tracing + +```bash +# Linux +strace -e trace=network hatch serve + +# macOS +dtruss -n hatch + +# Windows +netsh trace start capture=yes tracefile=trace.etl +``` + +### Core Dumps + +```bash +# Enable core dumps +ulimit -c unlimited + +# Run with core dump +hatch serve & +echo $! > /tmp/hatch.pid + +# If crash occurs, analyze +gdb /usr/local/bin/hatch core +``` + +## Getting Help + +### Documentation + +- [CLI Reference](cli.md) - Command documentation +- [Examples](../../examples/) - Usage examples +- [Architecture](hatch-architecture.md) - System design + +### Community + +- [GitHub Issues](https://github.com/elfoundation/hatch/issues) - Bug reports +- [Discussions](https://github.com/elfoundation/hatch/discussions) - Questions + +### Logs + +```bash +# Check application logs +docker logs -f hatch-container + +# Check system logs +journalctl -u hatch -f + +# Check access logs +tail -f /var/log/hatch/access.log +``` + +## Reporting Issues + +When reporting issues, include: + +1. **Environment details:** + ```bash + hatch version + go version + uname -a # Linux/macOS + systeminfo # Windows + ``` + +2. **Configuration:** + ```bash + env | grep HATCH + ``` + +3. **Reproduction steps:** + - Exact commands run + - Expected behavior + - Actual behavior + +4. **Logs:** + ```bash + # Attach relevant logs + docker logs hatch-container > hatch.log 2>&1 + ``` + +5. **Network info:** + ```bash + curl -v http://localhost:8080/healthz > network-debug.txt 2>&1 + ``` \ No newline at end of file diff --git a/docs/engineering/cli.md b/docs/engineering/cli.md new file mode 100644 index 00000000..2d8f3164 --- /dev/null +++ b/docs/engineering/cli.md @@ -0,0 +1,429 @@ +# Hatch CLI Reference + +The `hatch` CLI provides a powerful interface for interacting with Hatch servers. Use it to capture requests, inspect traffic, search logs, replay requests, configure mocks, and generate API documentation. + +## Installation + +### Pre-built Binaries (Recommended) + +Download the latest binary for your platform from the [Releases page](https://github.com/elfoundation/hatch/releases): + +- **Linux (x64)**: `hatch-linux-amd64` +- **Linux (ARM64)**: `hatch-linux-arm64` +- **macOS (Intel)**: `hatch-darwin-amd64` +- **macOS (Apple Silicon)**: `hatch-darwin-arm64` +- **Windows (x64)**: `hatch-windows-amd64.exe` + +After downloading: + +```bash +# Linux/macOS +chmod +x hatch-* +sudo mv hatch-* /usr/local/bin/hatch + +# Windows (PowerShell) +Rename-Item hatch-windows-amd64.exe hatch.exe +# Move to a directory in your PATH +``` + +### Build from Source + +Requires Go 1.25 or later: + +```bash +git clone https://github.com/elfoundation/hatch.git +cd hatch +CGO_ENABLED=0 go build -o hatch ./cmd/hatch +sudo mv hatch /usr/local/bin/ +``` + +### Docker + +```bash +docker pull ghcr.io/elfoundation/hatch:latest +docker run --rm -it ghcr.io/elfoundation/hatch:latest --help +``` + +## Configuration + +### Environment Variables + +| Variable | Description | Default | +|----------|-------------|---------| +| `HATCH_URL` | Hatch server URL | `http://localhost:8080` | + +### Global Options + +All commands support these flags: + +- `-h, --help`: Show help for the command +- `version`: Print version information + +## Commands + +### `hatch serve` + +Start the Hatch server. This is the default command when no subcommand is specified. + +```bash +# Start server on default port (8080) +hatch serve + +# Start with custom port (use environment variable) +PORT=9090 hatch serve +``` + +### `hatch capture ` + +Send a request to an endpoint and store it in Hatch. + +**Options:** + +- `-method METHOD`: HTTP method (default: `POST`) +- `-body BODY`: Request body as JSON string +- `-header KEY:VALUE`: Request header (repeatable) + +**Examples:** + +```bash +# Capture a simple POST request +hatch capture https://api.example.com/webhook + +# Capture with custom method and body +hatch capture /my-endpoint -method PUT -body '{"status":"active"}' + +# Capture with headers +hatch capture /api/events \ + -header 'Content-Type:application/json' \ + -header 'X-Webhook-Secret:abc123' \ + -body '{"event":"user.created","data":{"id":123}}' +``` + +**URL Handling:** + +- Full URLs: `https://api.example.com/webhook` → endpoint ID derived from path +- Relative paths: `/my-endpoint` → used directly as endpoint ID +- Empty/`/` → defaults to `default` endpoint + +### `hatch inspect ` + +Fetch captured requests as JSON. + +**Options:** + +- `-limit N`: Maximum number of requests to return (default: 100) + +**Examples:** + +```bash +# Inspect all requests for an endpoint +hatch inspect my-webhook + +# Limit to 10 most recent requests +hatch inspect my-webhook -limit 10 + +# Pretty-print JSON output +hatch inspect my-webhook | jq . +``` + +**Output Format:** + +```json +[ + { + "id": "abc123", + "method": "POST", + "path": "/webhook", + "headers": {"Content-Type": "application/json"}, + "body": "{\"event\":\"test\"}", + "status": 200, + "created_at": "2024-01-15T10:30:00Z" + } +] +``` + +### `hatch search ` + +Search captured traffic with query syntax. + +**Options:** + +- `-query QUERY`: Search query (required) +- `-limit N`: Maximum number of results (default: 100) + +**Query Syntax:** + +| Query | Description | +|-------|-------------| +| `status:500` | Filter by HTTP status code | +| `POST` | Filter by HTTP method | +| `user.created` | Search in request body | +| `Content-Type:application/json` | Filter by header | + +**Examples:** + +```bash +# Find all 500 errors +hatch search my-webhook -query 'status:500' + +# Find POST requests +hatch search my-webhook -query 'POST' + +# Search for specific content in body +hatch search my-webhook -query 'user.created' + +# Combine queries +hatch search my-webhook -query 'status:500 POST' +``` + +### `hatch replay ` + +Replay a previously captured request to a target URL. + +**Options:** + +- `-endpoint ENDPOINT`: Source endpoint ID (required) +- `-target URL`: Target URL to replay to (required) + +**Examples:** + +```bash +# Replay a request +hatch replay abc123 -endpoint my-webhook -target https://httpbin.org/post + +# Replay to a local development server +hatch replay def456 -endpoint api-calls -target http://localhost:3000/webhook + +# Replay to a different environment +hatch replay ghi789 -endpoint production-webhook -target https://staging.example.com/webhook +``` + +**Use Cases:** + +- Test webhook handlers in development +- Reproduce bugs by replaying failed requests +- Load testing with captured traffic patterns +- Migrating traffic between environments + +### `hatch mock set ` + +Configure mock responses for an endpoint. + +**Options:** + +- `-status CODE`: HTTP status code (default: 200) +- `-body BODY`: Response body (string or base64) +- `-header KEY:VALUE`: Response header (repeatable) + +**Examples:** + +```bash +# Return 200 with JSON body +hatch mock set my-webhook -status 200 -body '{"ok":true}' + +# Return error response +hatch mock set my-webhook -status 500 -body '{"error":"internal error"}' + +# Return with custom headers +hatch mock set my-webhook \ + -status 200 \ + -header 'X-RateLimit-Remaining:100' \ + -header 'Cache-Control:no-cache' + +# Simulate rate limiting +hatch mock set my-webhook \ + -status 429 \ + -header 'Retry-After:60' \ + -body '{"error":"rate limited"}' +``` + +**Mock Behavior:** + +- Once configured, all requests to the endpoint return the mock response +- Mock configuration persists until server restart or explicit reconfiguration +- Original request capture continues alongside mock responses + +### `hatch doc generate ` + +Generate OpenAPI 3.1 specification for an endpoint based on captured traffic. + +**Examples:** + +```bash +# Generate OpenAPI spec +hatch doc generate my-webhook + +# Save to file +hatch doc generate my-webhook > openapi.json + +# Use with Swagger UI +hatch doc generate my-webhook > openapi.json +docker run -p 8081:8080 -e SWAGGER_JSON=/openapi.json -v $(pwd):/usr/share/nginx/html/swagger swaggerapi/swagger-ui +``` + +**Output:** + +Generates a complete OpenAPI 3.1 JSON specification including: + +- All captured request/response patterns +- Schema definitions inferred from traffic +- Example values from real requests +- Endpoint documentation + +## Common Workflows + +### Development Environment Setup + +```bash +# 1. Start Hatch server +hatch serve & + +# 2. Capture incoming webhooks +hatch capture /api/webhooks -method POST -body '{"test":true}' + +# 3. Inspect captured traffic +hatch inspect api/webhooks + +# 4. Configure mock for frontend development +hatch mock set api/webhooks -status 200 -body '{"status":"ok"}' +``` + +### Bug Reproduction + +```bash +# 1. Find the failing request +hatch search api/payments -query 'status:500' + +# 2. Get request details +hatch inspect api/payments -limit 5 + +# 3. Replay to debug +hatch replay -endpoint api/payments -target http://localhost:8080/debug +``` + +### API Documentation Generation + +```bash +# 1. Capture representative traffic +for endpoint in users posts comments; do + curl -X POST http://hatch:8080/$endpoint -d '{"sample":"data"}' +done + +# 2. Generate OpenAPI specs +hatch doc generate users > users-api.json +hatch doc generate posts > posts-api.json + +# 3. Combine into single spec (using jq) +jq -s '.[0] * .[1]' users-api.json posts-api.json > combined-api.json +``` + +### Load Testing Preparation + +```bash +# 1. Capture production traffic patterns +hatch inspect api/critical-path -limit 1000 > traffic.json + +# 2. Extract request patterns +jq -r '.[] | "\(.method) \(.path)"' traffic.json | sort | uniq -c | sort -rn + +# 3. Replay to load testing tool +hatch inspect api/critical-path -limit 100 | \ + jq -r '.[] | "hatch replay \(.id) -endpoint api/critical-path -target https://loadtest.example.com"' +``` + +## Troubleshooting + +### Connection Issues + +**Problem:** `Error: request failed: connection refused` + +**Solution:** Ensure the Hatch server is running: + +```bash +# Check if server is running +curl http://localhost:8080/healthz + +# Start server if not running +hatch serve +``` + +### Authentication Errors + +**Problem:** `Error (HTTP 401): unauthorized` + +**Solution:** Check if your Hatch instance requires authentication: + +```bash +# For local development, ensure no auth is configured +# For production, check HATCH_AUTH_TOKEN environment variable +``` + +### Request Not Found + +**Problem:** `Error (HTTP 404): endpoint not found` + +**Solution:** Verify the endpoint ID exists: + +```bash +# List available endpoints +curl http://localhost:8080/v1/endpoints + +# Check if endpoint has captured requests +hatch inspect -limit 1 +``` + +### JSON Parsing Errors + +**Problem:** `Error: invalid character '}' looking for beginning of value` + +**Solution:** Ensure request body is valid JSON: + +```bash +# Use proper JSON escaping +hatch capture /api -body '{"key":"value"}' + +# Or use a file +hatch capture /api -body @request.json +``` + +### Permission Denied on Binary + +**Problem:** `Permission denied: ./hatch` + +**Solution:** Make the binary executable: + +```bash +chmod +x hatch +# Or move to a directory in PATH +sudo mv hatch /usr/local/bin/ +``` + +## Environment Variables Reference + +| Variable | Description | Default | Example | +|----------|-------------|---------|---------| +| `HATCH_URL` | Hatch server URL | `http://localhost:8080` | `https://hatch.example.com` | +| `PORT` | Server listening port | `8080` | `9090` | + +## Exit Codes + +| Code | Description | +|------|-------------| +| 0 | Success | +| 1 | General error | +| 2 | Invalid command or arguments | +| 3 | Network error | +| 4 | Authentication error | +| 5 | Resource not found | + +## Getting Help + +- **Command help:** `hatch -h` +- **General help:** `hatch --help` +- **Version:** `hatch version` +- **Issues:** [GitHub Issues](https://github.com/elfoundation/hatch/issues) +- **Documentation:** [docs/](../README.md) + +## Examples Repository + +For more examples, see the [examples/](../../examples/) directory or visit our [documentation site](https://hatch.sh/examples). \ No newline at end of file diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 00000000..70737414 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,189 @@ +# Hatch Examples + +Real-world examples and integration guides for using Hatch. + +## Examples Index + +| Example | Description | Use Case | +|---------|-------------|----------| +| [Webhook Integration](webhook-integration.md) | Comprehensive webhook capture, testing, and debugging | Payment processors, GitHub, Slack, API integrations | + +## Quick Start Examples + +### Capture Your First Request + +```bash +# Start Hatch server +hatch serve & + +# Capture a request +curl -X POST http://localhost:8080/my-endpoint \ + -H "Content-Type: application/json" \ + -d '{"event":"test","data":{"id":123}}' + +# View captured requests +hatch inspect my-endpoint +``` + +### Mock API for Development + +```bash +# Configure mock response +hatch mock set api/users \ + -status 200 \ + -header "Content-Type:application/json" \ + -body '[{"id":1,"name":"John Doe"}]' + +# Test your frontend +curl http://localhost:8080/api/users +``` + +### Debug Failed Webhooks + +```bash +# Find errors +hatch search webhooks -query "status:500" + +# Replay to debug +hatch replay \ + -endpoint webhooks \ + -target http://localhost:3000/debug +``` + +## Integration Guides + +### Stripe Webhooks + +See [Webhook Integration - Stripe Example](webhook-integration.md#example-1-stripe-webhook-testing) + +### GitHub Webhooks + +See [Webhook Integration - GitHub Example](webhook-integration.md#example-2-github-webhook-debugging) + +### Slack Integration + +See [Webhook Integration - Slack Example](webhook-integration.md#example-3-slack-integration-testing) + +## Use Cases + +### 1. Development Environment + +Use Hatch as a local mock server for frontend development. + +```bash +# Configure mocks for your API +hatch mock set api/users -status 200 -body '[]' +hatch mock set api/auth -status 200 -body '{"token":"mock-token"}' + +# Frontend code uses http://localhost:8080 as API base +``` + +### 2. Testing & QA + +Capture production traffic patterns and replay them in testing. + +```bash +# Capture traffic +hatch inspect api/critical-path -limit 1000 > traffic.json + +# Replay in test environment +cat traffic.json | jq -r '.[].id' | while read id; do + hatch replay "$id" -endpoint api/critical-path -target http://staging:8080 +done +``` + +### 3. API Documentation + +Generate OpenAPI specs from real traffic. + +```bash +# Capture representative traffic +hatch capture /api/users -method GET +hatch capture /api/users -method POST -body '{"name":"test"}' + +# Generate documentation +hatch doc generate api/users > users-api.json +``` + +### 4. Load Testing + +Replay captured traffic for load testing. + +```bash +# Capture production patterns +hatch inspect api/critical-path -limit 1000 > load-test-traffic.json + +# Create load test script +cat > load-test.sh << 'EOF' +#!/bin/bash +for i in {1..100}; do + hatch inspect api/critical-path -limit 10 | \ + jq -r '.[] | "hatch replay \(.id) -endpoint api/critical-path -target http://loadtest:8080"' | \ + bash & +done +wait +EOF +chmod +x load-test.sh +``` + +## Best Practices + +1. **Use descriptive endpoint names** + ```bash + # Good + hatch capture /webhooks/stripe-payments + hatch capture /api/v2/users + + # Bad + hatch capture /a + hatch capture /test + ``` + +2. **Include relevant headers** + ```bash + hatch capture /webhooks/github \ + -header 'X-GitHub-Event:push' \ + -header 'X-Hub-Signature:sha1=abc123' + ``` + +3. **Organize by environment** + ```bash + # Development + hatch mock set dev/api/users -status 200 -body '[]' + + # Staging + hatch mock set staging/api/users -status 200 -body '[{"id":1}]' + ``` + +4. **Use search for debugging** + ```bash + # Find all errors + hatch search api/webhooks -query 'status:500' + + # Find specific events + hatch search webhooks/stripe -query 'payment_intent' + ``` + +## Troubleshooting + +See [CLI Troubleshooting Guide](../docs/engineering/cli-troubleshooting.md) for common issues and solutions. + +## Contributing Examples + +To add a new example: + +1. Create a markdown file in this directory +2. Follow the naming convention: `.md` +3. Include: + - Clear use case description + - Step-by-step instructions + - Complete code examples + - Expected output + - Common pitfalls +4. Update this README.md to include your example in the index + +## Resources + +- [CLI Reference](../docs/engineering/cli.md) - Complete command documentation +- [Quick Reference](../docs/engineering/cli-quick-reference.md) - Command cheat sheet +- [Troubleshooting](../docs/engineering/cli-troubleshooting.md) - Common issues and solutions \ No newline at end of file diff --git a/examples/webhook-integration.md b/examples/webhook-integration.md new file mode 100644 index 00000000..003c2fbf --- /dev/null +++ b/examples/webhook-integration.md @@ -0,0 +1,389 @@ +# Webhook Integration Examples + +Real-world examples of using Hatch for webhook capture, testing, and debugging. + +## Example 1: Stripe Webhook Testing + +Capture and test Stripe webhook events in development. + +### Setup + +```bash +# Start Hatch server +hatch serve & + +# Capture Stripe webhook events +hatch capture /webhooks/stripe \ + -method POST \ + -header 'Stripe-Signature:whsec_test123' \ + -body '{"id":"evt_123","type":"payment_intent.succeeded","data":{"object":{"id":"pi_456","amount":2000,"currency":"usd"}}}' +``` + +### Development Workflow + +```bash +# 1. Capture incoming webhook +hatch capture /webhooks/stripe -body '{"type":"checkout.session.completed","data":{"object":{"id":"cs_789"}}}' + +# 2. Inspect captured events +hatch inspect webhooks/stripe + +# 3. Search for specific event types +hatch search webhooks/stripe -query 'payment_intent.succeeded' + +# 4. Replay to test handler +hatch replay \ + -endpoint webhooks/stripe \ + -target http://localhost:3000/stripe/webhook + +# 5. Configure mock for frontend testing +hatch mock set webhooks/stripe \ + -status 200 \ + -body '{"received":true}' +``` + +### Load Testing + +```bash +# Capture multiple events +for i in {1..10}; do + hatch capture /webhooks/stripe \ + -body "{\"id\":\"evt_$i\",\"type\":\"payment_intent.succeeded\"}" +done + +# Replay all to load test handler +hatch inspect webhooks/stripe -limit 10 | \ + jq -r '.[] | "hatch replay \(.id) -endpoint webhooks/stripe -target http://localhost:3000/stripe/webhook"' | \ + bash +``` + +## Example 2: GitHub Webhook Debugging + +Debug GitHub webhook delivery issues. + +### Capture GitHub Events + +```bash +# Capture push events +hatch capture /webhooks/github \ + -method POST \ + -header 'X-GitHub-Event:push' \ + -header 'X-Hub-Signature:sha1=abc123' \ + -body '{"ref":"refs/heads/main","commits":[{"id":"def456","message":"Fix bug"}]}' + +# Capture pull request events +hatch capture /webhooks/github \ + -method POST \ + -header 'X-GitHub-Event:pull_request' \ + -body '{"action":"opened","pull_request":{"number":42,"title":"New feature"}}' +``` + +### Debug Failed Deliveries + +```bash +# Find failed webhook deliveries +hatch search webhooks/github -query 'status:500' + +# Get details of failed request +hatch inspect webhooks/github -limit 5 + +# Replay to local debugging server +hatch replay \ + -endpoint webhooks/github \ + -target http://localhost:8080/debug +``` + +### Mock GitHub API Responses + +```bash +# Mock GitHub API for local development +hatch mock set api/github \ + -status 200 \ + -header 'Content-Type:application/json' \ + -body '{"login":"test-user","id":12345}' +``` + +## Example 3: Slack Integration Testing + +Test Slack app integrations without hitting real Slack APIs. + +### Capture Slack Events + +```bash +# Capture Slack events +hatch capture /slack/events \ + -method POST \ + -header 'X-Slack-Signature:v0=abc123' \ + -body '{"type":"event_callback","event":{"type":"message","text":"Hello world"}}' + +# Capture Slack interactive payloads +hatch capture /slack/actions \ + -method POST \ + -header 'X-Slack-Signature:v0=def456' \ + -body '{"type":"interactive_message","actions":[{"type":"button","value":"approve"}]}' +``` + +### Development Setup + +```bash +# Mock Slack API responses +hatch mock set slack/api \ + -status 200 \ + -header 'Content-Type:application/json' \ + -body '{"ok":true}' + +# Test message sending +hatch replay \ + -endpoint slack/events \ + -target http://localhost:3000/slack/events +``` + +## Example 4: Payment Provider Integration + +Test payment provider webhooks across different environments. + +### Multi-Environment Setup + +```bash +# Development environment +hatch mock set payments/webhook \ + -status 200 \ + -body '{"status":"received"}' + +# Staging environment +hatch capture payments/webhook \ + -body '{"type":"payment.completed","amount":1000,"currency":"USD"}' + +# Replay to different environments +hatch replay \ + -endpoint payments/webhook \ + -target http://localhost:8080/payments/webhook # Local +hatch replay \ + -endpoint payments/webhook \ + -target https://staging.example.com/payments/webhook # Staging +``` + +### Error Simulation + +```bash +# Simulate payment failure +hatch mock set payments/webhook \ + -status 200 \ + -body '{"status":"failed","error":"insufficient_funds"}' + +# Simulate network timeout (use with caution) +hatch mock set payments/webhook \ + -status 504 \ + -body '{"error":"gateway_timeout"}' +``` + +## Example 5: API Documentation Generation + +Generate OpenAPI documentation from real traffic patterns. + +### Capture API Traffic + +```bash +# Capture various endpoints +hatch capture /api/users -method GET +hatch capture /api/users -method POST -body '{"name":"John Doe"}' +hatch capture /api/users/123 -method GET +hatch capture /api/users/123 -method PUT -body '{"name":"Jane Doe"}' +hatch capture /api/posts -method GET +hatch capture /api/posts -method POST -body '{"title":"Hello World"}' +``` + +### Generate Documentation + +```bash +# Generate OpenAPI specs for each endpoint +hatch doc generate api/users > users-api.json +hatch doc generate api/posts > posts-api.json + +# Combine into single spec +jq -s '.[0] * .[1]' users-api.json posts-api.json > combined-api.json + +# Serve with Swagger UI +docker run -p 8081:8080 \ + -e SWAGGER_JSON=/openapi.json \ + -v $(pwd):/usr/share/nginx/html/swagger \ + swaggerapi/swagger-ui +``` + +## Example 6: Load Testing with Real Traffic + +Capture and replay production traffic for load testing. + +### Capture Production Patterns + +```bash +# Capture high-traffic endpoint +hatch capture /api/critical-path -limit 1000 + +# Export traffic patterns +hatch inspect api/critical-path -limit 1000 > traffic-patterns.json +``` + +### Analyze Traffic + +```bash +# Analyze request distribution +jq -r '.[] | "\(.method) \(.path)"' traffic-patterns.json | \ + sort | uniq -c | sort -rn + +# Find slow requests (if timing data available) +jq '.[] | select(.duration > 1000)' traffic-patterns.json + +# Identify error patterns +jq '.[] | select(.status >= 400)' traffic-patterns.json +``` + +### Replay for Load Testing + +```bash +# Create load test script +cat > load-test.sh << 'EOF' +#!/bin/bash +ENDPOINT="api/critical-path" +TARGET="https://loadtest.example.com" +REQUESTS=$(hatch inspect $ENDPOINT -limit 100) + +echo "$REQUESTS" | jq -r '.[] | .id' | while read -r id; do + echo "Replaying request $id" + hatch replay "$id" -endpoint "$ENDPOINT" -target "$TARGET" + sleep 0.1 # Rate limiting +done +EOF + +chmod +x load-test.sh +./load-test.sh +``` + +## Example 7: Mock Server for Frontend Development + +Set up a comprehensive mock server for frontend development. + +### Create Mock Endpoints + +```bash +# User API mock +hatch mock set api/users \ + -status 200 \ + -header 'Content-Type:application/json' \ + -body '[ + {"id":1,"name":"John Doe","email":"john@example.com"}, + {"id":2,"name":"Jane Smith","email":"jane@example.com"} + ]' + +# Authentication mock +hatch mock set api/auth \ + -status 200 \ + -header 'Content-Type:application/json' \ + -body '{"token":"mock-jwt-token-123","expires_in":3600}' + +# Error responses +hatch mock set api/errors \ + -status 401 \ + -header 'Content-Type:application/json' \ + -body '{"error":"unauthorized","message":"Invalid credentials"}' +``` + +### Frontend Integration + +```javascript +// Frontend code using mock API +const API_BASE = 'http://localhost:8080'; + +// Fetch users +const response = await fetch(`${API_BASE}/api/users`); +const users = await response.json(); + +// Login +const loginResponse = await fetch(`${API_BASE}/api/auth`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email: 'user@example.com', password: 'pass' }) +}); +``` + +## Best Practices + +### 1. Use Descriptive Endpoint Names + +```bash +# Good +hatch capture /webhooks/stripe-payments +hatch capture /api/v2/users + +# Bad +hatch capture /a +hatch capture /test +``` + +### 2. Include Relevant Headers + +```bash +# Capture with all relevant headers +hatch capture /webhooks/github \ + -header 'X-GitHub-Event:push' \ + -header 'X-Hub-Signature:sha1=abc123' \ + -header 'Content-Type:application/json' +``` + +### 3. Organize by Environment + +```bash +# Development +hatch mock set dev/api/users -status 200 -body '[]' + +# Staging +hatch mock set staging/api/users -status 200 -body '[{"id":1}]' +``` + +### 4. Use Search for Debugging + +```bash +# Find all errors +hatch search api/webhooks -query 'status:500' + +# Find specific event types +hatch search webhooks/stripe -query 'payment_intent' +``` + +### 5. Document Your Mocks + +```bash +# Add comments to mock configuration +hatch mock set api/users \ + -status 200 \ + -header 'X-Mock-Description:Returns list of test users' +``` + +## Troubleshooting + +### Common Issues + +1. **Connection refused**: Ensure Hatch server is running (`hatch serve`) +2. **Endpoint not found**: Check endpoint ID with `curl http://localhost:8080/v1/endpoints` +3. **Request not captured**: Verify request format and headers +4. **Mock not working**: Check if mock is configured for the correct endpoint + +### Debug Mode + +```bash +# Enable debug logging +DEBUG=true hatch serve + +# Check server logs +docker logs -f hatch-container +``` + +### Performance Issues + +```bash +# Limit concurrent connections +hatch inspect api/heavy-endpoint -limit 10 + +# Use pagination for large datasets +hatch inspect api/large-dataset -limit 50 +``` \ No newline at end of file diff --git a/scripts/hatch-setup.sh b/scripts/hatch-setup.sh new file mode 100755 index 00000000..e84e75ad --- /dev/null +++ b/scripts/hatch-setup.sh @@ -0,0 +1,280 @@ +#!/bin/bash + +# Hatch CLI Setup and Verification Script +# This script helps users install and verify the Hatch CLI + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Function to print colored output +print_status() { + local status=$1 + local message=$2 + + case $status in + "OK") + echo -e "${GREEN}✓${NC} $message" + ;; + "WARN") + echo -e "${YELLOW}⚠${NC} $message" + ;; + "ERROR") + echo -e "${RED}✗${NC} $message" + ;; + "INFO") + echo -e "${BLUE}ℹ${NC} $message" + ;; + esac +} + +# Function to check if command exists +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +# Function to get latest release version from GitHub +get_latest_version() { + if command_exists curl; then + curl -s https://api.github.com/repos/elfoundation/hatch/releases/latest | grep -o '"tag_name": "[^"]*"' | cut -d'"' -f4 + elif command_exists wget; then + wget -qO- https://api.github.com/repos/elfoundation/hatch/releases/latest | grep -o '"tag_name": "[^"]*"' | cut -d'"' -f4 + else + echo "unknown" + fi +} + +# Function to detect platform +detect_platform() { + local os=$(uname -s | tr '[:upper:]' '[:lower:]') + local arch=$(uname -m) + + case $os in + linux) + case $arch in + x86_64|amd64) + echo "linux-amd64" + ;; + aarch64|arm64) + echo "linux-arm64" + ;; + *) + echo "linux-unknown" + ;; + esac + ;; + darwin) + case $arch in + x86_64|amd64) + echo "darwin-amd64" + ;; + arm64) + echo "darwin-arm64" + ;; + *) + echo "darwin-unknown" + ;; + esac + ;; + mingw*|msys*|cygwin*) + echo "windows-amd64" + ;; + *) + echo "unknown" + ;; + esac +} + +# Function to install hatch +install_hatch() { + local platform=$(detect_platform) + local version=$(get_latest_version) + + if [ "$platform" = "unknown" ]; then + print_status "ERROR" "Unsupported platform: $(uname -s) $(uname -m)" + echo "Please install manually from https://github.com/elfoundation/hatch/releases" + exit 1 + fi + + if [ "$version" = "unknown" ] || [ -z "$version" ]; then + print_status "WARN" "Could not determine latest version" + print_status "INFO" "Please check https://github.com/elfoundation/hatch/releases" + exit 1 + fi + + local binary_name="hatch-${platform}" + local download_url="https://github.com/elfoundation/hatch/releases/download/${version}/${binary_name}" + + if [ "$platform" = "windows-amd64" ]; then + binary_name="hatch-windows-amd64.exe" + download_url="https://github.com/elfoundation/hatch/releases/download/${version}/${binary_name}" + fi + + print_status "INFO" "Detected platform: ${platform}" + print_status "INFO" "Latest version: ${version}" + print_status "INFO" "Download URL: ${download_url}" + + # Create temporary directory + local temp_dir=$(mktemp -d) + local temp_file="${temp_dir}/${binary_name}" + + print_status "INFO" "Downloading hatch..." + + # Download binary + if command_exists curl; then + curl -L -o "$temp_file" "$download_url" + elif command_exists wget; then + wget -O "$temp_file" "$download_url" + else + print_status "ERROR" "Neither curl nor wget found. Please install one." + exit 1 + fi + + if [ ! -f "$temp_file" ]; then + print_status "ERROR" "Failed to download binary" + exit 1 + fi + + # Make executable (Unix only) + if [[ "$platform" != windows-* ]]; then + chmod +x "$temp_file" + fi + + # Determine installation directory + local install_dir="" + if [ -d "/usr/local/bin" ] && [ -w "/usr/local/bin" ]; then + install_dir="/usr/local/bin" + elif [ -d "$HOME/.local/bin" ]; then + install_dir="$HOME/.local/bin" + # Ensure PATH includes ~/.local/bin + if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then + print_status "WARN" "Adding ~/.local/bin to PATH" + echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.bashrc" + echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.zshrc" 2>/dev/null || true + fi + else + install_dir="$HOME/.local/bin" + mkdir -p "$install_dir" + fi + + local install_path="${install_dir}/hatch" + + # Install binary + if [ -w "$install_dir" ]; then + mv "$temp_file" "$install_path" + else + print_status "INFO" "Using sudo to install to ${install_dir}" + sudo mv "$temp_file" "$install_path" + fi + + # Clean up + rm -rf "$temp_dir" + + print_status "OK" "Hatch installed to ${install_path}" + + # Verify installation + if command_exists hatch; then + print_status "OK" "Hatch is in PATH" + hatch version + else + print_status "WARN" "Hatch installed but not in PATH" + print_status "INFO" "You may need to restart your shell or add ${install_dir} to PATH" + fi +} + +# Function to verify installation +verify_installation() { + print_status "INFO" "Verifying Hatch installation..." + + # Check if hatch is installed + if ! command_exists hatch; then + print_status "ERROR" "Hatch is not installed or not in PATH" + echo "Please install hatch first:" + echo " $0 install" + exit 1 + fi + + # Check version + print_status "INFO" "Checking version..." + if hatch version; then + print_status "OK" "Version check passed" + else + print_status "ERROR" "Version check failed" + exit 1 + fi + + # Check help + print_status "INFO" "Checking help..." + if hatch --help > /dev/null 2>&1; then + print_status "OK" "Help command works" + else + print_status "ERROR" "Help command failed" + exit 1 + fi + + # Check if server is running + print_status "INFO" "Checking server connectivity..." + if curl -s http://localhost:8080/healthz > /dev/null 2>&1; then + print_status "OK" "Server is running and accessible" + + # Test capture command (dry run) + print_status "INFO" "Testing CLI commands..." + + # Test inspect (will fail if no endpoints, but that's OK) + if hatch inspect default -limit 1 > /dev/null 2>&1; then + print_status "OK" "CLI commands working" + else + print_status "WARN" "CLI commands may have issues (server might not have data)" + fi + else + print_status "WARN" "Server not running at http://localhost:8080" + print_status "INFO" "Start server with: hatch serve" + fi + + print_status "OK" "Installation verification complete" +} + +# Function to show usage +show_usage() { + echo "Hatch CLI Setup and Verification Script" + echo "" + echo "Usage: $0 [command]" + echo "" + echo "Commands:" + echo " install Download and install the latest hatch binary" + echo " verify Verify hatch installation and connectivity" + echo " help Show this help message" + echo "" + echo "Examples:" + echo " $0 install # Install hatch" + echo " $0 verify # Verify installation" + echo "" + echo "Manual installation:" + echo " 1. Download from https://github.com/elfoundation/hatch/releases" + echo " 2. chmod +x hatch-*" + echo " 3. sudo mv hatch-* /usr/local/bin/hatch" +} + +# Main script +main() { + local command=${1:-help} + + case $command in + install) + install_hatch + ;; + verify) + verify_installation + ;; + help|*) + show_usage + ;; + esac +} + +main "$@" \ No newline at end of file