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

Открыть демо
Настоящий Laravel и PostgreSQL на сервере сайта (схема sklad). Склад общий для всех посетителей; «Сбросить демо» возвращает стартовые остатки.
Приложение работает в браузере: на сервер ничего не отправляется.
Что показывает демо
Как попробовать
Зарезервируйте заказ
Откройте ЗАК-1006: датчиков не хватает — резерв не пройдёт ни по одной строке, а в ответе будет, чего и сколько.
Станьте кладовщиком
Соберите ЗАК-1002 по листу подбора и отгрузите — остаток уменьшится, в журнале появятся проводки.
Запустите гонку
На «Контроле» — сначала с блокировкой: второй процесс ждёт и получает отказ. Без неё оба продают одно и то же.
Сломайте и сверьте
«Сломать витрину», затем «Сверить» — расхождение найдено; «Пересчитать из журнала» его исправит.
Без платных нейросетей
Склад общий на всех посетителей, роли переключаются в шапке без логина (права всё равно проверяет сервер). Гонка без блокировки работает на отдельном демо-счётчике, а резерв гонки с блокировкой снимается сразу — настоящие остатки не меняются. Импорт идёт через очередь sync, без Redis. В рабочем проекте — песочницы или тенанты, Horizon и обмен с учётной системой.
Демо работает без API-ключей OpenAI, YandexGPT или GigaChat. Там, где рабочая система обращается к модели, стоит локальная заглушка с тем же интерфейсом — поэтому демо бесплатно, всегда доступно и ничего не выдумывает.
Что будет в рабочем проекте
- Вход и роли из SSO, отдельный склад на компанию
- Horizon: импорт и ночная сверка по расписанию с оповещением
- Обмен с МойСклад / 1С и резерв из сделки CRM
- Сканер штрихкодов на сборке и приёмке
Стек
- Все демо по стеку:
- PHP
- Laravel 12
- PHP 8.4
- PostgreSQL
- Eloquent
- Blade
- PHPUnit
Основано на
Книги и дисциплины, идеи из которых работают в этом демо.
Книга · Роберт Мартин
Идеальный программист
Складской учёт покрыт тестами PHPUnit: менять код можно, не боясь сломать остатки.
Книга · Харви Дейтел, Пол Дейтел, Дэвид Чофнес
Операционные системы. Основы и принципы
Гонка двух настоящих процессов PHP за один остаток в PostgreSQL — с блокировкой строки и без: видно, зачем общему ресурсу взаимоисключение.
Книга · Джеймс Мартин
Организация баз данных в вычислительных системах
Остаток — сумма проводок, а витрина остатков пересчитывается из журнала: то, как данные видят пользователи, отделено от того, как они хранятся.
Книга · Алексей Васильев
Программирование на PHP в примерах и задачах
Складской учёт на Laravel 12 и PHP 8.4 с тестами PHPUnit.
Книга · Брюс Ли
Путь совершенства
Стек выбираю под задачу, а не по привычке: складской учёт — на 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
