B2B PlatformLaravel 12React + FlutterMulti-channelEn cours de développement

Grossiste Pro

Plateforme B2B de commerce en gros de bout en bout avec un panneau d'administration web, une application mobile Flutter pour les commandes clients, et une API Laravel avec un inventaire FEFO, une machine d'états des commandes stricte et une tarification multi-niveaux.

3Clients de la plateforme
8+Modules Laravel
FEFOModèle d'inventaire
AR/FRCatalogue bilingue
Grossiste Pro · Admin Panel
Admin Panel
React SPA

284K

Revenue

41

Orders

98%

Stock

ORD-0041

Atlas Import Co.

delivering

ORD-0040

Souss Export Ltd

processing

ORD-0039

Maghreb Transit

delivered
Mobile App
Flutter

Browse catalog

AR/FR · 3 price tiers

Cart & checkout

Real-time sync

Order history

Status tracking

FEFO allocation

Lot 001 → 002 → 003 (expiry order)

Aperçu

Un écosystème de commandes B2B complet

Grossiste Pro est une plateforme B2B de commerce en gros full-stack conçue pour les distributeurs et leurs clients. Elle remplace les commandes manuelles par téléphone ou WhatsApp par un workflow numérique structuré - les clients parcourent un catalogue bilingue sur l'application mobile, passent des commandes avec leur niveau de prix négocié, et l'équipe d'entrepôt gère tout depuis le panneau d'administration avec une visibilité totale sur l'inventaire.

Le backend est un monolithe modulaire Laravel 12 avec 8 modules de domaine, un système strict d'allocation de lots FEFO, une machine d'états des commandes imposée et des requêtes signées HMAC pour le panneau web et l'application mobile.

Objectif

  • Offrir aux clients grossistes une application mobile en libre-service pour parcourir le catalogue bilingue, gérer leur panier et passer des commandes sans appeler le distributeur

  • Remplacer le suivi des stocks sur tableur par un système d'inventaire par lots FEFO qui évite la survente, suit les dates d'expiration et enregistre chaque mouvement

  • Imposer un cycle de vie de commande strict - de la création au traitement, à la livraison et au retour optionnel - avec chaque transition enregistrée et protégée par des règles métier

  • Prendre en charge la tarification multi-niveaux (détail, gros, demi-gros) et un canal POS pour les ventes en présentiel sur site aux côtés du canal application

Mon rôle

Full-stack en solo - backend, panneau d'administration et application mobile

Architecture backend & API

Conçu et développé le monolithe modulaire Laravel 12 - 8 modules de domaine chacun avec ses propres modèles, couche de services, pattern repository, DTOs et routes API. Authentification HMAC, RBAC Spatie, Laravel Horizon pour les files d'attente.

Système d'inventaire avec état

Implémenté l'allocation de lots FEFO avec verrouillage au niveau des lignes et transactions en base de données pour éviter les conditions de concurrence. Les champs de lots suivent les quantités initiales, disponibles et réservées séparément - les lots expirés ne sont jamais alloués.

Machine d'états des commandes

Construit un graphe de transitions imposées (en attente → traitement → livraison → livré → retourné, + canal sur site) via un OrderTransitionService - les transitions invalides sont rejetées, chaque transition est enregistrée avec l'utilisateur actant.

Panneau d'administration web

SPA React + TypeScript avec TanStack Router, stores Zustand, React Hook Form + Zod. Couvre les produits, commandes, POS, inventaire, achats, retours, clients, fournisseurs, rôles, règles de prix et comptes financiers.

Application mobile B2B

Application Flutter pour les clients grossistes avec gestion d'état Riverpod, GoRouter, Dio avec intercepteur de rafraîchissement automatique et flutter_secure_storage. Comprend la navigation dans le catalogue, le panier, l'historique des commandes et la localisation AR/FR.

Catalogue bilingue

Champs en arabe et en français partout - noms de produits, descriptions et noms de catégories entièrement bilingues. Les traductions françaises manquantes sont générées automatiquement via l'API Google Translate afin que les administrateurs puissent saisir d'abord en arabe.

Backend

