гора.
Last-mile Delivery Platform

Переезд с чужой платформы

Прежний подрядчик не отдавал проект. Как я забрал данные магазина через его же кабинет и перевёл продажи на новую платформу без дня простоя.

~6 мин чтения · 1270 слов

TL;DR

Переезд Last-mile Delivery Platform — это перенос живого магазина доставки с платформы прежнего подрядчика на мою, сделанный без его участия. Отдавать проект он не хотел: вместе с проектом уходила оплата за поддержку. У магазина был только его кабинет администратора, и через API этого кабинета я раз в час копировал данные в свою базу. Перенос шёл частями, с резервной копией перед каждым шагом. Прежняя платформа приняла последний заказ 24 января 2026 года, а 25-го заказы уже шли в новую. Покупатели переезда не заметили: тот же адрес сайта, те же пароли, та же история заказов.

С чего всё началось

В декабре 2025 года магазин работал на платформе другого разработчика. Сайт, кабинет администратора, база и код были у него, магазин платил за поддержку. Когда магазин решил перейти на собственную платформу, отдавать проект подрядчик не стал: ни выгрузки базы, ни кода. Домен он тоже держал до последнего.

Ситуация знакомая многим. Подрядчик, у которого магазин на поддержке, теряет деньги, если отдаёт проект, и не торопится. А у владельца бизнеса при этом нет ни базы, ни кода, только логин в админку.

Что было в руках

Только кабинет администратора магазина. Он работал через API, и всё, что видел администратор, этот API и отдавал: заказы, покупателей, товары, водителей, промокоды, отчёты. Это данные самого магазина, и забрать их можно было тем же доступом, с которым магазин работал.

Сборщик: свежая копия каждый час

Первым делом я написал сборщик. Раз в час он проходил по API кабинета и складывал всё в собственную базу PostgreSQL. Проход шёл в пять этапов: заказы, деньги, операционные данные, справочники, кошельки. Заказы запрашивались окнами по времени на год назад. В копию попадали заказы с полной историей статусов, покупатели и их кошельки, товары с вариантами, бренды, категории, водители, диспетчеры, промокоды, районы и слоты доставки, всего 30 таблиц. Полный проход занимал около минуты. До переключения сборщик проработал около недели.

Копия, которая обновляется сама, дала две вещи. Данные магазина перестали зависеть от доброй воли подрядчика: закрой он доступ, у магазина осталась бы копия не старше часа. И она оказалась полнее оригинала: 13 заказов, которые прежняя система у себя удалила, в копии остались.

План переноса

Схемы двух систем не совпадали почти ни в чём. В старой ID были числами, в новой UUID. Статусы, способы оплаты и типы доставки назывались по-разному. Части полей товара в новой схеме не было вовсе. Поэтому до переноса я записал план:

  • ID переводятся через таблицу соответствий «старый ID → новый UUID»: связи между записями не рвутся, и любой шаг можно прогнать повторно.
  • Таблицы переносятся от справочников к заказам: магазины, категории, бренды, товары, покупатели, сотрудники, зоны, слоты, промокоды, заказы, кошельки, баннеры. Каждая следующая ссылается только на уже перенесённые.
  • Семь статусов старой системы сводятся к шести новым: «оформлен» становится «ожидает», «готов» и «назначен» — «подтверждён», «принят водителем» — «назначен», «в пути» — «забран», «выполнен» — «доставлен», «отменён» так и остаётся.
  • Покупатели сопоставляются по телефону, приведённому к одному формату, а где телефона нет, по имени.
  • Новая схема получает 20 полей товара, которые были только в старой: 13 у самого товара и 7 у варианта.
  • Каждый шаг совместим с тем, что уже работает, и перед каждым шагом снимается копия новой базы.

Пароли покупателей переехали вместе с ними. Старая система хранила их в виде хэшей bcrypt, тем же алгоритмом, что и новая, поэтому хэши легли как есть. Самих паролей никто не видел, и никому из покупателей не пришлось заново регистрироваться или сбрасывать пароль.

Где пришлось переделать

На пробной загрузке позиции заказов задвоились: каждая легла в новую базу 18 раз. Править их по одной я не стал. Удалил все позиции и перезалил целиком из копии, потому что результат такого шага проще сверить с источником.

