Перейти к содержимому
Антон ГончаровРазработчик ИИ-систем

Веб-приложение · Laravel · PostgreSQL

Складской контур на Laravel

Менеджер не должен продать то, что уже лежит в чужом резерве, а кладовщик — искать товар по всему складу. Здесь 12 позиций по ячейкам и 6 заказов в разных статусах: заказ резервируется целиком или никак, лист подбора отсортирован по ячейкам, закупки видят, что опустилось ниже минимума, инвентаризация проводит излишки и недостачи. На странице «Контроль» два процесса одновременно резервируют последний ремень — с SELECT … FOR UPDATE и без, — а сверка находит витрину, которую «починили» UPDATE в обход журнала.

Сценарий: Склад комплектующих «Ячейка» — вымышленный.

Скриншот демо: Складской контур на Laravel

Открыть демо

Настоящий Laravel и PostgreSQL на сервере сайта (схема sklad). Склад общий для всех посетителей; «Сбросить демо» возвращает стартовые остатки.

Приложение работает в браузере: на сервер ничего не отправляется.

Что показывает демо

  • Обзор с KPI и задачами роли: продажам — резерв, кладовщику — сборка, закупкам — что заказать

  • Остатки по ячейкам: на полке, резерв, свободно и полоса запаса до минимума

  • Карточка товара с движением: каждая проводка и остаток после неё

  • Заказы: резерв «всё или ничего» с перечнем нехватки, лист подбора, отгрузка, отмена и возврат

  • Приёмка документом в одной транзакции и импорт CSV с построчным отчётом об ошибках

  • Инвентаризация: факт против учёта, разница уходит в излишек или списание

  • Журнал с фильтрами и выгрузкой CSV для Excel

  • Гонка двух процессов PHP с блокировкой строки и без, сверка и пересчёт витрины из журнала

Как попробовать

  1. Зарезервируйте заказ

    Откройте ЗАК-1006: датчиков не хватает — резерв не пройдёт ни по одной строке, а в ответе будет, чего и сколько.

  2. Станьте кладовщиком

    Соберите ЗАК-1002 по листу подбора и отгрузите — остаток уменьшится, в журнале появятся проводки.

  3. Запустите гонку

    На «Контроле» — сначала с блокировкой: второй процесс ждёт и получает отказ. Без неё оба продают одно и то же.

  4. Сломайте и сверьте

    «Сломать витрину», затем «Сверить» — расхождение найдено; «Пересчитать из журнала» его исправит.

Без платных нейросетей

Склад общий на всех посетителей, роли переключаются в шапке без логина (права всё равно проверяет сервер). Гонка без блокировки работает на отдельном демо-счётчике, а резерв гонки с блокировкой снимается сразу — настоящие остатки не меняются. Импорт идёт через очередь sync, без Redis. В рабочем проекте — песочницы или тенанты, Horizon и обмен с учётной системой.

Демо работает без API-ключей OpenAI, YandexGPT или GigaChat. Там, где рабочая система обращается к модели, стоит локальная заглушка с тем же интерфейсом — поэтому демо бесплатно, всегда доступно и ничего не выдумывает.

Что будет в рабочем проекте

  • Вход и роли из SSO, отдельный склад на компанию
  • Horizon: импорт и ночная сверка по расписанию с оповещением
  • Обмен с МойСклад / 1С и резерв из сделки CRM
  • Сканер штрихкодов на сборке и приёмке

Стек

  • Все демо по стеку:
  • PHP
  • Laravel 12
  • PHP 8.4
  • PostgreSQL
  • Eloquent
  • Blade
  • PHPUnit

Основано на

