docs(opus): вопросы по расхождениям архитектуры модификаторов с кодом

This commit is contained in:
Repinoid
2026-09-22 20:26:54 +03:00
parent c3683cbe65
commit e55ca14d5e
@@ -0,0 +1,64 @@
# Уточнения к архитектуре модификаторов — расхождения с фактическим кодом
Не принимаю предыдущие ответы за истину. Сверка с реальным кодом выявила расхождения.
Прошу пересмотреть/уточнить.
## Факт №1: `OperationSpec` — это алиас `lib.OperationSpec`, не локальный тип
В `TOOLS/resource-generator/internal/types/types.go`:
```go
type OperationSpec = lib.OperationSpec
type ParamSpec = lib.ParamSpec
```
Канонический YAML-контракт лежит в `TOOLS/lib/types.go` (пакет `tf-tools/lib`),
где уже определены `OperationSpec` (Name/ID/Kind/Action/Modifier/Subresource/Man/Params)
и `ParamSpec`.
Ошибка в прошлом ответе: «добавить в types.go:39» — НЕ указано, что это `lib`.
Новые поля `delete_strategy` / `idempotency` / `delete_params` должны быть
в `TOOLS/lib/types.go`, иначе yaml-generator (который тоже импортирует lib)
и resource-generator разойдутся.
Вопрос: подтверждаешь, что новый контракт добавляется в `lib/types.go\` (OperationSpec),
а `resource-generator` получает его через алиас? Или нужно отдельное
resource-generator-специфичное поле (не в lib, а в GenModifier)? Где граница:
что в lib, что локально в GenModifier?
## Факт №2: `normalizeUniversalValueV6` — приватная, живёт в core, принимает core-структуру
Прошлый ответ: «сравнивать desired vs current после normalizeUniversalValueV6».
Но:
- `normalizeUniversalValueV6(val string, param universalCfsParam)` — **приватная** (маленькая буква);
- принимает `universalCfsParam` (структуру пакета `core`);
- сравнение pre-check «desired == current» предполагалось в `resources_core`
(там `RunOperationByCodeWithTimeout`) или в шаблоне модификатора.
Вопрос: ГДЕ правильно делать pre-check и нормализованное сравнение?
- вариант A: в `core` (там доступны и cfsParams, и normalize), экспортировать сравнение;
- вариант B: в `resources_core` — тогда нужен экспортированный компаратор
(`JSONStringsEquivalent` там уже есть), но `universalCfsParam` недоступен;
- вариант C: сравнение только через `JSONStringsEquivalent` по JSON-строкам,
без `normalizeUniversalValueV6`? (но тогда `" 5"` vs `"5"`, `true` vs `1` дадут ложный diff).
Как совместить нормализацию типов (bool→"true", int→"5") с местом, где сравнение
происходит? Конкретный файл+функция.
## Дополнительные сомнения (прошу подтвердить/опровергнуть)
1. **Idempotency pre-check и «полный payload» конфликтуют?** Если desired==current → skip.
Но при этом «полный payload» не шлётся вообще (skip). Это согласуется? Или при
расхождении одного поля всё равно слать полный payload (и это нормализует всё)?
2. **`delete_strategy: inverse` + параметр, у которого НЕЛЬЗЯ обнулить** (напр.
`virtualServicesCount` integer>0): прошлый ответ — «inverse недопустим, fail-fast».
Но что если inverse-стратегия нужна только для ЧАСТИ полей, а не для всех?
Т.е. `delete_params` покрывает `needEnableAVI:false`, а `virtualServicesCount`
просто остаётся как есть. Допустимо ли «частичный inverse» (обратить только
обратимое, остальное не трогать)? Или inverse обязан покрывать все поля?
3. **`noop_warn` (дефолт) — всегда ли безопасен?** Удаление модификатора из state
при оставшемся эффекте на платформе — это drift. Допустимо ли вообще иметь
`noop_warn` как ДЕФОЛТ, или для необратимых (ip_space) правильнее дефолт `error`
(запретить destroy, пока не разберутся)? Что каноничнее?
Ответ — кратко, по пунктам.