118 lines
4.4 KiB
Markdown
118 lines
4.4 KiB
Markdown
# CLAUDE.md — Agent Instructions
|
|
|
|
This file is read automatically by Claude Code at the start of every session.
|
|
Keep it concise — the agent needs signal, not essays.
|
|
|
|
---
|
|
|
|
## Project overview
|
|
|
|
Go 1.24 template / PoC starter. Demonstrates: structured logging (zap),
|
|
config (viper), interfaces + mocks (mockery), linting (golangci-lint),
|
|
security scanning (gosec, govulncheck), git hooks, devcontainer, VSCode tasks.
|
|
|
|
Module: `github.com/your-org/go-template` — update this when you fork.
|
|
|
|
---
|
|
|
|
## Project structure
|
|
|
|
```
|
|
cmd/app/main.go composition root — wires deps, no logic here
|
|
internal/config/ Viper config loader (config.Load)
|
|
internal/logger/ Zap wrapper with WithField / WithFields
|
|
internal/greeter/ Example domain package (delete or repurpose)
|
|
mocks/greeter/ Generated mocks — regenerate with `make mocks`
|
|
config/dev.yaml Local dev config (committed, no secrets)
|
|
tools.go Tool version pinning (build tag: tools)
|
|
.golangci.yml Linter rules
|
|
.mockery.yaml Mockery code-gen config
|
|
.githooks/pre-commit Runs gofmt + golangci-lint + gosec before commit
|
|
```
|
|
|
|
---
|
|
|
|
## Project rules
|
|
|
|
- **Module imports** — always use the full module path `github.com/your-org/go-template/...`
|
|
- **Packages** — keep `cmd/` thin (wiring only); business logic belongs in `internal/`
|
|
- **Interfaces** — define interfaces where they are *used*, not where they are *implemented*
|
|
- **Errors** — wrap with `fmt.Errorf("context: %w", err)`; never swallow errors silently
|
|
- **Logging** — use `log.WithField("key", val)` for structured context, never `fmt.Sprintf` in log messages
|
|
- **Config** — all configuration through `internal/config`; no hard-coded values in logic packages
|
|
- **Secrets** — never commit `.env` files or credentials; use env var overrides of config keys
|
|
|
|
---
|
|
|
|
## Code style
|
|
|
|
- Follow `gofmt` + `goimports` formatting (enforced by linter and git hook)
|
|
- Imports: stdlib → blank line → external → blank line → internal (goimports handles this)
|
|
- Error variables: `err` for local, `ErrFoo` for package-level sentinels
|
|
- Constructors: `New(deps...) *Type` pattern
|
|
- Comment every exported symbol (golangci-lint will warn if missing)
|
|
- Max line length: 120 chars (configured in `.golangci.yml`)
|
|
- Prefer explicit over clever; PoC code should be readable first
|
|
|
|
---
|
|
|
|
## Testing rules
|
|
|
|
- All tests use **testify** (`assert` for soft checks, `require` for stop-on-fail)
|
|
- Test files: `package foo_test` (black-box) unless white-box access is needed
|
|
- Mock dependencies via **mockery**-generated mocks with `EXPECT()` chains
|
|
- Use `logger.NewNop()` when the test doesn't care about log output
|
|
- Table-driven tests with `t.Run("description", ...)` for multiple cases
|
|
- The race detector is enabled in CI (`make test-race`); don't introduce data races
|
|
- Never use `time.Sleep` in tests; use channels or `require.Eventually`
|
|
|
|
---
|
|
|
|
## Development commands
|
|
|
|
```bash
|
|
make init # first-time setup: fetch deps, install tools, git hooks
|
|
make build # compile to ./bin/app
|
|
make run # go run with config/dev.yaml
|
|
make test # run all tests
|
|
make test-race # tests + race detector
|
|
make lint # golangci-lint
|
|
make lint-fix # auto-fix lint issues
|
|
make security # gosec + govulncheck
|
|
make mocks # regenerate all mocks
|
|
make generate # run all //go:generate directives
|
|
make clean # remove bin/ and mocks/
|
|
```
|
|
|
|
VSCode: `Ctrl+Shift+B` = build, `Ctrl+Shift+T` = test.
|
|
Debug: use launch config "Debug: app" (F5).
|
|
|
|
---
|
|
|
|
## Adding new features (checklist)
|
|
|
|
1. Define the interface in `internal/<domain>/`
|
|
2. Write the implementation and its unit tests
|
|
3. Add the interface to `.mockery.yaml` and run `make mocks`
|
|
4. Wire it in `cmd/app/main.go`
|
|
5. Run `make lint test` before committing
|
|
|
|
---
|
|
|
|
## Known pitfalls
|
|
|
|
- `mocks/` are committed intentionally — regenerate after interface changes
|
|
- `govulncheck` makes network calls; excluded from pre-commit hook (run manually)
|
|
- `config/dev.yaml` is committed but never add real credentials here
|
|
- `tools.go` has `//go:build tools` — it won't compile into the binary
|
|
|
|
---
|
|
|
|
## Recent work
|
|
<!-- Agent: append a dated bullet when completing a significant chunk of work.
|
|
Keep this section to ~10 entries; remove stale items.
|
|
Format: YYYY-MM-DD — what was done and why. -->
|
|
|
|
- 2026-03-05 — Initial template scaffolded: config, logger, greeter example,
|
|
mocks, git hooks, devcontainer, VSCode tasks, golangci-lint, Makefile.
|