Как мы строили систему для проверки людей и компаний
Первая статья — без громких заявлений
Это моя первая статья на Хабре. Формат нащупываю. Хотелось бы сразу с кейсами и диаграммами, но решил начать с простого — краткий разбор архитектуры нашего сервиса и того, как мы пришли к текущему состоянию.
Сервис — это проверка физических и юридических лиц по открытым источникам. Пользователь вводит ИНН или ФИО и получает отчёт: есть ли долги, исполнительные производства, признаки банкротства, участие в сомнительных организациях и так далее. Отчёт собирается на лету по 10+ источникам.
Система существует давно. Код — не идеален. Архитектура — не микросервисная. Docker и Kubernetes у нас не прижились, зато есть реальный боевой опыт. Ниже — краткий разбор, как оно устроено, какие ошибки мы прошли и как всё это выживает под нагрузкой.
Что делает система
Принимает запросы от пользователей (веб и API);
Проводит серию проверок по разным источникам (ФНС, ФССП, ЕГРЮЛ, РАФП, Федресурс и пр.);
Обрабатывает ответы, собирает сводку;
Генерирует PDF-отчёт, который хранится и может быть повторно использован;
Если часть источников временно недоступна — запускает фоновую дозагрузку.
Почему это сложно (и местами больно)
1. Источники нестабильны
Пример: ФССП может вернуть 500 ошибку, а через 5 секунд — корректный ответ. ФНС иногда меняет структуру XML, не уведомляя. Где-то есть CAPTCHA, где-то падает TLS, а где-то выдача просто пустая без объяснений.
2. Срок годности данных разный
Некоторые данные можно кэшировать неделями (например, регистрационные сведения), другие — буквально часами (например, текущие долги). Это влияет и на отображение отчётов, и на логику их актуализации. Универсальной схемы нет.
3. Пользователи не читают, что "отчёт может быть неполным"
Это не претензия. Это факт. Если мы не обработали один из источников — мы это явно отображаем в отчёте, но всё равно кто-то напишет в поддержку: «Почему у меня нет данных ФССП?».
4. Ошибки случаются постоянно
Даже если всё «работает». Парсеры могут получить неожиданный контент, умирает соединение, возникают таймауты. Мы пишем собственные логи, сохраняем статусы на каждом этапе и ведём учёт отказов.
Текущая архитектура (упрощённо)
Монолит на PHP, фреймворк — не суть. Кодовая база взрослая, с рудиментами. Команда — небольшая, без DevOps-евангелистов.
Компоненты:
Слой парсеров: обрабатывают каждый источник отдельно, с retry, кешированием и fallback.
MySQL: отдельные таблицы для сырых данных, агрегатов и справочников.
Менеджер отчётов: собирает данные по объекту (ИНН, ФИО и т.д.) и формирует PDF-документ. Отчёт может быть частично собран, если часть источников не сработала.
Фоновый планировщик: перезапускает недособранные отчёты, проверяет истёкшие TTL, дозапрашивает.
Клиентская часть: сайт и API. Разные лимиты, разные таймауты, разные UX-ожидания.
Что мы осознали на практике
1. Устойчивость важнее модной архитектуры
Мы не смогли себе позволить microservices + message bus + orchestration, но добились стабильности за счёт простоты и контроля: каждый парсер — чёткий контракт, ошибки — логируются, отчёты — предсказуемы.
2. Пользователь ценит объяснение, а не скорость
Если отчёт собирается дольше, но с пояснениями (что именно не сработало, когда обновится), жалоб меньше. UX важнее рендеринга.
3. Автоматизация фейлов — ключ
Раньше всё падало и писали в поддержку. Теперь:
если источник не сработал → фоновый дозапрос,
если отчёт частичный → отображаем это явно,
если всё плохо → даём возможность пересобрать.
4. Хранить старые отчёты — необходимость
Юзеры возвращаются к проверкам через месяцы. А в правовой сфере важен «срез на дату». Поэтому мы храним не просто последнюю версию, а всю историю.
Что мы пока не решили
Переход с внешнего защитного решения на собственную инфраструктуру (чтобы убрать лишние зависимости, увеличить скорость и улучшить контроль);
Упрощение интерфейса: сейчас данных слишком много, и рядовому пользователю сложно понять, как с ними работать;
Автоматизация поддержки: значительная часть запросов могла бы обрабатываться без участия человека, но пока это ручная работа.
Дальше будет
Планирую писать:
про наши кейсы из техподдержки (20k тикетов в месяц, 80% — не баги);
методологию сбора данных, ошибки, которые казались неочевидными;
аналитику поведения пользователей (и что мы узнали про принятие решений);
немного про организацию и продукт в условиях ограничений (без HR и продуктолога, но с результатом).
P.S. мини-блок
Когда готовился к статье, параллельно читал статьи других авторов на Хабре — по архитектуре, парсингу, работе с госданными и построению отчётных систем. Некоторые идеи показались полезными, другие — спорными. В одном из следующих постов хочу собрать и сравнить разные подходы: что применимо в реальной работе, а что не выдерживает продакшн-нагрузки.
Если есть хорошие статьи на эту тему — скидывайте ссылки в комментарии. Я прочту и постараюсь включить в обзор.