Chapitre 7Projet SunuShop

Compléter le schéma — commandes, avis, paiements

Créer order_items (table pivot commande-produit), reviews (avec CHECK), payments (Wave, Orange Money). Insérer toutes les données de seed. Mettre à jour les totaux des commandes. Le schéma complet à 7 tables.

Concepts Théoriques

Au chapitre 6, nous avons créé les tables customers et orders. Mais une commande sans détail est inutile — on ne sait pas QUELS produits ont été commandés. Et un e-commerce sans avis clients ni suivi des paiements n'est pas complet. Ce chapitre finalise le schéma de SunuShop avec les 3 tables restantes et toutes les données de seed.

La table order_items — le cœur du e-commerce

order_items est la table la plus importante du schéma. Chaque ligne représente "X unités du produit Y dans la commande Z". C'est une table pivot entre orders et products — elle matérialise la relation N-N (une commande a plusieurs produits, un produit peut être dans plusieurs commandes).

Détail important : le prix unitaire est copié dans order_items (unit_price) et ne fait PAS référence au prix actuel du produit. Pourquoi ? Parce que le prix d'un produit peut changer (promo, hausse fournisseur), mais le prix de la commande doit rester fixe. Si un client a commandé un wax à 15 000 FCFA et que le prix passe à 18 000 deux jours plus tard, sa commande reste à 15 000.

La table reviews — les avis clients

Chaque avis est lié à UN produit et UN client. La note est entre 1 et 5 (contrainte CHECK). Un client peut laisser un avis par produit (en théorie — en pratique, on pourrait ajouter une contrainte UNIQUE(product_id, customer_id) pour empêcher les doublons).

ON DELETE CASCADE sur les deux clés étrangères : supprimer un produit supprime ses avis (logique — pas d'avis pour un produit qui n'existe plus), supprimer un client supprime ses avis.

La table payments — le suivi financier

Chaque paiement est lié à une commande. Les méthodes de paiement reflètent la réalité sénégalaise : Wave (le plus utilisé), Orange Money, carte bancaire, et espèces à la livraison. Le statut suit le cycle : pending → completed (ou failed, refunded).

ON DELETE CASCADE : supprimer une commande supprime ses paiements.

Le total des commandes

Le champ orders.total n'est pas calculé automatiquement par MySQL. Il faut le mettre à jour manuellement avec un UPDATE basé sur la somme des order_items. En Laravel, ce calcul sera automatisé avec un Observer ou un Event.

Les transactions — le "tout ou rien"

Quand un client passe une commande sur SunuShop, plusieurs opérations doivent se faire ENSEMBLE :

  1. Insérer la commande dans orders
  2. Insérer les lignes dans order_items
  3. Décrémenter le stock de chaque produit dans products
  4. Créer le paiement dans payments

Si l'étape 3 réussit mais que l'étape 4 échoue (erreur réseau, solde insuffisant), le stock a diminué mais la commande n'est pas payée. La base est dans un état incohérent.

Les transactions garantissent l'atomicité : soit TOUTES les opérations réussissent, soit AUCUNE ne s'applique. C'est le principe ACID (Atomicité, Cohérence, Isolation, Durabilité).

START TRANSACTION — démarre une transaction. Les modifications ne sont pas encore définitives. COMMIT — valide toutes les modifications depuis START TRANSACTION. Elles deviennent permanentes. ROLLBACK — annule toutes les modifications depuis START TRANSACTION. Comme si rien ne s'était passé.

START TRANSACTION;

-- Créer la commande
INSERT INTO orders (customer_id, status) VALUES (1, 'pending');
SET @order_id = LAST_INSERT_ID();

-- Ajouter les produits
INSERT INTO order_items (order_id, product_id, quantity, unit_price)
VALUES (@order_id, 1, 2, 15000.00);

-- Décrémenter le stock
UPDATE products SET stock = stock - 2 WHERE id = 1;

-- Vérifier que le stock n'est pas négatif
SELECT stock FROM products WHERE id = 1;
-- Si stock >= 0 → COMMIT
-- Si stock < 0  → ROLLBACK (annuler tout)

COMMIT;  -- Tout s'est bien passé → valider
-- OU
-- ROLLBACK;  -- Problème détecté → tout annuler

Par défaut, MySQL est en mode autocommit : chaque requête est une transaction individuelle qui se COMMIT automatiquement. Quand vous faites START TRANSACTION, vous désactivez l'autocommit jusqu'au COMMIT ou ROLLBACK.

En PHP/Laravel, les transactions sont gérées avec DB::transaction(function() { ... }); — si une exception est levée à l'intérieur, tout est automatiquement ROLLBACK.

En pratique, TOUTE opération qui modifie plusieurs tables liées devrait être dans une transaction. C'est un concept fondamental que vous utiliserez quotidiennement en entreprise.