Skip to content

Instantly share code, notes, and snippets.

@ali-aka-ahmed
Created November 10, 2025 22:42
Show Gist options
  • Select an option

  • Save ali-aka-ahmed/1a60ae8f55d01b4fd7a29a59dab34bf6 to your computer and use it in GitHub Desktop.

Select an option

Save ali-aka-ahmed/1a60ae8f55d01b4fd7a29a59dab34bf6 to your computer and use it in GitHub Desktop.
CLAUDE.md

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

⚠️ CRITICAL: Read This BEFORE Any Work

BEFORE modifying ANY code file:

  1. Read the relevant folder-level docs for the task (e.g., docs/internal/api-docs.md)
  2. Read relevant function-level docs for the task (e.g., docs/internal/api/handlers/health.md)
  3. Understand how it interacts with other files
  4. Follow the patterns documented there

BEFORE committing ANY code:

  1. Run: go build ./... && go test ./... && go test -race ./... && golangci-lint run ./...
  2. ALL must pass - no exceptions
  3. Update function-level docs (keep concise: 1-3 sentences)
  4. Update all folder-level docs if architecture changed (keep detailed)
  5. Verify all code files under 250 lines

See .claude/WORKFLOW.md for detailed workflow checklist

🛑 MANDATORY PRE-COMMIT CHECKLIST

Run this ONE command after ANY code change:

go build ./... && go test ./... && go test -race ./... && golangci-lint run ./...

What each command does:

  • go build ./... - Verifies code compiles without errors
  • go test ./... - Runs all tests (unit + integration + acceptance)
  • go test -race ./... - Detects race conditions and concurrency bugs
  • golangci-lint run ./... - Checks code quality, style, and potential bugs

If ANY command fails:

  • ❌ DO NOT proceed
  • ❌ DO NOT commit
  • ❌ DO NOT mark feature complete
  • ✅ Fix the issues first

🔴 Mandatory Development Rules

Rule 1: Read Documentation Before Modifying

ALWAYS read both documentation types before modifying code:

  1. Folder-Level Docs (Detailed) - Read the architecture overview for the folder
  2. Function-Level Docs (Concise) - Read the specific file documentation

Two-Tier Documentation System:

Folder-Level (Detailed):

  • docs/internal/api-docs.md → Architecture overview for internal/api/ folder
  • docs/internal/api/handlers-docs.md → Architecture overview for internal/api/handlers/ folder

Function-Level (Concise: 1-3 sentences):

  • docs/cmd/api/main.md → Documents cmd/api/main.go
  • docs/internal/api/router.md → Documents internal/api/router.go
  • docs/internal/api/handlers/health.md → Documents internal/api/handlers/health.go
  • docs/internal/config/config.md → Documents internal/config/config.go

After modifying code, update both documentation types:

Function-Level (keep concise: 1-3 sentences):

  • What the file/function does
  • Key interactions with other files

Folder-Level (keep detailed, update if architecture changed):

  • Design patterns and common tasks
  • How files work together
  • When to add new files vs modify existing

Rule 2: 250 Line Maximum (Extreme Modularity)

Every code file MUST be under 250 lines. Documentation files (*.md) are exempt.

When a code file approaches 250 lines:

  1. Identify logical boundaries
  2. Extract to new focused files
  3. Update imports
  4. Create corresponding docs/**/*.md files

Example split:

handlers.go (300 lines) → Split into:
- handlers_health.go (50 lines) + docs/handlers_health.md
- handlers_user.go (100 lines) + docs/handlers_user.md
- handlers_auth.go (100 lines) + docs/handlers_auth.md

Rule 3: Test-Driven Completion

A feature is NOT complete until:

  1. ✅ All code written (under 250 lines per file)
  2. ✅ Unit tests written and passing
  3. ✅ Integration tests written and passing
  4. go build ./... passes
  5. go test ./... passes
  6. go test -race ./... passes
  7. golangci-lint run ./... passes
  8. docs/**/*.md updated

Use the single command from the checklist above to verify all at once.

Rule 4: Minimal, High-Level Logging

DO Log (high-level, critical):

  • ✅ Server startup/shutdown
  • ✅ Fatal errors that prevent operation
  • ✅ External service failures
  • ✅ Request/response (middleware level only)

DO NOT Log (low-level, verbose):

  • ❌ Function entry/exit
  • ❌ Variable values during processing
  • ❌ Request/response bodies (security risk)
  • ❌ Information already logged by middleware

Documentation Structure

Two-tier system: Folder-level (detailed) + Function-level (concise)

Folder-Level Docs (Detailed)

Format: docs/<foldername>-docs.md in docs/ folder

