# AI Coding Instructions for DevOps

## Big Picture Architecture

- **Entry point**: cmd/devops-server. Startup sequence is **DB migrate → cron → services → eventbus → gRPC → HTTP API** (see run.go). Eventbus must start after services so subscriptions are registered.
- **HTTP API**: Gin server registers controllers grouped under /api/v1/devops (with auth), /api/v1/devops-internal (no auth), /api/v1/devops-external (no auth) in pkg/controller/api_server.go.
- **gRPC**: Separate server in pkg/controller/grpc_server.go; controllers register services via RegisterService.
- **Dependency Injection**: go.uber.org/dig container in pkg/infra/deps/deps.go wires infra clients, services, and controllers using groups (service/controller/grpc_controller).

## Core Conventions

- **Models vs Entities**: models/ are GORM tables; entity/ are domain structs. Service repos map via cvt converters (e2m/m2e), e.g. pkg/service/approval/repo/cvt and pkg/service/privilege/repo/cvt.
- **Repository layout**: per-domain repo is in pkg/service/<domain>/repo; service API interfaces live in pkg/service/<domain>/api; service implementation in pkg/service/<domain>/service.
- **Controller pattern**: controllers implement RegisterAPI(*Suite) and are registered in deps.go. Use controller.Success/Fail helpers for responses.

## Infra Utils Reuse

- **Prefer existing utils first**: before adding helper code, check `pkg/infra/utils` and reuse existing packages; avoid re-implementing generic helpers already provided here.
- **Scope of `pkg/infra/utils` packages**:
  - `auth`: token and IP validation helpers.
  - `container`: generic collection helpers (`map`/`set`/`slice`/`pair`/string helpers).
  - `exec`: structured command builder and command execution helpers.
  - `gorm`: DSN generation, DB connect helper, and GORM logger adapters.
  - `grpcutil`: gRPC response-to-error conversion and dial option presets.
  - `http`: reverse-proxy request/response helper utilities.
  - `k8s`: kubeconfig builders and Kubernetes client construction helpers.
  - `pointer`: pointer/deref/deep-copy helpers.
  - `repoopt`: reusable GORM query/filter option builders for repositories.
  - `signals`: process signal handling for graceful shutdown.
  - `time`: timestamp and `time.Time` conversion helpers.
  - `workqueue`: serial/parallel batch processing helpers with concurrency controls.
  - `test`: shared test framework, mocks, and assertion/helper utilities for unit tests.
- **Decision rule**: if a new helper overlaps with existing `infra/utils` capability, extend or reuse the existing package instead of adding a new scattered utility.

## Data Flow / Integration Points

- Event bus via tieventbus in pkg/infra/eventbus; internal + external topics are created and run together (Run()).
- External clients live under pkg/infra/clients (AWS/GCP/Jira/Lark/LLM/etc.) and are constructed via DI.

## Unit Tests

- **Frameworks**: standard `testing` plus Ginkgo/Gomega (see go.mod). Mocks are generated with `go.uber.org/mock` (install via make install-mockgen).
- **Reusable mocks**: when a unit test needs a reusable interface/client mock, add or update a `//go:generate ${GOBIN}/mockgen ...` directive and commit the generated mock file. Do not add package-level hand-written fake/mock structs for reusable clients.
- **Preferred framework**: for new unit tests, prefer **Ginkgo/Gomega** over plain `testing`; keep compatibility with existing tests only when extending legacy files.
- **Project style**: follow existing suite style (`RunSpecs`, `Describe/Context/It`, `BeforeEach/AfterEach`, `Expect` assertions, and `test.ReporterConfig()` where commonly used in the package).
- **Style**: table-driven tests for converters and repos are common, e.g. `pkg/service/approval/repo/cvt/converter_test.go` and `pkg/service/github/repo/cvt/converter_test.go`.

## Git & PR Workflow

- **Target branch for PRs**: always open pull requests against `main`.
- **Deploying to the dev environment**: merging a PR into `main` does **not** trigger a dev deployment. After a PR is merged to `main`, deploy to dev by merging `main` into `dev` and pushing:
  1. Switch to the `dev` branch locally.
  2. Merge `main` into `dev`.
  3. Push `dev` to origin — this triggers the dev deployment.
- Keep `dev` as a throwaway integration branch; treat `main` as the source of truth.
- **Pre-PR dev testing (optional)**: if you need to verify changes in dev before opening a PR, you may merge your feature branch directly into `dev` and push. This is exceptional — the normal flow is PR to `main` first.

## Developer Workflow (Makefile)

- Build: make build (or build-devops-server/build-jump-pod-agent/build-migrate-proxy).
- Test: make test (includes migrate test with ENABLE_MIGRATE=1).
- Lint: make lint / make lint-fix (golangci-lint).
- Codegen: make generate (go generate + swag + buf). Swagger output in docs/api/*.

## Database Migrations

- Migration records live in migrate/record_*.go and are executed by migrate.RunDBMigrate during startup. Use AddMigrateRecord with unique version strings.

## Adding Features (Concrete Path)

- New service: add entity/ + models/ + pkg/service/<domain>/repo (+ cvt), define pkg/service/<domain>/api, implement pkg/service/<domain>/service, then register constructor in pkg/infra/deps/deps.go.
- New HTTP API: define request/response in api/<domain>, implement controller in pkg/controller/<domain>, register in deps.go, and wire routing in RegisterAPI.

## Specific Examples

### Creating a New Service

1. Define entities in entity/<domain>.
2. Define models in models/<domain>.
3. Create pkg/service/<domain>/repo with converter pattern in repo/cvt.
4. Define service API interface in pkg/service/<domain>/api.
5. Implement service logic in pkg/service/<domain>/service.
6. Register in pkg/infra/deps/deps.go.

### Creating a New API Endpoint

1. (Optional) Implement corresponding Service first if needed.
2. Define request and response structs in api/<domain>.
3. Implement controller in pkg/controller/<domain> and wire routes in RegisterAPI.
