Создан  demius PM 4 года назад; Обновил  demius PM год и 6 месяцев назад

Система справочников позволяет создавать в каждом проекте свой набор типов, этапов, приоритетов, сложностей и прочего. Каждый со своими атрибутами. Так как меняются они редко, используются только в контексте проекта, мы не держим их в таблицах, а пакуем в json в поля проекта. Из него они распаковываются в объекты, которые сервисы подставляют в соответствующие Entity.

О системе

Система справочников позволяет создавать в каждом проекте свой набор типов, этапов, приоритетов, сложностей и прочего. Каждый со своими атрибутами. Так как меняются они редко, используются только в контексте проекта, мы не держим их в таблицах, а пакуем в json в поля проекта. Из него они распаковываются в объекты, которые сервисы подставляют в соответствующие Entity.

Сама система реализуется в рамках [tndt-4]

  • Справочник тип задачи [tndt-4]
  • Справочник этап задачи [tndt-5]
  • Справочник сложность задачи [tndt-13]
  • Справочник приоритетность задачи [tndt-15]

- Справочник тип документа (Планируется) тип документа сильно влияет на его логику, и их количество ограничено, будет сделано классическим enum

Архитектура

  • Класс DictionaryItem и производные от него хранят минимум свой id, название в поле name и описание.
  • Класс Dictionary при добавлении нового элемента, генерит ему уникальный id (просто самый большой имеющийся +1). Внешняя система может и свой id добавить, но Dictionary проверит его на уникальность внутри себя.
  • Справочник имеющий более дополнительную логику, наследуется от этих классов.
  • В первой реализации удалять элементы из справочников нельзя. В будущем можно дать возможность их скрывать. Если уж очень надо будет удалить, делать событие DictionaryItemDalateEvent, и удалять, только если все слушатели скажут окей.
  • Класс Dictionary/Fetcher умеет по сущности и переданному словарю извлечь словарь или его значение, чтобы обогатить хранящееся в сущности значение словаря полным итемом, со всей сопутствующей информацией.
  • Класс Dictionary/TypeEnum хранит все существующие типы словарей, где лежат их данные, и какие сущности пользуются их значениями. Там же будет лежать информация о том, где взять всю связанную с конкретным словарем логику.
  • Дополнительная логика, которую реализует справочники лежит в дополнительных сервисах
    • Styler опрашивает все виды справочников сущности, и те, кто должны повлиять на стиль вывода элемента здесь его собирают. (например Этап зачеркивает и закрашивает закрытые задачи, а Приоритет добавляет цветной фон)
    • StageService - определяет по справочнику какие этапы за какими идут, как кнопки можно выводить и где. Будет реализовано в tndt-49
    • BadgeService - добавляет в набор баджей задачи те, которые определяются справочниками Будет реализовано в tndt-55 уже реализовано в Service/Badge в виде набора хэндлеров, не все из которых относятся к справочникам

Обслуживание

порой приходится добавлять новый справочник, ранее не используемых, или сильно менять существующий, в проектах, в которых уже много задач. Чтобы не редактировать каждую из них, какието простые правила проставления новых значений справочников можно сделать через консольную команду app:dictionary:fill

Запуск локальной установки:

./bin/console app:dictionary:fill <projectsuffix> <dictionary>

Где projectsuffix - суффикс проекта. dictionary - справочник из списка:

  • task.type - тип задачи
  • task.stage - этап задачи
  • task.priority - приоритет задачи
  • task.complexity - сложность задачи

По умолчанию команда меняет только значения только в задачах, где значение справочника не установлено. Можно указать ключ --from-value тогда будут заменены указанные значения.

По умолчанию команда меняет значение справочника на указное по умолчанию, можно указать какое-то особое значение с помощью ключа to-value

Ключ -r - меняет значения с тех значений, для который в настройках более не указан справочник.

Пример запуска с хоста hsrv, - задача у проекта hsrv появилась сложность задачи, надо проставить всем задачам сложность по умолчанию

