Техническая документация для разработки и расширения Leech-ru backend.
Проект собран по слоям:
-
internal/adapters/controller/api/v1
HTTP-слой: хендлеры, декодинг query/body, валидация, маппинг ошибок в HTTP-коды. -
internal/domain/service
Бизнес-логика use-case уровня. Здесь не должно быть HTTP-деталей. -
internal/adapters/repository/postgres/.../valkey/.../minio/.../json
Доступ к хранилищам и внешним системам. -
internal/domain/dto
Контракты запросов/ответов API. -
internal/domain/schema+pkg/ent
Схемы и сгенерированный ORM (Ent).
Поток запроса:
- Handler принимает запрос.
- Service выполняет бизнес-логику.
- Repository читает/пишет данные.
- Service собирает DTO-ответ.
- Handler возвращает HTTP-ответ.
ServiceProvider (internal/adapters/app/service_provider) — центральный контейнер зависимостей приложения.
Он нужен, чтобы:
- создавать зависимости в одном месте;
- лениво инициализировать тяжелые ресурсы (DB, Redis, MinIO, сервисы);
- не размазывать
new(...)по хендлерам иserver.Setup.
Как работать правильно:
- новые сервисы и клиенты добавлять через Service Provider;
- в
server.Setupбрать зависимости только черезserviceProvider.*Service()/*Config()/*Middleware(); - не создавать руками репозитории/сервисы в хендлерах.
Это гарантирует единый lifecycle и предсказуемую инициализацию.
Когда добавляешь новый модуль (например, reviews), делай в таком порядке:
-
DTO
Добавь request/response структуры вinternal/domain/dto. -
Schema / Ent (если есть новая таблица)
Добавь/измени схему вinternal/domain/schema. -
Repository
Реализуй интерфейс доступа к данным вinternal/adapters/repository/postgres/<module>. -
Service
Добавь бизнес-логику вinternal/domain/service/<module>. -
Handler
Добавь HTTP-обработчики вinternal/adapters/controller/api/v1/<module>. -
Service Provider
Зарегистрируй интерфейс и фабрику вinternal/adapters/app/service_provider. -
Router setup
Подключи handler вinternal/adapters/controller/api/server/server.go. -
Swagger
Добавь/обнови swagger-комментарии и перегенерируй docs.
Важно:
- Handler не должен ходить в repo напрямую.
- Service не должен знать про Echo/HTTP.
- Repo не должен содержать бизнес-правила.
Для list-эндпоинтов используется структура:
{
"items": [],
"pagination": {
"total_items": 0,
"total_pages": 0,
"current_page": 1,
"has_next": false,
"has_previous": false
}
}Где:
- размер страницы берется из
limit; - смещение берется из
offset; total_itemsсчитается отдельнымCountс теми же фильтрами.
Генерация новой Ent-схемы:
go run entgo.io/ent/cmd/ent new --target internal/domain/schema [TableName]Генерация Ent ORM:
go run -mod=mod entgo.io/ent/cmd/ent generate --target ./pkg/ent ./internal/domain/schemaГенерация Swagger:
swag init -g cmd/main.go -o docsЕсли ключей нет, сгенерируй:
openssl genpkey -algorithm RSA -out keys/private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in keys/private.pem -out keys/public.pem