AGENT SKILL

zenrpc

Zenrpc — справочник по JSON-RPC 2.0 серверу для Go. Используй при создании и редактировании RPC-сервисов.

License 许可
MIT
最近更新
2026-11-05
Stars
★ 7
Forks
1

01 前言 Front Matter

name
zenrpc
description
Zenrpc — справочник по JSON-RPC 2.0 серверу для Go. Используй при создании и редактировании RPC-сервисов.

03 SKILL.md 正文

Zenrpc

Codegen

//go:generate go tool zenrpc

go.mod содержит tool github.com/vmkteam/zenrpc/v2/zenrpc. make generate — обязательно после любых изменений в API/моделях/аннотациях. Файлы *_zenrpc.go не редактировать.

Сервис

Встраивание zenrpc.Service; VT-сервисы дополнительно встраивают embedlog.Logger:

type ReviewService struct {
    rm *reviewer.ReviewManager
    zenrpc.Service
}

type ProjectService struct {
    zenrpc.Service
    embedlog.Logger
    projectRepo db.ProjectRepo
}

Сигнатура метода: func (Service) Method([ctx,] [args]) (<value>, <error>) — любой return опционален, value может быть pointer, error = error | *zenrpc.Error.

Аннотации (magic comments)

// GetByID returns review details.
//
//zenrpc:reviewId Review ID
//zenrpc:return Review
//zenrpc:500 Internal Error
//zenrpc:404 Not Found
func (s ReviewService) GetByID(ctx context.Context, reviewId int) (*Review, error) {
  • //zenrpc:<param> Description — описание параметра
  • //zenrpc:<param>=<default> Description — default value
  • //zenrpc:<httpCode> Description — код ошибки
  • //zenrpc:return Description — описание возврата

Без обратных кавычек в документации. Doc-комментарии метода, описания //zenrpc:<param> и //zenrpc:return, комментарии полей RPC-моделей zenrpc переносит в SMD как raw-строку `…`: обратная кавычка в тексте (`id`, markdown-код) обрывает строку, и *_zenrpc.go не компилируется. Имена в документации — без оформления или в одинарных кавычках. Текст ошибки //zenrpc:<код> попадает в строку "…" — без " и \.

Ошибки

RPC-слой использует zenrpc.NewStringError, для wrap — zenrpc.NewError:

var (
    ErrInternal   = zenrpc.NewStringError(http.StatusInternalServerError, "internal error")
    ErrNotFound   = zenrpc.NewStringError(http.StatusNotFound, "not found")
    ErrBadRequest = zenrpc.NewStringError(http.StatusBadRequest, "bad request")
)
func newInternalError(err error) *zenrpc.Error {
    return zenrpc.NewError(http.StatusInternalServerError, err)
}

VT-слой: хелпер httpAsRPCError(code int) *zenrpc.Error → ErrUnauthorized/Forbidden/NotFound/Internal.

«Не найдено» — не ошибка репозитория: сгенерированный EntityByID возвращает (nil, nil) на pg.ErrNoRows. Метод сервиса обязан проверить nil и вернуть ErrNotFound, иначе конвертер NewEntity(nil) упадёт с nil pointer dereference.

newInternalError(err) безопасен для клиента только при zm.WithErrorSLog в цепочке middleware: он отправляет причину в Sentry и заменяет message на «Internal error» (подробнее — /security).

Server (канонический шаблон)

В существующем сервисе сервер и middleware уже настроены в server.go — новый сервис регистрируется в RegisterAll, второй сервер не заводится.

//go:generate go tool zenrpc

func New(dbo db.DB, logger embedlog.Logger, isDevel bool) *zenrpc.Server {
    rpc := zenrpc.NewServer(zenrpc.Options{ExposeSMD: true, AllowCORS: true})
    rpc.Use(
        zm.WithDevel(isDevel),
        zm.WithHeaders(),
        zm.WithSentry(zm.DefaultServerName),
        zm.WithNoCancelContext(),
        zm.WithMetrics(zm.DefaultServerName),
        zm.WithTiming(isDevel, allowDebugFn()),
        zm.WithSQLLogger(dbo.DB, isDevel, allowDebugFn(), allowDebugFn()),
        zm.WithSLog(logger.Print, zm.DefaultServerName, nil),
        zm.WithErrorSLog(logger.Error, zm.DefaultServerName, nil),
    )
    rpc.RegisterAll(map[string]zenrpc.Invoker{
        "review": NewReviewService(dbo),
    })
    return rpc
}

Middleware (zm)

MW Назначение / gotcha
WithDevel(isDevel) dev-флаг в ctx
WithHeaders() UA(2048)/Platform(64)/Version(64)/X-Country(16) в ctx
WithSentry(serverName) scope: params, duration, IP, platform, version, method
WithNoCancelContext() обязателен для go-pg: подавляет ctx.Cancel
WithMetrics(serverName) app_rpc_error_requests_total, app_rpc_responses_duration_seconds — labels: method, code, platform, version, server
WithTiming(isDevel, allowFn) DurationLocal в response extensions (ms)
WithSQLLogger(db, isDevel, allow1, allow2) SQL/DurationSQL в extensions
WithSLog(logger.Print, name, nil) slog.InfoContext
WithErrorSLog(logger.Error, name, nil) code==500 или <0 → лог + Sentry
WithAPILogger(printFn, name) legacy Printf-style

Кастомный auth-middleware

func authMiddleware(commonRepo *db.CommonRepo, logger embedlog.Logger) zenrpc.MiddlewareFunc {
    return func(h zenrpc.InvokeFunc) zenrpc.InvokeFunc {
        return func(ctx context.Context, method string, params json.RawMessage) zenrpc.Response {
            ns := zenrpc.NamespaceFromContext(ctx)
            if ns == NSAuth && method == RPC.AuthService.Login {
                return h(ctx, method, params)
            }
            // проверка auth header...
            return h(context.WithValue(ctx, userKey, dbu), method, params)
        }
    }
}

Context accessors

req, ok := zenrpc.RequestFromContext(ctx)  // *http.Request
ns := zenrpc.NamespaceFromContext(ctx)     // namespace
id := zenrpc.IDFromContext(ctx)            // request id

Сгенерированные файлы

*_zenrpc.go: Invoke() (роутинг), SMD, константы RPC.ServiceName.MethodName, парсинг params. Не редактировать вручную.

VT-конвенции (CRUD)

Стандартный набор на сущность: Count, Get, GetByID, Add, Update, Delete, Validate. Приватные хелперы: byID, dbSort, isValid.

Три типа моделей: Entity (полная), EntitySearch (фильтры + ToDB()), EntitySummary (для списков).

ViewOps{Page, PageSize (max 500), SortColumn, SortDesc} — пагинация/сортировка.

Валидация (только VT): Validator{fields []FieldError; err error}; теги validate:"required,max=255,status,alias".

Чеклисты

Новый метод: аннотации → модели → make generate.

Новый CRUD VT-сервис: namespace-константа → модели (Entity/Search/Summary) → конвертеры (NewEntity, NewEntitySummary) → сервис (Count/Get/GetByID/Add/Update/Delete/Validate) → регистрация в server.go → make generate.

04 同仓库更多 Skills

vmkteam
vmkteam/claude-plugins

youtrack

YouTrack — задачи через REST API и pcurl. Используй для поиска issues, создания, обновления описаний, смены assignee/stage/приоритета, логирования времени и работы с комментариями.

★ 7
vmkteam
vmkteam/claude-plugins

topsrv

topsrv — метрики, алерты, CVE и HTTP-логи серверов проекта через публичный JSON-RPC API app.topsrv.io. Используй, когда нужна загрузка CPU, памяти или диска хоста, метрики PostgreSQL/nginx/angie агента topsrv (`topsrv_*`), какие алерты горят, уязвимые пакеты на серверах или кто (боты, сети, IP) нагружает сайт.

★ 7
vmkteam
vmkteam/claude-plugins

testing

Testing — используй всегда, когда пишешь или правишь Go-тесты (*_test.go), в том числе по сценариям Given/When/Then из spec: фреймворк как в соседних файлах, префикс TestDB, фабрики pkg/db/test, реальная БД без моков. Также при настройке TestMain/test-short и когда тесты падают в gate, но проходят локально.

测试与质量
★ 7
vmkteam
vmkteam/claude-plugins

solve

Solve — полный цикл решения задачи из YouTrack: preflight → анализ → план → реализация → ревью → коммит. Используй при любой YouTrack-задаче (`/solve PLF-819`); флаг `--fast` сокращает HITL для тривиальных багфиксов.

★ 7
vmkteam
vmkteam/claude-plugins

skills-check

Skills Check — smoke-тесты интеграций из project-index.md. Используй для проверки что pcurl-профили и URL всех data-source скиллов ещё живы.

★ 7
vmkteam
vmkteam/claude-plugins

sentry

Sentry — мониторинг ошибок (issues, events, releases) через REST API. Используй когда нужно найти ошибку по ключевым словам, разобрать stack trace, проверить что релиз поднялся или сопоставить ошибку с коммитом.

★ 7