Laravel 12PHP 8.2+MySQLRedisLaravel HorizonSpatie PermissionSpatie MediaLibraryLaravel SanctumHMAC AuthFEFO AllocationOrder State MachineAuto-translation (Google)Repository PatternService LayerDTOs

Admin Panel

ReactTypeScriptViteTanStack RouterZustandReact Hook FormZodAxiosi18n (EN/FR/AR)POS mode

Mobile App

FlutterRiverpodGoRouterDioflutter_secure_storageAR/FR locale

Fonctionnalités principales

Plus qu'un catalogue - un workflow B2B complet

Catalogue de produits

  • Champs arabe + français avec traduction automatique
  • Catégories hiérarchiques avec traductions
  • Tarification multi-niveaux : détail, gros, demi-gros
  • Gestion des images avec Spatie MediaLibrary
  • Suivi des lots : quantité initiale, disponible, réservée
  • Import massif de produits depuis un modèle

Gestion des commandes

  • Machine d'états stricte : 6 transitions imposées
  • Multicanal : application (B2B) + sur site (POS)
  • Allocation de lots FEFO à la création de la commande
  • Historique complet des statuts par commande (utilisateur + horodatage)
  • Validation de la limite de crédit pour les clients à paiement différé
  • Retours de commandes avec logique de réapprovisionnement des lots

Inventaire et lots

  • FEFO : les lots à expiration la plus proche sont alloués en premier
  • Le verrouillage au niveau des lignes empêche la double allocation
  • available_quantity ne passe jamais en négatif
  • Suivi séparé des quantités réservées et disponibles
  • Journal de mouvements IN / OUT / RETURN
  • Blocage des lots expirés au moment de l'allocation

Application mobile B2B

  • Application Flutter avec Riverpod + GoRouter
  • Catalogue bilingue (AR/FR) avec images
  • Panier avec synchronisation API en temps réel
  • Passage de commandes et historique
  • Token de rafraîchissement automatique avec intercepteur Dio
  • Stockage sécurisé des tokens (flutter_secure_storage)
Inventory · Lot Management

Product: Huile Olive Extra — Lot allocations (FEFO)

LOT-2024-001

Expires 2025-03-15

exhausted

200

Initial

0

Available

0

Reserved

LOT-2024-018

Expires 2025-09-20

active

500

Initial

140

Available

60

Reserved

LOT-2025-003

Expires 2026-06-10

queued

300

Initial

300

Available

0

Reserved

FEFO rule: Lot-2024-018 is allocated first — its expiry date is earliest among non-exhausted lots. available_quantity is the single source of truth for allocation.

Système d'inventaire

Inventaire FEFO avec garanties de concurrence

Ce n'est pas un simple champ de stock CRUD - c'est un système d'inventaire avec état. Chaque lot de produit suit trois quantités distinctes : initiale (référence immuable), disponible (peut être allouée) et réservée (retenue par les commandes actives). FEFO garantit que le lot dont la date d'expiration est la plus proche est toujours consommé en premier.

  • Prévention des conditions de concurrence

    Toute allocation s'exécute dans des transactions de base de données avec SELECT FOR UPDATE. Deux commandes simultanées ne peuvent pas sur-allouer le même lot.

  • Allocation partielle de lots

    Un seul article de commande peut couvrir plusieurs lots - FEFO remplit depuis le lot à expiration la plus proche et déborde sur le suivant.

  • Cycle de vie par canal

    Les commandes de l'application réservent du stock (disponible −qté, réservé +qté). Les commandes sur site/POS consomment immédiatement (disponible −qté, mouvement OUT). Les annulations libèrent les réservations.

  • Journal de mouvements complet

    Chaque changement de stock - IN (achat), OUT (livraison), RETURN - est enregistré comme un mouvement d'inventaire pour l'audit et les rapports.

Machine d'états des commandes

Chaque transition est imposée, enregistrée et protégée

Les transitions invalides sont rejetées. Chaque transition valide ajoute une entrée au journal de statut enregistrant l'utilisateur actant, le statut précédent, le nouveau statut et un horodatage.

-pending

Créer (app / grossiste)

Le client mobile passe une commande. Stock réservé via allocation FEFO.

Channel: app

-processing

