Кейс крупным планом · ИЮН — АВГ 2026
Ротон интернет-магазин медтехники
+12%
поискового трафика через три месяца после переезда
20 ч
в месяц освободил менеджеру обмен с 1С — оценка заказчика
- Проблема
- Сайт взломали, страница грузилась 4 секунды, а товары на сайте менеджер обновлял вручную.
- Решение
- Перенёс магазин на чистую сборку, настроил обмен с 1С и заказ через чат.
- Результат
- Страница грузится за 1,1 секунды вместо 4,1 — по шкале Google было «плохо», стало «хорошо». 1 100 товаров обновляются из 1С сами, заказы приходят через чат, позиции в поиске вернулись за три недели.
Сайт снова чистый и открывается за секунду
Старый сайт на Bitrix был взломан — 435 вредоносных файлов — и грузился по 4 секунды. Перенёс магазин на чистую сборку без заражённого кода: страница открывается за 1,1 секунды, все метрики скорости Google в зелёной зоне. Медленная страница теряет покупателей раньше, чем они увидят товар.
Как это сделаносвернуть
Перевёл интернет-магазин медицинских товаров со взломанного сайта на Bitrix в чистую сборку на Next.js и WordPress/WooCommerce. Время загрузки страниц (LCP) сократилось с 4,1 до 1,1 секунды.
WordPress с WooCommerce остались закрытой админкой, публичная часть работает на Next.js: списковые страницы собираются заранее, карточки по запросу и живут в кэше готовых ответов, который обмен сбрасывает точечно вебхуком, только по тронутым товарам. Раздача с собственного сервера за Caddy с автоматическим TLS, кэш объектов WordPress в Redis. Все метрики Core Web Vitals в зелёной зоне, сервер отдаёт карточку товара за 0,3 секунды.
Старый сайт был скомпрометирован: 435 вредоносных файлов, включая веб-шеллы в папках со случайными именами. Данные вытащил в чистую сборку, заражённый код не переносил. Плюс вход по SSH только по ключу, fail2ban, автоматический HTTPS.
— открыть крупно
Товары из 1С обновляются на сайте сами
Раньше товары на сайте менеджер обновлял вручную. Теперь каждую ночь по будням 1 100 товаров с остатками и фото приходят из 1С сами, а размеры и цвета собираются в одну карточку. 96% товаров публикуются без участия человека. По оценке заказчика, это освободило менеджеру 20 часов в месяц.
Как это сделаносвернуть
Настроил автоматический обмен с 1С и написал на Python парсер характеристик: около 1 100 товаров с остатками и фото обновляются на сайте сами. По оценке заказчика, это освободило менеджеру 20 часов в месяц.
Обмен идёт по CommerceML каждую ночь по будням: товары, категории, размеры, цвета, остатки и изображения, около 1 100 позиций и 2 300 торговых предложений за четверть часа. Сайт и 1С расходятся не дольше чем до следующего обмена. Плагин обмена чинил под PHP 8: 11 правок накладываются скриптом при старте контейнера, поэтому переустановка плагина их не теряет.
Парсер разбирает справочник размеров. В поле «Размер» у заказчика склеено до пяти сущностей: размер, сторона, обхват в сантиметрах, класс компрессии и длина изделия, плюс путаница кириллицы и латиницы. Из 233 уникальных значений разобраны 227, это 97%, а по частоте употребления 99,7% товаров; шесть нестандартных ушли на ручной разбор. Правила закрыты 47 модульными тестами, написанными до кода. На витрине разбор не выполняется: там поиск по готовой таблице, а неизвестное значение уводит товар в карантин до решения человека. Сейчас в карантине 40 позиций из 1 070, то есть 96% публикуются без ручного вмешательства. Размеры и цвета стали выбором внутри карточки, 2 300 предложений свернулись в 940 карточек.
— открыть крупно
Поисковый трафик пережил переезд и вырос
При смене движка магазин рискует позициями в поиске: старые ссылки начинают вести в пустоту. Все 1 192 старых адреса ведут на нужные страницы, позиции просели не больше чем на 5% и за три недели вернулись, а к концу третьего месяца поисковый трафик вырос на 12%.
Как это сделаносвернуть
Сохранил поисковый трафик при смене движка: все старые адреса ведут на нужные страницы, а позиции в поиске вернулись к прежним за три недели.
Товар связан с позицией 1С по её идентификатору, поэтому повторная выгрузка обновляет ту же страницу, а адрес переживает и переименование товара в 1С, и смену движка. Собрал инвентарь из 1 192 адресов старого сайта и закрыл их 33 правилами переадресации, каждое ведёт на осмысленную живую страницу. Плюс структурированные данные, карта сайта, человекопонятные адреса с транслитерацией. Позиции просели не больше чем на 5% в первые две недели, органика к концу третьего месяца выросла на 12%.
Покупатель находит товар и заказывает в чате
Поиск с фильтрами по бренду, размеру и типу изделия отвечает сразу и не предлагает вариантов, по которым ничего не найдётся. Заказ — без формы и регистрации, в чате на сайте; менеджер отвечает из Telegram. Раньше кнопка уводила в мессенджер, и покупатель терялся, теперь конверсия чата — 4,2%. Когда связь с Telegram однажды оборвалась, переписку восстановил целиком: ни одно обращение не потерялось.
Как это сделаносвернуть
Сделал поиск с фильтрами и заказ через чат на сайте: сообщение уходит менеджерам в Telegram, ответ возвращается посетителю в тот же чат.
Поиск на Meilisearch: мгновенная выдача и фильтры по бренду, размеру, разделу и типу изделия на каталоге из тысячи позиций. Значения фильтров и счётчики считает сам поиск, поэтому в списке не бывает пунктов, которые ничего не находят.
Заказ без формы и регистрации: раньше кнопка уводила в мессенджер и посетитель терялся. Конверсия чата 4,2%. Позже мост молча умер, сервер потерял доступ к Telegram, и менеджеры неделями не видели обращений. Нашёл, поднял собственный релей на Cloudflare Workers и восстановил переписку целиком, ни одно обращение не потерялось.
— открыть крупно
— открыть крупно
Сбои видно сразу, а проект не привязан ко мне
Три сторожа следят за обменом с 1С и сообщают о сбое в Telegram и на почту, так что устаревшие остатки не висят на сайте незамеченными. Каждую ночь шифрованная копия базы уходит в облако, и восстановление из неё проверено: последний прогон поднял все 60 таблиц. Документация, автотесты и выкладка одной командой — проект может вести другой разработчик.
Как это сделаносвернуть
Настроил мониторинг обмена и резервное копирование с проверкой восстановления. Подготовил проект к передаче другому разработчику: документация, автотесты, выкладка одной командой.
Три независимых сторожа: ночной наблюдатель ведёт окно выгрузки и присылает разницу каталога, утренняя проверка ловит протухшие данные, третий поднимает наблюдение по факту обращений 1С, чтобы выгрузка вне расписания не прошла молча. Критерий успеха — метка, которую обмен ставит каждому разобранному товару: она не зависит от того, что обмен ответил, а по стандарту он отвечает «200 OK» и на ошибку. Канал доставки задублирован, Telegram через собственный релей плюс почта.
Ночные шифрованные копии уезжают в облако кусками в четыре потока, это обход лимита провайдера в 16 КБ/с на соединение, из-за которого целиком они не доезжали. Отдельный режим проверки скачивает копию, расшифровывает и поднимает дамп, последний прогон восстановил все 60 таблиц.
Отказы разбирал до причины. Импорт из 1С падал на очистке кэша: сторонний плагин звал сброс каждую тысячу элементов XML, при внешнем кэше это стирание всей базы Redis, 20 290 раз за месяц. Однажды очистка не уложилась в таймаут и откатила всю выгрузку. Заменил на очистку памяти процесса, перенёс полный сброс в конец обмена, сделал сбой кэша неопасным для страницы. Другой случай: ночной отчёт показал минус 73 позиции в наличии, заказчик уже собирался сверять склад, но замер сняли посреди фонового пересчёта. Исправил признак завершённости работы и сам сказал заказчику, что тревога была ложной.
Воспроизводимая среда в Docker, выкладка одной командой с автоматическим откатом при неудачной сборке, 6 700 строк документации по развёртыванию, восстановлению и эксплуатации, 16 скриптов эксплуатации, 16 инструментов проверки каталога, 106 автотестов витрины. Отдельный файл разобранных ошибок на 157 записей: что сломалось, почему и какой признак это ловит.
Как шла работа
Работал в паре с Claude Code: архитектуру и приёмку держал за собой, рутинный код писал агент, и каждый результат проходил автотесты и ревью. Поэтому весь переезд магазина сделал один человек без команды, и у заказчика был один ответственный от первого разговора до передачи проекта.
Есть похожая задача? Опишите её — предложу, с чего начать.
Написать в Telegram