This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
BEFORE modifying ANY code file:
- Read the relevant folder-level docs for the task (e.g.,
docs/internal/api-docs.md) - Read relevant function-level docs for the task (e.g.,
docs/internal/api/handlers/health.md) - Understand how it interacts with other files
- Follow the patterns documented there
BEFORE committing ANY code:
- Run:
go build ./... && go test ./... && go test -race ./... && golangci-lint run ./... - ALL must pass - no exceptions
- Update function-level docs (keep concise: 1-3 sentences)
- Update all folder-level docs if architecture changed (keep detailed)
- Verify all code files under 250 lines
See .claude/WORKFLOW.md for detailed workflow 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 errorsgo test ./...- Runs all tests (unit + integration + acceptance)go test -race ./...- Detects race conditions and concurrency bugsgolangci-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
ALWAYS read both documentation types before modifying code:
- Folder-Level Docs (Detailed) - Read the architecture overview for the folder
- Function-Level Docs (Concise) - Read the specific file documentation
Two-Tier Documentation System:
Folder-Level (Detailed):
docs/internal/api-docs.md→ Architecture overview forinternal/api/folderdocs/internal/api/handlers-docs.md→ Architecture overview forinternal/api/handlers/folder
Function-Level (Concise: 1-3 sentences):
docs/cmd/api/main.md→ Documentscmd/api/main.godocs/internal/api/router.md→ Documentsinternal/api/router.godocs/internal/api/handlers/health.md→ Documentsinternal/api/handlers/health.godocs/internal/config/config.md→ Documentsinternal/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
Every code file MUST be under 250 lines. Documentation files (*.md) are exempt.
When a code file approaches 250 lines:
- Identify logical boundaries
- Extract to new focused files
- Update imports
- Create corresponding
docs/**/*.mdfiles
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
A feature is NOT complete until:
- ✅ All code written (under 250 lines per file)
- ✅ Unit tests written and passing
- ✅ Integration tests written and passing
- ✅
go build ./...passes - ✅
go test ./...passes - ✅
go test -race ./...passes - ✅
golangci-lint run ./...passes - ✅
docs/**/*.mdupdated
Use the single command from the checklist above to verify all at once.
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
Two-tier system: Folder-level (detailed) + Function-level (concise)
Format: docs/<foldername>-docs.md in docs/ folder
Examples:
docs/internal/api-docs.md→ Architecture overview forinternal/api/docs/internal/api/handlers-docs.md→ Architecture overview forinternal/api/handlers/docs/internal/database-docs.md→ Architecture overview forinternal/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
Location: docs/**/*.md mirroring code structure (1:1 mapping)
Examples:
docs/cmd/api/main.md→ Documentscmd/api/main.godocs/internal/api/router.md→ Documentsinternal/api/router.godocs/internal/api/handlers/health.md→ Documentsinternal/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
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/
# 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# 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- 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
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:
- Entry Point (
cmd/api/) - Server initialization and lifecycle - API Layer (
internal/api/) - Routing, middleware, handlers - Database (
internal/database/) - PostgreSQL connection and migrations - Services (
internal/services/) - Embedding generation (OpenAI) - Configuration (
internal/config/) - Environment-based config - Static Files (
static/) - Frontend assets - Testing (
tests/) - Unit → Integration → Acceptance - Documentation (
docs/) - Per-file code documentation
# Run directly
go run cmd/api/main.go
# Or use VSCode launch configuration "Launch API" (F5)# 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 ./...# Run linter (must pass before commits)
golangci-lint run ./...
# Auto-fix some issues
golangci-lint run --fix ./...# Download dependencies
go mod download
# Update dependencies
go mod tidy
# Add new dependency
go get github.com/some/package# 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# 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# Deploy
fly deploy
# View logs
fly logs
# Set secrets
fly secrets set DATABASE_URL="postgres://..." OPENAI_API_KEY="sk-..."
# Scale
fly scale count 2- Read
docs/internal/api/handlers-docs.md(folder-level, detailed) - Create handler:
internal/api/handlers/foo.go - Create function-level docs:
docs/internal/api/handlers/foo.md(concise: 1-3 sentences) - Register route in
internal/api/router.go - Update
docs/internal/api/router.md - Write tests:
tests/unit/handlers_test.go - Run checklist:
go build ./... && go test ./... && go test -race ./... && golangci-lint run ./... - Update
docs/internal/api/handlers-docs.mdif you changed the architecture
- Read
docs/internal/api-docs.md(folder-level, detailed) - Create middleware:
internal/api/middleware/auth.go - Create function-level docs:
docs/internal/api/middleware/auth.md(concise: 1-3 sentences) - Register in
internal/api/router.go(order matters!) - Update
docs/internal/api/router.md - Write tests:
tests/integration/api_test.go - Run checklist
- Update
docs/internal/api-docs.mdif you changed the middleware architecture
- Update
internal/config/config.go(add field to Config struct) - Update
docs/internal/config/config.md - Update this file (CLAUDE.md) environment variables table
- Update
README.mdif user-facing - Update
fly.tomlif needed for deployment
| 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)
The Go module path is github.com/ali-aka-ahmed/jarvis/backend
Tests Workflow (.github/workflows/tests.yml):
- Runs on push/PR to main
- Executes:
golangci-lint run ./... - Executes:
go test -race ./... - Must pass before merge
- Graceful shutdown with 10-second timeout
- ReadTimeout: 15 seconds
- WriteTimeout: 15 seconds
- IdleTimeout: 60 seconds
- Always set
Content-Typeheader before writing response - Use
json.NewEncoder(w).Encode()with error handling - Return appropriate HTTP status codes
- 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 ./...
Code Change → Read Folder-Level Docs → Read Function-Level Docs → Modify Code → Run Checklist → Update Both Doc Types → Commit
Example:
- Want to modify
internal/api/router.go - Read
docs/internal/api-docs.mdfirst (folder-level, detailed architecture) - Read
docs/internal/api/router.mdsecond (function-level, concise: 1-3 sentences) - Make changes to
internal/api/router.go - Run:
go build ./... && go test ./... && go test -race ./... && golangci-lint run ./... - Update
docs/internal/api/router.mdwith changes (keep concise: 1-3 sentences) - Update
docs/internal/api-docs.mdif architecture changed (keep detailed) - Verify all files under 250 lines (code only, docs exempt)
- Commit all files together
.claude/WORKFLOW.md- Ultra-concise workflow checklistREADME.md- User-facing documentationdocs/- Per-file code documentation