make console "app:dictionary:fill hsrv task.complexity"
Комментарии могут оставлять только авторизованные пользователи
 demius год и 6 месяцев назад

Это все надо перепроектировать.

  • Сущности должны хранить элементы справочников, а не их примитивные значения.
  • Элемент справочника должен проверять себя на валидность и предлагать разные варианты своего отображения.
  • Элемент справочника, должен легко собираться сам, или с помощью фабрики

Возможно (в буущем точно, сейчас под вопросом), элемент справочника имеет свое отображение в презентации управляющее тем. как его показывать.

 demius 3 года назад

Надо дополнить:

  • Как еще Fetcher умеет извлекать справочники
  • Что он не дополняет сущность, так как атрибуты сущности не могут менять тип без дерганья докрины
  • В каких объектах лежат справочники TaskSettings и как извлекаются (через магию с построением пути геттеров в TypesEnum)
  • Что вычисление этапов сейчас в TaskService (в будущем TaskStagesService)
  • Что Stylizer уедет в TableObjectStylizer и вобще мы будем логику не по сравочникам, а по системам которые их используют распределять
  • Что есть еще BadgeHandler’ы
  • Какие еще настройки мы храним в справочниках
 demius 4 года назад

BadgeService уже реализован в виде Service/Badge с набором хэндлеров не всегда завязанных на справочниках. Страницу необходимо обновить после решения по tndt-84

 demius 4 года назад

StageService - реализует логику поведения задачи, а не справочника. Справочник просто способ реализации, если справочник не работает, вместо него логика использует флаг is_closed

 demius 4 года назад

Я пока не уверен, что нам нужен параллельный флаг enabled, пусть справочник и говорит о своей готовности к работе.

 demius 4 года назад

И так мы пришли к справочникам по умолчанию. Дать какие-то шаблоны для облегчения настройки мы хотели, но вовсе не хотели, обязывать справочниками пользоваться тем, кому они не нужны.

 demius 4 года назад

Не пора ли выносить Dictionary в свою папочку верхнего уровня?

 demius 4 года назад

Делить пока рано, класс мал, но в целом для внешнего кода, логичным будет Fetcher, он получает инфу из entity, а будет ли он её кешировать уже вопрос к внутренней реализации

 demius 4 года назад

А если мы уж напишем сложную реалиацию кеша, стоит сервис разделить, на Fetcher и между ним и миром прокси в виде Regisry?

 demius 4 года назад

Честно говоря к DictionaryService Registry то же не очень клеится. То, что он умеет кешировать в себе словари (сейчас нет, только проекты), внутренняя реализация, и знать об этом внешнему коду не обязательно. Может DictionaryFetcher или DictionaryGetter?

 demius 4 года назад

Кстати, справочники, в виде классической таблицы позволят их сортировать корректнее. Правда поменять порядок все равно потребует поменять значение для каждой задаче в таблице. В общем открытый вопрос, как лучше, делать их таблицей, или как я сейчас настройкой в проекте

 demius 4 года назад

С использованием здесь serrializer’а есть две проблемы.

  1. Сериалайзер ориентируется на типы, а не аннотации, ему нельзя скачать ,что в аттрибуте не просто массив, а массив DictionaryItem
  2. Сериалайзер невозможно незаметно вклеить между сущностью и доктриной, так, чтобы в любой момент жизни сущности в ней лежал объект, а доктрина работала с массивом, сама его сериализуя и разворачивая из строки.

Но если мы придумаем как это сделать, будет хорошо. Сейчас у меня Jlob-объекты сами за этим следят

 demius 4 года назад

Может быть его получать в subscriber на entity::postLoad() здесь некрасивое его использование но как пример

 demius 4 года назад

Есть такой стандартный компонент symfony synfony/serializer Он предоставляет из коробки, все, что я хотел в JsonEntity. Правда его конечно лучше в сервис, а значит в эентити не инъектируешь. Вобще его можно создавать через new, но делать это в геттере, или плодить в классе скрытые поля, не являющиеся частью сущности, весьма такое.