Web app · Laravel · PostgreSQL
Warehouse system on Laravel
A sales manager mustn’t sell what’s already in someone else’s reservation, and a storekeeper shouldn’t search the whole warehouse for an item. Here there are 12 items across bins and 6 orders in different statuses: an order is reserved in full or not at all, the pick list is sorted by bin, purchasing sees what has dropped below the minimum, and stocktaking posts surpluses and shortages. On the “Control” page two processes reserve the last belt at the same time — with SELECT … FOR UPDATE and without — and reconciliation finds a stock view that was “fixed” by an UPDATE bypassing the ledger.
Scenario: Yacheyka components warehouse — fictional.

Open the demo
Real Laravel and PostgreSQL on the site’s server (the sklad schema). The warehouse is shared by all visitors; “Reset demo” restores the starting stock.
The app runs in your browser: nothing is sent to a server.
What the demo shows
How to try it
Reserve an order
Open ЗАК-1006: there aren’t enough sensors — the reservation fails for every line, and the response says what’s missing and how much.
Be the storekeeper
Pick ЗАК-1002 from the pick list and ship it — stock decreases and entries appear in the ledger.
Run the race
On “Control” — first with locking: the second process waits and is refused. Without it, both sell the same item.
Break and reconcile
“Break the stock view”, then “Reconcile” — the discrepancy is found; “Rebuild from ledger” fixes it.
No paid neural networks
The warehouse is shared by all visitors, and roles switch in the header without a login (the server still checks permissions). The race without locking runs on a separate demo counter, and the reservation from the locked race is released immediately — real stock doesn’t change. Import goes through the sync queue, without Redis. In a production project: sandboxes or tenants, Horizon and exchange with the accounting system.
The demo runs without OpenAI, YandexGPT or GigaChat API keys. Wherever a production system calls a model, there’s a local stub with the same interface — so the demo is free, always available and never makes things up.
What a production project adds
- Sign-in and roles from SSO, a separate warehouse per company
- Horizon: scheduled import and nightly reconciliation with alerts
- Exchange with MoySklad / 1C and reservations from a CRM deal
- A barcode scanner for picking and receiving
Stack
- All demos by stack:
- PHP
- Laravel 12
- PHP 8.4
- PostgreSQL
- Eloquent
- Blade
- PHPUnit
Based on
Books and university courses whose ideas are at work in this demo.
Book · Robert C. Martin
The Clean Coder
Warehouse accounting is covered by PHPUnit tests: the code can be changed without fear of breaking stock levels.
Book · Harvey Deitel, Paul Deitel, David Choffnes
Operating Systems
A race between two real PHP processes for the same stock in PostgreSQL — with a row lock and without: you can see why a shared resource needs mutual exclusion.
Book · James Martin
Computer Data-Base Organization
Stock is the sum of postings, and the stock view is rebuilt from the journal: how users see the data is separate from how it is stored.
Book · Alexey Vasiliev
PHP Programming in Examples and Exercises
Warehouse accounting on Laravel 12 and PHP 8.4 with PHPUnit tests.
Book · Bruce Lee
Bruce Lee: Artist of Life
I pick the stack for the task, not out of habit: warehouse accounting on Laravel and PostgreSQL, bots on Python, shops on WordPress.
University course · CMC MSU
Databases
Goods receipt as one transaction, all-or-nothing reservations and a row lock against stock races.
University course · CMC MSU
Operating Systems
A race between two PHP processes for a shared resource and the lock that prevents it.
Developer’s comment
Anton Goncharov
AI systems developer · Python
For business
- The same item won’t be sold twice: the reservation holds it for the order, and two simultaneous requests won’t slip through.
- An order is reserved in full or not at all — there’s never “half an order” stuck in reserve.
- The picker follows the pick list by bin, purchasing sees when it’s time to reorder — everyone gets their own task screen.
- Reconciliation catches manual edits that bypass the books, and recalculating from the journal fixes them.
For developers
- Stock is mutated only through StockService: balance rows are locked with lockForUpdate in product_id order, so two orders don’t deadlock.
- The race is two artisan sklad:race-worker processes via proc_open with a shared start moment; in SQLite tests the sides run one after the other.
- Laravel 12, a sklad schema in PostgreSQL, Blade without a frontend build; PHPUnit for orders, import, reconciliation, roles and the race.
Tips
Tip 01
Don’t decrement qty in a controller: one domain service, a journal of postings and a row lock.
Tip 02
Multi-line documents go in one transaction with locks in a single order, otherwise you get deadlocks under load.
Tip 03
Make reconciliation a report that can be run manually and on a schedule.
Want the same for your business?
Tell me about your task — I’ll tell you what from the demo fits, how long it will take and what I’ll need from you.
Other demos in this section
All demos- live
Web app · OCR · validating company details
Document recognition
Upload an invoice or a certificate of completion — a photo, scan or PDF. The app recognizes the text, extracts company details and table rows and validates them: tax ID and account checksums, the total and VAT.
- React
- TypeScript
- In-browser neural network
- live
Web app · conversations · deals · analytics
Operator panel
The workspace of an operator who receives difficult requests from a bot: a queue with a timer, a conversation summary, a reply draft, deals on a kanban board and analytics — on a live stream of customers.
- React
- TypeScript
- live
Web app · Recharts · RBAC · audit
SaaS dashboard
A SaaS revenue team’s workspace: MRR by plan, revenue movement, churn, customer health, CSV export for Excel and an activity log. All numbers are calculated from a single year of history — changing a plan in a customer card moves MRR on the charts immediately.
- React
- TypeScript
- live
Web app · metrics · alerts
Bot monitoring
How a bot is watched in production: how many requests, how fast it answers, how often it fails or doesn’t know the answer. A request log with a trace of every answer and rules that message the on-call engineer in Telegram when something goes wrong.
- React
- TypeScript
- live
Python scraper · runs in the browser
Competitor price monitoring
A Python scraper crawls the websites of three competitors of an electronics store every day: an HTML catalog with pagination, a sitemap with JSON-LD and an SPA with an API. It matches products with the catalog, sends notifications about changes, recommends a price by rules and exports a report to Excel. Python runs right in the browser.
- Python
- React
- TypeScript
- live
Web app · PWA · vanilla JS
Offline courier app
A courier’s working day: orders, a call to the customer, handover with a photo and signature. The app opens and works without a network, and changes go to dispatch when the connection returns. If the dispatcher changed the same order in the meantime, the courier chooses which version is right.
- Vanilla JS
