---
# System prepended metadata

title: 'Получение, хранение и отображение информации об изменённых полях'
tags: [+AgentCRM]

---

---
tags: +AgentCRM
---

# Получение, хранение и отображение информации об изменённых полях

### Пояснение

Эта заметка содержит размышления по поводу реализации Истории "Специалист может посмотреть историю изменения полей объекта недвижимости".

Вопросы по задаче:
    1. Как и где публиковать изменения? 
    2. Как получать наименование поля?
    3. Как получать тип поля?
    4. В каком формате хранить сложные поля (сложные поля - это ValueObject и ValueObjectCollection)?
    5. Как отображать сложные поля?
    6. Как показывать изменения отдельных сущностей (объявление, объект, здание, адрес)?
    7. Как отображать изменения в связях?

### Мысли

- Для отображения нужны следующие данные:
    + Дата изменения
    + Автор изменений (специалист по недвижимости) 
    + Наименование поля
    + Наименование переменной поля
    + Тип поля (для формирования представления)
    + Тип измененной сущности (объект, объявление и т. д.)
    + Старое значение
    + Новое значение

### Ответ

Ответы на поставленные вопросы:
    1. Созданием события об изменении поля должна заниматься сущность, а не UseCase или другой сервис. Публиковаться данные события должны только после записи в репозиторий (уже реализовано - см. EntityEvents).
        + Сырая идея: можно создать аннотацию, которая автоматически будет добавлять в очередь события при изменении поля. Работать такая аннотация может при помощи прокси. Нужно почитать про производительность прокси в Node 10 - если всё ОК, то можно делать
    2. Наименования полей хранить в аннотациях и реализовать сервис получения наименования поля из сущности по названию. Опубликованное событие будет содержать название аттрибута класса - но нему и следует получать наименование
    3. Можно это делать с помощью typeof (для примитивных типов) и instanceof (для ValueObject). Для коллекций можно ввести поле "Является коллекцией" в таблицу изменений, а в "Тип" записывать тип любого элемента массива.
    4. Поля хранить в JSON. Хорошо было-бы стандартизовать сложные поля, чтобы придать им универсальности. Тогда в "Тип" можно будет записывать не тип конкретного ValueObject, а его универсальный тип, который клиент будет понимать и отображать всё соответствующим образом. Тем не менее, всё стандартизовать не получится. Например, тип ENUM придётся кодировать каким-то образом, чтобы на клиенте понять, что именно это за ENUM и какие строковые значения он может содержать.
    5. Разбирать JSON-значение  очередного поля, смотреть его тип, и в зависимости от него возвращать тот или иной компонент для отображения
    6. Для этого потребуется в таблице изменений также хранить тип измененной сущности - объект, объявление, адрес, здание. Изменения для них отображать по единым правилам.
    7. Объект может хранить в себе связи на специалистов по недвижимости (в трёх разных полях, одно из которых - коллекция), на доп. статусы, на проекты и др. Какие-то из них (например, специалисты) - уникальны и требует отдельного компонента отображения; какие-то (напр., проекты) являются простыми словарями; какие-то (напр., статус) являются словарями с цветом. Для неуникальных типов можно разработать универсальные компоненты отображения (по аналогии с ValueObject). Сама таблица изменений в случае со связями будет хранить только ID связи и наименование сущности.

#### Итого

Так как реализация функции хранения изменений поля отложена на время после релиза, нет смысла более подробно рассматривать этот вопрос. Однако, следует обозначить то, что можно сделать для этой задачи сейчас:

- Реализовать сервис публикации событий сущности (сделано)
- Реализовать аннотацию для хранения названий сущности и сервис для получения этих названий
- Не делать большую вложенность ValueObject (а в идеале, не делать её совсем)