← Все статьи

Как проектировать современную ERP-систему в 2026 году: от монолита к платформе

Metadata Driven Architecture, движки платформы, стек фронтенда и стратегия миграции — как строить ERP, которая развивается десятилетиями без переписывания каждые пять лет.

Содержание

Большинство ERP-систем начинают жизнь одинаково: первая таблица в базе данных, первая форма, первый отчёт. Затем добавляется новый модуль, потом ещё один. Через несколько лет система успешно решает задачи бизнеса, но становится сложной в развитии.

Любое новое поле требует изменения базы данных, backend-кода, frontend-кода, отчётов и прав доступа. Новые разделы создаются месяцами. Архитекторы боятся рефакторинга. Разработчики боятся трогать старые модули.

В 2026 году ответ на эту проблему — не очередная «большая перепись» и не микросервисы ради моды. Ответ — переход от ERP как приложения к ERP как платформе: системе, которая описывает структуру через метаданные, хранит бизнес-данные в нормальных таблицах PostgreSQL и позволяет новым модулям появляться за дни, а не за кварталы.

Ключевые выводы

ERP должна быть платформой для создания модулей, а не набором модулей. Код, таблицы и формы — следствие описания, а не единственный способ расширения.

Metadata Driven — про структуру, не про EAV. Метаданные управляют сущностями, полями, workflow и интерфейсами. Бизнес-данные живут в реальных таблицах с индексами и связями.

CRUD — необходимый минимум, но не цель. Промышленная ERP автоматизирует процессы: сроки, уведомления, согласования, аналитику — и именно это составляет основную сложность.

Готового open-source конструктора ERP-уровня не существует. Low-code платформы и CRUD-фреймворки закрывают часть задач, но не заменяют платформенный слой.

Миграция — эволюция, не революция. Переписать систему целиком почти всегда провал. Правильный путь — поэтапное внедрение движков платформы и перенос модулей один за другим.

Главный вопрос при проектировании ERP сегодня звучит не «как реализовать новый модуль», а «как построить платформу, на которой новые модули будут появляться максимально дёшево и быстро».


Введение

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

Типичная траектория выглядит знакомо: на старте всё быстро, команда из пяти человек знает весь код, диаграмма помещается на салфетку. Бизнес растёт — растёт и ERP. Появляются филиалы, новые продуктовые линейки, требования регуляторов. Каждое изменение бизнеса требует отражения в системе. ERP становится центральной нервной системой компании.

И в какой-то момент скорость разработки падает. Не потому что «плохие программисты», а потому что архитектура не рассчитана на накопление сложности. Каждая новая фича затрагивает половину кодовой базы. Каждое исключение зашивается в код. Каждый отчёт — отдельный проект.

Современная ERP в 2026 году — это попытка разорвать этот цикл. Не через магию low-code и не через бесконечную универсальность EAV, а через платформенную архитектуру: набор движков, которые превращают описание системы в работающий код, интерфейс и процессы.


Почему большинство ERP стареют

Типичный жизненный цикл

Жизненный цикл большинства корпоративных ERP предсказуем:

Таблица
  ↓
PHP-код (или любой backend)
  ↓
React-форма
  ↓
Отчёт
  ↓
Ещё один модуль

На каждом шаге создаётся ручная связка между слоями. Таблица corrosion_maps — контроллер CorrosionMapController — компонент CorrosionMapForm — SQL-запрос в отчёте «Коррозия по объектам» — правило в permissions.php. С каждым годом количество таких связок растёт экспоненциально.

Появляются предсказуемые симптомы:

  • Дублирование логики. Валидация поля «Скорость коррозии» написана в трёх местах: в API, в форме и в импорте из Excel.
  • Копирование CRUD. Каждый новый модуль — копипаста предыдущего с заменой имён.
  • Десятки одинаковых экранов. Таблица + фильтры + форма + карточка — один и тот же паттерн, но каждый раз с нуля.
  • Сложные интеграции. Модуль A напрямую читает таблицы модуля B, потому что «так быстрее».
  • Проблемы с производительностью. Отчёты считаются часами, потому что никто не проектировал аналитический слой.

