| name | philosophy |
| description | Philosophy — манифест разработки vmkteam: Go idioms, принципы, архитектурная культура. Используй как справку при спорных решениях по коду/архитектуре и при обосновании стиля проекту. |
Philosophy — манифест vmkteam
Принципы разработки vmkteam. Источник: https://vmkteam.dev
Код
- Пиши простой код. Думай о том, кто будет его читать через год
- Кодогенерация лучше ручного кода. Меньше ручного кода — меньше багов
- Не используй интерфейсы без необходимости. Конкретные типы понятнее
- Каждый слой имеет свои модели. Конвертеры между слоями обязательны
- Три строки простого кода лучше одной умной абстракции
Go idioms we follow
Конкретные правила, которых придерживаемся на всех слоях. Большинство — mainstream Go, часть — vmkteam-специфика (явно помечено).
Базовые
context.Context — всегда первый аргумент (после receiver), никогда не в структурах
error — последний возврат. Ошибки не теряются
- Обёртывание:
fmt.Errorf("context: %w", err). Проверка: errors.Is / errors.As. Свои типы ошибок — через структуру с методом Error(), а не sentinel string
defer для ресурсов сразу после захвата. defer rows.Close(), defer mu.Unlock()
- Zero-value ready типы — структура должна быть валидна без конструктора, когда это возможно
Типы и пакеты
- "Accept interfaces, return structs" — принимающие функции/методы работают с интерфейсами, фабрики возвращают конкретные типы
- Интерфейсы объявляются на стороне потребителя, не провайдера
- Короткие имена пакетов, одно слово. Никаких
util, common, helpers
- Экспорт по необходимости — начинай с lowercase, поднимай регистр когда появляется реальный внешний потребитель
Конкурентность
- Не запускай горутины без способа их остановить.
ctx + errgroup — базовый паттерн
- Каналы для сигналинга, мьютексы для разделяемого состояния — не наоборот
- Background-процессоры — метод
Run(ctx) error, возврат при ctx.Done() (см. /gold-arch)
Именование
- Getters без префикса
Get: user.Name(), не user.GetName()
- Аббревиатуры в одном регистре:
userID, HTTPServer, URL
- Переменная цикла —
i, u (короткое), параметр функции — длиннее и содержательнее
Производительность
- Не оптимизируй без бенчмарка.
testing.B + go test -bench
pprof через /appkit когда нужно искать узкие места на живом сервисе
vmkteam-специфика (явный выбор, не универсальный идиом)
- Слоистая архитектура db → domain → rpc (/gold-arch) — выбрана осознанно для типичного CRUD + фоновые процессоры + несколько API
- Кодогенерация как default (mfd, colgen, zenrpc, rpcgen) — заменяет ручной boilerplate, вне vmkteam-стека этого может быть слишком
- Без моков в тестах — интеграционные тесты против реальной БД (/testing)
- Embed вместо композиции для логгера:
type Service struct { embedlog.Logger } (/embedlog)
Что не-идиоматично и избегаем
- Глобальные переменные, init-функции с побочными эффектами
- Пакет
domain, service, utils как зонтик для всего подряд
- Интерфейсы «на вырост» (с одной реализацией, «вдруг понадобится»)
interface{} / any без причины — лучше generic или конкретный тип
- Panics в библиотечном коде (только в main для фатальных init-ошибок)
Архитектура
- Simple Architecture: DB → Domain → API, JSON-RPC 2.0 (/gold-arch)
- Не делай domain-слой для простого CRUD
- DI через конструкторы. Никакого global state
- Документация в git, не в Confluence. ADR для решений
- C4-диаграммы из метрик Prometheus (genc4)
Процесс
- Планируй перед кодом. Spec перед реализацией (/solve)
- Тесты перед кодом — TDD (/testing)
- Ревью обязателен, даже собственного кода (/go-review)
- Коммиты с номером задачи (/commit-msg)
- Любой workflow стартует с актуальной базовой ветки (обычно
devel). Устаревшая база = устаревший анализ и ревью
- Не деплой в пятницу
Безопасность
- Валидируй на границе системы (/security)
- Секреты в OS keychain (pcurl) или env vars. Никогда в коде
- gosec, govulncheck, gitleaks в CI (/ci-cd)
LLM и автоматизация
- LLM — инструмент, не автор. Код должен быть понятен без AI
- Кодогенерация с AI допустима когда: есть спецификация, результат проверяем тестами, код следует паттернам проекта
- Артефакты LLM сохраняются в
docs/llm/ (tasks/ для задач, incidents/ для инцидентов) — прозрачность процесса
- Не создавай зависимость от LLM
Стадии проекта
| Стадия | БД | Миграции | Мониторинг |
|---|
| Идея | sql файл актуальный, make db с нуля | Нет | Нет |
| Dev | + pgmigrator, sql всё ещё актуальный | Да | Sentry, возможно Prometheus |
| Production | + полный мониторинг | Да | Sentry, Prometheus, Loki, Grafana, Nomad |
Ссылки