Aller au contenu

← Retour au projet sur l'accueil

Iyabo Hair

En ligne · Accès privé

Iyabo Hair

Un outil qui gère les commandes et les fonds entre un commerçant et ses livreurs. Il permet de connaître ses stocks et surtout où va chaque franc, avec détails et historique des deux côtés. La démo montre les commandes, la caisse et les trois suivis sur des données fictives ; la gestion de stock n'en fait pas partie.

Essayer la démo

Client
Iyabo Hair, Dakar
Rôle
Conception et développement, seul
Année
2026
Iyabo Hair

Une commande, trois suivis

Iyabo HairIyabo HairEn ligneSimulation · données fictives
Qu'est-ce qui est réel ?

Simulation construite sur le code de Iyabo Hair, données fictives.

Code réel
Les règles de ce qui est dû, payé et restant, de ce qu'un livreur détient et remet, et de la façon dont un statut de livraison déplace le produit viennent du code d'Iyabo Hair, consolidées et vérifiées contre le calcul d'origine. Les statuts et les libellés sont ceux de l'application.
Données fictives
Les vingt commandes, les trois livreurs, les produits et les prix sont inventés. Aucune cliente, aucun numéro de téléphone.
Illustration ajoutée
L'interrupteur « Et si tout était un seul enregistrement ? » est une explication ajoutée par ce site. Ce n'est pas une fonction de l'application. La mise en page des écrans est aussi recomposée pour la démo.
Iyabo Hair

Iyabo Hair

La démo ne se charge que si vous la demandez.

  1. 01

    Le problème

    Iyabo Hair vend des perruques dans tout Dakar. Une perruque peut quitter l'étagère le lundi, être livrée le mercredi et payée le vendredi, parfois partiellement, parfois au livreur plutôt qu'à la boutique. Un statut de commande unique ne sait pas raconter ces trois histoires.

  2. 02

    Trois suivis

    Chaque commande porte trois enregistrements séparés : où est le produit, où en est la livraison, et ce qui a été payé. Changer le statut de livraison déplace le produit physiquement (chez le livreur, livré, retourné) mais ne touche jamais à l'argent. Enregistrer un paiement ne change jamais un statut.

    Sous le capot

    La commande a un statut pour le produit, un statut pour la livraison, et aucun champ d'argent : l'argent se déduit des paiements typés.

    Fichier : Iyabo Hair · prisma/schema.prisma · lignes 191 à 201

      // Les TROIS suivis indépendants  productStatus  ProductStatus  @default(EN_STOCK)  deliveryStatus DeliveryStatus @default(A_PREPARER)  // Le suivi ARGENT est calculé à partir des Payment liés :  // resteAPayer perruque = quantity * unitPrice - somme(Payment PERRUQUE)  // resteAPayer livraison = deliveryFee - somme(Payment LIVRAISON)   // Qui est prévu pour encaisser ce qui n'est pas encore payé  // (détermine ce que le livreur doit récupérer à la livraison)  perruqueEncaisseur  PlannedCollector @default(LIVREUR)  livraisonEncaisseur PlannedCollector @default(LIVREUR)

    Code réel du projet, copié et anonymisé.

  3. 03

    Chaque franc a une place

    Un paiement concerne soit la perruque, soit la livraison, jamais les deux, et il note qui l'a physiquement reçu. C'est ainsi que l'application sait répondre à « où est chaque franc ? ». Une livraison ne peut pas être clôturée avec un impayé silencieux : le livreur confirme ce qu'il a encaissé et comment, ou signale un problème.

    Sous le capot

    Avant de clôturer une livraison, le reste de chaque volet est calculé et tout solde impayé la bloque.

    Fichier : Iyabo Hair · app/livreur/livraisons/[id]/actions.ts · lignes 106 à 132

      const payeP = order.payments    .filter(function (p) {      return p.type === "PERRUQUE";    })    .reduce(function (sum, p) {      return sum + p.amount;    }, 0);  const payeL = order.payments    .filter(function (p) {      return p.type === "LIVRAISON";    })    .reduce(function (sum, p) {      return sum + p.amount;    }, 0);   const restePerruque = order.quantity * order.unitPrice - payeP;  const resteLivraison = order.deliveryFee - payeL;   // Cohérence : si un montant restait dû et que le livreur ne  // l'a pas reçu, il doit passer par "Problème" plutôt que  // valider une livraison avec un impayé silencieux  if (restePerruque > 0 && perruqueRecue !== "OUI") {    return "La perruque n'est pas payée (" + restePerruque.toLocaleString("fr-FR") + " F). Encaisse-la ou signale un problème.";  }  if (resteLivraison > 0 && livraisonRecue !== "OUI") {    return "La livraison n'est pas payée (" + resteLivraison.toLocaleString("fr-FR") + " F). Encaisse-la ou signale un problème.";  }

    Code réel du projet, copié et anonymisé.

  4. 04

    Des frais prépayés ne sont pas encore dus

    Quand une cliente paie les frais de livraison d'avance, la boutique détient cet argent, mais il ne devient celui du livreur qu'une fois la commande livrée. Une livraison échouée ou reportée le laisse en attente. La remise de caisse d'un livreur, c'est l'argent qu'il détient moins les frais qui lui sont désormais dus.

    Sous le capot

    Les frais encaissés par la boutique ne sont dus au livreur que sur les commandes livrées ; les autres restent en attente.

    Fichier : Iyabo Hair · app/livreur/caisse/page.tsx · lignes 39 à 61

      const livraisonsAcquises = await prisma.payment.findMany({    where: {      type: "LIVRAISON",      remiseId: null,      collectedBy: { role: "ADMIN" },      order: { livreurId: livreurId, deliveryStatus: "LIVREE" },    },  });  const totalAcquises = livraisonsAcquises.reduce(function (sum, p) {    return sum + p.amount;  }, 0);   const livraisonsEnAttente = await prisma.payment.findMany({    where: {      type: "LIVRAISON",      remiseId: null,      collectedBy: { role: "ADMIN" },      order: { livreurId: livreurId, deliveryStatus: { not: "LIVREE" } },    },  });  const totalEnAttente = livraisonsEnAttente.reduce(function (sum, p) {    return sum + p.amount;  }, 0);

    Code réel du projet, copié et anonymisé.

  5. 05

    Essayez vous-même

    Ouvrez une commande, changez son statut, enregistrez un paiement, livrez-la côté livreur, puis faites la remise de caisse d'un livreur et validez-la côté boutique. Activez la question sur l'enregistrement unique pour voir ce qu'un seul statut cacherait. Ce bloc est une illustration ajoutée par ce site, pas une fonction de l'application.

