Юнифай Консалт, команда экспертов Николая Епифанова Обсудить задачу
☰
← Все материалы

Практика агентстваСтатья

Организация разработки сложной логистической системы с помощью Codex

Мы разрабатываем диспетчерскую систему для сетей водоматов с привозной водой. Она получает телеметрию и данные о продажах, помогает оценить потребность точек в пополнении, строит рейсы водовозов и показывает диспетчеру рабочую картину дня. Система состоит из нескольких связанных модулей, поэтому разработку в Codex мы распределили между семью постоянными тредами. У каждого свой участок работы, а интеграционные проверки связывают их результаты в один продукт.

Короткий ролик · 52 секунды
Иллюстрация из ролика: станция воды, водоматы и рабочее место диспетчера
В ролике мы показали водоматы, водовоз и диспетчерскую как части одной задачи. Это постановочная иллюстрация, а не экран действующей системы.

Несколько независимых контуров работы с данными в одной системе

Водомат продаёт воду из резервуара, который пополняет водовоз. Если приехать слишком рано, машина потратит часть вместимости на точку, где вода ещё есть. Если опоздать, автомат может остаться пустым и потерять продажи. Диспетчеру приходится учитывать состояние многих точек, прогноз спроса, доступность машины и порядок движения по зонам. Карта сама по себе эту задачу не решает.

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

Как данные превращаются в рейс водовоза

  1. Система получает сведения о точках. Внешний сервис передаёт остатки воды, продажи и состояние водоматов. Перед расчётом данные проверяются на свежесть и полноту. Пропавшую или подозрительную запись нельзя молча заменить удобным числом.
  2. Планировщик оценивает потребность к моменту приезда. Полный сейчас резервуар может опустеть к вечеру. Поэтому для каждой точки важен не только текущий остаток, но и прогноз расхода по часам до возможного прибытия водовоза.
  3. Из потребности собирается последовательность рейсов. Расчёт учитывает вместимость машины, зоны, согласованный порядок точек, временные окна и дорожное расстояние. Самый короткий путь на карте не обязательно будет правильным маршрутом для водовозки.
  4. Диспетчер проверяет результат. В интерфейсе он видит точки, предложенные рейсы, исходные данные и состояние выполнения дня. Если ситуация изменилась, человек может пересчитать план и принять решение по актуальной картине, а не править маршрут вслепую в таблице.
  5. Следующие данные помогают сверить план с фактом. Изменение уровня воды после обслуживания позволяет оценивать выполнение рейса. Если данных недостаточно для однозначного вывода, система должна показать неопределённость, а не объявить точку обслуженной автоматически.
Иллюстрация рабочего места диспетчера в логистической системе
Рабочее место диспетчера в визуальной модели ролика. Это иллюстрация сценария, а не скриншот действующего интерфейса.

Из каких модулей состоит продукт

Мы разделяем продуктовые модули и треды разработки. Модуль выполняет функцию в системе, а тред Codex отвечает за проектирование, изменение и проверку определённой части. Один тред может затрагивать несколько модулей, если задача проходит через их границу.

  1. Данные и интеграции. Этот модуль получает телеметрию и продажи из внешнего источника, связывает записи с нужными точками и отмечает проблемы качества данных. Планировщик должен понимать, на каком снимке основан расчёт и можно ли ему доверять.
  2. Прогноз и планирование. Здесь остаток воды пересчитывается на ожидаемое время приезда. Затем алгоритм подбирает точки и строит рейсы с учётом вместимости водовоза, зон, порядка обслуживания и ограничений по времени. Дорожный сервис даёт расстояния и длительность пути, но не подменяет бизнес-правила маршрута.
  3. Диспетчерская. Рабочий экран показывает состояние точек, рассчитанный план, историю его версий и выполнение дня. Диспетчеру важно не только увидеть линию на карте, но и понять, почему точка попала в рейс, какие данные использованы и где требуется его решение.
  4. Правила и проверка изменений. Зоны, порядок точек и другие ограничения задают логику, которую нельзя незаметно менять в коде. Для проверки изменений предусмотрен отдельный «Полигон», где результат можно сравнить с рабочим сценарием до применения новых правил.
  5. Мониторинг и эксплуатация. Регулярное обновление данных, контроль свежести, сигналы о проблемах и восстановление после сбоев нужны для ежедневной работы. Удачный ручной расчёт ещё не означает, что система будет надёжно работать по расписанию.
  6. Доступ и выпуск. Пользователь видит только разрешённую ему часть системы. Новая версия проходит проверки до публикации, чтобы изменение расчёта, интерфейса или интеграции не нарушило уже работающий сценарий.

Как мы распределили работу между семью тредами Codex

Сложный продукт нельзя поручить одному длинному чату и ожидать, что он одновременно удержит все правила маршрута, источники данных, интерфейс и условия выпуска. Мы закрепили направления за постоянными тредами. У каждого есть свой контекст, границы решений и результат, который другие направления могут принять и проверить.

