Дэшборды, Автоматизация | Олег Брагинский, Максим Мухтаров
Основатель «Школы траблшутеров» Олег Брагинский и ученик Максим Мухтаров рассказывают, как разработать приложение по управлению справочной информацией, использующейся в отчётности многопрофильных отечественных медицинских учреждениях.
Разработку отчётов в BI-системе крупной сети частных клиник тормозило отсутствие необходимых заказчикам атрибутов в исходных приложениях и централизованных связей между одинаковыми сущностями. Предыдущий обход проблемы перестал удовлетворять всех участников процесса.
Использование сопоставлений и группировок внутри кода, загрузка таблиц в хранилище нативным мастером MS SQL Server создавали лишнюю нагрузку на аналитиков при поддержке, а импорт файлов из сетевых директорий python-скриптами не устраивал заказчиков ненаглядностью правок.
Доработка вендорного решения 1С:MDM и уход от двухсторонних интеграций между системами казались отдалённой перспективой: внедрение двух справочников в эксплуатацию заняло больше года, и приоритет отдавали в пользу организации обменов данными высшего класса критичности.
Предстояло придумать приемлемое решение: дешёвое по инфраструктурным ресурсам, знакомое по технологиям, доступное для развития и поддержки аналитиками, достаточно дружелюбное для заказчиков, быстрое к использованию в процессах обновления отчётности.
Выбрали разработать лёгкое веб-приложение на знакомом языке программирования. Получили виртуальную Linux-машину, создали GitLab-репозиторий, настроили CI/CD. Базу данных развернули на сервере хранилища: стала сразу видна запросам, наполняющим витрины отчётов.
Приступили к кодированию по фреймворку Django для веб-сайтов – его административный раздел видели целевым рабочим местом заказчика, хотя впоследствии создавали и статичные страницы для выделенных кейсов. В честь основного функционального элемента проект назвали BI Admin.
Организовывать авторизацию пользователей через Active Directory (AD) для разграничения доступа к внутренним приложениям и таблицам сочли слишком трудозатратным. Остановились на встроенной выдаче технических учётных записей – по одной на подразделение заказчиков.
Коробочный интерфейс обеспечил удобство единичных манипуляций – создание, изменение, удаление записей в таблицах. Библиотека django-import-export воспроизвела привычную заказчикам загрузку файлов, дополнительно подсвечивая предварительный результат операции:
Таблицы для удобства отображения группировали по внутренним приложениям. Структурирование проводили по двум критериям: а) происхождение данных – откуда загружается информация; б) предметная область – для чего предназначены сведения.
Первой категорией по происхождению определили сущности корпоративных приложений для обогащения и сопоставления (core): клиники, специальности, контрагенты. Второй стали локальные таблицы ручного ввода (input) без аналогов в источниках: KPI, коэффициенты, нормативы.
Справочники, требующие автоматического обновления, наполняли из первого слоя хранилища: таблиц-копий исходных систем. Загрузку настраивали органичными для выбранной BI-архитектуры инструментами: хранимыми процедурами, запускаемыми через SQL Agent.
Если компактная и вычищенная от дубликатов сущность принадлежала только одной системе, то аналитические атрибуты предусматривали прямо в таблице. Придерживались нормализационного подхода при проектировании: группировку подтягивали по ключу, а не хранили текстовым полем.
Иначе создавали три таблицы: а) эталонную; б) исходную с оригинальными идентификаторами и искусственными кодами источников, строки в которую грузили друг под друга; в) ассоциативную – для настройки связей между первыми двумя. Категориальные параметры помещали в эталон.
По предназначению выделяли: паспорта клиник, отделений, кабинетов, оборудования для расчёта мощности и загрузки (clinic_passport); промежуточные таблицы для перекладывания в базу данных с управленческой отчётностью (finance); расходы на онлайн-рекламу (digital_marketing).
Постепенно стали пользователями своей же разработкой (support). Собственная техническая поддержка вела справочники серверов и путей к группам AD; аналитики – настроечные таблицы обновлений OLAP-кубов и фильтров для процедур, обновляющих дэшборды, реестры BI-продуктов.
Для регламентации процесса доработки и обеспечения взаимозаменяемости между аналитиками подготовили инструкцию в облачной базе знаний, включавшую необходимые доступы, подробные шаги, соглашения о наименовании, примеры, ссылки на настройку вспомогательных инструментов.
Полный процесс содержал шесть этапов, из которых первый исполняли обязательно, остальные проходили по мере необходимости. Четыре первых стадии относились к разработке веб-приложения, две оставшиеся – к работе в хранилище:
- Модель – описание таблицы в базе.
- Ресурс – настройка импорта и экспорта.
- Форма – дополнение отображения на сайте.
- Интерфейс – регулирование встроенного представления.
- Процедура – наполнение справочника из систем-источников.
- SQL-задание – автоматизация загрузки через постановку в расписание.
Внутри этапа кодировали, тестировали локально, проверяли в продуктивном контуре, отправляли заказчику ссылки на интерфейсы таблицы. Если для выполнения задачи требовалось несколько шагов, то работа с системой контроля версий велась в единой ветке и в одном коммите.
Код структурировали по принципу «таблица в БД» = «файл модели» = «файл ресурса» = «файл формы» = «файл интерфейса» = «процедура» = «шаг в SQL-задании». Python-файлы для приложения распределяли по четырём package-папкам: а) models; б) resources; в) forms; г) admin.
Модели описывали таблицы в базе данных, создававшиеся при миграциях. Указывали ключи, ограничения, типы полей. По необходимости переопределяли метод save(): например, не давали вставить строку в таблицу паспортов, если запись пересекалась по периоду действия с другими.
Классы-ресурсы из библиотеки django-import-export определяли условия импорта и экспорта. Для столбцов-связей добавляли колонки-наименования при выгрузке. В качестве поля для идентификации изменения строки при загрузке выбирали суррогатный или бизнес-ключ.
Папка с формами пополнялась редко: использование обозначало переопределение коробочного поведения административного интерфейса. Случаи сводились к выведению списка значений из ассоциативной исходной таблицы для массовой настройки связей с эталонной.
Сердцем проекта служили файлы с административными представлениями. Настраивали столбцы для отображения, поля «только для чтения», автозаполняемые атрибуты, сортировку по умолчанию, панель фильтров, строку поиска, совместный показ ассоциированных сущностей.
Корпоративные архитекторы призывают уходить от технологических «костылей» и «зоопарков» при внедрении и развитии информационных систем, но, как представители затратных подразделений, забывают о важнейшей цели: бережливом производстве и оптимизации ресурсов.
Недопустимо прикрываться бюрократическими комитетами и бездействовать, заставляя более близкие к клиенту коллективы страдать и раздувать штатные расписания. Прозрачные локальные решения – приемлемые варианты дождаться адаптации ИТ-ландшафта к планируемому виду.