Case Study
HumHum EG
Daily-goods and e-commerce style platform from MyWork/Valux/humhum, originally built on Laravel 5.6 and since upgraded to Laravel 10 (PHP 8.1): localized consumer storefront (`{lang}` + `Website` controllers) with cart, payment, orders, favourites, and nested categories; a parallel JSON catalog under `/api` (`Api` controllers, `apiLocale`); mobile account flows on `/api/user` with login or signup then resource routes for orders, cart, and favorites protected by custom `api:apiUser` middleware that validates an `Authorization` header against a `Token` model (Sanctum is in composer but this path uses the bespoke token table); staff dashboard at `{lang}/dashboard` with `admin:admin` middleware; separate vendor portal at `{lang}/store` with `vendor:vendor` for store prices, orders, and product images. Stack includes `laravelcollective/html` and Guzzle.

Impact
Operators, vendors, and end customers could work against one deployment with clear URL boundaries for each role, on a framework version that stays patchable—without discarding years of proven domain logic from the original 5.6 build.
Problem
Grocery-style retail needs three audiences at once: shoppers on web and mobile, internal staff curating catalog and orders, and third-party vendors updating their own inventory—without three divergent codebases or inconsistent pricing.
Solution
`RouteServiceProvider` maps five route files onto one Laravel app: `routes/api.php` for public mobile catalog and auth helpers, `routes/user.php` under prefix `api/user` for authenticated shopper APIs, `routes/web.php` for the Blade storefront, `routes/admin.php` for operations, and `routes/store.php` for vendors. Shared Eloquent models back catalog, carts, and fulfillment while middleware (`locale`, `apiLocale`, `admin`, `vendor`) keeps each surface scoped. The structure reflects a long-lived codebase first written for 5.6, then modernized in place to Laravel 10 rather than rewritten from scratch.
Highlighted implementation
Route map entrypoints (RouteServiceProvider)
PHPpublic function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
$this->mapAdminRoutes();
$this->mapUserRoutes();
$this->mapStoreRoutes();
}
// Each map*Routes() loads routes/api.php, web.php, admin.php,
// user.php under prefix api/user, or store.php respectively.Testing & quality
PHPUnit 10 in the project after the upgrade; manual regression on cart quantity routes, payment resource, vendor login, admin multi-delete paths, and mobile login or token rejection—especially important across the 5.6 to 10 jump where framework defaults changed.
Architecture
API Structure
Public API groups `Route::resource` endpoints for `home`, `banners`, `categories` through `subsubcategories`, `products` plus view and sell variants, `offer`, `stores`, `cites` (cities), `regions`, `complaints`, `contacts`, `suggestions`, and `settings`. User API splits guest posts (login, signup) from a middleware-wrapped block for `orders`, `cart`, and `favorites` resources.
Data Flow
Shopper adds lines in cart (session on web, API cart on mobile) → checkout and payment controllers persist orders → admin and vendor dashboards read the same order and product tables for fulfillment or price updates.
Backend Decisions
Isolated vendor routes under `{lang}/store` instead of overloading admin roles; custom API token middleware keeps mobile headers explicit even though Sanctum is available for future SPA work; throttle and bindings ship with the default `api` middleware group. The classic `RouteServiceProvider::map` layout and string-style route namespaces are legacy-friendly choices carried from the 5.6 era while still valid on Laravel 10.
Challenges
Keeping vendor price edits, admin product changes, and active cart lines coherent across web and mobile; token-based mobile auth must rotate or revoke safely without orphaning in-flight checkouts. Major-version upgrades (5.6 to 10) require wide regression passes because middleware stacks, default configs, and PHP language features all shifted underneath existing controllers.
Technical Decisions
Project began on Laravel 5.6; upgraded to Laravel 10 on PHP 8.1 while retaining familiar patterns where they still fit—classic `RouteServiceProvider::map` registration, Collective HTML for dense admin forms, and the custom `Token` + `Authorization` mobile gate instead of forcing a full Sanctum migration in one step. Soft deletes on `User` remain enabled in the model to avoid hard-deleting purchase history.