Производство · Внутренняя система
Naryado
Мебельное производство: заявка, план цеха и отгрузка идут одним номером. Пять систем, которые уже стояли, обмениваются данными через общий контур, а не через таблицы.
- Роль
- Аналитика, бэкенд, интеграции
- Срок
- 8 месяцев
- Стек
- Python · PostgreSQL · Redis
Что изменилось
- 20 минут
- от подтверждения заявки до строки в плане цеха. Раньше заявка попадала туда на следующее утро.
- 9 → 0
- точек, где одни и те же данные набирали руками во вторую систему.
- 0,4%
- расхождение остатков на месячной инвентаризации. До перехода было от 4 до 6%.
- 1,5 дня
- в неделю, которые уходили у двух человек на сверку перед отчётом руководству. Отчёт теперь собирается сам, из журнала.
Что не изменилось — срок производства. Он зависит от загрузки цеха и поставки плиты, а не от учёта. Контур сделал срок предсказуемым: дату отгрузки называют в день приёма заявки, и она держится. Коротким срок не стал.
Что было до
Заявку подтверждал менеджер в CRM, в таблицу «План цеха» переносил её руками он же, остатки плиты и кромки проверял склад в своей программе, документы выписывала бухгалтерия, рейс бронировал логист на портале перевозчика. Между «клиент подтвердил» и «строка в плане» проходила смена, а срочное шло по телефону мимо всех таблиц и попадало в них задним числом.
- У одной заявки было четыре номера: в CRM, в таблице цеха, в накладной и в рейсовом листе. Чтобы сказать клиенту, где его заказ, менеджер звонил в три места.
- Двенадцать таблиц в шести отделах и девять точек, где одни и те же данные набирали во второй раз.
- Раз в неделю два человека полтора дня сводили цифры к отчёту для руководства и каждый раз находили расхождения — чаще всего в остатках.
Что сделали
Единый номер заявки: приём, план цеха и отгрузка стали одной записью с историей изменений вместо четырёх строк в четырёх местах.
Пять интеграций: бухгалтерия, склад, CRM, система раскроя и портал перевозчика обмениваются через очередь, каждая своим протоколом.
Отчётность из тех же данных: недельный отчёт руководству и утренний список расхождений собираются из журнала событий, без сверки руками.
Результат
Пять систем остались на местах, но заявка больше не переезжает между ними руками: она проходит от приёма до отгрузки одним номером, а обмен делает контур. Статус заказа виден менеджеру без звонка в цех, недельный отчёт собирается из журнала, а спор о том, чьи цифры правильные, кончился вместе с двенадцатью таблицами.
Кто заказчик
Контрактное мебельное производство: делает корпусную мебель по чертежам заказчиков — для торговых сетей, застройщиков и салонов. Два цеха, около двухсот человек, до семидесяти заявок в день, перед осенним сезоном — до ста двадцати.
Заявка — это не одно изделие, а комплект: раскрой плиты, кромка, присадка, фурнитура, упаковка. В день с площадки уходит около сорока пяти отгрузок, часть из них собрана из нескольких заявок. Справочник — сорок тысяч позиций, от декоров ЛДСП до крепежа.
Задача
- Как ставил заказчик
- «Хотим одну систему вместо таблиц»: заменить учёт в Excel и, по возможности, всё остальное — чтобы данные лежали в одном месте и менеджеры перестали вести свои файлы.
- Как задача выглядела после разбора
- Заменить пять систем было нельзя: бухгалтерию ведёт внешний подрядчик, складская программа коробочная, раскрой считается в конструкторской системе. Да и время терялось не на вводе — ввод занимал минуты. Оно терялось на ожидании: план цеха жил отдельно от заявки, и статус нельзя было узнать, не позвонив. Поэтому задачу переформулировали: не единая система, а единый номер и единый статус поверх пяти живых систем.
Почему нельзя было в лоб
Пять систем уже стояли, работали и принадлежали разным людям. Каждая поставила своё условие, и каждое из этих условий видно в архитектуре.
- Бухгалтерия (1С)
- На поддержке внешнего подрядчика, релизы раз в квартал. Доработок мы не заказывали: читаем через OData, пишем ровно один документ — реализацию по факту отгрузки.
- Складская программа
- Коробочная, без API. Единственный выход наружу — выгрузка CSV в общую папку раз в пятнадцать минут. Значит, остаток в контуре в худшем случае на четверть часа старше правды, и это нужно было не спрятать, а показать.
- Система раскроя
- Считает карты раскроя и нормы времени, трогать её никто не дал. Читаем реплику её базы, обратно не пишем ничего.
- CRM отдела продаж
- Отдаёт вебхуки, но позволяет править подтверждённую заявку задним числом: комплектация меняется после того, как клиент уже сказал «да». Контур обязан принимать изменение, а не считать заявку замороженной.
- Портал перевозчика
- SOAP, один запрос в секунду, ночные окна обслуживания. Ходить туда синхронно нельзя: рейс бронируется не в тот момент, когда логист нажал кнопку.
- Справочник номенклатуры
- Одна и та же плита называлась по-разному в трёх системах: артикул поставщика в закупке, внутренний код на складе, наименование в бухгалтерии. Пока их не сопоставили, любой сводный отчёт был спором о том, чьи цифры правильные.
Как шла работа
- 01
Разбор
1 месяцДвадцать три интервью, от менеджера до кладовщика, и путь заявки, нарисованный на стене. Там и посчитали двенадцать таблиц, девять точек двойного ввода и четыре номера у одной заявки. Итог этапа — не техзадание, а решение не заменять пять систем.
- 02
Ядро учёта
1,5 месяцаМодель заявки, плана и отгрузки, единый номер, таблица соответствий с внешними идентификаторами, журнал событий. Только PostgreSQL, без интеграций: контур сначала научился жить сам, на данных, введённых руками.
- 03
Интеграции
2 месяцаПять подключений и сопоставление номенклатуры. По артикулу автоматически сошлись 86% позиций; оставшиеся 5 600 три недели разбирали два человека со стороны заказчика — по правилу и списку исключений.
- 04
План цеха и отгрузка
1,5 месяцаОчередь по участкам, комплектность заявки, отгрузка, собранная из нескольких заявок, бронь рейса. Здесь же появились статусы, которые видит менеджер, — то, ради чего всё и затевалось.
- 05
Параллельная работа и переход
2 месяцаШесть недель контур и таблицы вели одно и то же одновременно, расхождения разбирали каждое утро. Таблицы выключали по одной; последними ушли цеховая и логистическая.
Технические решения
Три вещи в стеке, и у каждой здесь одна работа: Python разговаривает с чужими системами, PostgreSQL хранит данные и отвечает за их согласованность, Redis держит обмен асинхронным.
Один номер вместо четырёх
Заявка, план и отгрузка — записи одной базы, связанные внешними ключами и меняющиеся в одной транзакции: отгрузка не может уехать по заявке, которой нет в плане. Идентификаторы пяти систем лежат рядом, в таблице соответствий, — это она позволяет ответить, какой документ в 1С стоит за строкой цеха.
Журнал вместо текущего состояния
Каждое изменение — событие в append-only таблице PostgreSQL: кто, когда, из какой системы и что было до. Партиции по месяцам. Отсюда два ответа, которых раньше не было: почему цифра именно такая и в какой момент она разошлась.
Пять интеграций — пять разных способов
OData у бухгалтерии, вебхуки у CRM, CSV из общей папки у склада, реплика базы у раскроя, SOAP у перевозчика. Python здесь выбран ровно за то, за что его обычно и берут в интеграции: разобрать чужой формат и заговорить на чужом протоколе — библиотечная работа, своим кодом описываются только правила.
Очередь, а не прямые вызовы
Обмен идёт через Redis: у каждой системы свой поток и своя скорость, повтор — с растущим отступом, ключ события живёт двое суток, поэтому повторная доставка не создаёт вторую отгрузку. Там же ограничение частоты для портала перевозчика и для 1С: обе ложатся, если ходить чаще, чем они просили. И там же кэш справочника на сорок тысяч позиций — склад отдаёт его файлом, читать файл на каждый экран бессмысленно.
Расхождения не прячем
Остаток подписан временем последней выгрузки со склада — до пятнадцати минут назад, и это видно. Всё, что не сошлось при обмене, не исправляется молча, а падает в отдельный список: его разбирает планировщик утром. За первые полгода список ни разу не был пуст, и для контура, сшитого из пяти чужих систем, это нормальное состояние, а не поломка.
Что осталось за рамками
Часть работы сознательно не входила в контур, часть отложена до данных, которых пока нет.
Интерфейсы. Их собирал фронтенд-разработчик заказчика поверх нашего API: на нас были модель данных, сервис и пять интеграций.
Планирование загрузки станков. Контур показывает очередь по участкам, но не расставляет её: для этого нужны фактические времена операций хотя бы за год, а они копятся только с запуска.
Отметка операций на рабочих местах. Участок пока отмечает выполнение с планшета мастера, терминалы у станков — следующий этап.
Закупки и снабжение. Остались в бухгалтерии и в почте: втягивать их в контур до того, как он устоится на заявках, никто не хотел.
Сейчас в работе: срок по факту вместо норм — считаем по журналу за первый год — и перенос недельного отчёта в самообслуживание, чтобы за ним не приходили к нам.
Другие проекты
Логистика
Vezira
Транспортная компания со смешанным автопарком: ассистент понимает запрос диспетчера, собирает данные из CRM, TMS и телематики, проверяет ограничения и делает разрешённое.
3 системы
отвечают на один запрос диспетчера
NestJS · PostgreSQL · OpenAI API
Электронная торговля
Onvela
Интернет-магазин косметики: первую линию поддержки держит ИИ-бот. Он не пересказывает FAQ, а находит заказ покупателя, смотрит доставку и платёж и отвечает по данным.
18 секунд
до первого содержательного ответа вместо 27 минут в часы пик
NestJS · PostgreSQL · Qdrant
Контакты
Пришлите описание задачи
Ответ с объёмом работ, сроками и оценкой бюджета придёт в течение 24 часов.
Первый звонок — 30 минут, без обязательств с вашей стороны.