Перейти к содержанию

Бизнес-логика в Provisa

Проблема

У каждой организации есть стандарты для бизнес-логики, и большинство команд им следует. Но с годами, по мере того как системы строятся и заменяются, а команды меняются, логика расползается по ETL-заданиям, дашбордам, API и хранимым процедурам. Каждая часть по отдельности имеет смысл. Часто никто не планировал целое, а ещё чаще никто не планировал целое во времени. Результат знаком: «чистую выручку» считают тремя способами в трёх местах, и никто не может сказать, какой из них верный.

Для отдельных частей этой проблемы у отрасли есть ответы. Слой метрик, который часто продают как семантический слой, определяет «чистую выручку» один раз для всех инструментов. Open Data Product Standard (ODPS) описывает продукты данных, а Open Data Contract Standard (ODCS) описывает контракты данных. Provisa экспортирует оба. Всё это хорошие идеи, и все они набирают популярность, но каждая покрывает лишь одну часть. Главный вопрос в том, как они вписываются в контролируемые, управляемые данные как одна целостная, составная модель. Логике, которая выводит или изменяет данные, нужно то же управление, что и самим данным: кто может её использовать, что она читает и пишет и куда уходят её результаты.

Каналы доставки усугубляют проблему. Логику встраивают в каждый из них: вычисляемое поле в BI-инструменте, правило в обработчике API, фильтр в резолвере приложения. В итоге у каждого канала своя версия истины, и один и тот же вопрос, заданный через два из них, редко получает одинаковый ответ. В конце концов люди сдаются: они начинают принимать этот беспорядок как цену специализации и обслуживания множества разных заинтересованных сторон.

Что такое бизнес-логика

Бизнес-логика — это правила, которые создают, изменяют, удаляют или преобразуют данные.

Бизнес-терминология — отдельная вещь. Имена и описания доменов, таблиц и столбцов, а также термины онтологии говорят, что означают данные. Бизнес-логика говорит, что с ними делают.

Три роли

Каждое правило играет одну из трёх ролей, и каждую роль можно написать тремя способами:

Роль SQL Внешний вызов Код
Набор данных представление, команда-инструкция API или процедура, возвращающая строки резолвер кода @table, @stream; команда python или script
Значение выражение представления, метрика — команда python или script
Изменение INSERT, UPDATE, DELETE, команда-инструкция запись через API, мутация, процедура @command; команда python или script
  • Внешний вызов. API GraphQL, REST или gRPC другой системы либо хранимая процедура базы данных, зарегистрированные как команда.
  • Таблицы как аргументы. Команда может принимать таблицы как аргументы, поэтому набор данных можно построить из других наборов данных.
  • Метрика. Именованный агрегат, определённый один раз, например net_revenue как SUM(orders.amount) - SUM(orders.refunds). Каждый запрос разбивает его по нужным ему измерениям, поэтому хранилище, дашборд и API читают одно и то же число.

Скрытые побочные эффекты

Скрытый побочный эффект — это эффект, которого не видно из определения правила.

Каждое правило имеет имя и тип, зарегистрировано, проходит аудит и защищено. Команда также может требовать одобрения перед запуском.

Возможные побочные эффекты Чем ограничены
SQL Нет —
Внешний вызов Собственные процессы, уведомления и каскады другой системы Список разрешённого исходящего трафика (HTTP, gRPC); учётные данные, хранящиеся как секреты (процедуры, операции источника)
Резолвер кода Вызовы внешних сервисов и сетей; изменчивые результаты; стоимость Закреплённый код, закреплённый отпечаток хоста, песочница, учёт
Код на хосте Читает всё, что может прочитать сервер (память, учётные данные, файлы, сеть); может истощить сервер или обрушить его commands.allow_host_code, по умолчанию выключено

Внешний вызов типизирован собственной схемой системы или аргументами и возвращаемыми столбцами, которые вы объявляете при регистрации команды.

Код резолвера кода закреплён версией пакета, коммитом Git или хешем архива, поэтому он продвигается вместе с моделью.

Код на хосте — это команда python или script. Он работает внутри сервера с полным доступом сервера, поэтому вредоносный, ошибочный или жадный код может прочитать всё, что может сервер, истощить его или обрушить. Это удобно и безопасно, когда вы доверяете коду. Модель хранит только ссылку (module:attr или командную строку), поэтому код не переносится при продвижении. Он работает только там, где включено commands.allow_host_code.

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

Что даёт модель

  • Логика живёт в модели, а не в канале. Каждый канал (SQL, GraphQL, REST, Arrow Flight, MCP и остальные) читает одни и те же правила, поэтому один и тот же вопрос везде получает один и тот же ответ.
  • Каждое правило зарегистрировано в домене, с правами.
  • Каждое правило управляется одинаково, как бы оно ни было написано.
  • Каждое правило видно в lineage.