This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Bucketeer is an open-source feature management and experimentation platform. It provides feature flags with targeted rollouts, Bayesian A/B testing, automated progressive rollouts, and audit logging. It is designed to scale from Docker Compose (small/medium) to Kubernetes (100M+ users).
cmd/ # Four binary entrypoints: api, web, batch, subscriber
pkg/ # All Go business logic, organized by domain
proto/ # Protobuf definitions; generated .pb.go files live here too
ui/dashboard/ # React 19 + Vite + TailwindCSS + TypeScript frontend (Admin console)
manifests/ # Helm charts for Kubernetes deployment
migration/ # Atlas-managed SQL migrations (mysql/ and postgres/)
docker-compose/ # Docker Compose local dev setup
tools/ # Dev tooling (certs, tokens, etc.)
evaluation/ # Go and other SDK evaluation logic
hack/ # One-off utility scripts
| Binary | Role |
|---|---|
cmd/api |
API Gateway — SDK-facing gRPC/HTTP endpoints |
cmd/web |
Web Gateway — Admin UI and internal service APIs |
cmd/batch |
Batch processor — scheduled jobs (experiment calculation, rollups) |
cmd/subscriber |
Event subscriber — processes Pub/Sub events asynchronously |
Most domain packages follow this structure (not all layers are present in every domain — e.g. auth has api/ and client/ but no domain/ or storage/):
domain/— core business logic and domain typesapi/— gRPC service handlersstorage/v2/— MySQL/Postgres persistence (BigQuery instorage/bigquery/)client/— gRPC client for inter-service communicationmock/— generated mocks (do not edit manually)
Key domains: feature, experiment, autoops, eventcounter, account, environment, auth, notification, push, auditlog, insights, coderef, tag, team.
make local-depsInstalls: goimports, golangci-lint, mockgen, protoc-gen-go, protoc-gen-grpc-gateway, protoc-gen-openapiv2, protolock, yq.
Also required (not managed by local-deps):
protocv23.4 (libprotoc 23.4) — the repo expects exactly this version; generated.pb.gofiles must showprotoc v4.23.4clang-format— required forproto fmtstep (brew install clang-format)
make build-go # Build all Go binaries into bin/
make build-<service> # Build a single binary, e.g. make build-api
make build-web-console # Build the React frontendmake start-httpstan # Required before running tests (Bayesian experiment package needs it)
make test-go # Run all Go unit tests
make stop-httpstan # Optional cleanup after tests
# Run a single test or package directly:
TZ=UTC CGO_ENABLED=0 go test -v ./pkg/feature/...
TZ=UTC CGO_ENABLED=0 go test -v -run TestFoo ./pkg/feature/domain/Tests use a table-driven format ([]struct{ ... } test cases iterated with t.Run). Follow this pattern when adding new tests.
make lint # golangci-lint on cmd/, pkg/, evaluation/go/, hack/, test/
make gofmt # Format with goimports (run after any Go changes)
yarn style:all --write # Format after making changes to TypeScript filesmake generate-all # Regenerate proto Go files + mocks (runs proto-all + mockgen)
make proto-all # Regenerate only proto Go files + OpenAPI/Swagger specs
make mockgen # Regenerate only mocks (after changing interfaces that have mocks)- Run
make proto-allafter any.protofile change — this regenerates Go bindings and OpenAPI/Swagger specs. - Run
make mockgenafter changing any Go interface that has generated mocks in amock/directory. - The generated files are committed to the repo.
protocv23.4 must be on PATH ahead of any other version for the version header in.pb.gofiles to stay atv4.23.4. - Prefer running generation inside the dev container via the
devcontainer-generateskill — the container guarantees protoc v23.4, while a host version mismatch churns every generated file.
Dev container + Minikube (preferred):
Development actions — proto generation, builds, deploys, kubectl/helm — should run inside the Bucketeer dev container, where tool versions are guaranteed (protoc v23.4, go-tools, minikube/helm/kubectl). Check for a running dev container first before running these on the host. Use the project skills:
devcontainer-run— detect the running dev container (local devcontainer or Codespace) and run any command inside it:bash .claude/skills/devcontainer-run/scripts/exec.sh statusdevcontainer-generate— proto/mock generation inside the containerdevcontainer-deploy— deploy to the minikube cluster inside the container
make start-minikube # Inside the dev container. Always use this, not `minikube start` directly
make deploy-bucketeer # Deploy all Helm charts to minikubeNever run kubectl/helm bare on the host — the host kubectl context may point at a real GKE cluster, not minikube.
Docker Compose (host-based alternative):
make docker-compose-up # Start all services
make docker-compose-status # Check status
make docker-compose-logs # View logs
make docker-compose-down # Stop services
make docker-compose-clean # Remove all containers, networks, volumesAdd to /etc/hosts:
127.0.0.1 web-gateway.bucketeer.io
127.0.0.1 api-gateway.bucketeer.io
make migration-validate # Validate migration files with Atlas
make migration-hash-check # Check Atlas migration hash is up to dateMigrations live in migration/mysql/ and migration/postgres/ and are managed with Atlas.
All service interfaces are defined in proto/ and generated into proto/<domain>/*.pb.go and *.pb.gw.go. The omitempty JSON tag is intentionally stripped from all generated files (see proto/Makefile) because legacy projects rely on empty environment_id fields being serialized.
The subscriber service consumes Google Cloud Pub/Sub events. Its runtime behavior is configured via JSON files in docker-compose/config/subscriber-config/: subscribers.json, onDemandSubscribers.json, processors.json, onDemandProcessors.json.
The codebase supports MySQL, PostgreSQL, and BigQuery as the event data warehouse. The active backend is controlled by dataWarehouse.type in manifests/bucketeer/values.dev.yaml. The Makefile auto-detects this to set POSTGRES_ENABLED / BIGQUERY_ENABLED. The web and subscriber services must use the same event store.
Mocks are generated by go generate -run="mockgen" triggered from //go:generate directives in the source files. They are regenerated by make mockgen (or make generate-all). Never edit files in mock/ directories manually.
The Go module is github.com/bucketeer-io/bucketeer/v2. Use this prefix for all internal imports.