SelectedModifications приведена к BaseEntity

Запрос на изменение Версия: 0.2 done

SelectedModifications получает суррогатный Id — как и все остальные сущности модуля (общая инфраструктурная конвенция BaseEntity), вместо композитного ключа из двух FK. Уникальность пары (VehicleCalc, VehicleModification), которую раньше обеспечивал сам композитный ключ, зафиксирована отдельно.

⟨/⟩ Исходник

1. Источник (как есть)

SelectedModifications была единственной доменной сущностью модуля без Id — явное архитектурное решение («строка хранит пару ключей, отдельного идентификатора и собственных атрибутов у связи нет»), композитный первичный ключ из двух FK (VehicleCalc, VehicleModification).

Реальная инфраструктура (src/Common/Abstracts/BaseEntity.cs, BaseEntityConfiguration<TEntity> where TEntity : BaseEntity) устроена иначе и жёстче: Id — всегда суррогатный первичный ключ (builder.HasKey(c => c.Id)), плюс пять технических колонок (CreatedDate/CreatedBy/ModifiedDate/ModifiedBy/xmin), которые достаются любой сущности через этот базовый класс автоматически. Проверено по всему Ntr.Domain (26 сущностей через BaseEntity, плюс справочники через BaseReferenceEntity/BaseEnumEntity) — ни одной сущности-связи без собственного Id не найдено; альтернативной инфраструктуры под композitный ключ в проекте нет. Nts.Domain (персистентный слой ЭНТС) пока не существует вовсе — для ЭНТС есть только Nts.Calc (калькулятор).

2. Разбор

  1. Id — техническое решение, не бизнес-атрибут связи. Отобранные модификации ТС по-прежнему не имеет собственных БИЗНЕС-атрибутов — только пара ссылок на VehicleCalc и VehicleModification; добавленный Id не меняет это, он — следствие общей инфраструктурной конвенции, которой подчиняются все остальные сущности модуля.
  2. Добавление Id само по себе — не полное решение. Композитный ключ бесплатно гарантировал: одна и та же модификация не может быть отобрана для одного расчёта дважды. При замене на суррогатный Id эта гарантия не сохраняется автоматически — нужна отдельно заданная уникальность пары (VehicleCalc, VehicleModification). Это зафиксировано явно в документе («Идентификатор и уникальность»), а не оставлено подразумеваемым.
  3. Не предмет этого CR: собственно БД-уровень (уникальный индекс в Nts.Domain/EF-конфигурации) — реализовать нечего, этого слоя для ЭНТС ещё нет; зафиксировано как требование к будущей реализации, не как код.

3. Blast radius

3.1. Спецификация

Документ Правка
Nts/50_Domain/SelectedModifications.cs класс-doc и Purpose — убрано «нет идентификатора», добавлен раздел «Идентификатор и уникальность»; сущность SelectedModifications — добавлено поле Id; Description у VehicleCalc/VehicleModification — отсылка на уникальность пары

3.2. Вне объёма

src/Nts.Domain не существует — backend-реализация (EF-конфигурация, уникальный индекс) не часть этого CR, зафиксирована как требование к будущей реализации в тексте Отобранные модификации ТС.

4. План

  1. SelectedModifications.cs — правка спецификации (сделано).
  2. Собрать (dotnet build, build-html.cmd) (сделано).
  3. doc — проверка.
  4. Зафиксировать «Итог».

5. Acceptance criteria

6. Итог

Выполнено. SelectedModifications получила Id (та же конвенция [DomainField(Alias = "id", RequiredOnCreate = true, Range = "UUID", Immutable = true)], что у всех остальных сущностей модуля), уникальность пары (VehicleCalc, VehicleModification) зафиксирована явно в Purpose.

doc нашёл 1 находку: факт про Id/уникальность был изложен дважды (в XML-doc класса и в Purpose) почти идентичными, но не идентичными формулировками — введено этой же правкой. Исправлено: XML-doc класса сокращён до краткого назначения с отсылкой «см. Purpose», полное изложение осталось в одном месте. Остальные проверки (структурные связи, blast radius, согласованность атрибутов Id с остальными 21 сущностью модуля, факты CR про BaseEntity/Ntr.Domain) — без находок, прецедент в реальном коде подтверждён doc фактической проверкой (26/26 сущностей через BaseEntity).

Связанные артефакты

Документы