Conserver la vérité métier locale, même quand le système externe échoue.
LE PROJET EN 30 SECONDESAlex ATC / Product Engineer
01L’intention
Conserver la vérité métier locale, même quand le système externe échoue.
02Ma contribution
Cadrer le problème métier, les acteurs, les anomalies et les critères d’acceptation avant de choisir les tables ou les routes.
03Ce qui existe
Un parcours client complet : connexion, catalogue contractuel, panier, commande et historique.
01 / Le sujet
J’ai conçu et construit un MVP B2B qui permet de commander en ligne tout en conservant chaque commande, même si l’ERP échoue.
FlowDesk remplace les commandes B2B dispersées entre emails et appels par un parcours numérique complet. Le client consulte son catalogue et son prix contractuel, ajuste son panier puis valide sa commande. L’API revérifie prix et stock dans une transaction PostgreSQL, conserve la commande avant l’appel ERP et réserve le stock. Un mock ERP permet de vérifier l’acceptation, l’écart de prix et l’indisponibilité. Le client suit ses commandes; l’opérateur traite les anomalies et consulte la piste d’audit. Le MVP tourne en local avec Docker; le déploiement public n’est pas configuré.
Des captures réelles, reliées à une action et à son résultat.
01 / Catalogue
Afficher le bon prix pour la bonne organisation
L’interface React charge le catalogue de l’organisation avec TanStack Query. Chaque produit rassemble SKU, prix contractuel, stock et disponibilité, avec des états distincts pour le chargement, le vide et l’erreur.
Organisation · prix contractuel · stock · états UI
02 / Tranche verticale
Valider le panier dans une transaction
Au checkout, l’API relit les prix et le stock, verrouille les lignes concernées, crée la commande et ses prix historiques, réserve les quantités puis convertit le panier dans une seule transaction. Le client retrouve ensuite sa commande et son statut.
Revalidation · prix figé · stock réservé · historique
03 / Résilience ERP
Rendre les incidents ERP traitables
L’adapter isole le format externe et transmet la commande de façon idempotente. PRICE_MISMATCH bloque la commande et ouvre une anomalie; ERP_UNAVAILABLE laisse la commande en attente. Un opérateur peut suivre le statut, relancer la même commande et consulter les événements d’audit.
Cadrer le problème métier, les acteurs, les anomalies et les critères d’acceptation avant de choisir les tables ou les routes.
02
Modéliser organisations, prix contractuels, stock, paniers, commandes et anomalies avec des contraintes PostgreSQL explicites.
03
Structurer un monolithe modulaire qui sépare présentation, application, domaine et infrastructure.
04
Livrer catalogue, authentification par rôles, panier, checkout transactionnel et historique des commandes.
05
Isoler le mock ERP derrière un adapter, traiter PRICE_MISMATCH et ERP_UNAVAILABLE avec un espace opérateur.
06
Ajouter la piste d’audit, les tests API et Playwright, la sécurité HTTP, Docker et une CI GitHub Actions validée.
Étude de casProblème, décisions et résultats.Le détail reste disponible pour vérifier les faits et les arbitrages.Ouvrir l’étude complète
01 / Problème
Les commandes B2B passent encore par mail ou téléphone vers un fournisseur équipé d’un ERP legacy. Cette chaîne crée des doubles saisies, masque les prix réellement applicables et rend les échecs externes difficiles à comprendre. Le sujet produit est de donner de l’autonomie au client sans laisser l’ERP devenir la seule source de vérité du parcours.
02 / Rôle · équipe · durée · contraintes
Rôle
Product Engineer — cadrage métier, modélisation du domaine, UX du catalogue, architecture et développement full-stack.
Équipe
Projet personnel mené du cadrage métier à un MVP B2B fonctionnel, vérifié en local et intégré dans une CI.
Durée
Durée non publiée. L’historique Git n’est pas converti en estimation de charge.
Contraintes
Composer avec un ERP externe qui peut être lent, indisponible ou renvoyer des données incohérentes.
Isoler les données de chaque organisation et appliquer son prix contractuel.
Conserver une commande locale avant toute transmission au système externe.
Rester simple à déployer et à tester pendant le MVP, sans microservices prématurés.
03 / Hypothèses
Un catalogue relié à l’organisation réduit les vérifications manuelles de prix et de disponibilité.
Une commande persistée avant l’appel ERP évite qu’une panne externe efface l’intention du client.
Des anomalies typées et visibles donnent à l’opérateur un point de départ concret pour traiter les écarts.
Une première tranche verticale complète révèle plus tôt les problèmes de frontière qu’un développement couche par couche.
Alternatives étudiées
Des microservices ont été écartés pour le MVP : ils ajouteraient du réseau et de la cohérence distribuée avant que le domaine le justifie.
GraphQL seul a été écarté pour les actions métier ; REST garde des effets comme créer ou relancer une commande explicites.
REST seul limite les lectures composées du catalogue et du futur back-office ; GraphQL complète ces lectures sans créer une seconde logique métier.
Mettre Effect dans le domaine a été écarté afin que les règles restent du TypeScript simple, indépendant du framework.
04 / Arbitrages UX & tech
Monolithe modulaire plutôt que services séparés : moins d’opérations, mais des frontières internes à faire respecter.
REST et GraphQL ensemble : interfaces adaptées aux usages, au prix de deux contrats à documenter.
Stock global dans le MVP : modèle plus simple, mais pas encore de stock par organisation ou entrepôt.
Interface volontairement minimale : elle valide la donnée et les états avant le panier et le back-office.
05 / Tests · incidents · itérations
Le domaine et le use case de commande ont été écrits avant le schéma PostgreSQL afin de figer les invariants utiles.
Le schéma ajoute clés étrangères, index, unicités et contrôles sur les montants, stocks et quantités.
Le catalogue a été construit comme une tranche verticale : seed PostgreSQL, repository Drizzle, use case Effect, routes REST/GraphQL, hook Query et écran React.
L’interface couvre chargement, erreur avec nouvelle tentative, catalogue vide et catalogue alimenté.
Les tests API et mock ERP couvrent les cas de succès et d’erreur; Playwright traverse connexion, panier, commande, confirmation ERP et vérification de la piste d’audit côté opérateur.
GitHub Actions vérifie PostgreSQL, migrations et seed, pnpm check, Playwright, les dépendances de production et la construction des trois images Docker.
06 / Résultats observés
Le parcours Playwright traverse le rôle client jusqu’à la confirmation de commande par le mock ERP, puis vérifie les événements d’audit avec un compte opérateur.
Les scénarios simulés confirment que les commandes restent enregistrées en cas d’écart de prix ou d’indisponibilité ERP et peuvent être relancées sans créer de doublon.
La CI valide les migrations, les tests, les builds et les images Docker; l’audit de dépendances est exécuté dans GitHub Actions.
Aucun taux d’adoption, gain de temps ou taux de réduction d’erreur n’est revendiqué : le produit est un MVP local, sans déploiement public.
Preuves
Preuves et accès.
Produits publics, captures et traces de validation disponibles.