Симптомы стареющей ERP

Если узнаёте себя — система уже на плато развития:

  • Новый модуль создаётся неделями, хотя по сути это «ещё одна сущность с полями и статусами».
  • Любое изменение требует участия нескольких разработчиков — backend, frontend, DBA, автор отчётов.
  • Бизнес-процессы зашиты в кодif ($status == 'approved') вместо описания workflow.
  • Пользователи не могут настроить интерфейс под себя — колонки, фильтры, представления жёстко заданы разработчиком.
  • Архитектурные решения принимаются исходя из ограничений старого кода, а не из требований бизнеса.

Старение ERP — не баг и не следствие «устаревшего стека». Это накопленный эффект архитектуры «каждый модуль — отдельный мини-проект».


ERP как платформа, а не как приложение

Самое важное изменение мышления при проектировании современной ERP:

ERP должна быть не набором модулей. ERP должна быть платформой для создания модулей.

Классическая модель:

ERP = Код + Таблицы + Формы

Каждый новый раздел — новый цикл разработки: миграция, API, UI, права, тесты, документация.

Платформенная модель:

ERP = Платформа + Метаданные + Бизнес-модули

Платформа — набор движков: метаданные, миграции, CRUD-runtime, workflow, права, события, аудит.

Метаданные — описание сущностей, полей, связей, процессов и интерфейсов в данных, а не в коде.

Бизнес-модули — специализированная логика, которую нельзя выразить декларативно: расчёт остаточного ресурса, прогноз коррозии, интеграция с внешней SCADA.

Разница принципиальна. В классической ERP добавление сущности «Коррозионная карта» — проект на две недели. В платформенной ERP — описание в Metadata Engine и автоматическая генерация таблицы, API, формы и списка. Специализированная логика подключается как плагин, а не как очередной монолитный контроллер.

Это не означает «без программирования для всего». Это означает, что 80% типовых операций — CRUD, списки, фильтры, базовые workflow — не требуют ручного кода, а 20% сложной доменной логики получает чёткие точки расширения.


Что такое Metadata Driven Architecture

Metadata Driven Architecture (MDA) — подход, при котором структура системы хранится в данных, а не только в коде.

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

Сущность: Коррозионная карта

Поля:
  - Номер (string, required, unique)
  - Объект (relation → Equipment)
  - Скорость коррозии (decimal, mm/year)
  - Дата измерения (date)
  - Статус (enum: draft, review, approved)

Платформа на основе этого описания самостоятельно понимает:

  • как хранить данные — создать таблицу corrosion_maps с типизированными колонками;
  • как отображать форму — сгенерировать UI с валидацией и связями;
  • как строить таблицу — список с сортировкой, фильтрами и пагинацией;
  • как валидировать поля — required, unique, диапазоны, кастомные правила;
  • как применять права — кто видит, кто редактирует, кто утверждает.

Важно: MDA не отменяет программирование. Она переносит рутину с уровня «написать ещё один CRUD» на уровень «описать сущность и добавить бизнес-логику там, где она действительно нужна».

Что хранится в метаданных

Категория Примеры
Сущности Название, таблица, иконка, модуль
Поля Тип, валидация, значение по умолчанию, видимость
Связи One-to-many, many-to-many, каскады
Workflow Статусы, переходы, условия, действия
Права Роли, политики, доступ к полям и действиям
Интерфейсы Списки, формы, дашборды, виджеты

Метаданные — источник истины для структуры. Код — для того, что нельзя выразить декларативно.


Почему EAV — не решение

Услышав слово «метаданные», многие разработчики сразу вспоминают Entity–Attribute–Value — класическую схему «универсального хранения»:

entity_values
  entity_id
  field_id
  value

На демо EAV выглядит идеально: любое поле, любая сущность, никаких миграций. В продакшене — катастрофа:

  • Плохая производительность. Каждый запрос — JOIN на JOIN. Типичный список из 50 записей с 10 полями превращается в 500 строк промежуточного результата.
  • Сложные запросы. «Показать карты со скоростью коррозии > 0.5 mm/year за последний квартал» — SQL, который DBA будет оптимизировать неделю.
  • Отсутствие нормальных индексов. Индексировать value в TEXT-колонке, где лежит и число, и дата, и строка — бессмысленно.
  • Сложная аналитика. BI-инструменты, отчёты, агрегации — всё требует ETL поверх EAV.

