12 KiB
TODO: привести Go-бэкенд к стандарту
Аудит проведён по evening_detective_server 2026-10-02.
Результат проверки
gofmt -l— нарушений форматирования не найдено.go vet ./...— замечаний нет.go test ./...— не проходит в sandbox: тесты gateway и MCP не могут открыть локальный TCP-порт (operation not permitted). Остальные пакеты проходят.- Сгенерированные
proto/*.pb.go, Swagger,.gotmp,.gocacheи.VSCodeCounterне входят в ручной аудит.
Приоритет P0 — сначала исправить границы приложения
GO-001 — убрать прямые зависимости handler-ов от repos и технических modules
-
Статус:
DONE(этапы GO-001.1–GO-001.7 выполнены) -
Результат: runtime
internal/appне импортируетinternal/repos; error mapping перенесён на границы services; одноиспользуемыйformatter_utilsудалён. -
Проверка:
gofmt,go vet ./...,go test ./...проходят. -
Стандарт нарушен:
internal/appдолжен вызывать прикладные сервисы и делать только transport mapping. -
Прямые repository-зависимости:
app/scenario_archive.go,app/team_qr.go,app/team_registration.go,app/users.go. -
Прямые module-зависимости с прикладной логикой/хранилищем:
app/files.go,app/story_mapper.go,app/game_mapper.go,app/team_mapper.go. -
Перенести операции в существующие сервисы, оставив в handler-е извлечение запроса, вызов одного сервиса и преобразование ответа.
-
Проверка:
go vet ./..., targeted testsinternal/app/..., затемgo test ./....
GO-002 — разорвать неправильные зависимости modules от application layers
-
Статус:
DONE(этапы GO-002.1–GO-002.5 выполнены) -
Результат: archive module использует собственный input type,
game_modelперенесён вinternal/services/game_model, старые module-зависимости удалены. -
Проверка: runtime modules не импортируют repos/services/app;
gofmt,go vet ./...иgo test ./...проходят. -
internal/modules/game_modelимпортируетinternal/reposиinternal/services/scenarios_service. -
internal/modules/scenario_archiveимпортирует типыinternal/repos. -
Это нарушает правило: module не знает конкретный use case, service и storage models не должны протекать в технический module.
-
Оставить доменные типы у владельца; mapper-ы перенести на границы service или app. Не вводить
common/utilsдля обхода цикла. -
Проверка:
go list -deps/ревью импортов иgo test ./....
GO-003 — привести ошибки handler-ов к единому gRPC/gateway-механизму
- Во многих handler-ах (
answers.go,games.go,scenarios.go,teams.go,users.go,game_reviews.go,tickets.go) внутренняя ошибка превращается вerr.Error()внутри успешного protobuf-ответа. - Это теряет тип ошибки и ведёт к разным правилам HTTP/gRPC mapping; стандарт требует возвращать ошибку через существующий transport-механизм.
- Ввести/переиспользовать единый mapping sentinel-ошибок в одном месте; не дублировать проверки по handler-ам и не отдавать внутренние тексты наружу.
- Добавить минимальные тесты на коды
NotFound,InvalidArgument,ConflictиInternalдля representative endpoint-ов.
Приоритет P1 — механические нарушения стандарта
GO-004 — отформатировать SQL и вызовы pgx по правилам проекта
- Нарушены многострочный raw SQL, вертикальные clauses и многострочные вызовы.
- Зафиксированные примеры:
repos/screen_sessions_repo/repo.go(несколькоExecв одну строку),repos/teams_repo/repo.go,repos/teams_repo/participation.go,repos/tickets_repo/repo.go,repos/users_repo/repo.go. - Пройти все runtime-файлы
internal/repos, не менять SQL-смысл. - Одновременно проверить для каждого
Query:defer rows.Close()сразу после успешного запроса и обязательныйrows.Err(). - Проверка:
gofmt -wизменённых файлов,go test ./internal/repos/....
GO-005 — исправить имена конструкторов и интерфейсов
- Generic-конструкторы
Newнаходятся вrepos/health_repo/repo.goиrepos/tickets_repo/repo.go; переименовать в предметныеNewHealthRepo/NewTicketsRepoи обновить wiring. - Интерфейсы без обязательного префикса
I:GamePlayer,AnswerSubmitter,usersRepository; проверить также дублирующийICleanerвmodules/storytelling/dependency.go. - Не создавать новые интерфейсы: только переименовать или удалить дубликаты, если это не ломает границу подмены.
- Проверка:
go test ./....
GO-006 — убрать generic-пакеты *_utils
- Стандарт запрещает
utilsдля несвязанных функций; найденыmodules/formatter_utilsиmodules/network_utils. - Переименовать их по ответственности и обновить импорты: например, пакет форматирования результата и пакет определения локальных адресов.
- Не переносить код и не добавлять общий helper-пакет без конкретного владельца.
- Проверка: поиск
utils|helpers|common|miscсреди пакетов иgo test ./....
GO-007 — привести комментарии исходников к русскому стандарту
- Найдены английские комментарии в runtime/test-коде, например
modules/processor_jwt/context.goи комментарий вservices/gameplay_service/finished_story_test.go. - Перевести только комментарии проекта; директивы
go:embedи сгенерированный код не трогать. - Заодно документировать публичные символы, у которых комментарий отсутствует и назначение неочевидно.
- Проверка: ручной проход
go doc-символов иgo vet ./....
Приоритет P1 — привести тесты к зафиксированному стандарту
GO-008 — убрать прямую подготовку и проверку SQL из тестовых сценариев
repos/tickets_repo/accept_test.goиrepos/teams_repo/registration_test.goнапрямую вызываютExec/QueryRowи создают схему в тесте.- Подготовку выполнять миграциями инфраструктурного слоя и публичными методами repository/service; проверки поведения делать через API тестируемого слоя.
- Сохранить отдельную БД через
TEST_DATABASE_URL; не подключаться к production. - Проверка: targeted integration tests с отдельной PostgreSQL-базой.
GO-009 — стабилизировать сетевые тесты и общий тестовый gate
cmd/evening_detective_server/gateway_test.goиservices/mcp_service/http_test.goтребуют loopback TCP; в текущем окружении они завершаютсяoperation not permitted.- Сделать сетевой слой тестов запускаемым в поддерживаемом CI-окружении либо
отделить такие тесты явным integration/build tag; не ослаблять проверки
поведения и не маскировать ошибки
t.Skipбез условия окружения. - После этого зафиксировать обязательный зелёный gate
go test ./....
GO-010 — выровнять структуру unit-тестов
- Проверить
*_test.goна правило: тесты рядом с владельцем поведения, бизнес-правила — без PostgreSQL, новая ветка — с минимальным регрессионным тестом, кейсы — table-driven. - В первую очередь пройти тесты с прямым
panic, сравнением текста ошибки и неописательными сценариями; напримерusers_service/service_test.go,users_service/change_password_test.go,scenarios_service/service_test.go. - Не переписывать существующие тесты механически, если это не повышает проверяемость конкретного правила.
Приоритет P2 — завершить миграцию без изменения поведения
GO-011 — инвентаризировать mapping и модели по владельцам
- Часть mapper-ов находится в
app, часть в service, часть в modules; есть mapping через repository-типы и потенциальные дубли моделей. - Для каждого mapping выбрать единственного владельца по контракту стандарта:
transport —
app, use-case/storage — соответствующий service/repo. - Литералы mapping оставить вертикальными; I/O и бизнес-решения из mapper-ов убрать.
- Проверка: review зависимостей и targeted tests mapper-ов.
GO-012 — ввести лёгкий автоматический guard стандарта
- После исправления кода добавить только минимальные проверки без новой
зависимости:
gofmt -l,go vet ./..., проверка запрещённых импортовapp → repos,services → proto,repos → proto, а такжеgo test ./.... - Разместить команду в существующем
Makefile, если она не дублирует уже имеющуюся проверку. - Не подключать golangci-lint/staticcheck только ради этого списка.
Порядок выполнения сегодня
GO-001→GO-002→GO-003.GO-004→GO-005→GO-006→GO-007.GO-008→GO-009→GO-010.GO-011→GO-012.
Сгенерированные protobuf-файлы не форматировать вручную. Коммиты и push не выполнять.