---
name: go-review-pr
description: "Review all changes in the current branch against GOB project conventions before opening a PR. Diff-aware: only analyzes what changed, not the entire codebase. Triggers: \"review pr\", \"revisar pr\", \"pre-pr check\", \"review branch\", \"revisar branch\", \"checar antes do pr\", \"quality gate\"."
---

# CSTK Adaptation

Adapted from `JotJunior/cstk` skill `go-review-pr` at commit `35922cf`.
Use this as a Codex skill; follow local repository instructions and Codex tool names when source text mentions Claude-specific commands or slash commands.

# Go Review PR

Perform a diff-aware quality review of ALL changes in the current branch before opening a PR. This is the final quality gate — it checks everything that `go-review-service` checks, but scoped to the diff only.

## Arguments

the user's request should specify:
- **Base branch** (optional, default: `main`) — the branch to compare against

## Step 1: Gather the Diff

```bash
# Get the base branch (default: main)
BASE=${1:-main}

# All changed files in this branch vs base
git diff --name-only $BASE...HEAD

# Full diff for context
git diff $BASE...HEAD

# Commits in this branch
git log --oneline $BASE..HEAD
```

Categorize changed files:
- **Go source files** (*.go, excluding *_test.go)
- **Go test files** (*_test.go)
- **Migration files** (migrations/*.sql)
- **Frontend files** (*.ts, *.tsx)
- **Config files** (*.json, *.yaml, *.toml, go.mod, go.sum)
- **Documentation** (*.md)

## Step 2: Per-Service Analysis

For each service with changed files, read the changed files and run these checks:

### Check A: Compilation
```bash
cd services/{service} && go build ./...
```

### Check B: Tests Pass
```bash
cd services/{service} && go test ./... -count=1 -timeout 60s
```

### Check C: Lint
```bash
cd services/{service} && golangci-lint run ./... 2>&1 || true
```

## Step 3: Convention Checks (on diff only)

For each changed Go file, verify:

### 3.1 Code in English
- All new variable names, function names, comments, error messages are in English
- **FAIL** if Portuguese found in code (excluding string literals for user-facing messages)

### 3.2 JSON Tags snake_case
- All new struct fields with `json:""` tags use snake_case
- **FAIL** if camelCase or PascalCase found in json tags

### 3.3 DB Tags Match Columns
- All new struct fields with `db:""` tags use snake_case matching column names
- Cross-reference with migration files if available

### 3.4 Schema Prefix in SQL
- All SQL queries in repository files use `{schema}.{table}` format
- **FAIL** if any bare table name found (e.g., `FROM members` instead of `FROM member.members`)

### 3.5 Route Registration Order
- In handler files: static routes BEFORE parameterized `/:id` routes
- Sub-groups BEFORE `/:id` catch-all
- **FAIL** if order is wrong (Fiber trie conflict)

### 3.6 Error Patterns
- Service layer: sentinel errors (`var ErrXxxNotFound`), no HTTP codes
- Handler layer: `errors.Is()` dispatch, `dto.ErrorResponse` returns
- Repository layer: `sql.ErrNoRows` → `nil, nil`

### 3.7 Import Hierarchy
Verify no import cycles:
```
domain → (nothing)
dto → domain (if needed)
repository → domain
service → repository + domain
handler → service + dto + domain
factory → repository + postgres
```
**FAIL** if handler imports repository directly, or service imports handler, etc.

### 3.8 Context First Parameter
- All repository and service methods have `context.Context` as first parameter
- **FAIL** if any public method is missing context

### 3.9 Middleware Order (if main.go changed)
Verify order: recover → requestid → nrfiber → logging → cors → [dryrun] → audit → endpoints

### 3.10 Test Coverage
- Every new .go file (excluding main.go, migrations, mocks) should have a corresponding _test.go
- New service methods should have test cases for: happy path, not found, validation error, repo error

## Step 4: Migration Checks (if migrations changed)

### 4.1 Naming Convention
- Format: `{NNN}_{descriptive_name}.up.sql` / `{NNN}_{descriptive_name}.down.sql`
- Number is sequential (no gaps, no duplicates)
- Up and down files exist as pairs

### 4.2 Schema Prefix
- CREATE TABLE uses `{schema}.{table_name}`
- All references use schema prefix

### 4.3 Rollback Safety
- Down migration has `DROP TABLE IF EXISTS ... CASCADE` or appropriate reversal
- Down migration reverses ALL changes in up migration

### 4.4 CIM Format
- Any CIM values in seed data use 7-digit zero-padded format (e.g., `'0051522'`)
- Uses `LPAD` if converting from integer sources

### 4.5 Idempotency
- Uses `IF NOT EXISTS` for CREATE TABLE/INDEX
- Uses `DO $$ ... IF NOT EXISTS` for enum types

## Step 5: Frontend Checks (if frontend files changed)

### 5.1 API Client Usage
- Uses `apiClient` (not raw fetch/axios/ky)
- snake_case in request bodies (backend expects it)
- FormData uploads use `{ body: data }` (not `{ json: data }`)
- `transformResponse` camelCase conversion accounted for in types

### 5.2 Portuguese Accents
- UI text uses proper Portuguese accents (é, ã, ç, ô, í)
- Lodge display format: "No {number} - {name}" (not just name)

### 5.3 Type Safety
- No `any` types where a proper type could be used
- Response types match backend DTOs
- Query key factories pattern used (`fooKeys.all/lists/detail`)

### 5.4 Shared Components
- Uses `PageHeader` for page titles (not custom headers)
- Uses `ServerPagination` for tables (not custom pagination)
- Uses `useConfirmDialog` for destructive actions (not inline confirm)
- CRUD forms on dedicated pages, NOT modals

### 5.5 Navigation
- Parent nav items use `end: true` to prevent highlight on child routes
- New routes registered in `src/config/navigation.ts`

## Step 6: Cross-Cutting Checks

### 6.1 go.mod Consistency
- No replace directives (unless justified — `go-commons` replace is expected)
- `go mod tidy` was run (no extra/missing deps)

### 6.2 Submodule State
- If changes span multiple services, submodule pointers are updated

### 6.3 AGENTS.md Updates
- If new routes/endpoints added, check if routing table in AGENTS.md needs update
- If new service added, check if service table needs update

### 6.4 Storage API (if S3/storage used)
- Uses `storage.Storage` interface (not direct S3 calls)
- Key pattern: `{service}/{category}/{entityID}/{uuid}-{filename}.ext`
- Upload uses `Upload(ctx, key, reader, size, contentType)` — NOT `Put`
- Presigned URL uses `PresignedGetURL(ctx, key, expiry)` — NOT `GetPresignedURL`

### 6.5 RabbitMQ Events (if publisher/consumer changed)
- Publisher uses `AMQPPublisher` + `NoopPublisher` (graceful degradation)
- Consumer uses `ExchangeDeclarePassive` for foreign exchanges (not `ExchangeDeclare`)
- Channel reopened after passive declare failure
- Return `nil` for unrecognized event routing keys (not error)

### 6.6 Inter-Service Clients (if client/ changed)
- Authenticated with `X-Internal-Key` header
- Key from ETCD `INTERNAL_API_KEY` or `SHARED_INTERNAL_API_KEY`
- Graceful degradation: service continues if external service unavailable

## Output Format

```markdown
# PR Review: {branch-name}
Date: {date}
Base: {base-branch}
Changes: {N} files across {M} services

## Build & Test
| Service | Build | Tests | Lint |
|---------|-------|-------|------|
| gob-xxx-service | PASS | PASS (12/12) | PASS |
| gob-yyy-service | FAIL | - | - |

## Convention Checks
| # | Check | Status | Details |
|---|-------|--------|---------|
| A | Code in English | PASS | |
| B | JSON tags snake_case | FAIL | dto/member.go:45 — `firstName` should be `first_name` |
| C | Schema prefix | PASS | |
| ... | ... | ... | ... |

## Migration Checks
| # | Check | Status | Details |
|---|-------|--------|---------|
| 1 | Naming | PASS | |
| 2 | Rollback | WARNING | 015_add_column.down.sql missing |
| ... | ... | ... | ... |

## Summary
- **PASS**: X checks
- **FAIL**: Y checks (must fix before merge)
- **WARNING**: Z checks (review recommended)

## Required Actions
1. [List of things that MUST be fixed]

## Recommendations
1. [List of things that SHOULD be fixed]
```

## Important Notes

- This skill is **read-only** — it does NOT modify any files
- Always provide `file:line` references for FAIL and WARNING results
- If the branch has no Go changes, skip Go-specific checks
- If the branch has no migration changes, skip migration checks
- Run Build & Test checks first — if build fails, skip convention checks for that service
- Be thorough but avoid false positives — when uncertain, use WARNING not FAIL

## Source License

This skill includes material adapted from `JotJunior/cstk`, licensed under MIT. The copyright and permission notice are included in `references/cstk-license.md`.

