К основному содержанию
скилл CX Codex

encore-go-code-review — скилл для Claude Code: ревью Encore Go

Скилл проверяет Go-код на Encore: инфраструктура внутри функций, забытый context, SQL-инъекции и другие анти-паттерны перед мержем.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add encoredev/skills --skill encore-go-code-review -a claude-code
npx skills add encoredev/skills --skill go-code-review -a claude-code
Открыть на GitHub

Что делает encore-go-code-review

Скилл включается, когда вы ревьюите пул-реквест, аудите существующий код или ищете специфичные для Encore анти-паттерны перед слиянием. Для нового кода, который ещё пишется, он не нужен.

Внутри — чеклист из девяти пунктов с примерами «как неправильно» и «как правильно». Критичные: инфраструктура объявлена внутри функции вместо уровня пакета, у API-эндпоинта нет context.Context первым параметром, SQL собирается через fmt.Sprintf вместо параметров $1, ответ возвращается значением вместо указателя, ошибки игнорируются. В предупреждениях — непроверенный sqldb.ErrNoRows, публичные внутренние эндпоинты, неидемпотентные обработчики подписок, незакрытые rows без defer rows.Close().

Результат выдаётся строками [CRITICAL], [WARNING] и [GOOD] с указанием файла и строки. Скилл рассчитан именно на Encore Go: вне этого стека проверки вроде errs.B и sqldb.Query смысла не имеют.

Какие задачи решает

  • найти инфраструктуру, объявленную внутри функций, и вынести её на уровень пакета
  • поймать SQL-инъекцию из-за склейки строки вместо параметров
  • проверить, что у каждого API-эндпоинта есть context.Context первым параметром
  • отловить неидемпотентный обработчик подписки до того, как он спишет деньги дважды
  • убедиться, что rows закрываются через defer rows.Close()

Примеры запросов агенту

  • отревьюй этот PR на анти-паттерны Encore
  • проверь код перед мержем: инфраструктура, context, SQL
  • сделай аудит пакета на code smell в Encore Go

Как установить encore-go-code-review

1Через Skills CLI (Vercel)

npx skills add encoredev/skills --skill encore-go-code-review -a claude-code
npx skills add encoredev/skills --skill go-code-review -a claude-code

2Вручную: положить файлы

~/.claude/skills/go-code-review/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/go-code-review/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о encore-go-code-review

Как установить encore-go-code-review в Claude?

Через skills CLI: npx skills add encoredev/skills --skill encore-go-code-review -a claude-code. После этого файл скилла лежит в ~/.claude/skills/go-code-review/SKILL.md.

Что делает encore-go-code-review?

Прогоняет существующий Encore Go-код по чеклисту из девяти анти-паттернов и выдаёт замечания с уровнями [CRITICAL], [WARNING] и [GOOD].

Для какого кода скилл не подходит?

Для нового кода, который ещё активно пишется: скилл рассчитан на ревью и аудит готового кода, а не на написание с нуля.

Исходный текст

SKILL.md · Apache-2.0
---
name: encore-go-code-review
description: Review existing Encore Go code for best practices and common anti-patterns.
when_to_use: >-
  User is reviewing a pull request, auditing existing code, or checking for Encore-specific anti-patterns before merging — infrastructure declared inside functions, missing service files, wrong import paths, raw `errors.New(...)` thrown instead of `errs.B`, untyped APIs, panicking in handlers. SKIP for greenfield code being actively written. Trigger phrases: "audit", "review", "before merge", "PR review", "anti-patterns", "code smell", "lint this".
---

# Encore Go Code Review

## Instructions

When reviewing Encore Go code, check for these common issues:

## Critical Issues

### 1. Infrastructure Inside Functions

```go
// WRONG: Infrastructure declared inside function
func setup() {
    db := sqldb.NewDatabase("mydb", sqldb.DatabaseConfig{...})
    topic := pubsub.NewTopic[*Event]("events", pubsub.TopicConfig{...})
}

// CORRECT: Package level declaration
var db = sqldb.NewDatabase("mydb", sqldb.DatabaseConfig{
    Migrations: "./migrations",
})

var topic = pubsub.NewTopic[*Event]("events", pubsub.TopicConfig{
    DeliveryGuarantee: pubsub.AtLeastOnce,
})
```

