- BrainTools - https://www.braintools.ru -

Многие команды продолжают использовать приложения на платформе CUBA, которые хорошо работают и ежедневно решают реальные бизнес-задачи. Но со временем неизбежным становится вопрос: стоит ли продолжать поддерживать приложение на старом стеке или лучше перенести его на Jmix?
В этой статье я хочу показать, как такая миграция выглядит на практике. Мы перенесли приложение-пример Timesheets с CUBA Platform на Jmix и записали процесс шаг за шагом. Timesheets – это не маленькое демо с несколькими сущностями и CRUD-экранами. Это приложение для учета рабочего времени с согласованиями, несколькими способами ввода времени, кастомным UI-поведением, календарем, диаграммами и немалым объемом бизнес-логики.
С самого начала было понятно, что миграция “в один клик” для нетривиального проекта невозможна. Наша цель была более реалистичной: использовать ИИ-агентов для решения рутинных задач и тем самым ускорить миграцию.
Ниже я расскажу, почему переход с CUBA Platform на Jmix имеет смысл, что усложняло эту миграцию, как был организован процесс, где ИИ-агенты помогли больше всего и как итоговые трудозатраты соотносятся с оценками.
Прежде чем переходить к деталям, краткая версия: мы успешно завершили миграцию Timesheets и затратили на порядок меньше усилий, чем ожидалось. Полезные ссылки:

