Задача выглядела простой: разделить список сущностей на две категории — обычные и особые. На практике это обернулось путешествием по трём базам данных, пяти сервисам systemd и нескольким тысячам строк чужого кода. К делу периодически подключался кот, который особенно любил появляться рядом с клавиатурой во время запуска миграций.
Архитектура оказалась нетривиальной. Панель управления записывает данные в одну БД, отдельный агрегатор синхронизирует их во вторую, а API работает уже с третьей, где всё заранее подготовлено для быстрого чтения. Чтобы новый признак дошёл от источника данных до пользовательского интерфейса, требовались буквально одна колонка и несколько строк SQL. Самым сложным оказалось не изменение логики, а поиск точки, где её нужно внести.
Заодно удалось навести порядок в именовании сущностей. Вместо случайных наборов символов появились понятные идентификаторы вроде CUSERS-0029. Стало удобнее читать логи, искать записи и работать с системой в целом. Одновременно проверил жизненный цикл объектов: отключение, удаление и каскадную очистку связанных данных. В итоге база осталась без осиротевших записей и зависших ссылок.
Следующим этапом стал интерфейс. Ключевые метрики переехали в заголовки секций, освободив место на экране. Длинные таблицы теперь скрываются и раскрываются по необходимости, а состояние интерфейса сохраняется между обновлениями. Метрики стали отображаться компактнее: лишние знаки после запятой исчезли, а данные читаются заметно быстрее. Дополнительно появилась карточка трафика с разбивкой по группам и отображением остатка лимита.
Параллельно пришлось разбираться с окружениями Python. После обновления системы терминал перестал показывать активное виртуальное окружение. Причина оказалась неожиданной: новая версия Bash изменила работу PROMPT_COMMAND, из-за чего старые механизмы формирования приглашения перестали работать.
Решение оказалось универсальным. Я отключил встроенное изменение промпта через VIRTUAL_ENV_DISABLE_PROMPT=1, написал собственную функцию определения активного окружения и зарегистрировал её в PROMPT_COMMAND. Для известных проектов используется явное сопоставление, а для новых окружений название берётся автоматически из структуры каталогов. Теперь любое новое окружение корректно отображается без дополнительной настройки.
После этого дошла очередь до мониторинга. Один из сервисов каждую минуту собирает статистику и синхронизирует её с рабочими таблицами. Раньше он делал это молча. Я добавил механизм отслеживания изменений: новых записей, отключений и удалений.
Чтобы не выполнять лишние запросы, логика сравнения была встроена в существующий агрегатор. Дополнительная таблица хранит предыдущий снимок состояния, а на каждом запуске выполняется сравнение с текущими данными. При обнаружении изменений формируются уведомления. Первый запуск лишь сохраняет состояние и отправляет короткое сообщение о старте мониторинга, не заваливая канал сотнями событий.
Отдельно автоматизировал работу с фронтендом. Изменения приходилось вносить внутрь JavaScript-шаблонов вручную, постоянно следя за кавычками и экранированием. Чтобы избавиться от рутины, написал скрипт-патч на Python. Он находит нужное место в файле, добавляет новые блоки интерфейса и CSS-правила, создаёт резервную копию и сохраняет результат. Скрипт идемпотентный: если изменения уже внесены, повторный запуск ничего не ломает.
В итоге дашборд стал компактнее и информативнее, мониторинг получил полноценные уведомления, а рутинные правки превратились в один запуск скрипта. И хотя инфраструктура теперь работает заметно аккуратнее, я всё ещё не уверен, что кот не оставил свой след в финальном деплое. Судя по времени некоторых коммитов, такая возможность исключать рано.