Современная ERP должна использовать реальные таблицы PostgreSQL и реальные связи между сущностями. Метаданными управляется структура системы — какие таблицы создать, какие поля добавить, как построить форму. Не хранение бизнес-данных.

Правильная модель:

Метаданные описывают → Migration Engine создаёт → PostgreSQL хранит

Таблица corrosion_maps с колонками number, equipment_id, corrosion_rate, measured_at — это нормальная реляционная модель. Metadata Engine знает, что эта таблица существует, какие у неё поля и как их отображать. Entity Engine читает и пишет данные через типизированный runtime, а не через entity_values.

EAV допустим для ограниченных точек расширения — пользовательские атрибуты, редкие кастомные поля. Не для ядра ERP.


Основные движки платформы

Платформенная ERP — это не один «умный фреймворк», а набор специализированных движков, каждый из которых решает одну задачу хорошо.

Metadata Engine

Центральный источник истины о структуре системы.

Хранит и версионирует:

  • сущности и их поля;
  • связи между сущностями;
  • определения workflow;
  • политики доступа;
  • описания интерфейсов (списки, формы, дашборды).

Metadata Engine отвечает на вопрос: «что существует в системе и как это устроено». Все остальные движки читают метаданные, а не хардкодят структуру.

Требования к реализации:

  • Версионирование — изменение схемы не ломает работающие модули.
  • API для чтения — frontend и backend получают актуальное описание в runtime.
  • Валидация — нельзя создать поле без типа или связь на несуществующую сущность.

Migration Engine

Отвечает за синхронизацию структуры базы данных с метаданными.

Принцип работы:

Desired State (метаданные)
        ↓
Actual State (текущая схема БД)
        ↓
SQL Diff (миграция)

Разработчик добавляет поле «Комментарий» в описание сущности — Migration Engine генерирует ALTER TABLE corrosion_maps ADD COLUMN comment TEXT и применяет безопасно. Не нужно вручную писать миграции для каждого модуля.

Критичные свойства:

  • Идемпотентность — повторный запуск не ломает схему.
  • Rollback — возможность откатить изменение.
  • Zero-downtime — для крупных таблиц: добавление колонки без блокировки.

Entity Engine

Универсальный runtime-движок для работы с сущностями.

Вместо генерации тысяч контроллеров CorrosionMapController, EquipmentController, InspectionController — один механизм:

GET    /api/entities/corrosion_maps
POST   /api/entities/corrosion_maps
GET    /api/entities/corrosion_maps/:id
PATCH  /api/entities/corrosion_maps/:id
DELETE /api/entities/corrosion_maps/:id

Entity Engine:

  • читает метаданные сущности;
  • строит SQL-запросы к реальным таблицам;
  • применяет валидацию из описания полей;
  • проверяет права через Permission Engine;
  • пишет в Audit Engine;
  • публикует события в Event Bus.

Специализированная логика подключается через хуки и расширения: beforeCreate, afterApprove, кастомные валидаторы.

Workflow Engine

Бизнес-процессы становятся данными, а не цепочками if в коде.

Вместо:

if ($status == 'approved') {
    $this->notifyManager($card);
    $this->createInspectionTask($card);
}

Описание процесса:

Черновик → Согласование → Утверждён

Переход «Согласование → Утверждён»:
  - Условие: роль = «Инженер по коррозии»
  - Действие: уведомить ответственного
  - Действие: создать задание на повторное обследование

Workflow Engine:

  • хранит определения процессов в метаданных;
  • проверяет допустимость переходов;
  • выполняет действия при смене статуса;
  • ведёт историю переходов.

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

Permission Engine

Единая система управления доступом для всей платформы.

