Case Study
NUMO.SA
Large Laravel 9 learning-commerce monolith for NUMO: separate route modules for the public NUMO site, branch-scoped storefronts (`/b/{branch}` with branch middleware), the teacher or learner platform area, and a heavy Livewire-powered Board back-office—plus a Sanctum-backed API v1, Breeze auth, Spatie Permission and Translatable, cart and checkout (Moyasar, Tabby), Zoom and Vimeo, Maatwebsite Excel, Horizon on Redis, S3 via Flysystem, and Vapor-oriented deployment packages.

Impact
A single deployable product that spans marketing, branch commerce, learning platform features, and operations tooling—easier to reason about than four separate repos for the same business.
Problem
A national training brand needs more than a brochure site: course discovery, branch-specific offers, carts and installments, teacher workflows (projects, discussions, attendance exports), certificate verification, and operations dashboards—all without fragmenting into unrelated apps that drift out of sync.
Solution
One Laravel application registers multiple web route groups (`numo.php`, `branch.php`, `platform.php`, `board.php`) from `RouteServiceProvider`, each backed by dozens of Livewire components for catalog, checkout, teacher tools, and board administration. Payments integrate with Moyasar and Tabby; media and documents lean on S3; long work runs through Horizon and Redis; APIs expose branches, courses, payments, and user forms for integrated clients.
Highlighted implementation
Route modules (from RouteServiceProvider)
PHP$this->routes(function () {
Route::middleware('api')->prefix('api')->group(base_path('routes/api.php'));
Route::middleware('web')->group(base_path('routes/web.php'));
Route::middleware('web')->group(base_path('routes/board.php'));
Route::middleware('web')->group(base_path('routes/platform.php'));
Route::middleware('web')->group(base_path('routes/numo.php'));
Route::middleware('web')->group(base_path('routes/branch.php'));
});Testing & quality
PHPUnit in the repo for automated checks; manual regression on checkout (card + Tabby), branch switching, and critical Board lists after Laravel or Livewire upgrades. Inspector APM can trace slow queries in production when enabled.
Architecture
API Structure
`routes/api.php` exposes versioned JSON under `/api/v1` (branches, courses, payments, user forms) alongside resource-style endpoints for American Board and shipping-certificate payments. The main UX remains session-based web plus Livewire; Sanctum secures token access where needed.
Data Flow
Learner or staff request → middleware (locale, branch, teacher, or board context) → controllers or Livewire components → Eloquent models and domain services → MySQL. File uploads and certificates route to S3; notifications and realtime UI can use Pusher; heavy exports and notifications enqueue through Horizon.
Backend Decisions
Kept a monolith with clear route file boundaries instead of premature microservices: shared auth (Breeze), shared models, and Spatie roles across surfaces. Chose first-party Laravel queue and cache primitives with Horizon for visibility; payment and BNPL providers stay behind service-style wrappers so checkout templates do not embed gateway details.
Challenges
Branch isolation (middleware, insurance checks, Tabby return URLs) must not leak data across tenants. Board Livewire tables and Excel exports must stay performant on wide user and payment datasets. Teacher platform flows (projects, discusses, certificate OTP) need consistent authorization with the rest of the app.
Technical Decisions
Livewire 2 for dense admin and checkout UX; Laravel Breeze for account flows; Spatie Permission plus Translatable for Arabic or English content; Redis + Horizon over ad hoc cron for retries; S3 + Vapor core for cloud-friendly assets and config.