### 2. Missing Context Parameter

```go
// WRONG: Missing context
//encore:api public method=GET path=/users/:id
func GetUser(params *GetUserParams) (*User, error) {
    // ...
}

// CORRECT: Context as first parameter
//encore:api public method=GET path=/users/:id
func GetUser(ctx context.Context, params *GetUserParams) (*User, error) {
    // ...
}
```

### 3. SQL Injection Risk

```go
// WRONG: String interpolation
query := fmt.Sprintf("SELECT * FROM users WHERE email = '%s'", email)
rows, err := db.Query(ctx, query)

// CORRECT: Parameterized query
rows, err := sqldb.Query[User](ctx, db, `
    SELECT * FROM users WHERE email = $1
`, email)
```

### 4. Wrong Return Types

```go
// WRONG: Returning non-pointer struct
//encore:api public method=GET path=/users/:id
func GetUser(ctx context.Context, params *GetUserParams) (User, error) {
    // ...
}

// CORRECT: Return pointer to struct
//encore:api public method=GET path=/users/:id
func GetUser(ctx context.Context, params *GetUserParams) (*User, error) {
    // ...
}
```

### 5. Ignoring Errors

```go
// WRONG: Ignoring error
user, _ := sqldb.QueryRow[User](ctx, db, query, id)

// CORRECT: Handle error
user, err := sqldb.QueryRow[User](ctx, db, query, id)
if err != nil {
    return nil, err
}
```

## Warning Issues

### 6. Not Checking for ErrNoRows

```go
// RISKY: Returns nil without proper error
func getUser(ctx context.Context, id string) (*User, error) {
    user, err := sqldb.QueryRow[User](ctx, db, `
        SELECT * FROM users WHERE id = $1
    `, id)
    if err != nil {
        return nil, err  // ErrNoRows returns generic error
    }
    return user, nil
}

// BETTER: Check for not found specifically
import "errors"

func getUser(ctx context.Context, id string) (*User, error) {
    user, err := sqldb.QueryRow[User](ctx, db, `
        SELECT * FROM users WHERE id = $1
    `, id)
    if errors.Is(err, sqldb.ErrNoRows) {
        return nil, &errs.Error{
            Code:    errs.NotFound,
            Message: "user not found",
        }
    }
    if err != nil {
        return nil, err
    }
    return user, nil
}
```

### 7. Public Internal Endpoints

```go
// CHECK: Should this cron endpoint be public?
//encore:api public method=POST path=/internal/cleanup
func CleanupJob(ctx context.Context) error {
    // ...
}

// BETTER: Use private for internal endpoints
//encore:api private
func CleanupJob(ctx context.Context) error {
    // ...
}
```

### 8. Non-Idempotent Subscription Handlers

```go
// RISKY: Not idempotent (pubsub has at-least-once delivery)
var _ = pubsub.NewSubscription(OrderCreated, "process-order",
    pubsub.SubscriptionConfig[*OrderCreatedEvent]{
        Handler: func(ctx context.Context, event *OrderCreatedEvent) error {
            return chargeCustomer(ctx, event.OrderID)  // Could charge twice!
        },
    },
)

// SAFER: Check before processing
var _ = pubsub.NewSubscription(OrderCreated, "process-order",
    pubsub.SubscriptionConfig[*OrderCreatedEvent]{
        Handler: func(ctx context.Context, event *OrderCreatedEvent) error {
            order, err := getOrder(ctx, event.OrderID)
            if err != nil {
                return err
            }
            if order.Status != "pending" {
                return nil  // Already processed
            }
            return chargeCustomer(ctx, event.OrderID)
        },
    },
)
```

### 9. Not Closing Query Rows