Схема семи тредов Codex: Product HQ связывает планирование, интерфейс, данные, эксплуатацию, доступ и проверку выпуска
Это распределение ответственности в разработке, а не схема подразделений заказчика и не устройство программных модулей.
  1. Product HQ. Связывает продуктовую задачу с работой остальных направлений. Здесь формулируют приоритет, фиксируют решения заказчика, разрешают пересечения между модулями и определяют, какой результат можно считать частью общего продукта.
  2. Data & Integrations. Отвечает за получение телеметрии и продаж, качество входных данных и контракты с внешними источниками. Если меняется формат или свежесть данных, этот тред должен обозначить последствия для расчёта и диспетчерской.
  3. Planner Core. Ведёт прогноз потребности, ограничения маршрутов и расчёт рейсов. Его задача — не просто получить красивую линию на карте, а выдать воспроизводимый план, который соответствует правилам обслуживания точек.
  4. Dispatcher UX. Переводит расчёт в рабочий интерфейс. Тред отвечает за то, как диспетчер видит состояние точек, план, объяснение решений и действия, доступные ему в конкретной ситуации.
  5. Automation & Operations. Собирает ежедневный режим работы системы из расчётов, обновления данных, мониторинга и восстановления. Он проверяет, что процесс продолжает работать после перезапуска и что сбой не остаётся незамеченным.
  6. Hosting & External Access. Отвечает за размещение, авторизацию и доступ с рабочих мест пользователей. Удобный интерфейс бесполезен, если диспетчер не может безопасно открыть его в нужный момент.
  7. QA & Release. Проверяет не только отдельные функции, но и путь через несколько модулей. Этот тред сопоставляет реализацию с требованиями и собирает доказательства того, что конкретное изменение готово к выпуску.

Как одна продуктовая задача проходит через треды

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

Product HQ фиксирует ожидаемое поведение и распределяет работу. Data & Integrations проверяет, какие сведения пришли о новой точке и достаточно ли их для расчёта. Planner Core не допускает точку в маршрут без нужного правила. Dispatcher UX показывает диспетчеру, почему она пока не участвует в плане и что требует внимания. Automation & Operations проверяет, как это состояние проходит через плановые обновления. Hosting & External Access сохраняет права на просмотр и изменение. QA & Release проверяет весь путь на связанном сценарии.

Схема передачи данных между модулями: входные данные, расчёт, интерфейс диспетчера и сквозная проверка
Изменение проходит через данные, расчёт и интерфейс, после чего проверяется как единый сценарий. Расписание, мониторинг и права доступа затрагивают весь путь.

Треды могут работать параллельно, пока их решения не противоречат друг другу. Для этого мы описываем входы и выходы каждого изменения, сохраняем общее решение на уровне продукта и проверяем его после объединения. Если источник данных меняет формат, планировщик должен получить ожидаемые поля. Если расчёт по-новому определяет статус точки, интерфейс должен показать именно это состояние и объяснить его диспетчеру.

Что проверяем и чего пока не обещаем

Локальный тест планировщика отвечает только на вопрос о расчёте. Перед выпуском мы отдельно проверяем, что данные относятся к нужным точкам, маршрут не нарушает правила, диспетчер видит ту же версию плана, доступ ограничен по ролям, а ошибка или нехватка данных не превращаются в ложное «всё готово». Проверка проходит через модули, которыми будет пользоваться человек, а не только через код каждого треда.

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

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

Фотографии в этом материале взяты из постановочного ролика. Они объясняют предметную область и не являются скриншотами интерфейса.

Экономика сети из 60 водоматов

У системы три основных экономических рычага. Прогноз пополнения помогает снижать риск пустого водомата и сохранять продажи. Маршрут с учётом вместимости машины и порядка зон позволяет избегать лишних километров. Диспетчер тратит меньше времени на перенос данных между таблицами, ручную проверку точек и повторное составление плана. История версий и сопоставление плана с фактом помогают понять, где возникло отклонение, вместо спора по памяти.

Около 200 000 ₽ в месяц для сети из 60 водоматов — возможный эффект в условном расчёте, а не измеренная экономия нашего проекта. Для каждого клиента расчёт нужно делать отдельно. В разных регионах различаются расстояния и затраты на рейсы, а результат также зависит от расположения водоматов, спроса, маржи, числа машин и режима работы сети.

Возьмём условную сеть из 60 водоматов, которую обслуживают пять водовозов. Каждый проезжает 160 км за рабочий день, в месяце 25 рабочих дней. Публично подтверждённых данных о фактической экономии этого проекта пока нет. Все цены, объёмы и улучшения ниже — допущения для оценки потенциала, а не показатели AquaLux.

  1. Меньше пробега. Если общий пробег снизится на 10 %, а переменные затраты составят 50 ₽ на километр, расчёт даст 5 × 160 × 25 × 10 % × 50 = 100 000 ₽ в месяц. Это возможное сокращение расходов на движение машин, а не гарантированный результат алгоритма.
  2. Меньше потерянных продаж. Допустим, за месяц удастся предотвратить 20 случаев, когда водомат стоял бы пустым по четыре часа. При условных продажах 50 л в час и валовой марже 15 ₽ на литр это 20 × 4 × 50 × 15 = 60 000 ₽ сохранённой валовой прибыли. Выручка была бы выше этой суммы, но для экономического эффекта важна именно маржа.
  3. Меньше ручной работы. Если диспетчер освободит два часа в день, то при условной стоимости рабочего часа 800 ₽ это ещё 2 × 25 × 800 = 40 000 ₽ в месяц в пересчёте на трудозатраты. Деньги останутся в бюджете только тогда, когда это время заменит оплачиваемые часы или позволит обработать больший объём без нового сотрудника.

В таком модельном сценарии сокращение транспортных расходов и сохранённая валовая прибыль дают 160 000 ₽ в месяц. Ещё 40 000 ₽ — стоимость высвобожденного времени, а не обязательное снижение расходов. Вместе потенциальный эффект составляет около 200 000 ₽ в месяц для сети из 60 водоматов, или около 2,4 млн ₽ за год до расходов на разработку, внедрение и поддержку. Для реальной оценки нужны исходный пробег, стоимость километра, история простоев, маржа и замеры работы диспетчера до и после внедрения. Пока этих измерений нет, цифру нельзя называть экономией заказчика.

Разработаем для вас продукт любой сложности

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

Обсудить задачу