Поддерживает уровни:

  • Роли — «Инженер», «Руководитель участка», «Аудитор».
  • Политики — «может редактировать карты своего участка».
  • Доступ к полям — «скорость коррозии видят все, прогноз остаточного ресурса — только инженеры».
  • Доступ к действиям — «утверждать может только роль X при статусе Y».

Permission Engine интегрирован с Entity Engine и Workflow Engine: права проверяются на каждом запросе, а не размазаны по контроллерам.

Event Bus

Основа слабосвязанной архитектуры внутри ERP.

Модули не вызывают друг друга напрямую. Они публикуют и подписываются на события:

ContractApprovedEvent
        ↓
   Notification Module → email ответственному
        ↓
   Audit Module → запись в журнал
        ↓
   Integration Module → webhook во внешнюю систему

Преимущества:

  • новый модуль подписывается на событие без изменения существующего кода;
  • интеграции изолированы от ядра;
  • проще тестировать — mock событий вместо mock всей цепочки вызовов.

Реализация: in-process event bus для монолита, RabbitMQ / NATS при горизонтальном масштабировании.

Audit Engine

Фиксирует полную историю изменений — кто, когда, что именно изменил.

Отвечает на вопросы, которые в промышленной ERP задают ежедневно:

  • Кто изменил скорость коррозии с 0.3 на 0.8?
  • Когда карта перешла в статус «Утверждён»?
  • Какие поля были изменены при последнем редактировании?

Audit Engine работает на уровне Entity Engine: каждая операция create/update/delete автоматически логируется. Не нужно вручную добавлять $this->auditLog() в каждый контроллер.


Почему CRUD уже недостаточно

Большинство туториалов по ERP заканчиваются на CRUD: создать, прочитать, обновить, удалить. Для демо этого достаточно. Для промышленной эксплуатации — нет.

Простая система

Позволяет:

  • создать коррозионную карту;
  • изменить поля;
  • удалить запись;
  • вывести список.

Реальная промышленная система

Требует:

  • контролировать сроки обследований — карта просрочена, если дата следующего осмотра прошла;
  • прогнозировать остаточный ресурс — расчёт на основе скорости коррозии и толщины стенки;
  • уведомлять ответственных — при превышении порога, при приближении срока;
  • создавать задания — автоматически при смене статуса или по расписанию;
  • строить аналитические панели — тренды коррозии по объектам, участкам, периодам;
  • управлять согласованием — workflow с ролями, комментариями, историей.

Именно эта логика — процессы, расчёты, уведомления, аналитика — составляет 80% сложности промышленной ERP. CRUD — оставшиеся 20%, которые при этом занимают 80% времени разработки в классической архитектуре.

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


Что показало исследование готовых решений

При проектировании платформы был проведён обзор существующих open-source инструментов:

Решение Категория Сильные стороны Ограничения для ERP
Appsmith Low-code Быстрые дашборды, коннекторы к БД Нет workflow engine, нет metadata-driven сущностей
ToolJet Low-code Визуальный конструктор, self-hosted Ограниченная кастомизация, нет enterprise-прав
Budibase Low-code Простота, внутренние инструменты Не масштабируется на сложные процессы
Directus Headless CMS Отличная работа с данными, API из коробки CMS-мышление, не ERP-процессы
React Admin CRUD-фреймворк Быстрые списки и формы на React Нет workflow, нет metadata engine
Refine CRUD-фреймворк Гибкость, headless-подход Framework, не платформа

Главный вывод

Готового open-source конструктора интерфейсов для ERP найдено не было.

Существующие решения делятся на две категории:

Low-code платформы (Appsmith, ToolJet, Budibase) быстро создают интерфейсы, но накладывают архитектурные ограничения и навязывают собственную модель данных. Подходят для внутренних инструментов и прототипов, но не для ERP, которая должна жить десятилетие.

Framework-подход (React Admin, Refine) ускоряет разработку CRUD-интерфейсов, но не решает задачи платформенного уровня: metadata engine, migration engine, workflow designer, permission engine, audit.

Вывод: платформенный слой придётся строить. Можно и нужно опираться на готовые библиотеки для UI, но архитектура ERP — собственная.


Почему React Admin не решает проблему

