Workflow в продакшене

Артём Дехтярь

Павел Степанец

m@artemd.ru

pahhan.ne@gmail.com

Кто мы?

https://symfony-bro.com/

Что мы умеем

5+ лет коммерческой разработки

DDD, pure OOP, react paradigm

Архитектура корпоративных проектов

PHP, Java, C#

Symfony, Yii2

Миграция и аудит legacy-проектов

GERP

Управление заявками - GERP

  • SaaS решение
  • RESTful api + Mobile App
  • Интеграции (SOAP, Xml, Json, etc.)
  • Отчёты
  • Графики
  • Биллинг
  • QA выполнения заявок
  • Ещё много разного

GERP

Была смигрирована из этого

В Symfony!

Проблема

Сложный граф состояний

Проблема

  • Сложный граф состояний заявки

Данные и комментарии

Требования

Дата время

Текст

Файлы

Сложные формы

Проблема

  • Сложный граф состояний за
  • Дополнительные данные при смене состояния
  • Отметки в тикете при изменениях тикета

"Подключаемые" workflow

для бандлов

Проблема

  • Сложный граф состояний за
  • Дополнительные данные при смене состояния
  • Отметки в тикете при изменениях тикета
  • "Подключаемые" workflow

Безопасные переходы

Transition guard

Проблема

  • Сложный граф состояний заявки
  • Дополнительные данные при смене состояния
  • Отметки в тикете при изменениях тикета
  • "Подключаемые" workflow
  • Ограничения безопасности

Исследование

Form Component

для передачи дополнительных данных при смене состояния

Команды и Обработчики

Compiler passes

для сборки workflow сервисов из конфигурации бандла

FrameworkExtension::registerWorkflowConfiguration

Workflow listeners

для контроля доступа

gtt/workflow-extensions-bundle

Expression Language and 

Workflow guard events

Разработка

Command bus

от League of Extraordinary packages

Tactician

http://tactician.thephpleague.com/

WorkflowMiddleware

public function execute($command, callable $next)
{
    //...
    
    $result = $next($command);
    
    //...
    
    try {
        $workflow = $this->registry->get($task, $workflowName);
        $workflow->apply($task, $command->getTransition());
    } catch (Exception $exception) {
        throw new TaskException( /* ... */ );
    }
}

Пример формы

Формы

SymfonyBro\TaskBundle\Form\TransitionType

"Радио батоны" - это доступные для перехода состояния из workflow для данного субьекта

Создание команды на изменение - flow

"Подключаемые" workflows

  • На основе FrameworkExtension::registerWorkflowConfiguration делаем AbstractRegisterWorkflowPass
  • добавлем кастомные опции переходов
  • guard опции
  • позволяют легкое расширение, например раскраска состояний

Security

Gorserv/Gerp/TaskServiceBundle/Resources/config/workflow.yml

    transitions:
        delay:
            from: new
            to: delayed
            guard: 'is_granted(["ROLE_DISPATCHER"])'
        dispatch:
            from: new
            to: scheduled
            guard: 'is_granted(["ROLE_DISPATCHER"])'
        to_work:
            from: scheduled
            to: in_work
            guard: 'is_granted(["ROLE_TECH"])'

TransitionToRolePass

строит роли из workflow и инжектит их в контейнер

это позволяет строить безопасность на основе формальной модели, например HRU

workflow

cancel:
    from: new
    to: canceled

to_agreement:
    from: new
    to: wait_agreement

dispatch:
    from: new
    to: scheduled

security.role_hierarchy.roles

ROLE_SERVICE_TRANSITION_CANCEL:



ROLE_SERVICE_TRANSITION_TO_AGREEMENT:



ROLE_SERVICE_TRANSITION_DISPATCH:

That's all folks!

https://goo.gl/AtAwso

Workflow component в реальном проекте

By Artem Dekhtyar

Workflow component в реальном проекте

Слайды к небольшому докладу на митапе Symfony комьюнити в Санкт-Петербурге, март 2018

  • 266