```go
// WRONG: Rows not closed
func listUsers(ctx context.Context) ([]*User, error) {
    rows, err := sqldb.Query[User](ctx, db, `SELECT * FROM users`)
    if err != nil {
        return nil, err
    }
    // Missing: defer rows.Close()
    
    var users []*User
    for rows.Next() {
        users = append(users, rows.Value())
    }
    return users, nil
}

// CORRECT: Always close rows
func listUsers(ctx context.Context) ([]*User, error) {
    rows, err := sqldb.Query[User](ctx, db, `SELECT * FROM users`)
    if err != nil {
        return nil, err
    }
    defer rows.Close()
    
    var users []*User
    for rows.Next() {
        users = append(users, rows.Value())
    }
    return users, rows.Err()
}
```

## Review Checklist

- [ ] All infrastructure at package level
- [ ] All API endpoints have `context.Context` as first parameter
- [ ] SQL uses parameterized queries (`$1`, `$2`, etc.)
- [ ] Response types are pointers
- [ ] Errors are handled, not ignored
- [ ] `sqldb.ErrNoRows` checked where appropriate
- [ ] Internal endpoints use `private` not `public`
- [ ] Subscription handlers are idempotent
- [ ] Query rows are closed with `defer rows.Close()`
- [ ] Migrations follow naming convention (`1_name.up.sql`)

## Output Format

When reviewing, report issues as:

```
[CRITICAL] [file:line] Description of issue
[WARNING] [file:line] Description of concern  
[GOOD] Notable good practice observed
```

© encoredev · Apache-2.0 · encoredev/skills

Похожие скиллы

Всё по теме «Код-ревью и рефакторинг» →
go-code-review cxuu Проверяет Go-код по общепринятым стандартам стиля и выдаёт замечания по severity. Пригодится перед отправкой PR. CX Codex +1 1 700установок golang-patterns affaan-m Скилл подсказывает идиоматичные паттерны Go при написании, ревью и рефакторинге кода. Пригодится, когда нужно проверить структуру пакета или обработку ошибок. CX Codex +1 5 200установок dotnet-design-pattern-review официальный github Проверяет выбранный C#/.NET-код на применение паттернов проектирования и предлагает правки без изменения файлов. Подходит для ревью архитектуры проекта. 11 609установок python-expert-best-practices-code-review wispbit Набор правил по Python для написания, ревью и рефакторинга кода. Пригодится, когда агент правит обработку ошибок или чистит словари. CX Codex +1 673установок architecture-review decebals Скилл для макроразбора Java-проекта: структура пакетов, границы модулей, направление зависимостей и слои. Пригодится, когда кодовая база разрослась и непонятно, где что лежит. CX Codex +1 338установок golang-naming samber Скилл задаёт правила имён в Go: пакеты, типы, ошибки, булевы поля и тесты. Пригодится при написании, ревью и рефакторинге кода. CX Codex +1 40 900установок

Из того же набора10

encore-api Помогает агенту писать эндпоинты Encore.ts через api(...): типы запроса и ответа, параметры пути, валидация, ошибки. CX Codex +1 828установок encore-code-review Скилл проверяет код на Encore.ts перед мержем: инфраструктура внутри функций, require() вместо импортов, сырые Error вместо APIError. CX Codex +1 819установок encore-testing Помогает писать и запускать автотесты для Encore.ts через encore test и vitest или jest. Пригодится, когда нужно покрыть эндпоинт или сервис и не возиться с изолированными базами вручную. CX Codex +1 791установок encore-frontend Скилл связывает фронтенд на React, Next.js, Vue или Svelte с бэкендом Encore.ts: генерация типизированного клиента, CORS и токены авторизации. CX Codex +1 763установок encore-bucket Учит агента работать с объектным хранилищем Encore.ts: загрузка, скачивание, список и удаление файлов через Bucket. CX Codex +1 419установок encore-webhook Скилл учит агента принимать входящие вебхуки от Stripe, GitHub, Slack и других сервисов через api.raw() и проверять подписи. CX Codex +1 418установок encore-go-secret Скилл учит агента объявлять API-ключи и пароли в Encore Go через структуру secrets и задавать значения по окружениям. CX Codex +1 307установок encore-go-bucket Скилл подсказывает агенту, как объявлять бакеты и работать с файлами в Encore Go: загрузка, выгрузка, подписанные ссылки. CX Codex +1 307установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой