docs(plan): финализировать план + запрос на ревью Опуса

This commit is contained in:
Repinoid
2026-09-22 20:52:15 +03:00
parent fba4cbda37
commit e06a2c0b11
2 changed files with 70 additions and 50 deletions
+31 -50
View File
@@ -131,53 +131,35 @@ idle-гейт (`waitForInstanceIdle`) уже стоит выше — не тро
---
## Шаг 8. YAML-разметка в `generated/dev/resources_yaml/`
## Шаг 8. YAML-разметка (источник-канон) в `TOOLS/yaml-generator`
`19_vc_org.yaml` (modify 207, modifier ip_space):
```yaml
- name: modify
id: 207
kind: modifier
modifier: ip_space
delete_strategy: error
idempotency: check_before_run
Источник-канон — реестр исключений `serviceSpecificModifiers` в
`TOOLS/yaml-generator/main.go` (Ключ — имя сервиса → имя modifier).
`generated/dev` перегенерируется — туда НЕ вносить вручную.
Контракт в `lib.OperationSpec` (алиас в обоих генераторах), значит yaml-generator
должен проставлять флаги при маршале. Расширить реестр со `map[string]string`
до структуры, несущей: `ModifierName`, `DeleteStrategy`, `Idempotency`,
`DeleteParams []struct{Code,Value}`:
```go
type modifierException struct {
ModifierName string
DeleteStrategy string // noop_warn | inverse | error
Idempotency string // none | check_before_run
DeleteParams []deleteParam // только для inverse
}
type deleteParam struct { Code, Value string }
var serviceSpecificModifiers = map[string]modifierException{
"vc_org": {ModifierName: "ip_space", DeleteStrategy: "error", Idempotency: "check_before_run"},
"vc_nsxt": {ModifierName: "network", DeleteStrategy: "inverse",
DeleteParams: []deleteParam{{"needEnableAVI", "false"}}},
}
```
`22_vc_nsxt.yaml` (modify 111, modifier network):
```yaml
- name: modify
id: 111
kind: modifier
modifier: network
delete_strategy: inverse
delete_params:
- code: needEnableAVI
value: "false"
```
ВАЖНО: `generated/dev` — gitignored/генерируемый. Канон YAML — в yaml-generator
(источник из API), поэтому разметку `delete_strategy`/`idempotency` надо вносить в
**источник** (механизм исключений yaml-generator, а не в generated), иначе перегенерация
её сотрёт. Уточнить: где живёт источник правил модификаторов (registry исключений).
---
## Шаг 9. Тесты
`provider/internal/core/` — unit:
- `modifierDesiredEqualsCurrent`: совпадение/расхождение по bool/int/map-fixed/array-map-fixed;
- досылка: live→default→skip (integer>0 без дефолта не шлёт `"0"`).
`TOOLS/resource-generator` — unit:
- `ValidateSpec`: неизвестный enum, inverse без delete_params, delete_params.code вне params.
---
## Шаг 10. Сборка и заливка
- `go build ./...` + `go vet ./...` по всем 5 модулям;
- подать сборку `TOOLS/scripts/03_build_and_upload_provider.sh --profile TOOLS/config/dev`
(bump версии отдельным коммитом).
В цикле над ops (там, где `Kind="modifier"`): проставить `op.DeleteStrategy`,
`op.Idempotency`, `op.DeleteParams`.
---
@@ -188,15 +170,14 @@ idle-гейт (`waitForInstanceIdle`) уже стоит выше — не тро
3. `refactor(gen): шаблон modifier — reconcile, без CompactParams, ID identity, Delete стратегия`
4. `refactor(core): вынести JSON-эквивалентность в jsonutil`
5. `feat(core): modifierDesiredEqualsCurrent + флаг idempotent`
6. `feat(yaml): разметка ip_space/network`
6. `feat(yaml): реестр исключений модификаторов (delete_strategy/idempotency)`
7. `test(core,gen): unit-кейсы`
8. `chore(dev): bump версии`
---
## Открытый вопрос (блокирует шаг 8)
## Открытый вопрос — закрыт
**Где живёт источник-канон YAML модификаторов** (не `generated/dev`)? Разметку
`delete_strategy`/`idempotency` надо вносить в источник, а не в сгенерированный файл,
иначе перегенерация (`01_generate_yamls.sh`) сотрёт. Нужно найти механизм
(yaml-generator exceptions / registry), где держать эти флаги.
Источник-канон — реестр `serviceSpecificModifiers` в `TOOLS/yaml-generator/main.go`.
Разметка `delete_strategy`/`idempotency` расширяет этот реестр, а НЕ правится вручную
в `generated/dev`.
+39
View File
@@ -0,0 +1,39 @@
# Ревью плана реализации: редизайн модификаторов
Прошу отревьюить план `PLAN_modifier_redesign.md` (10 шагов). Это проект к реализации,
не код. Вызовись: найди дыры, пропущенные кейсы, ошибки в порядке шагов, нестыковки.
## Контекст решения (уже согласовано, НЕ пересматривать)
- Модификатор = декларативная проекция полей родителя, единый `reconcile()` (Create≡Update).
- Полный payload (не дельта), досылка: задан→значение, иначе live→default→skip.
- `delete_strategy`: noop_warn | inverse | error (дефолт noop_warn), `idempotency`: none | check_before_run.
- Pre-check `desired==current` в `core` (не в resources_core, не в шаблоне), по живому `state_params`.
- `is_modifiable` — единственный сигнал изменяемости (фикс CreateOnly уже есть).
## Ключевые файлы-факты (сверены с кодом)
- `TOOLS/lib/types.go``OperationSpec`/`ParamSpec` (алиасы в обоих генераторах).
- `TOOLS/yaml-generator/main.go``serviceSpecificModifiers` (реестр исключений, источник канона).
- `TOOLS/resource-generator/internal/loader/loader.go` — ветка `kind==modifier`, `ValidateSpec`.
- `TOOLS/resource-generator/internal/templates/modifier.go` — шаблон.
- `provider/internal/resources_core/crud.go``RunOperationByCodeWithTimeout`.
- `provider/internal/resources_core/json_normalize.go``JSONStringsEquivalent` (импорт в core = цикл).
- `provider/internal/core/operation_run_bycode.go` — клиентский запуск.
## Вопросы к ревью (ответить кратко, по пунктам)
1. Порядок шагов 1–10 корректен? Где есть скрытая зависимость, которую я пропустил?
2. Шаг 5 (вынос JSON-эквивалентности в `core/jsonutil`) — правильный путь снять цикл
импорта, или есть чище (напр. оставить `JSONStringsEquivalent` в resources_core и
передавать нормализованные строки в core уже готовыми)?
3. Шаг 6 — сигнатура `modifierDesiredEqualsCurrent(desired map[string]string, cfsParams []universalCfsParam) bool`
корректна? Хватает ли данных для сравнения всех типов (bool/int/string/map-fixed/array-map-fixed)?
4. Шаг 4.4 Delete=inverse — как именно слать modify: `delete_params` + досылка live остальных
(полный payload) — это правильно, или есть подводный камень?
5. Шаг 8 — расширение реестра `serviceSpecificModifiers` до структуры: верный источник?
Или `delete_strategy`/`idempotency` правильнее держать отдельным реестром (не трогая тип map)?
6. Пропущен ли какой-то кейс из 16 (13 + taint/replace/partial/unknown)?
7. Есть ли риск сломать instance-ресурсы (не модификаторы) любым из шагов 1–8?
Ответ — тезисно, с указанием конкретного шага и что в нём поправить.