Large delivery platforms dominate major cities. Smaller towns get nothing. This project was built to fill that gap — a fully custom, multi-vendor delivery platform designed for markets where the big players don’t operate.
The Problem
Local businesses in smaller markets have no infrastructure to offer delivery. No platform, no logistics layer, no way to compete. The goal was to build something production-ready that a local operator could run independently — vendors managing their own stores, couriers handling deliveries, and customers getting a modern ordering experience.
Architecture
Built on Laravel 12 + Vue 3 + Inertia.js with Filament v5 powering both the admin and vendor panels. Real-time features run through Laravel Reverb WebSockets — order status updates, courier notifications, and wallet entries all broadcast through private channels with role-based authorization.
Three separate user roles with distinct interfaces:
- Customer — web app + installable PWA, full ordering flow with real-time status tracking
- Vendor — Filament panel for order management, inventory, store settings, and courier wallet oversight
- Courier — mobile-first PWA with real-time task notifications, Google Maps integration, and a wallet tracking system for cash-on-delivery orders
Key Technical Decisions
Server-side pagination at scale — a single store can have 1000+ products. Client-side filtering caused performance issues. The solution was a hybrid architecture: category-grouped product lists with sequential loading, IntersectionObserver-based prefetching at 1200px rootMargin, and skeleton states to prevent layout flash.
Normalized multilingual search — product names contain characters from two languages with diacritics that break standard LIKE queries. A NormalizeSearch helper class handles transliteration, with two pre-computed search columns per product, populated automatically via Eloquent model hooks. The same normalization runs on CSV import and the ERP sync API.
ERP stock sync — a Sanctum-authenticated POST /api/stock/sync endpoint handles batch upserts from an external ERP system. Up to 1000 items per request, decimal quantity support (decimal(8,3)), automatic category creation, and saveQuietly() to suppress model events during bulk operations.
Courier wallet system — cash-on-delivery creates a reconciliation problem. Couriers collect money from customers and return it to vendors. A courier_wallet_entries table with ULID primary keys and idempotency guards tracks every transaction. Vendors confirm receipt through a checkbox UI with real-time totals; couriers see their open and settled entries grouped by store.
Decimal quantities throughout the stack — the ERP sends decimal stock values. Every layer handles this consistently: database columns, API validation, cart state (Pinia), and the UI stepper which shows integer controls for countable items and 0.1/1.0 step buttons for units like kg, L, ml.
Scale
4 user roles · 3 Filament panels · bilingual UI · PWA for courier and customer · REST API with Sanctum auth · WebSocket channels across order, store, courier, and wallet domains · 120+ automated tests
Status
The platform is currently in the final stages of development. Client-side integrations and content are still being finalized, which is why there’s no live link or screenshots available yet.