From e06a2c0b1133306a239fe878aaca4ac7ec030d01 Mon Sep 17 00:00:00 2001 From: Repinoid Date: Tue, 22 Sep 2026 20:52:15 +0300 Subject: [PATCH] =?UTF-8?q?docs(plan):=20=D1=84=D0=B8=D0=BD=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20=D0=BF?= =?UTF-8?q?=D0=BB=D0=B0=D0=BD=20+=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81?= =?UTF-8?q?=20=D0=BD=D0=B0=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20=D0=9E=D0=BF?= =?UTF-8?q?=D1=83=D1=81=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PLAN_modifier_redesign.md | 81 ++++++++++--------------- prompt_for_opus_modifier_plan_review.md | 39 ++++++++++++ 2 files changed, 70 insertions(+), 50 deletions(-) create mode 100644 prompt_for_opus_modifier_plan_review.md diff --git a/PLAN_modifier_redesign.md b/PLAN_modifier_redesign.md index 8596349..24ec747 100644 --- a/PLAN_modifier_redesign.md +++ b/PLAN_modifier_redesign.md @@ -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`. diff --git a/prompt_for_opus_modifier_plan_review.md b/prompt_for_opus_modifier_plan_review.md new file mode 100644 index 0000000..c044889 --- /dev/null +++ b/prompt_for_opus_modifier_plan_review.md @@ -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? + +Ответ — тезисно, с указанием конкретного шага и что в нём поправить.