using Rugrid.Sdaid.Notation.Documents;
namespace Rugrid.Sdaid.Epas.Nts.ChangeRequests
{
/// <summary>
/// Карточка модификации ТС (`DOC_VehicleModificationCard`) открывается из реестра и из окна
/// подбора по одному и тому же пути создания/валидации записи — различается только
/// предзаполнение и поведение после сохранения, не реализация сохранения. Прототип
/// (`openCreateModTool`) приведён в соответствие: поля «Марка»/«Модель» — выбор из
/// справочника с возможностью ввода нового значения, как в спеке, а не произвольный текст.
/// </summary>
public class DOC_CR_2026_11_02_ModificationCardSharedSaveEngine : IChangeRequestDocument, IHasStructuralLinks, IFolder<NtsChangeRequestsFolder>
{
public SdaidLink[] Links => new[]
{
Rel.Uses<Rugrid.Sdaid.Epas.Nts.Ui.DOC_VehicleModificationCard>(),
Rel.Uses<Rugrid.Sdaid.Epas.Nts.Ui.DOC_ModificationSelectionModal>(),
Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleMark>(),
Rel.Uses<Rugrid.Sdaid.Epas.Nts.Domain.DOC_VehicleModel>(),
};
public static string _refName = "CR 2026-11-02: общий путь сохранения карточки модификации";
public string Name => "Карточка модификации: общий путь сохранения для обеих точек входа";
public string Description =>
@"Карточка модификации ТС открывается из реестра и из окна подбора по одному и тому же пути создания/валидации записи — различия только в предзаполнении и поведении после сохранения. Прототип (openCreateModTool) приведён в соответствие: поля «Марка»/«Модель» стали выбором из справочника с возможностью ввода нового значения, как в спеке, вместо произвольного текста/datalist.";
public string Version => "0.2";
public string Status => "done";
public string[] Comments => new string[0];
public static string Source = """
## Источник (как есть)
При разборе прототипа окна подбора модификаций обнаружено: поля «Марка» и «Модель» в
форме «Создать модификация» (`openCreateModTool`, `Ntr/65_Ui/html/shell.js`) были
обычным текстовым вводом (у «Марки» — с HTML `<datalist>`-подсказками, у «Модели» —
вообще без них), хотя спека (`VehicleModificationCard.cs`, «Основные интерфейсные
элементы») описывает оба поля как «выбор существующей записи справочника или ввод
нового значения». При сохранении результат пушился плоской строкой прямо в
`window.NTS_REF`, минуя какое-либо понятие о записи `VehicleMark`/`VehicleModel`.
В обсуждении с пользователем встал более общий вопрос: «карточка модификации
открывается из реестра и из окна подбора — значит ли это, что из окна подбора должна
открываться отдельная, специально заточенная под эту задачу форма, а не та же
карточка записи справочника?»
""";
public static string Analysis = """
## Разбор
Решение (обсуждение с пользователем): не «одна форма» против «две формы» буквально, а
разделение по тому, что действительно обязано быть общим, а что — нет.
**Общее, обязательно одно:** сама операция создания/изменения записи `VehicleModification`
и связанных `VehicleMark`/`VehicleModel` — состав полей, валидация, правило «выбор или
создание новой записи». Два независимых места, создающих один и тот же тип записи —
источник дрейфа: ровно это уже произошло в прототипе (`openCreateModTool` обходил
доменную модель целиком, в отличие от того, что подразумевает спека).
**Разное, по праву:** то, что специфично для точки входа — предзаполнение (из окна
подбора вид ТС/топливо подставляются точно, марка/модель — предложением распознавания;
из реестра — пусто или значения редактируемой записи) и поведение после сохранения
(реестр → возврат в реестр; подбор → возврат в то же окно, новая запись доступна для
отбора, группа не применяется автоматически). Это уже было прописано в спеке
(`VehicleModificationCard.cs`, «Поведение») и остаётся в силе — явно подтверждено
отдельным абзацем в «Структуре экрана», чтобы не читалось как «различие только в
предзаполнении» (буквальная формулировка, с которой начался вопрос).
Если для задачи подбора в будущем понадобится что-то специфичное для контекста ТС
(например, «Сохранить и отобрать» как отдельное действие) — это **дополнение к общему
пути** (доп. кнопка/поведение поверх тех же создания/валидации), а не повод заводить
вторую независимую реализацию. Такое дополнение в этом CR не вводится — спека его не
описывает, это осталось бы домыслом без отдельного запроса пользователя.
""";
public static string BlastRadius = """
## Blast radius
### Спецификация
| Документ | Правка |
|---|---|
| `Nts/65_Ui/VehicleModificationCard.cs` | «Структура экрана» — явный абзац: путь создания/валидации один у обеих точек входа, различие — предзаполнение и поведение после сохранения, не реализация |
### Прототип
| Файл | Правка |
|---|---|
| `Ntr/65_Ui/html/shell.js`, `buildSelect` | новый опциональный параметр `opts.allowCustom` — непустой текст, не совпавший со списком, становится значением (Enter без совпадения, потеря фокуса) |
| `Ntr/65_Ui/html/shell.js`, `openCreateModTool` | поля «Марка»/«Модель» — `buildSelect(..., {allowCustom:true})` вместо текста/`<datalist>`; «Модель» сужена выбранной маркой (`modelsOfMark`, как в окне подбора) |
""";
public static string Plan = """
## План
1. `VehicleModificationCard.cs` — абзац про общий путь (сделано).
2. `shell.js` — `buildSelect` с `allowCustom`; `openCreateModTool` на новые поля
(сделано).
3. Собрать (`build-html.cmd`).
4. `doc`/`testovich` — проверка.
5. Зафиксировать «Итог».
""";
public static string Acceptance = """
## Acceptance criteria
- **AC-1.** Спека явно утверждает общий путь создания/валидации записи модификации для
обеих точек входа карточки.
- **AC-2.** Поле «Марка» в форме «Создать модификация» — выбор из списка марок или
ввод нового значения (не просто текст с подсказками).
- **AC-3.** Поле «Модель» — выбор из списка моделей выбранной марки или ввод нового
значения; список пересобирается при смене марки.
""";
public static string Result = """
## Итог
Спека: `VehicleModificationCard.cs` явно утверждает общий путь создания/валидации
записи для обеих точек входа. Прототип: `buildSelect` получил `opts.allowCustom`
(непустой текст без совпадения в списке фиксируется по Enter/потере фокуса — старое
поведение без этого флага не изменилось); `openCreateModTool` переведён на такие
`buildSelect` для «Марка»/«Модель», `<datalist>` и обычный текстовый ввод убраны,
«Модель» сужается выбранной маркой (`modelsOfMark`).
`doc` — без нарушений (одно стилистическое замечание: внутридокументная ссылка «см.
«Поведение»» голым текстом, не блокирует). `testovich` реальным выполнением (jsdom)
подтвердил все AC: выбор существующей записи, ввод новой с фиксацией по Enter/blur,
пересборка списка моделей при смене марки, отсутствие регрессии у прежних вызовов
`buildSelect` без `allowCustom`, корректное сохранение записи в `NTS_REF`.
**После закрытия, по замечанию пользователя (не найдено ни `doc`, ни `testovich`):**
список «Марка» показывал одну и ту же марку несколько раз (например, «Toyota» четыре
раза подряд) — `marksList` строился как `NTS_BRANDS.map(b => b[1])` без уникализации,
а `NTS_BRANDS` — пары «ключ-алиас → каноническая марка» (один алиас маппится один в
один, но у марки несколько алиасов — у Toyota их 4, реальным подсчётом). Исправлено:
`marksList` — уникальные канонические значения, отсортированные по алфавиту (584 пары
→ 534 уникальные марки, подтверждено выполнением). `testovich` проверял выбор и ввод
конкретных значений, но не состав/уникальность самого списка опций — пробел в охвате
проверки, не в логике фикса.
""";
}
}