Товары сопоставлялись по названию: сошлись 133 товара из 133 и 402 варианта из 427. В старой системе товаров было 139, в новой 133. Разница оказалась тремя дублями и тремя тестовыми товарами, настоящих товаров было поровну.

Переключение без дня простоя

Пока шёл перенос, старая платформа продолжала принимать заказы, а сборщик продолжал снимать копию каждый час. Большой прогон прошёл 22 января, заказы следующих дней доехали в новую базу следом. 24 января старая платформа приняла последний заказ, а 25-го первый заказ пришёл уже в новую. История покупателей, балансы их кошельков и прежние заказы переехали вместе с ними.

Домен пришлось забирать отдельно: подрядчик не отдавал его до последнего. Сайт остался на прежнем адресе, поэтому для покупателя ничего не изменилось: тот же адрес, тот же логин и пароль, та же история заказов и тот же баланс.

Сколько это заняло

  • 4 января 2026 — первый коммит новой платформы.
  • Около недели до переключения — сборщик каждый час снимает копию старой системы.
  • 22 января — большой прогон переноса.
  • 24 января — последний заказ в старой системе.
  • 25 января — первый заказ в новой. От первого коммита прошло три недели.

Что получилось

  • Ни одного дня без заказов: последний заказ в старой системе 24 января, первый в новой 25-го.
  • В новой базе живёт история прежней платформы: 64 доставленных заказа со статусами, покупатели, их кошельки.
  • 13 заказов, удалённых старой системой, сохранены.
  • Покупатели переезда не заметили: адрес сайта, пароли, история заказов и балансы остались прежними.
  • Забрано всё, что было у магазина в старой системе, и домен тоже.
  • Через восемь месяцев на новой платформе магазин доставил 1 035 заказов за сентябрь. Как это было, рассказано в истории проекта.

Если вы в той же ситуации

Что я проверил бы первым:

  1. Что у вас есть прямо сейчас: доступ к админке, к базе, к хостингу, к домену, и что в договоре с подрядчиком сказано о данных и передаче проекта. Домен и аккаунты хостинга должны быть записаны на вас, а не на подрядчика: в этом проекте домен пришлось забирать отдельно.
  2. Начните с копии. Регулярная выгрузка всего, что отдаёт ваш кабинет, в базу, которая принадлежит вам, — это страховка ещё до решения о переезде.
  3. Сверьте копию с оригиналом по числу заказов и покупателей. Если что-то пропадает у подрядчика, у вас оно уже сохранено.
  4. До переноса запишите таблицу соответствий ID и статусов, порядок таблиц и правило «копия базы перед каждым шагом».
  5. Переключайтесь, когда новая система уже приняла перенесённые данные, а сборщик ещё работает: заказы последних дней доедут следом.

Вопросы, которые задают чаще всего

Можно ли забрать данные, если подрядчик не отдаёт базу?

Часто да. Если у вас есть рабочий доступ к своему кабинету администратора, всё, что кабинет показывает, отдаёт и его API. Сборщик по этому API копирует данные в базу, которая принадлежит вам. Начинать стоит с договора: что в нём сказано о данных и о передаче проекта.

Что будет с заказами во время переезда?

Ничего страшного. Старая система работает до последнего дня, сборщик копирует её каждый час, и заказы последних дней доезжают в новую базу следом. Переключение происходит, когда всё уже на месте. В этом проекте не было ни одного дня без заказов.

Придётся ли покупателям заново регистрироваться?

Нет, если старая система хранила пароли в виде хэшей распространённым алгоритмом. Тогда хэши переносятся как есть, и покупатель входит со своим старым паролем. Здесь так и вышло: старая и новая системы использовали bcrypt, и покупатели переезда не заметили.

Сколько это занимает?

Здесь от первого коммита новой платформы до первого заказа в ней прошло три недели, а сборщик до переключения работал около недели. Срок зависит от того, сколько данных и что отдаёт кабинет. Точнее оценить можно после того, как сборщик снимет первую копию.

Чего этот переезд не делал

  • Код прежней платформы не переносился: новая написана с нуля.
  • Данные забирались только доступом самого магазина, без чужих логинов и без доступа к серверам подрядчика.

Ссылки