История, которую мы не могли рассказать два года
В АЙТИФОКС мы делаем сложные штуки: финтех, ИИ, высоконагруженные системы. Шесть лет на рынке, больше шестидесяти человек в штате, проекты, которыми гордимся.
Но есть проекты, о которых молчишь не потому, что нечем гордиться — наоборот. Потому что NDA, жёсткий контракт, стратегический заказчик.
Этот кейс два года лежал под замком. Теперь можно рассказать. И это, пожалуй, самая суровая история из тех, что с нами случались.
С чем мы зашли
Заказчик — онлайн-платформа-агрегатор: инвестиционные проекты, консалтинг, драгметаллы, недвижимость. Ключевой актив — реестр, который собирает данные из кучи внешних систем.
Формально нас позвали «на поддержку и развитие». Звучало как плановая работа: поддержка, доработки, развитие.
А по факту — реанимация.
До нас над реестром работали две команды подряд. Обе не справились. И вот нам передают проект с формулировкой «посмотрите, что можно сделать». А через полтора месяца — ключевое отраслевое мероприятие. Продукт обязан работать и презентовать новую аналитику.
Представьте: мы проектируем архитектуру под сотни запросов в секунду, запускаем финтех-интеграции, копаемся в чужом коде без документации. А клиент открывает реестр и видит белый экран на минуту. Или данные непонятно откуда. Или интеграцию, которая молча потеряла заявку.
Это как если бы скорая приехала на вызов, а там уже две бригады до неё пытались помочь — и уехали. Пациент в коме, карта потеряна, а в коридоре толпа ждёт, когда всё заработает.
В каком состоянии мы получили проект
Первые две недели ушли просто на ресёрч. Картина вскрылась жёсткая.
Все роуты были построены по единому «сверхжадному» шаблону на самописном фреймворке. Чтобы показать карточку компании, запрос тянул вообще всё: команду, аккаунты, историю сделок, контракты. Гигантский объём нерелевантных данных. Плюс Elasticsearch был настроен неоптимально и добавлял к загрузке ещё 5+ секунд. Ключевые страницы грузились по 20–60 секунд. Не миллисекунд — секунд.
Интеграции с внешними системами работали фрагментарно. Часть данных не передавалась, заявки терялись. Фоновые задачи вроде отправки экспертных заключений просто не выполнялись. Таймаутов и обработчиков ошибок не было — любой сбой молча вешал задачу без уведомлений.
Инфраструктуры как класса не существовало. Тестового контура нет. Деплой ручной. Sentry не подключён. Логи не собираются. Линтеры и чекеры кода не используются.
Ключевой сотрудник предыдущей команды то «болел», то «ничего не знал». Нам не передали ни знаний об архитектуре, ни логики принятых решений. Единственное, что мы получили — медленный, нестабильный код и критику заказчика в адрес предыдущих разработчиков.
И поверх всего — организационная специфика: B2B-сегмент с высокими регуляторными требованиями, строгая двухнедельная отчётность по шаблонам, протоколы испытаний с тест-кейсами, согласование на уровне высшего руководства. Каждый отчёт могли вернуть на доработку до пяти раз.
Как мы дважды могли провалиться, но не провалились
Первый риск был очевиден. Классический подход «сначала долгий ресёрч, потом разработка» не влезал в полтора месяца до важного интенсива. Сырой продукт на ключевом мероприятии — это был бы конец.
Второй риск — более коварный. Начать латать старый код. Симптомы были как на ладони: медленные запросы, падающие интеграции. Исправить «по верхам» и сдать как «поддержку»? Но мы понимали: проблема не в багах, а в архитектуре. Латание означало бы отсрочку на пару месяцев, после которой всё посыпалось бы снова.
Мы выбрали третий путь: тактическая стабилизация параллельно с ресёрчем, а затем системное переписывание фундамента.
Что сделали
Разбили работу на три этапа.
Этап 1. Тактическая стабилизация и проектно-образовательный интенсив.
Две недели ресёрча параллельно с разработкой. Внедрили кэширование страниц — не архитектурное решение, а временная мера, которая «заморозила» проблему медленной загрузки и дала пользователям приемлемый опыт. Параллельно форсировали новую аналитику для мероприятия. Команда работала с повышенной нагрузкой, но это была разовая история, а не система. Продукт успешно прошёл интенсив.
Этап 2. Пересборка архитектуры (около года)
Править старые запросы было бессмысленно — логика связей слишком глубоко зашита в самописном фреймворке. Мы переписали все критические роуты в новую версию API (v2) с нуля, используя паттерн «сервис-репозиторий». Каждый роут теперь запрашивал только те данные, которые реально нужны фронту. Результат: загрузка сократилась с 20–60 секунд до 200–500 миллисекунд. В 50 и более раз.
Отказались от Elasticsearch для пользовательского поиска. Внедрили полнотекстовый поиск на базе самого PostgreSQL — убрали 5-секундную задержку и упростили архитектуру. Elasticsearch оставили только в админке, где его использование оправдано.
Для нормализации хаоса с внешними сервисами внедрили собственную шину данных на Kafka. Любое взаимодействие — отправка данных, запрос статусов, получение описаний — теперь проходит через контролируемый контур. Шина записывает все сообщения в БД, фиксирует статусы и ошибки. Впервые интеграции стали прозрачными.
Полностью переписали обмен с ключевыми внешними системами: SOAP и REST API, CRM, внешние шины проектов. Настроили полные циклы обмена, валидацию по справочникам, обработку коллизий — например, когда сервер возвращает 500 ошибку, но данные при этом записывает.
Подняли тестовый контур и связали его с тестовыми средами внешних систем. Внедрили Sentry и логирование. Настроили автоматический деплой и alembic для миграций БД.
Отдельная история — отчётность. После многократных доработок мы изучили все нормативные требования заказчика и создали собственные шаблоны, которые утвердили раз и навсегда. Проблема формальных правок исчезла.
Этап 3. От стабильности к интеллектуальному поиску
Когда архитектура перестала быть узким горлышком, перешли к развитию. На основной платформе заказчика требовался поиск, понимающий сложные профессиональные запросы: от стартапов по технологиям до анализа недвижимости по доходности.
Проблема: данные были «шумными» — анкеты заполнялись вручную, содержали дубли, пропуски, разную структуру. Просто подключить нейросеть означало бы получить галлюцинации вместо точных ответов.
Мы написали скрапер, который обошёл сайты компаний и собрал актуальные данные по 98 000 профилей. Выстроили многоуровневую очистку: TF-IDF для удаления дублей, фильтрация технического мусора, унификация структуры. Очищенные данные перевели в векторное представление через YandexGPT PRO и сохранили в ChromaDB. Внедрили поиск на базе RAG — модель ищет ответ не в своей «памяти», а в актуальных данных платформы.
Результат: доля отказов снизилась на 24%, конверсия выросла на 18%. Поиск начал реально понимать пользователя.
Что получилось
Два года назад нам передали проект, который не грузился, не интегрировался и не имел документации. Сегодня:
✅ Загрузка страниц — 200–500 миллисекунд вместо 20–60 секунд. В 50 и более раз быстрее.
✅ Интеграции работают и логируются через шину данных. Ошибки не теряются, статусы отслеживаются.
✅ Отчётность сдаётся по утверждённым шаблонам без доработок.
✅ ИИ-поиск понимает инвестиционные запросы: доля отказов −24%, конверсия +18%.
✅ Заказчик, дважды обжигавшийся на других командах, работает с нами до сих пор.
И главное — мы больше ни от кого не зависим. Ни от чужого самописного фреймворка, ни от потерянной документации, ни от решений, которые закладывались без понимания роста. Мы пересобрали фундамент — и теперь платформа масштабируется.
Проект перестал быть слабым звеном. Теперь это аргумент в переговорах заказчика, а не повод оправдываться.
Что мы вынесли из этой истории
Главное — не относитесь к legacy как к приговору. Две команды до вас провалились? Архитектура заложена с ошибками? Документации нет, а дедлайн вчера? Это не повод опускать руки. Это повод включить голову и действовать системно: сначала стабилизировать, потом пересобрать фундамент, потом развивать.
Принимать чужой код после других команд — это отдельная компетенция. Мы теперь знаем, как это делать.
Иногда надо просто взять и сделать. Выделить команду, защитить её от дёрганий, поставить жёсткий срок — и довести до ума. Даже если проект выглядит безнадёжным.
📎 Ссылка на полный разбор кейса — https://itfox-web.ru/ru/cases/dva-goda-i-60-sekund-zagruzki-stali-200-ms-poteria-dannykh-prozrachnoi?utm_source=yandex_dzen&utm_medium=blog&utm_campaign=content_2026&utm_content=article
Там честно про архитектуру, Kafka, интеграции и ИИ-поиск.
👇 Приходилось вам принимать проекты после других команд? Как справлялись?