Ce que vous pouvez y faire

  • Changer le statut de livraison de vingt commandes fictives
  • Enregistrer un paiement et voir ce qui reste dû
  • Clôturer une livraison en tant que livreur
  • Remettre la caisse et la valider en tant que gérante
  • Voir les suivis du produit, de la livraison et de l'argent se mettre à jour séparément

Stack

Next.js 16 · TypeScript · Tailwind CSS v4 · Prisma 7 · Neon Postgres · NextAuth v5 · Vercel

Contexte

Iyabo Hair vend des perruques dans tout Dakar. Les commandes arrivent par les réseaux sociaux, le stock circule entre quelques personnes, et des livreurs en moto encaissent en espèces ou en mobile money. Avant cette application, tout cela tenait dans des cahiers et des fils de discussion. Personne ne pouvait répondre à deux questions simples en même temps : qu'est-ce qu'on a vraiment en stock, et qui doit combien à qui.

Le problème

La gérante n'avait pas besoin d'une boutique en ligne. Elle avait besoin d'arrêter de perdre de l'argent dans l'écart entre trois choses qui n'avancent pas à la même vitesse : le produit, la livraison et l'argent. Une perruque peut quitter l'étagère le lundi, être livrée le mercredi et payée le vendredi, parfois partiellement, parfois au livreur plutôt qu'au commerce. Tout système qui traite cela comme un seul événement produit silencieusement de faux chiffres. Et dans ce métier, un faux chiffre, c'est le salaire de quelqu'un.

Contraintes

  • L'équipe travaille exclusivement sur des téléphones Android de milieu de gamme, souvent en données mobiles instables
  • Aucune caisse enregistreuse, aucun terminal de paiement, aucun logiciel comptable auquel se connecter
  • Les paiements arrivent par Wave et Orange Money, ou en espèces à un livreur
  • Les livreurs ne sont pas salariés et leur rémunération se calcule à la livraison
  • L'équipe n'avait jamais utilisé d'outil interne : tout ce qui serait déroutant serait abandonné en une semaine

Ce que j'ai construit

  • Saisie des commandes avec décrémentation du stock et marge par article
  • Attribution des livraisons, suivi des statuts et règlement des livreurs
  • Journal de caisse rapprochant mobile money, espèces et soldes en attente
  • Rôles distincts pour la gérante, les administrateurs et les livreurs
  • Codes de paiement Wave et Orange Money scannables, rattachés à chaque commande
  • Application web progressive installable, ouverte depuis l'écran d'accueil comme n'importe quelle autre app

Décisions structurantes

  1. 01

    Trois suivis qui ne s'écrivent jamais l'un dans l'autre

    La conception évidente consiste à faire d'une commande un enregistrement unique qui met à jour le stock, la livraison et la caisse ensemble. Je l'ai écartée. Le produit, la livraison et l'argent sont suivis comme trois flux indépendants, et aucune action dans l'un ne modifie automatiquement les autres. Marquer une livraison comme terminée ne solde pas l'argent. Enregistrer un paiement ne clôt pas la livraison. Cela coûte quelques appuis supplémentaires, mais une erreur reste locale au lieu de corrompre silencieusement les deux autres suivis. Dans un commerce où les chiffres déterminent qui est payé, un montant faux coûte infiniment plus cher qu'un appui de trop.

  2. 02

    Les frais de livraison ne sont jamais l'argent du commerce

    Les frais de livraison appartiennent au livreur, le prix de la perruque appartient au commerce. Les deux sont séparés dès la saisie et ne sont jamais fusionnés nulle part, y compris dans les rapports. Cela paraît évident jusqu'au moment où une cliente règle le tout en un seul virement mobile money. Modéliser cela comme un montant unique à répartir plus tard, c'est exactement comme ça qu'un commerce dépense la paie de ses livreurs sans s'en rendre compte, puis en discute en fin de mois.

  3. 03

    Le prépayé ne compte qu'une fois la livraison faite

    Quand une cliente paie à l'avance, la rémunération du livreur est enregistrée mais n'entre dans ce qui lui est dû qu'une fois la livraison effectivement terminée. L'autre option, créditer dès le paiement, donne un solde livreur juste à l'écran et faux dans la réalité, et se retourne mal sur les retours et les livraisons échouées. Cette seule règle a supprimé toute une catégorie de litiges de fin de semaine.

Résultat

  • Cahiers et fils de discussion remplacés par une source unique de vérité
  • Installée sur les téléphones de l'équipe depuis l'écran d'accueil, sans passer par un store