fix backend
This commit is contained in:
+164
@@ -0,0 +1,164 @@
|
|||||||
|
# План GO-002: разорвать зависимости modules от repos и services
|
||||||
|
|
||||||
|
## Цель
|
||||||
|
|
||||||
|
Технические modules не импортируют прикладные `services` и storage `repos`.
|
||||||
|
Модуль получает собственные входные типы, а преобразование repository-моделей
|
||||||
|
делается на границе service.
|
||||||
|
|
||||||
|
Не меняем:
|
||||||
|
|
||||||
|
- protobuf/API и сгенерированные файлы;
|
||||||
|
- формат `scenario.json`, ZIP-архива и публичные ответы;
|
||||||
|
- бизнес-правила и SQL;
|
||||||
|
- `internal/modules/storytelling`, пока он не импортирует repos/services;
|
||||||
|
- GO-006 (`*_utils`) и GO-003 (единый error mapping).
|
||||||
|
|
||||||
|
## Фактические нарушения
|
||||||
|
|
||||||
|
| Module | Нарушение | Callers |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `modules/game_model` | импортирует `repos` и `services/scenarios_service` | game, gameplay, answer, team, MCP, app |
|
||||||
|
| `modules/scenario_archive` | `Pack` принимает `*repos.Scenario` | `scenarios_service`, module tests |
|
||||||
|
| `modules/scenario_archive` | импортирует `repos` только для storage-модели | только archive implementation |
|
||||||
|
|
||||||
|
## Правило миграции
|
||||||
|
|
||||||
|
Каждый кусок заканчивается рабочим компилятором и targeted-тестами. После
|
||||||
|
каждого шага проверять запрещённые импорты:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd evening_detective_server
|
||||||
|
rg -n '"evening_detective_server/internal/(repos|services)' internal/modules --glob '*.go' --glob '!*_test.go'
|
||||||
|
go test ./internal/modules/... ./internal/services/...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Маленькие этапы
|
||||||
|
|
||||||
|
### GO-002.0 — зафиксировать baseline
|
||||||
|
|
||||||
|
1. Сохранить список runtime-файлов с нарушениями:
|
||||||
|
`modules/game_model/game.go`, `game_mapper.go`, `team_mapper.go` и
|
||||||
|
`modules/scenario_archive/interface.go`/`archive.go`.
|
||||||
|
2. Проверить чистое состояние тестов:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
GOCACHE=/tmp/evening-detective-go-cache go test ./internal/modules/... ./internal/services/...
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Не менять callers и не создавать `common`, `domain` или `utils` только для
|
||||||
|
обхода импортов.
|
||||||
|
|
||||||
|
Готово, если baseline проходит и список зависимостей зафиксирован.
|
||||||
|
|
||||||
|
### GO-002.1 — выделить собственный входной тип archive module
|
||||||
|
|
||||||
|
Файлы: `internal/modules/scenario_archive/interface.go`, `archive.go` и
|
||||||
|
`archive_test.go`.
|
||||||
|
|
||||||
|
1. Добавить в module небольшой тип входа для упаковки архива, содержащий только
|
||||||
|
нужные поля: `Name`, `Description`, `Image` и сериализованную `Story`.
|
||||||
|
2. Изменить `IScenarioArchive.Pack` так, чтобы он принимал этот тип, а не
|
||||||
|
`*repos.Scenario`.
|
||||||
|
3. В implementation заменить обращения к `scenario.Scenario`,
|
||||||
|
`scenario.Description` и другим полям на поля нового типа.
|
||||||
|
4. Перевести module tests на новый тип. Формат `ScenarioJSON` не менять.
|
||||||
|
|
||||||
|
Проверка:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd evening_detective_server
|
||||||
|
find internal/modules/scenario_archive -name '*.go' -print0 | xargs -0 gofmt -w
|
||||||
|
go test ./internal/modules/scenario_archive
|
||||||
|
! rg 'internal/repos' internal/modules/scenario_archive --glob '*.go'
|
||||||
|
```
|
||||||
|
|
||||||
|
Ожидаемый результат: archive module полностью независим от storage package.
|
||||||
|
|
||||||
|
### GO-002.2 — сделать mapping repository → archive в scenarios service
|
||||||
|
|
||||||
|
Файлы: `internal/services/scenarios_service/service.go`, mapper и тесты.
|
||||||
|
|
||||||
|
1. В `scenarios_service` собрать новый archive input из уже полученного
|
||||||
|
`*repos.Scenario`.
|
||||||
|
2. Передавать его в `scenarioArchive.Pack`; repository-зависимость остаётся
|
||||||
|
только в service, где ей место.
|
||||||
|
3. Не переносить в module права, запросы, storage и protobuf.
|
||||||
|
4. Сохранить поведение изображений, `nil`-описания и ссылок на story.
|
||||||
|
5. Добавить/обновить один round-trip тест `DownloadArchive` → `UploadArchive`.
|
||||||
|
|
||||||
|
Проверка:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd evening_detective_server
|
||||||
|
go test ./internal/services/scenarios_service ./internal/modules/scenario_archive
|
||||||
|
! rg 'internal/repos' internal/modules/scenario_archive --glob '*.go'
|
||||||
|
```
|
||||||
|
|
||||||
|
### GO-002.3 — отделить game model от modules
|
||||||
|
|
||||||
|
Файлы: текущий `internal/modules/game_model/*` и callers.
|
||||||
|
|
||||||
|
1. Переместить типы `Game` и `Team` в пакет с той же предметной ответственностью
|
||||||
|
под `internal/services/game_model`.
|
||||||
|
2. Сохранить имена типов и поля, чтобы это была механическая смена import path,
|
||||||
|
а не новая модель или DTO.
|
||||||
|
3. Перенести вместе с типами текущие `MapGame`, `MapGames`, `MapTeam`,
|
||||||
|
`MapTeams`; они являются преобразованием storage-моделей в use-case-модели.
|
||||||
|
4. Обновить callers в `game_service`, `gameplay_service`, `answer_service`,
|
||||||
|
`team_service`, `mcp_service`, app и тестах.
|
||||||
|
5. Не делать пакет `common` и не дублировать структуры.
|
||||||
|
|
||||||
|
Проверка после механического переноса:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd evening_detective_server
|
||||||
|
find internal/services/game_model internal/services/game_service internal/services/gameplay_service internal/services/answer_service internal/services/team_service internal/services/mcp_service internal/app -name '*.go' -print0 | xargs -0 gofmt -w
|
||||||
|
go test ./internal/services/game_model ./internal/services/game_service ./internal/services/gameplay_service ./internal/services/answer_service ./internal/services/team_service ./internal/services/mcp_service ./internal/app
|
||||||
|
! rg 'internal/modules/game_model' --glob '*.go'
|
||||||
|
```
|
||||||
|
|
||||||
|
### GO-002.4 — удалить старый module game_model
|
||||||
|
|
||||||
|
1. После успешного переноса убедиться, что `internal/modules/game_model` больше
|
||||||
|
не импортируется и не нужен через тесты.
|
||||||
|
2. Удалить только старые файлы package; новые копии не оставлять параллельно.
|
||||||
|
3. Проверить `go list ./...`, чтобы не осталось пустого/дублирующего пакета.
|
||||||
|
|
||||||
|
Проверка:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd evening_detective_server
|
||||||
|
go list ./...
|
||||||
|
go test ./...
|
||||||
|
! test -d internal/modules/game_model
|
||||||
|
```
|
||||||
|
|
||||||
|
### GO-002.5 — финальная проверка направления зависимостей
|
||||||
|
|
||||||
|
1. Runtime modules не импортируют `internal/repos`, `internal/services` или
|
||||||
|
`internal/app`.
|
||||||
|
2. `scenario_archive` принимает только собственные типы и callbacks; SQL,
|
||||||
|
права и storage остаются снаружи.
|
||||||
|
3. `cmd` по-прежнему собирает concrete repositories/modules/services.
|
||||||
|
4. Проверить, что сценарный архив и game/team responses побайтно/структурно не
|
||||||
|
изменились в существующих тестах.
|
||||||
|
5. Запустить финальный gate:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd evening_detective_server
|
||||||
|
find internal -type f -name '*.go' -print0 | xargs -0 gofmt -l
|
||||||
|
go vet ./...
|
||||||
|
go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Только после успешного полного gate отметить GO-002 как `DONE` в `todo.md`.
|
||||||
|
|
||||||
|
## Критерий готовности GO-002
|
||||||
|
|
||||||
|
- `rg 'internal/(repos|services)' internal/modules --glob '*.go' --glob '!*_test.go'` не находит runtime-импортов.
|
||||||
|
- Нет дубликатов `Game`, `Team` или archive input model.
|
||||||
|
- Все callers используют один пакет `services/game_model`.
|
||||||
|
- ZIP/`scenario.json`, game/team responses и существующие error semantics не
|
||||||
|
изменились.
|
||||||
|
- `gofmt`, `go vet ./...` и `go test ./...` проходят.
|
||||||
@@ -33,6 +33,12 @@
|
|||||||
|
|
||||||
### GO-002 — разорвать неправильные зависимости modules от application layers
|
### 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/modules/game_model` импортирует `internal/repos` и
|
||||||
`internal/services/scenarios_service`.
|
`internal/services/scenarios_service`.
|
||||||
- `internal/modules/scenario_archive` импортирует типы `internal/repos`.
|
- `internal/modules/scenario_archive` импортирует типы `internal/repos`.
|
||||||
|
|||||||
Reference in New Issue
Block a user