Книги и дисциплины, идеи из которых работают в этом демо.

  • Книга · Роберт Мартин

    Идеальный программист

    Складской учёт покрыт тестами PHPUnit: менять код можно, не боясь сломать остатки.

  • Книга · Харви Дейтел, Пол Дейтел, Дэвид Чофнес

    Операционные системы. Основы и принципы

    Гонка двух настоящих процессов PHP за один остаток в PostgreSQL — с блокировкой строки и без: видно, зачем общему ресурсу взаимоисключение.

  • Книга · Брюс Ли

    Путь совершенства

    Стек выбираю под задачу, а не по привычке: складской учёт — на Laravel и PostgreSQL, боты — на Python, магазины — на WordPress.

  • Дисциплина · ВМК МГУ

    Базы данных

    Приёмка документом в одной транзакции, резерв «всё или ничего» и блокировка строки против гонки остатков.

  • Дисциплина · ВМК МГУ

    Операционные системы

    Гонка двух процессов PHP за общий ресурс и блокировка, которая её предотвращает.

Комментарий от разработчика

Антон Гончаров

Разработчик ИИ-систем · Python

Для бизнеса

  • Один и тот же товар не продадут дважды: резерв держит его под заказ, а два одновременных запроса не проскочат.
  • Заказ резервируется целиком или никак — не бывает «половины заказа», зависшей в резерве.
  • Кладовщик идёт по листу подбора по ячейкам, закупки видят, что пора заказать, — каждому свой экран задач.
  • Сверка ловит ручные правки в обход учёта, а пересчёт из журнала их исправляет.

Для разработчиков

  • Мутации остатка только через StockService: строки баланса блокируются lockForUpdate в порядке product_id, поэтому два заказа не ловят дедлок.
  • Гонка — два процесса artisan sklad:race-worker через proc_open с общим моментом старта; в тестах на SQLite стороны идут по очереди.
  • Laravel 12, схема sklad в PostgreSQL, Blade без сборки фронтенда; PHPUnit на заказы, импорт, сверку, роли и гонку.

Советы

  • Совет 01

    Не декрементируйте qty в контроллере: один доменный сервис, журнал проводок и блокировка строки.

  • Совет 02

    Многострочные документы — в одной транзакции и с блокировкой в одном порядке, иначе дедлоки под нагрузкой.

  • Совет 03

    Сверку делайте отчётом, который можно запустить вручную и по расписанию.

Нужен такой же для вашего бизнеса?

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

Другие демо в этом разделе

Все демо
  • Веб-приложение · OCR · проверка реквизитов

    работает

    Распознавание документов

    Загрузите счёт или акт — фото, скан или PDF. Приложение распознаёт текст, вытаскивает реквизиты и строки таблицы и проверяет их: контрольные суммы ИНН и счетов, итог и НДС.

    • React
    • TypeScript
    • Нейросеть в браузере
  • Веб-приложение · диалоги · сделки · аналитика

    работает

    Панель оператора

    Рабочее место оператора, которому бот передаёт сложные обращения: очередь с таймером, резюме диалога, черновик ответа, сделки на канбане и аналитика — на живом потоке клиентов.

    • React
    • TypeScript
  • Веб-приложение · Recharts · RBAC · аудит

    работает

    SaaS-дашборд

    Кабинет команды выручки SaaS: MRR по тарифам, движение выручки, отток, здоровье клиентов, выгрузка CSV для Excel и журнал действий. Все цифры считаются из одной истории за год — смена тарифа в карточке клиента сразу двигает MRR на графиках.

    • React
    • TypeScript
  • Веб-приложение · метрики · оповещения

    работает

    Мониторинг бота

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

    • React
    • TypeScript
  • Парсер на Python · работает в браузере

    работает

    Мониторинг цен конкурентов

    Парсер на Python каждый день обходит сайты трёх конкурентов магазина электроники: HTML-каталог с пагинацией, sitemap с JSON-LD и SPA с API. Сопоставляет товары с каталогом, присылает уведомления об изменениях, рекомендует цену по правилам и выгружает отчёт в Excel. Python работает прямо в браузере.

    • Python
    • React
    • TypeScript
  • Веб-приложение · PWA · нативный JS

    работает

    Офлайн-приложение курьера

    Рабочий день курьера: заказы, звонок клиенту, вручение с фото и подписью. Приложение открывается и работает без сети, а изменения уходят в диспетчерскую, когда связь вернётся. Если диспетчер за это время изменил тот же заказ — курьер выбирает, чья версия верная.

    • Нативный JS