Перейти к содержанию

Общие пакеты (pkg/)

Директория pkg/ содержит переиспользуемые пакеты, которые разделяются между микросервисами монорепозитория Univex. Каждый пакет решает одну конкретную задачу и не имеет бизнес-логики. Всего 15 пакетов.


balogan/

Путь: pkg/balogan/

Назначение: Пакет структурированного логирования. Предоставляет единый интерфейс логгера для всех сервисов монорепозитория.

Ключевые возможности:

  • Структурированные поля (key-value) в каждой записи лога
  • Уровни: Debug, Info, Warn, Error
  • Интеграция с контекстом (context.Context) для передачи trace/correlation ID
  • Настраиваемый формат вывода (JSON для продакшена, текст для разработки)

Пример:

import "pkg/balogan"

logger := balogan.New(balogan.Config{Format: "json", Level: "info"})

logger.Info(ctx, "trade saved",
    balogan.Field("ticker", trade.Ticker),
    balogan.Field("price", trade.Price),
    balogan.Field("exchange_time", trade.ExchangeTime),
)

clients/

Путь: pkg/clients/

Назначение: HTTP/gRPC-клиенты для взаимодействия с внешними и внутренними сервисами.

Содержит два подпакета:

clients/exchange/

HTTP-клиент для взаимодействия с Exchange HTTP API. Используется сервисом Trades Aggregator для получения торговых данных.

  • Получение списка торгов за временной диапазон
  • Поддержка фильтрации по торговым парам (тикерам)
  • Retry-логика при временных сбоях
  • Настраиваемые таймауты и заголовки аутентификации
import "pkg/clients/exchange"

client := exchange.NewClient(exchange.Config{
    BaseURL: "https://exchange.example.com",
    APIKey:  "...",
    Timeout: 10 * time.Second,
})

trades, err := client.GetTrades(ctx, exchange.GetTradesParams{
    Ticker: "BTC_USDT",
    From:   time.Now().Add(-time.Hour),
    To:     time.Now(),
})

clients/apigen/

OpenAPI-сгенерированный клиент для Exchange HTTP API. Содержит типы запросов/ответов на основе OpenAPI-спецификации. Используется как зависимость для clients/exchange/. Не предназначен для ручного редактирования.


deps/

Путь: pkg/deps/

Назначение: Вспомогательные функции для организации инъекции зависимостей (Dependency Injection). Упрощает сборку компонентов сервиса.

Ключевые возможности:

  • Базовые интерфейсы для объявления зависимостей
  • Вспомогательные функции для инициализации с обработкой ошибок
  • Паттерн MustProvide — паника при невозможности создать зависимость (используется при старте сервиса)
import "pkg/deps"

// При старте сервиса: паника при ошибке конфигурации
db := deps.MustProvide(func() (*sqlx.DB, error) {
    return sqlx.Connect("postgres", cfg.DatabaseURL)
})

find/

Путь: pkg/find/

Назначение: Вспомогательные функции для поиска элементов в коллекциях и структурах данных. Обобщённые утилиты для типичных задач поиска без написания повторяющегося кода.


hawk/

Путь: pkg/hawk/

Назначение: Утилиты для обработки ошибок. Предоставляет удобные обёртки для создания, оборачивания и проверки ошибок в Go, совместимые со стандартным интерфейсом error.


jsonify/

Путь: pkg/jsonify/

Назначение: Вспомогательные функции для работы с JSON. Упрощает типичные операции сериализации/десериализации и устраняет повторяющийся boilerplate-код.

Ключевые возможности:

  • Marshal(v any) ([]byte, error) — сериализация в JSON
  • Unmarshal(data []byte, v any) error — десериализация из JSON
  • MustMarshal(v any) []byte — сериализация с паникой при ошибке (для тестов/констант)
  • Поддержка prettified вывода для отладки

metrics/

Путь: pkg/metrics/

Назначение: Интеграция с Prometheus для сбора метрик. Предоставляет единый способ регистрации и экспорта метрик из всех сервисов монорепозитория.

Ключевые возможности:

  • Регистрация счётчиков, гистограмм, gauge
  • HTTP-эндпоинт /metrics для Prometheus scrape
  • Предустановленные метрики для gRPC (latency, error rate)

mocks/

Путь: pkg/mocks/

Назначение: Тестовые моки для gRPC-клиентов и внутренних интерфейсов. Используются в unit-тестах сервисов для изоляции зависимостей.


pointer/

Путь: pkg/pointer/

Назначение: Вспомогательные функции для работы с указателями на примитивные типы Go. Устраняет boilerplate при создании указателей на литеральные значения.

Ключевые функции:

// Возвращает указатель на переданное значение
func To[T any](v T) *T

// Возвращает значение указателя или дефолтное, если указатель nil
func FromOrDefault[T any](p *T, def T) T

// Проверяет, что указатель не nil и возвращает значение
func From[T any](p *T) (T, bool)

Пример:

import "pkg/pointer"

req := &SomeRequest{
    Limit:  pointer.To(100),
    Offset: pointer.To(0),
    Name:   pointer.To("BTC_USDT"),
}

