Back to Projects

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.

Laravel 10PHPMySQLREST APIMultilingualLaravel Collective
Tri-portal (web, admin, vendor)Dual API surfaceCustom API tokensLaravel 5.6 to 10Localized routes
HumHum EG cover

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)

PHP
public 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.

HumHum EG architecture diagram
High-level diagram of web dashboard, REST API, Laravel layers, and MySQL.

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.