Examples:

  • docs/internal/api-docs.md → Architecture overview for internal/api/
  • docs/internal/api/handlers-docs.md → Architecture overview for internal/api/handlers/
  • docs/internal/database-docs.md → Architecture overview for internal/database/

Content (Detailed):

  • Design patterns and architectural decisions
  • Common tasks and how to approach them
  • How files in the folder work together
  • When to add new files vs modify existing ones
  • Dependencies and integration points

Purpose: Read BEFORE working in that folder to understand the big picture

Function-Level Docs (Concise)

Location: docs/**/*.md mirroring code structure (1:1 mapping)

Examples:

  • docs/cmd/api/main.md → Documents cmd/api/main.go
  • docs/internal/api/router.md → Documents internal/api/router.go
  • docs/internal/api/handlers/health.md → Documents internal/api/handlers/health.go

Content (Concise: 1-3 sentences):

  • What the file/function does
  • Key interactions with other files
  • Public functions/types overview

Purpose: Read BEFORE modifying specific files

Full Structure

backend/
├── cmd/
│   └── api/
│       └── main.go
├── internal/
│   ├── api/
│   │   ├── router.go
│   │   ├── handlers/
│   │   │   ├── health.go
│   │   │   └── hello.go
│   │   └── middleware/
│   │       └── logger.go
│   └── config/
│       └── config.go
└── docs/
    ├── cmd/
    │   └── api/
    │       └── main.md              # Function-level (concise)
    ├── internal/
    │   ├── api-docs.md              # Folder-level (detailed)
    │   ├── api/
    │   │   ├── handlers-docs.md     # Folder-level (detailed)
    │   │   ├── router.md            # Function-level (concise)
    │   │   ├── handlers/
    │   │   │   ├── health.md        # Function-level (concise)
    │   │   │   └── hello.md         # Function-level (concise)
    │   │   └── middleware/
    │   │       └── logger.md        # Function-level (concise)
    │   └── config/
    │       └── config.md            # Function-level (concise)
    └── tests/
        ├── unit/
        ├── integration/
        └── acceptance/

Quick Reference

Most Common Commands

# Development
go run cmd/api/main.go                    # Run server
go test ./...                             # Run all tests
go test -race ./...                       # Run tests with race detector
golangci-lint run ./...                   # Run linter

# Testing specific tiers
go test ./tests/unit                      # Unit tests
go test ./tests/integration               # Integration tests
go test ./tests/acceptance                # Acceptance tests

# Build
go build ./...                            # Build all packages

# Deployment
fly deploy                                # Deploy to Fly.io
fly logs                                  # View logs

Before Every Commit

# 1. Run mandatory checks (ONE command)
go build ./... && go test ./... && go test -race ./... && golangci-lint run ./...

# 2. Verify documentation updated
# Check that docs/**/*.md reflects code changes

# 3. Verify line counts
# All code files under 250 lines

Feature Completion Checklist

  • Code written and under 250 lines per file
  • Read folder-level docs before working in folder
  • Read function-level docs before modifying specific files
  • Unit tests written and passing
  • Integration tests written and passing
  • go build ./... passes
  • go test ./... passes
  • go test -race ./... passes
  • golangci-lint run ./... passes
  • Function-level docs updated (concise: 1-3 sentences)
  • Folder-level docs updated if architecture changed (detailed)
  • Logging is minimal and high-level only

Project Overview

Jarvis Backend is a production-ready Go web API service with static file serving, database integration, and AI embedding capabilities.

Key Technologies:

  • Go 1.21+
  • Chi v5 router with middleware
  • PostgreSQL with pgvector (Neon)
  • OpenAI embeddings API
  • Prometheus metrics
  • Docker containerization
  • Fly.io deployment

Core Components:

  1. Entry Point (cmd/api/) - Server initialization and lifecycle
  2. API Layer (internal/api/) - Routing, middleware, handlers
  3. Database (internal/database/) - PostgreSQL connection and migrations
  4. Services (internal/services/) - Embedding generation (OpenAI)
  5. Configuration (internal/config/) - Environment-based config
  6. Static Files (static/) - Frontend assets
  7. Testing (tests/) - Unit → Integration → Acceptance
  8. Documentation (docs/) - Per-file code documentation

Development Commands

Running the Application

# Run directly
go run cmd/api/main.go

# Or use VSCode launch configuration "Launch API" (F5)

Testing

# Run all tests
go test ./...

# Run specific test suite
go test ./tests/unit
go test ./tests/integration
go test ./tests/acceptance    # Requires API_BASE_URL

# Run single test
go test ./tests/unit -run TestSpecificFunction

# With coverage
go test ./... -coverprofile=coverage.out
go tool cover -html=coverage.out

