1. Проблема: пропрієтарний «чорний ящик» метаданих

У традиційних облікових системах структура метаданих є жорстко зашитою у платформу. Зв'язки між об'єктами зберігаються у внутрішніх бінарних таблицях, що робить неможливим природне використання інструментів розробки: Git diff, автогенерацію API, інтеграцію зі статичними аналізаторами коду та сучасними ORM/Query Builders.

Коли розробник хоче подивитися, що змінилося між версіями документа, він змушений користуватися внутрішнім інструментом порівняння конфігуратора, який часто дає збої на великих конфігураціях.

2. Рішення Ruta: Декларативні метадані + чисті SQL-схеми

У Ruta ми розмежували два шари:

  • Рівень конфігурації (Design-time): структура сутностей описується у декларативних схемах (YAML / JSON / внутрішні системні таблиці). Кожна зміна прозора, фіксується у Git і має зрозумілий diff.
  • Рівень бази даних (Runtime): генератор схеми транслює метадані у чисті, високопродуктивні SQL-таблиці з реальними зовнішніми ключами (Foreign Keys), індексами та обмеженнями цілісності (Constraints).
Це означає, що ваші дані більше не сховані за незрозумілими назвами полів на кшталт _Reference12_IDRRef. Таблиця довідника «Контрагенти» називається зрозуміло, а її поля мають прямі семантичні назви: id, code, name, tax_id.

3. Ієрархія підсистем через модель Nested Set

Командний інтерфейс користувача та дерево підсистем у Ruta оптимізовані для миттєвого рендерингу. Замість повільних рекурсивних запитів (CTE) або N+1 проблем ми використовуємо реляційну модель Nested Set. Це дає змогу отримати повне дерево розділів і меню за один простий SQL-запит:

SELECT node.id, node.name, node.synonym, node.depth FROM _sys_metadata_tree AS node JOIN _sys_metadata_tree AS parent ON node.left_key BETWEEN parent.left_key AND parent.right_key WHERE parent.id = 'root' AND node.is_active = 1 ORDER BY node.left_key;

4. Сувора типізація та захист інваріантів

Усі реквізити об'єктів мають чіткі типи:

  • String (з фіксованою або довільною довжиною);
  • Number (з фіксацією розрядності цілої та дробової частини, наприклад 15.2 для валют);
  • Boolean, Date, UUID;
  • Reference (суворе типізоване посилання на інший об'єкт метаданих із контролем посилальної цілісності).

Будь-яка зміна властивостей об'єкта метаданих або запису проходить через централізований метод валідації updateProperties(patch). Це унеможливлює створення «битого» або частково записаного об'єкта.