sha256/

Путь: pkg/sha256/

Назначение: Утилиты для хэширования на основе алгоритма SHA-256. Используется Exchange Integration для хэширования паролей перед сохранением в БД.

Ключевые возможности:

  • Hash(input string) string — вычисление SHA-256 хэша строки, возврат hex-представления
  • Compare(input, hash string) bool — сравнение строки с её хэшем (constant-time)
import "pkg/sha256"

hashed := sha256.Hash(req.Password)
// Сохранить hashed в БД

ok := sha256.Compare(req.Password, storedHash)
// ok == true если пароль совпадает

slicex/

Путь: pkg/slicex/

Назначение: Обобщённые утилиты для работы со срезами (дженерики Go 1.18+). Устраняет необходимость в повторяющемся коде при типичных операциях со срезами.

Ключевые функции:

// Фильтрация среза по предикату
func Filter[T any](slice []T, fn func(T) bool) []T

// Трансформация элементов среза
func Map[T, R any](slice []T, fn func(T) R) []R

// Проверка наличия элемента
func Contains[T comparable](slice []T, item T) bool

// Удаление дублей
func Unique[T comparable](slice []T) []T

// Разбиение на группы
func Chunk[T any](slice []T, size int) [][]T

sqlxtrm/

Путь: pkg/sqlxtrm/

Назначение: Управление SQL-транзакциями для sqlx. Предоставляет удобный паттерн для работы с транзакциями в PostgreSQL.

Ключевые возможности:

  • WithTransaction(ctx, db, fn) — выполнить функцию в транзакции с автоматическим commit/rollback
  • Поддержка вложенных транзакций через savepoint
  • Интеграция с context.Context для отмены транзакции
import "pkg/sqlxtrm"

err := sqlxtrm.WithTransaction(ctx, db, func(tx *sqlx.Tx) error {
    if _, err := tx.ExecContext(ctx, insertQuery, args...); err != nil {
        return err // автоматический rollback
    }
    if _, err := tx.ExecContext(ctx, updateQuery, args...); err != nil {
        return err // автоматический rollback
    }
    return nil // автоматический commit
})

temporal/

Путь: pkg/temporal/

Назначение: Обёртки над Temporal.io SDK для упрощения работы с workflow и activity. Используется сервисами Ledger, P2P, UnivexID.

Ключевые возможности:

  • Инициализация Temporal Worker с общей конфигурацией
  • Базовые типы для регистрации workflow и activity
  • Вспомогательные функции для запуска workflow с повторами
  • Структуры конфигурации (адрес Temporal, namespace, очереди задач)
import "pkg/temporal"

worker := temporal.NewWorker(temporal.Config{
    HostPort:  "temporal:7233",
    Namespace: "univex",
    TaskQueue: "trades-aggregator",
})

worker.RegisterWorkflow(TradesFetchWorkflow)
worker.RegisterActivity(FetchTradesActivity)

if err := worker.Start(); err != nil {
    log.Fatal(err)
}

utils/

Путь: pkg/utils/

Назначение: Общие утилиты, не вошедшие в специализированные пакеты. Вспомогательные функции для работы со строками, временем, UUID и другими базовыми типами.


validator/

Путь: pkg/validator/

Назначение: Утилиты для валидации входных данных в gRPC-хэндлерах и domain-слое.

Ключевые возможности:

  • Валидация обязательных строковых полей (не пусто, не пробелы)
  • Валидация UUID-идентификаторов
  • Валидация числовых диапазонов (положительные значения, минимум/максимум)
  • Валидация email-адресов и номеров телефонов
  • Агрегация нескольких ошибок валидации в одну
import "pkg/validator"

func (s *Server) Register(ctx context.Context, req *pb.RegisterRequest) (*pb.RegisterResponse, error) {
    if err := validator.ValidateAll(
        validator.Required("account_id", req.AccountId),
        validator.Required("password", req.Password),
        validator.MinLen("password", req.Password, 8),
    ); err != nil {
        return nil, status.Error(codes.InvalidArgument, err.Error())
    }
    // ...
}

Сводная таблица пакетов

Пакет Используется в Назначение
balogan Все сервисы Структурированное логирование
clients/exchange/ Trades Aggregator HTTP-клиент Exchange API
clients/apigen/ clients/exchange/ OpenAPI-сгенерированные типы
deps Все сервисы Инъекция зависимостей
find Все сервисы Утилиты поиска в коллекциях
hawk Все сервисы Обработка ошибок
jsonify Все сервисы JSON-утилиты
metrics Все сервисы Метрики Prometheus
mocks Тесты Тестовые моки
pointer Все сервисы Указатели на примитивные типы
sha256 Exchange Integration Хэширование паролей
slicex Все сервисы Обобщённые операции со срезами
sqlxtrm Exchange Integration, Trades Aggregator, Ledger Управление SQL-транзакциями
temporal Ledger, P2P, UnivexID Temporal workflow/activity обёртки
utils Все сервисы Общие утилиты
validator Все сервисы Валидация входных данных