Aller au contenu
M. SALL
Travaux

Mission professionnelle · mars 2025

KÀLAMA

Plateforme EdTech ouest-africaine : marketplace de cours, classes live et paiement Mobile Money, en architecture microservices.

Problème
Les plateformes de cours en ligne existantes supposent une carte bancaire et une connexion stable — deux hypothèses fausses en Afrique de l'Ouest.
Résultat
Plateforme en production sur kàlama.com : service d'authentification séparé derrière une gateway Nginx, classes en direct BigBlueButton, paiement Mobile Money via PayTech avec confirmation asynchrone par IPN, et portefeuille interne.
Rôle
Lead Developer Full-Stack
FastAPISQLAlchemy 2.0PostgreSQLRedisBigBlueButtonPayTechNginxDockerCloudflareboto3 / S3slowapiReact 18Material UIVite
Page d'accueil de KÀLAMA : « L'excellence du savoir accessible à tous », avec accès à la marketplace et aux replays.Marketplace de cours de KÀLAMA, avec le catalogue des formations disponibles.
KÀLAMA sur mobile : la même page d'accueil adaptée à un écran de téléphone.
Captures de la plateforme en production.

Quel problème KÀLAMA résout-il ?

Construire une marketplace de cours pour le marché sénégalais, c'est se heurter d'emblée à deux contraintes que les plateformes occidentales n'ont pas :

  • Le paiement. La carte bancaire est marginale. Le Mobile Money (Orange Money, Wave, Free Money) est le moyen réel, avec ses flux asynchrones, ses webhooks et ses états intermédiaires.
  • Le réseau. Une classe live doit rester utilisable sur une connexion irrégulière, et le replay n'est pas un confort mais un filet de sécurité.

Quelles décisions d'architecture ont été prises sur KÀLAMA ?

Microservices derrière une gateway Nginx, pas un monolithe. Le service de paiement a un cycle de vie propre : il encaisse des webhooks de fournisseurs externes, avec des retries et des états qui ne ressemblent à rien d'autre dans l'application. L'isoler évitait que sa complexité contamine le domaine pédagogique.

Un service d'authentification séparé. auth/ a son propre Dockerfile, ses propres dépendances et ses propres tests. Ce n'est pas du zèle architectural : l'authentification est le seul composant dont une panne doit rester circonscrite, et le seul qu'on veut pouvoir redéployer sans toucher au catalogue.

PayTech pour le paiement. L'agrégateur couvre les moyens réellement utilisés au Sénégal. La confirmation arrive en IPN — une notification asynchrone du fournisseur — doublée de webhooks. Un routeur dédié par canal, parce que ces flux n'ont ni le rythme ni les garanties du reste de l'application.

BigBlueButton plutôt qu'un SDK propriétaire. Auto-hébergeable, sans coût par minute, et avec le contrôle sur la qualité adaptative — ce qui compte quand la bande passante du participant est la variable inconnue. Surtout, il apporte ce qu'une visioconférence générique n'a pas : tableau blanc, partage de présentation, sondages et salles de travail — les gestes d'un cours, pas ceux d'une réunion.

Les rôles dans un seul module. core/roles.py définit les ensembles de rôles une fois pour toutes. Un littéral ["formateur", "admin", …] recopié dans quinze fichiers finit toujours par diverger, et une divergence sur une règle d'autorisation est une faille.

Cloudflare en façade. Mise en cache des ressources statiques au plus près des apprenants, terminaison TLS et protection contre les abus. Servir une plateforme éducative ouest-africaine depuis une seule origine, c'est imposer la latence de cette origine à tout le monde.

Comment KÀLAMA a-t-il été implémenté ?

Le backend expose vingt-et-un routeurs : sessions et actions de session, médias, packs et contenu de packs, paiements, PayTech, IPN, webhooks, portefeuille, finance administrateur, analytique, tableau de bord, invitations, partage, notifications, retours et même un routeur SEO. JWT via python-jose, mots de passe en bcrypt, limitation de débit adossée à Redis.

Les médias de session partent sur du stockage objet via boto3 : un replay ne doit jamais transiter par le disque de l'application.

Le frontend React 18 en TypeScript strict consomme cette API, avec Material UI pour un socle de composants accessibles et Vite pour un cycle de développement court.

L'ensemble tourne en conteneurs : chaque service a son image, Nginx route et termine le TLS, Cloudflare met en cache au plus près des apprenants. Un runbook de bascule est versionné avec le code — écrire la procédure de panne avant la panne, c'est la seule façon qu'elle serve à quelque chose.

Qu'est-ce que KÀLAMA m'a appris ?

La partie difficile n'était pas la vidéo ni le paiement pris isolément, mais la cohérence entre les deux : un participant a payé, le webhook du fournisseur arrive avec trois minutes de retard, et la classe commence maintenant. Rendre cet état intermédiaire explicite dans le modèle de données — plutôt que de le traiter comme une erreur — a réglé une classe entière de bugs.

Un projet du même calibre ?

Basé à Thiès, disponible à dakar & télétravail. Je réponds sous 48 h.

En discuter