React Admin — отличный инструмент. Он помогает за часы собрать:

  • таблицы с сортировкой и фильтрами;
  • формы с валидацией;
  • карточки сущностей;
  • базовые права через authProvider.

Но он не помогает создавать:

  • Dashboard Builder — конструктор аналитических панелей с виджетами;
  • Workflow Designer — визуальный редактор бизнес-процессов;
  • пользовательские представления — когда конечный пользователь настраивает колонки и фильтры;
  • конструкторы интерфейсов — когда архитектор описывает форму в метаданных, а не в JSX.

React Admin — CRUD-фреймворк. Для простых админок и внутренних панелей он идеален. Для ERP с десятками модулей, сложными workflow и персонализацией его возможности заканчиваются на втором-третьем месяце разработки.

Правильное использование: React Admin (или его паттерны) — как строительный блок внутри Entity Engine для рендеринга списков и форм на основе метаданных. Не как замена платформы.


Современный стек фронтенда для ERP

Если не использовать готовую платформу целиком, в 2026 году разумно опираться на проверенный набор библиотек:

Библиотека Задача
React Компонентная модель, экосистема
TypeScript Типизация метаданных и API
Ant Design Enterprise UI: таблицы, формы, layout
TanStack Query Кэширование, синхронизация с API
TanStack Table Гибкие таблицы с виртуализацией
React Hook Form Производительные формы
React Flow Workflow Designer, диаграммы процессов
dnd-kit Drag-and-drop для конструкторов
Apache ECharts Аналитические графики и дашборды

Этот набор покрывает большую часть задач корпоративного интерфейса:

  • Ant Design + TanStack Table — списки сущностей с фильтрами, сортировкой, экспортом.
  • React Hook Form + Ant Design — динамические формы на основе метаданных полей.
  • React Flow — визуальный редактор workflow для архитекторов.
  • dnd-kit — конструктор дашбордов: перетаскивание виджетов.
  • ECharts — графики коррозии, тренды, KPI-панели.
  • TanStack Query — единый слой работы с Entity Engine API.

Ключевой принцип: UI рендерится из метаданных, а не хардкодится для каждой сущности. Один компонент EntityList получает описание из Metadata Engine и рисует таблицу. Один EntityForm — форму. Специализированные экраны — исключение, а не правило.


ERP Studio и персонализация пользователя

В современной ERP необходимо разделять два уровня настройки — с разными пользователями, правами и инструментами.

Уровень архитектора (ERP Studio)

Архитектор или администратор системы управляет структурой:

  • сущности и поля — создание, типы, валидация;
  • workflow — статусы, переходы, действия;
  • права — роли, политики, доступ к полям;
  • интерфейсы — базовые списки, формы, дашборды.

ERP Studio — это среда, в которой архитектор описывает систему, а платформа материализует описание в таблицы, API и UI. Аналогия: Figma для структуры ERP, только изменения сразу работают в prod.

Инструменты ERP Studio:

  • конструктор сущностей (drag-and-drop полей);
  • редактор workflow (React Flow);
  • настройщик прав (матрица ролей и действий);
  • предпросмотр форм и списков.

Уровень пользователя (Personalization)

Конечный пользователь управляет своим рабочим пространством:

  • фильтры — сохранённые наборы условий;
  • представления — какие колонки показывать, в каком порядке;
  • дашборды — какие виджеты на главной;
  • рабочие пространства — набор вкладок и модулей под роль.

Пользователь не создаёт сущности и не меняет workflow. Он настраивает интерфейс под себя — как закладки в браузере или колонки в Excel.

Разделение критично: если дать конечному пользователю доступ к Metadata Engine, система развалится. Если не дать персонализацию — пользователи будут ненавидеть «жёсткий» интерфейс.


Стратегия миграции существующей ERP

Самая распространённая ошибка — попытка переписать систему целиком. Такой проект почти всегда заканчивается провалом: бизнес не может остановиться на год, требования меняются быстрее, чем пишется новый код, команда выгорает.

Правильный путь — эволюция, а не революция.