Créer (app / détail)

Le client de détail passe une commande. Traitée immédiatement en cours de traitement.

Channel: app · retail

-delivered

Créer (sur site / POS)

L'administrateur crée une commande sur site. Stock consommé immédiatement, sans réservation.

Channel: onsite

pendingprocessing

Traiter

L'administrateur confirme la commande. Gardes : pas de réservations de lots expirés.

Channel: admin

processingdelivering

Livrer

Libère les réservations et enregistre le mouvement OUT dans l'inventaire.

Channel: admin

deliveredreturned

Retourner

Restaure available_quantity et enregistre le mouvement RETURN sur les articles restockables.

Channel: admin

Panneau d'administration

Gestion commerciale complète dans une seule SPA

Le panneau d'administration React couvre tous les modules du backend - du catalogue et des commandes aux mouvements d'inventaire, bons de commande, retours, CRM clients et RBAC.

Dashboard
Products
Categories
Orders
POS (Onsite Sales)
Inventory & Movements
Purchases
Returns
Clients
Suppliers
Payments
Financial Accounts
Pricing Rules
Tax & Settings
Users & Roles (RBAC)
Print Settings

Captures d'écran

Un aperçu de la plateforme

En cours de développement

Panneau d'administration

Grossiste Pro · Dashboard
Dashboard

Dashboard

Grossiste Pro · Orders
Order Management

Order Management

Grossiste Pro · Order #0041
Order Details

Order Details

Grossiste Pro · Products
Product Details

Product Details

Grossiste Pro · Inventory
Inventory

Inventory

Grossiste Pro · Settings
Print Settings

Print Settings

Grossiste Pro · لوحة التحكم
Arabic Support

Arabic Support

Application mobile

Product Catalog

Product Catalog

Shopping Cart

Shopping Cart

Architecture

Monolithe modulaire avec des frontières de domaine strictes

Le backend est un monolithe modulaire Laravel 12 — pas une application CRUD. Chaque module (Produit, Commande, Inventaire, Panier, Client, Fournisseur, Achat, Média) possède sa propre couche de services, interface de repository, DTOs et politiques. Les contrôleurs sont minces : validation + réponse uniquement. Toute la logique de domaine réside dans les services.

  • 8 modules Laravel — chacun autonome avec son propre ServiceProvider
  • Pattern repository : tout accès aux données derrière des interfaces, bindings dans les providers
  • Requêtes signées HMAC : web et mobile utilisent des secrets séparés pour empêcher l'usurpation
  • Laravel Horizon (Redis) pour la gestion des files — tâches asynchrones pour le traitement des médias et les emails
  • Trois services critiques qui ne doivent jamais être contournés : AllocationService, InventoryService, OrderTransitionService
  • La SPA React et l'application Flutter consomment la même API REST — déploiement indépendant

Points clés

Les invariants de domaine sont du code, pas de la documentation

FEFO, la non-négativité du stock et les transitions de la machine d'états sont imposés dans les services — pas dans les contrôleurs ou les commentaires. Si la règle n'est pas dans le code, elle n'existe pas.

La concurrence nécessite une conception explicite

Chaque opération de stock nécessite une transaction de base de données et un verrouillage au niveau des lignes. Une plateforme B2B à fort trafic rencontrera des allocations concurrentes — cela doit être correct par conception, pas par chance.

Le client mobile change le contrat UX

Une application de commande mobile pour les clients B2B transforme entièrement le produit — l'UX du catalogue, la synchronisation du panier et le statut des commandes doivent fonctionner de manière tolérante aux déconnexions et rapidement sur mobile, pas seulement sur bureau.

Le bilinguisme est un choix de modèle de données

Des champs AR/FR sur chaque entité — pas une table de traduction jointe plus tard — maintient les requêtes simples et efficaces en cache. La traduction automatique supprime la friction de saisir les deux langues manuellement.

Travaillez avec moi

Besoin d'une plateforme B2B bien construite ?

Qu'il s'agisse d'un système de commandes en gros, d'un backend orienté inventaire ou d'une application mobile pour vos clients — je vous aide à concevoir le bon modèle de données avant d'écrire une seule ligne de code.