Суть: Заменили 157 устаревших Drupal-параграфов на 41 React-компонент с JSONB-хранением. Бизнес-пользователи получили drag-and-drop дашборды без участия разработчика.
Крупная платформа автоматизации (RPA) столкнулась с проблемой: бизнес-пользователи нуждались в гибкой визуальной аналитике, но существующее решение было построено на устаревшей архитектуре Drupal Paragraphs. Каждый дашборд был набором параграфов в Drupal-ноде, связанных со сложной системой формул.
Архитектура построена на принципе разделения данных и представления. Бэкенд возвращает только сырые числа, клиент форматирует.
| Компонент | Технология | Назначение |
|---|---|---|
| Frontend | React 19, TypeScript (strict), Vite 8 | UI дашбордов |
| Grid layout | React-Grid-Layout | Drag-and-drop виджетов (как в Grafana) |
| Графики | Chart.js + react-chartjs-2 | 9 типов графиков |
| Хранение | PostgreSQL JSONB | Гибкое хранение без миграций |
| Формулы | ExpressionLanguage (DSL) | Вычисления на сервере |
| Переводы | i18next + key-based JSON | Интернационализация |
| Backend | PHP 8.2, Drupal 10 | API + бизнес-логика |
data.values никогда не сохраняются в БД.data JSONB NOT NULL вместо 20+ Drupal-полей. Схема расширяется без миграций.WidgetPluginInterface.| Метрика | До (Legacy) | После (V2) | Эффект |
|---|---|---|---|
| Связь данных и UI | Жёсткая (Paragraphs) | Разделение (data/config) | Чистая архитектура |
| Изменение дашборда | Задача разработчику | Drag-and-drop бизнес-пользователем | ~90% быстрее |
| Добавление индикатора | SQL + формула | Выбор из available-fields | ~95% быстрее |
| Хранение схемы | Drupal Entity (20+ полей) | 1 столбец JSONB | ~80% меньше кода |
| Расширяемость | Новая entity type | Новый WidgetPlugin | Дни → часы |
«Мы заменили 157 параграфов и 75+ формул на 41 React-компонент в одной JSONB-таблице. Время добавления нового индикатора сократилось с 2 дней до 15 минут.»
React 19 TypeScript Vite 8 Chart.js react-chartjs-2
React-Grid-Layout i18next PHP 8.2 Drupal 10
PostgreSQL JSONB ExpressionLanguage PHPUnit Vitest
Playwright Docker
Хотите обсудить похожую задачу? Свяжитесь с нами →