Этап 1. Аудит текущей архитектуры

  • Инвентаризация модулей, таблиц, интеграций.
  • Карта зависимостей: кто от кого зависит.
  • Выявление «горячих точек» — модулей, которые меняются чаще всего.
  • Оценка: какие модули кандидаты на первый перенос.

Результат: документ с приоритетами и рисками. Не «переписать всё», а «начать с модуля X, потому что он самый болезненный и относительно изолированный».

Этап 2. Внедрение Metadata Engine

  • Описать существующие сущности в метаданных (без изменения БД).
  • Metadata Engine читает описание, но пока не управляет миграциями.
  • Цель: проверить модель метаданных на реальных данных.

Этап 3. Внедрение Migration Engine

  • Подключить синхронизацию метаданных со схемой БД.
  • Первые автоматические миграции — на тестовом окружении.
  • Существующие таблицы остаются; новые поля добавляются через Metadata Engine.

Этап 4. Создание Entity Engine

  • Универсальный API для CRUD на основе метаданных.
  • Параллельно с существующими контроллерами — не замена, а альтернативный путь.
  • Первый модуль переводится на Entity Engine.

Этап 5. Разработка новых модулей на платформе

  • Все новые сущности создаются только через Metadata Engine + Entity Engine.
  • Старый код не трогается.
  • Команда привыкает к платформенному workflow.

Этап 6. Постепенный перенос старых разделов

  • По одному модулю, по приоритету из аудита.
  • Strangler Fig Pattern: новый API оборачивает старый, frontend переключается постепенно.
  • Старый код удаляется только когда модуль полностью перенесён и протестирован.

Типичные сроки: 12–24 месяца для средней ERP (20–50 модулей). Не «большой взрыв», а непрерывная доставка ценности.


Какими будут ERP через 10 лет

С высокой вероятностью индустрия движется к следующей модели:

От ERP как набора экранов — к ERP как платформе.

  • Новые сущности появляются через конструкторы, а не через спринты разработки.
  • Интерфейсы собираются динамически из метаданных и пользовательских настроек.
  • Бизнес-процессы настраиваются архитектором без изменения кода.
  • Разработчики сосредоточены на сложной доменной логике: расчёты, ML-прогнозы, интеграции с оборудованием.
  • AI-ассистенты помогают архитекторам описывать сущности и процессы на естественном языке — но ядро остаётся metadata-driven, а не «сгенерированным на лету без структуры».

Технологии сменятся. React уступит место чему-то новому. PostgreSQL останется или нет. Но платформенная модель — метаданные, движки, слабая связанность — переживёт конкретный стек, потому что она решает фундаментальную проблему: как сделать изменение дешёвым.

Компании, которые продолжают развивать ERP как классический монолит «таблица → код → форма», рано или поздно упрются в потолок. Компании, которые строят платформу, получают возможность развивать систему годами — добавляя модули, процессы и интеграции без переписывания фундамента.


Заключение

Современная ERP в 2026 году — это уже не набор таблиц и форм. Это платформа, объединяющая:

  • метаданные — описание структуры в данных;
  • движки — migration, entity, workflow, permission, audit, events;
  • бизнес-модули — специализированная логика поверх платформы;
  • персонализацию — ERP Studio для архитекторов, настройки для пользователей;
  • интеграции — через Event Bus, а не прямые вызовы.

Ключевые принципы:

  1. Метаданные управляют структурой, PostgreSQL хранит данные — не EAV, не универсальные таблицы.
  2. CRUD — автоматизируется платформой — разработчики пишут то, что нельзя описать декларативно.
  3. Миграция — эволюция — Metadata Engine сначала, Entity Engine потом, перенос модулей постепенно.
  4. Готового решения нет — стек библиотек есть, платформенный слой строится под себя.

Главный вопрос при проектировании ERP сегодня звучит не:

«Как реализовать новый модуль?»

а:

«Как построить платформу, на которой новые модули будут появляться максимально дёшево и быстро?»

Ответ на этот вопрос определяет, будет ли ваша ERP расти вместе с бизнесом — или станет следующим монолитом, который через пять лет придётся переписывать снова.