Files
egress-proxies-operator/CLAUDE.md
Jan Novak 076bc66ebe Scaffold proxy-operator with kubebuilder v4.15.0 (go/v4)
Bootstraps the empty repo into a kubebuilder go/v4 project: group
crawl.example.com, version v1alpha1, kind Proxy (namespaced). Keeps the
existing module path and preserves the repo's Go/testing/changelog
conventions from CLAUDE.md untouched.

Drops the scaffolded GitHub Actions workflows since the remote is Gitea,
not GitHub. Everything else is default kubebuilder output, unmodified,
so later diffs stay reviewable against a known baseline.

Full implementation plan: docs/plans/2026-08-07-1747-proxy-operator.md

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-07 20:17:45 +02:00

6.1 KiB

CLAUDE.md

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

What this is

A Kubernetes operator for managing egress proxies — currently an empty scaffold with no controller code yet. Intended shape: a controller-runtime manager reconciling custom resources (or existing workload types) to provision/configure egress proxy infrastructure. TODO: confirm the actual CRD(s)/API group once implemented.

Commands

No Makefile, linter, or entrypoint exists yet. Verified state as of bootstrap:

go build ./...   # nothing to build yet — no .go source files exist
go test ./...    # no test files exist yet

No linting or formatting tools are configured in this project yet — golangci-lint and gofumpt are pre-approved in .claude/settings.json for when they're wired up, but neither has a config file or CI step yet. There is no main.go or cmd/ entrypoint yet, so there's nothing to run locally.

Architecture

Not yet built. TODO: once the controller-runtime manager and reconcile loop exist, document the data-flow diagram and package/role table here, following the standard reconcile-loop shape: fetch → resolve → list related → compute desired state → merge → patch only on diff.

Conventions

Go Conventions

  • Use the latest stable Go version (check https://go.dev/dl/ before starting a new feature).
  • Use slog for structured logging.
  • context.Context is the first parameter of every function that does I/O or can be cancelled.
  • No init() unless there is no other option.
  • Error wrapping: fmt.Errorf("...: %w", err) for single errors; errors.Join for multiple.
  • Prefer stdlib over third-party dependencies where reasonable.
  • No vendoring unless explicitly requested.
  • Fail fast, return early.
  • No obvious comments.

Testing

All new Go code must have corresponding tests.

  • Use stdlib testing — no testify unless already present in the module.
  • Table-driven tests are the default pattern.
  • Test files live next to source: foo.gofoo_test.go.
  • Name tests Test<Function>_<scenario> (e.g. TestParseRoster_emptyInput).
  • Use t.Parallel() where safe.
  • Use subtests for table entries: t.Run(tc.name, func(t *testing.T) { ... }).
  • Test behaviour, not implementation.
  • Guard slow tests with testing.Short(): if testing.Short() { t.Skip() }.
  • Integration tests that need real infra (DB, network) go behind //go:build integration and use testcontainers-go rather than mocking the infra away.

Useful test commands

go test ./...               # all unit tests
go test -v ./...            # verbose
go test -cover ./...        # with coverage
go test -short ./...        # skip slow/integration tests
go test -v ./internal/...   # specific package tree
go test -race -v -run TestName ./path/to/package   # single test, race detector on
go test -tags=integration ./...                    # integration tests (requires infra)

Plans

When Claude Code's plan mode is used, save the plan file inside the repo at docs/plans/YYYY-MM-DD-HHMM-<slug>.md instead of the default ~/.claude/plans/ location. Get the timestamp with date "+%Y-%m-%d-%H%M". The <slug> is a short kebab-case summary of the plan's topic.

Include the same timestamp in the plan's header, e.g.:

# Plan: <title>
**Created:** 2026-08-07 15:30

Create docs/plans/ on first use. Plan files are committed to the repo so other contributors can review historical decisions.

Changelog

Maintain a running changelog in CHANGELOG.md at the repo root. After every significant change, fix, or update — once the user confirms it works — append a new entry at the top of the file in this format:

## YYYY-MM-DD HH:MM TZ — short title

- One-line summary of what changed and why.
- Key files touched (optional, only if useful for traceability).

Get the timestamp with date "+%Y-%m-%d %H:%M %Z". Never write a literal placeholder like HH:MM — always run date first to get the real current time. Skip trivial edits (typos, formatting, comment tweaks); only log changes a future reader would care about.

Branching & Merge Requests

The remote is Gitea (gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator). For features, do not commit to main directly. Use a branch + merge request flow:

  1. Create a branch off main before starting work:

    • feat/<slug> for features (e.g. feat/roster-import)
    • fix/<slug> for bug-fix branches the user explicitly asks for
    • <slug> is short kebab-case
  2. Commit on the branch following the commit conventions below.

  3. Push the branch to origin with -u so it tracks.

  4. Open the MR with tea rather than printing a compare URL:

    tea pr create \
      --title "<short title>" \
      --description "<body>" \
      --base main \
      --head <branch>
    

    tea is already authenticated against the Gitea instance; just run it. Print the resulting PR URL for the user. If tea is unavailable, fall back to printing the compare URL (gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/compare/main...<branch>) and let the user open the MR manually.

  5. Do not merge or delete the branch from the CLI — neither via tea, gh, nor git push --delete. The user does that in Gitea.

Exceptions — committing straight to main is fine for:

  • Small bug fixes / hotfixes the user describes as such.
  • Typo / comment / formatting tweaks.
  • Edits the user explicitly says to push to main.

When uncertain whether something is a feature or a small fix, ask before branching.

Git Commits

Always append a Co-Authored-By trailer to indicate AI assistance:

Co-Authored-By: Claude <noreply@anthropic.com>

TODO: no .gitea/workflows/ CI pipeline exists yet — add a CI/CD subsection here once one is set up.

Gotchas

  • This repo currently contains only go.mod (module gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator) — no controller code, main.go, Dockerfile, k8s manifests, Makefile, or CI config exist yet. Nothing in this file describes working software; it's the convention scaffold to build against.