Для пользователей CUBA Platform Jmix – это естественный следующий шаг. Он продолжает линию фреймворка и дает доступ к актуальному стеку, современным API и инструментам.
Это основная причина для миграции: в какой-то момент оставаться на старой платформе становится дороже, чем двигаться вперед. Даже если приложение все еще работает, команде приходится поддерживать знания устаревшего фреймворка и UI-паттернов. Старые зависимости могут содержать известные уязвимости безопасности, которые сложнее исправить на устаревшем стеке. Со временем это усложняет поддержку и дальнейшую разработку.
В то же время важно быть реалистами. С тех пор как мы завершили развитие CUBA Platform и представили Jmix, прошло 6 лет. Миграция с CUBA Platform на Jmix – это не просто переименование пакетов. С изменениями на бэкенде обычно легко справиться, но часть, связанная с UI, гораздо сложнее. Старый CUBA Generic UI и новый Jmix Flow UI основаны на одних и тех же идеях, но используют разные API, разные компоненты и подходы к компоновке. Поэтому задача заключается не просто в переносе кода, а в переписывании экранов с сохранением их поведения [4].
Именно так и получилось в этой миграции.
Исходный проект – это система учета рабочего времени в компании. Он включает:
14 сущностей, 5 перечислений
4 сервиса, 1 слушатель сущности
35 экранов, 1 фрейм
Дополнения Reports и Charts
Пользователи могут вводить время несколькими способами: через недельные таймшиты, календарный экран и список собственных записей времени. Также есть компонент командной строки для быстрого массового ввода, например ввод команды @Portal #Development 4h30m для заполнения рабочих дней на всю неделю.
Приложение также поддерживает процесс согласования. Менеджеры и согласующие могут просматривать отправленные таймшиты и подтверждать или отклонять их. Это означает, что UI – это не только интерфейс для ввода данных. Он также включает поведение [5], зависящее от ролей, валидацию, сводные данные, динамические компоненты и действия, связанные с процессом.
С точки зрения [6] размера кода в исходном проекте было:
Java: 8062 строк
XML: 2252 строки
SQL: 2151 строка
Таким образом, проект достаточно большой, чтобы быть реалистичным, но при этом достаточно компактный, чтобы можно было рассмотреть его в рамках одной истории миграции.
Прежде чем переходить к работе, полезно посмотреть на оценку Jmix Migration Advisor [7].
Для этого проекта Migration Advisor дал общую оценку в 315 человеко-часов, разбитую на следующие части:
начальная миграция: 100 часов (фиксированная часть оценки для любого проекта)
сущности: 16 часов
слушатели: 1 час
экраны: 198 часов
Оценка экранов была самой важной частью. Инструмент сгруппировал экраны по сложности следующим образом: 12 тривиальных, 16 простых, 4 средних, 2 сложных, 3 очень сложных.
Эта оценка полезна не потому, что точно предсказывает итоговое число, а потому что показывает, где сосредоточена основная стоимость работ. В этом проекте, как и в большинстве реальных миграций, ожидалось, что экраны потребуют большую часть усилий.
Это ожидание оказалось верным. Основное отличие заключалось в том, что ИИ-агенты изменили то, как именно были потрачены эти усилия.
Без помощи ИИ эта миграция тоже была бы возможна. Но она заняла бы гораздо больше времени, особенно в части UI.
Причина проста. Многие задачи миграции повторяются, но при этом не являются тривиальными. Разработчику нужно сравнить исходный и целевой фреймворки, понять назначение экрана, сопоставить компоненты, переписать обработку событий, учесть различия жизненного цикла, запустить результат, проверить ошибки [8] выполнения и затем снова внести правки. Делать это экран за экраном – долго, скучно и утомительно.
ИИ-агент может существенно помочь в такой работе.
В нашем случае агент использовался как практический инструмент разработки:
для миграции сущностей и фетч-планов
для переноса бизнес-логики
для анализа исходных экранов и составления планов реализации целевых экранов
для генерации первой версии экранов на Jmix Flow UI
для реакции [9] на ошибки выполнения и доработки сгенерированного кода
для помощи в повторяющихся преобразованиях паттернов фреймворка
Это не была полностью автоматическая миграция, ручные действия все равно были необходимы. Например, целевой проект был создан в Jmix Studio, Liquibase changelog был сгенерирован через Studio, некоторые стили были настроены вручную, а часть проблем исправлялась вручную там, где это было быстрее и надежнее.
Поэтому нельзя сказать, что “ИИ выполнил миграцию”, более точная формулировка: ИИ-агенты сделали миграцию практичной. Для многих команд это может стать разницей между миграцией, которую откладывают, и миграцией, которую действительно начинают.
Настройка среды была основана на проекте jmix-migration-from-cuba-platform [2], что сделало процесс понятным и воспроизводимым.
Рабочее пространство для миграции содержало два проекта:
исходный проект CUBA в workspace/source-projects
целевой проект Jmix в workspace/target-projects
Целевой проект был создан в Jmix Studio с тем же базовым пакетом, что и у исходного проекта. Мы сразу добавили дополнение Reports, поскольку исходное приложение использовало отчеты. Также был инициализирован Git-репозиторий, оба проекта были открыты в IntelliJ IDEA, а в IDE был включен MCP Server, чтобы агент мог работать с кодовой базой.
Поскольку мы использовали агента OpenAI Codex, после клонирования репозитория мы переименовали папку workspace/.claude, содержащую навыки агента (skills), в .codex.
Чтобы дать Codex инструменты, необходимые для работы с проектами Jmix, мы добавили файл AGENTS.md [10] и skills из репозитория jmix-agent-guidelines [3] в целевой проект. Мы также настроили JetBrains MCP, Context7 MCP и Playwright CLI для Codex, следуя инструкциям из этого репозитория.
Мы запускали сессии Codex из корневой директории workspace, чтобы агент имел доступ к обоим проектам. На протяжении всей миграции мы использовали модель GPT-5.3-Codex с уровнем рассуждений Medium.
Миграция выполнялась в несколько этапов.
Мы начали с миграции сущностей, используя очень простой запрос: “Migrate all entities”.
Агент перенес все элементы модели данных из исходного проекта в целевой проект Jmix: персистентные сущности с аннотациями Jmix, атрибуты @Id и системные поля, перечисления, DTO-сущности, локализованные сообщения. Дополнительные поля пользователя были перенесены из ExtUser в User. Агент также оставил TODO-заметки для оставшихся шагов, таких как миграция слушателей сущностей, и проверил результат успешным запуском compileJava.
После этого вручную была создана новая пустая база данных для целевого приложения, и в Studio был сгенерирован Liquibase changelog.
Это хорошая отправная точка практически для любой миграции. Когда модель данных готова, последующие этапы становятся более стабильными.
Следующими шагами стали миграция общих фетч-планов и бизнес-логики. Мы выполняли их в отдельных сессиях Codex с запросами “Migrate all shared fetch plans” и “Migrate all business logic”.
Агент преобразовал все общие фетч-планы из файла CUBA views.xml в Jmix fetch-plans.xml, сопоставил стандартные фетч-планы CUBA с эквивалентами Jmix, зарегистрировал конфигурационный файл в application.properties [11] и проверил результат успешной сборкой. Затем он перенес основной слой бизнес-логики: сервисы, вспомогательные бины, слушатель сущности, вспомогательные утилитные классы и локализованные сообщения бизнес-слоя.
Бизнес-логику обычно можно мигрировать почти полностью автоматически. Это особенно верно, если в проекте уже есть автоматические тесты, которые агент может использовать для проверки своей работы.
Для крупных проектов лучше разбивать этот этап на несколько шагов, чтобы избежать перегрузки контекста LLM. Например, можно делить работу по пакетам с запросами вроде “Migrate business logic of x.y.z package” или по классам — “Migrate X, Y and Z services”. Также лучше сначала переносить низкоуровневые классы, чтобы в целевом проекте уже были зависимости, необходимые для более высокоуровневых сервисов.
Этап UI был основной частью работы.
Миграция началась с простых справочных экранов, таких как holiday, task type, work time settings и client. Затем она продолжилась другими пакетами справочников: project, project participant, tag, tag type, task и activity type. Запросы выглядели так: “Migrate all screens of com.haulmont.timesheets.gui.holiday [12] and com.haulmont.timesheets.gui.tasktype packages”.
На данном этапе агент создал новые экраны списков, деталей и выбора, обновил меню и наборы сообщений и сохранил важное поведение исходных экранов, такое как открытие в диалогах, поддержка выбора и обновление кэша праздников. Для простых CRUD-экранов первый проход был почти завершенным. Результат проверялся с помощью инспекций IDE и успешных сборок проекта.
После этого перешли к более интересным экранам:
экран списка и редактирования проектов
редактирование Task и Tag Type
фрагмент CommandLine
экраны Calendar, Time Entry и Weekly Timesheets
экраны согласования
графики
Такой порядок имел смысл: начать с более простых экранов, набраться опыта [13] и постепенно переходить к экранам, где поведение важнее, чем компоновка.
Для более сложных UI-задач мы использовали подход “сначала план”. Вместо того чтобы сразу просить агента сгенерировать код, мы сначала просили его проанализировать исходный экран и составить план реализации с помощью запроса вроде: “Analyze MyTimeEntries source screen and make a plan for how to migrate it to the target project”.
Только после этого мы переходили к реализации и тестированию. Это работало лучше, потому что заставляло агента сосредоточиться на поведении, компоновке и потоке данных, а также давало разработчику возможность просмотреть и скорректировать план перед реализацией.
Ниже приведены несколько примеров, показывающих, как на практике выглядела миграция нетривиального UI. Это был не плавный процесс автоматических преобразований, а повторяющийся цикл анализа, реализации, тестирования и исправлений.

Миграция экрана TagTypeEdit сначала выглядела простой, но это оказалось не совсем так. При ручном тестировании результата обнаружились проблемы с добавлением и удалением тегов, и пришлось попросить агента их исправить.
Именно такие проблемы делают миграцию UI дорогой. Экран может выглядеть завершенным, но поток данных и персистентность требуют тщательной проверки и доработки.

Календарь оказался одной из самых сложных частей. Исходная реализация имела кастомную компоновку и поведение, и миграция потребовала принятия архитектурного решения еще до начала кодирования. Сначала экран не открывался, затем понадобились исправления для drag-and-drop и выравнивания итогов.
Это хороший пример того, что миграция – это не только перенос XML-дескрипторов. Сложный экран часто приходится переосмысливать с учетом подходов Jmix.

Функция командной строки оказалась особенно интересной, потому что это кастомная возможность приложения, связанная с удобством использования. Она позволяет пользователям вводить время в компактной текстовой форме и использует подсказки для проектов и задач.
Реализация в целевом проекте прошла несколько итераций. Первая версия, предложенная агентом, использовала подход на основе ComboBox. Затем разработчик попросил переработать её с использованием CodeEditor и подсказок. Обработка клавиши Enter оставалась неудобной, поэтому разработчик попросил агента улучшить её. Результаты были неудачными: в разные моменты нажатие Enter либо создавало новую строку, либо не применяло команду, либо приводило к ошибкам из-за обработки JSON в событии редактора. В итоге мы отказались от обычного Enter и использовали Ctrl+Enter как команду применения.
Это хороший пример компромисса при миграции: иногда слишком сложно в точности воспроизвести поведение исходного приложения.

Экран SimpleWeeklyTimesheets стал еще одним примером скрытой сложности. Во время миграции возникали проблемы с идентификаторами сущностей, фиксацией строк, пограничными случаями при разборе времени и потерей фокуса при вводе.
В одном эпизоде UI-тест, выполненный агентом, скорректировал предположение разработчика. Сначала казалось, что новая строка исчезает после нажатия Submit All. Но тестирование через Playwright показало, что данные не теряются. На самом деле новая строка после перезагрузки объединялась с существующей строкой для того же проекта и задачи. Это хороший пример того, как агент с возможностями UI-тестирования иногда может точнее понять реальное поведение системы, чем человек.
ИИ-агент был наиболее полезен при выполнении повторяющихся задач миграции между CUBA и Jmix: преобразовании сущностей, обновлении аннотаций, изменений в XML и конвертации использования API. Эти задачи несложные, но их очень много, и выполнение вручную занимает много времени и чревато ошибками.
Еще одной полезной возможностью стало сравнение в большом контексте. Агент мог сопоставлять исходный и целевой код, находить недостающие части и предлагать, что нужно добавить. Это особенно помогало для сложных экранов, где он мог быстро подготовить план миграции перед реализацией.
В то же время участие человека оставалось необходимым. Разработчик должен был решать, какое поведение действительно важно, выбирать между альтернативными вариантами UX и принимать или отклонять предложения агента.
Таким образом, это была не конвертация одним проходом, а интерактивная разработка с множеством коротких циклов: формулировка запроса, проверка результата, тестирование, запрос на исправление и повторное тестирование.
Реальная миграция не заканчивается на том, что проект успешно компилируется.
В этом проекте завершающие этапы также включали:
создание инициализатора демо-данных
ручную реорганизацию главного меню
перенос данных безопасности из SQL insert в ресурсные роли
ручное добавление политик для сущностей и атрибутов, которые отсутствовали после автоматической миграции
проверку поведения UI, зависящего от прав доступа
Эти завершающие работы важны, потому что именно они превращают мигрированную кодовую базу в полноценное работающее приложение.
Готовое мигрированное приложение доступно в репозитории jmix-timesheets [1].
Теперь сравним фактические трудозатраты с предварительными оценками.
Migration Advisor оценил этот проект в 315 человеко-часов. Поскольку 100 часов — это фиксированная базовая часть для любого проекта, оценка, зависящая от самого проекта, составила 215 человеко-часов.
Фактически на эту миграцию было затрачено 25 человеко-часов.
В итоге мигрированный проект содержит 10916 строк Java-кода и 3513 строк XML. Таким образом, целевая кодовая база стала примерно на 20% больше, чем исходная. Это неудивительно: во многих случаях экраны Flow UI требуют другой, иногда более явной структуры по сравнению со старыми экранами CUBA.
Ключевой вывод – фактические трудозатраты оказались значительно ниже стандартной оценки.
Конечно, это не означает, что любая миграция с CUBA на Jmix потребует столь малой доли от оценки. Имеют значение структура проекта, сложность кастомного UI, качество кода и опыт команды. Но этот кейс показывает, что при структурированном подходе и использовании ИИ практические затраты могут быть снижены очень существенно.
Миграция Timesheets стала хорошим тестом, поскольку включала те аспекты, которые обычно усложняют процесс: множество экранов, кастомное поведение UI, динамический ввод, календарь, графики и особенности безопасности.
Результат оказался обнадеживающим.
Миграция не была полностью автоматической и по-прежнему требовала внимательной проверки, тестирования и некоторых ручных исправлений. Но с использованием ИИ-агентов процесс стал значительно более практичным.
Для пользователей CUBA Platform это, пожалуй, главный вывод. Переход на Jmix – все еще серьезная задача, но это не обязательно долгий процесс переписывания вручную. При правильной настройке и поэтапном подходе даже приложение со сложным UI можно мигрировать за разумное время.
Автор: haulmont
Источник [14]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/28525
URLs in this post:
[1] Новый проект Timesheets: https://github.com/jmix-framework/jmix-timesheets
[2] Шаблон миграции: https://github.com/jmix-framework/jmix-migration-from-cuba-platform
[3] Jmix agent guidelines: https://github.com/jmix-framework/jmix-agent-guidelines
[4] поведения: http://www.braintools.ru/article/9372
[5] поведение: http://www.braintools.ru/article/5593
[6] зрения: http://www.braintools.ru/article/6238
[7] Jmix Migration Advisor: https://github.com/jmix-framework/jmix-migration-advisor
[8] ошибки: http://www.braintools.ru/article/4192
[9] реакции: http://www.braintools.ru/article/1549
[10] AGENTS.md: http://AGENTS.md
[11] application.properties: http://application.properties
[12] com.haulmont.timesheets.gui.holiday: http://com.haulmont.timesheets.gui.holiday
[13] опыта: http://www.braintools.ru/article/6952
[14] Источник: https://habr.com/ru/companies/haulmont/articles/1019892/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1019892
Нажмите здесь для печати.