# With race detector (ALWAYS before committing)
go test -race ./...

Code Quality

# Run linter (must pass before commits)
golangci-lint run ./...

# Auto-fix some issues
golangci-lint run --fix ./...

Dependencies

# Download dependencies
go mod download

# Update dependencies
go mod tidy

# Add new dependency
go get github.com/some/package

Building

# Build for current platform
go build -o bin/jarvis-backend cmd/api/main.go

# Build for all platforms
GOOS=linux GOARCH=amd64 go build -o bin/jarvis-backend-linux cmd/api/main.go
GOOS=darwin GOARCH=amd64 go build -o bin/jarvis-backend-darwin cmd/api/main.go

Docker

# Build image
docker build -t jarvis-backend .

# Run container
docker run -p 8080:8080 -e DATABASE_URL=$DATABASE_URL -e OPENAI_API_KEY=$OPENAI_API_KEY jarvis-backend

Deployment (Fly.io)

# Deploy
fly deploy

# View logs
fly logs

# Set secrets
fly secrets set DATABASE_URL="postgres://..." OPENAI_API_KEY="sk-..."

# Scale
fly scale count 2

Code Organization Patterns

Adding New API Endpoint

  1. Read docs/internal/api/handlers-docs.md (folder-level, detailed)
  2. Create handler: internal/api/handlers/foo.go
  3. Create function-level docs: docs/internal/api/handlers/foo.md (concise: 1-3 sentences)
  4. Register route in internal/api/router.go
  5. Update docs/internal/api/router.md
  6. Write tests: tests/unit/handlers_test.go
  7. Run checklist: go build ./... && go test ./... && go test -race ./... && golangci-lint run ./...
  8. Update docs/internal/api/handlers-docs.md if you changed the architecture

Adding New Middleware

  1. Read docs/internal/api-docs.md (folder-level, detailed)
  2. Create middleware: internal/api/middleware/auth.go
  3. Create function-level docs: docs/internal/api/middleware/auth.md (concise: 1-3 sentences)
  4. Register in internal/api/router.go (order matters!)
  5. Update docs/internal/api/router.md
  6. Write tests: tests/integration/api_test.go
  7. Run checklist
  8. Update docs/internal/api-docs.md if you changed the middleware architecture

Adding Configuration

  1. Update internal/config/config.go (add field to Config struct)
  2. Update docs/internal/config/config.md
  3. Update this file (CLAUDE.md) environment variables table
  4. Update README.md if user-facing
  5. Update fly.toml if needed for deployment

Environment Variables

Variable Description Default Required
PORT Server port 8080 No
LOG_LEVEL Logging level (debug, info, warn, error) info No
DATABASE_URL PostgreSQL connection string (Neon) - Yes
OPENAI_API_KEY OpenAI API key for embeddings - Yes
API_BASE_URL Base URL for acceptance tests - For tests only

Local Development: Use .env file (see .env.example)

Module Path

The Go module path is github.com/ali-aka-ahmed/jarvis/backend

CI/CD

GitHub Actions

Tests Workflow (.github/workflows/tests.yml):

  • Runs on push/PR to main
  • Executes: golangci-lint run ./...
  • Executes: go test -race ./...
  • Must pass before merge

Important Notes

Server Configuration

  • Graceful shutdown with 10-second timeout
  • ReadTimeout: 15 seconds
  • WriteTimeout: 15 seconds
  • IdleTimeout: 60 seconds

Handler Requirements

  • Always set Content-Type header before writing response
  • Use json.NewEncoder(w).Encode() with error handling
  • Return appropriate HTTP status codes

Testing Requirements

  • Minimum 80% code coverage for unit tests
  • All critical paths covered by integration tests
  • All user-facing features covered by acceptance tests
  • Always run with race detector: go test -race ./...

Documentation Workflow

Code Change → Read Folder-Level Docs → Read Function-Level Docs → Modify Code → Run Checklist → Update Both Doc Types → Commit

Example:

  1. Want to modify internal/api/router.go
  2. Read docs/internal/api-docs.md first (folder-level, detailed architecture)
  3. Read docs/internal/api/router.md second (function-level, concise: 1-3 sentences)
  4. Make changes to internal/api/router.go
  5. Run: go build ./... && go test ./... && go test -race ./... && golangci-lint run ./...
  6. Update docs/internal/api/router.md with changes (keep concise: 1-3 sentences)
  7. Update docs/internal/api-docs.md if architecture changed (keep detailed)
  8. Verify all files under 250 lines (code only, docs exempt)
  9. Commit all files together

See Also

  • .claude/WORKFLOW.md - Ultra-concise workflow checklist
  • README.md - User-facing documentation
  • docs/ - Per-file code documentation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment