← Retour aux projets
07Social · Mobile2025

Stoodi

Un réseau social étudiant à identité vérifiée combinant messagerie temps réel, mise en relation, groupes et événements. J’ai conçu et construit l’architecture métier backend, la vérification d’identité, le pipeline de confiance et sécurité, et les frontières imposées par la CI qui le gardent maintenable en croissance.

Le code source est privé. L’étude de cas se concentre sur les frontières de domaines, la confiance identitaire et le contrat d’architecture imposé par la CI plutôt que sur les données utilisateurs.

Modèle produit
Réseau social étudiant vérifié
Public
Étudiants universitaires
Période
2025
Mon rôle
Architecte backend & ingénieur plateforme
Contexte
Produit commercial privé
Périmètre
Architecture métier · temps réel · confiance & sécurité · CI/CD
11modules métier
85%couverture de tests imposée
12étapes du pipeline CI

01

Surfaces produit

Surfaces produit

Des surfaces distinctes rendaient visibles les responsabilités école, association et campus avant même de regarder l’architecture.

Workflow privé

Parcours de vérification étudiante

Déclaration d’inscription, rapprochement registre et parcours de relance avant l’accès complet.

Capture à venir

Découverte & messagerie temps réel

Mise en relation et conversations directes/groupe livrées via des connexions WebSocket authentifiées.

UI produit privée

Opérations confiance & sécurité

Revue des signalements, sanctions et appels opérant sur la même identité vérifiée que le graphe social.

02

Problème et contraintes

Problème et contraintes

Un produit social étudiant ne peut pas reposer sur une inscription déclarée, et ne peut pas laisser 11 domaines fonctionnels en croissance — identité, découverte, messagerie, groupes, événements, modération et facturation — s’emmêler en imports directs. Confiance et architecture devaient être imposées, pas supposées.

Déclarations d’identité invérifiables

Une déclaration d’école auto-rapportée ne donne aucun signal de confiance réel pour un produit construit autour d’étudiants vérifiés.

La messagerie temps réel exige sa propre frontière d’authentification

Un identifiant HTTP longue durée ne convient pas à une connexion socket persistante.

Pression de croissance des domaines

Onze domaines fonctionnels partageant un même code tendent à éroder l’isolation sous la pression de livraison, sauf si les frontières sont imposées mécaniquement.

La sécurité ne peut pas être purement réactive

Certains risques, comme les utilisateurs mineurs, exigent une détection et un confinement automatiques plutôt que d’attendre un signalement manuel.

03

Mon périmètre exact

Mon périmètre exact

J’ai conçu

  • L’architecture métier complète : 11 domaines délimités, chacun derrière services, sélecteurs et adaptateurs, composés via des ports explicites plutôt que des imports directs.
  • Le modèle de confiance reliant inscription déclarée, vérification registre et modération en un cycle d’identité cohérent.
  • L’approche de mise en relation et de classement déterministe pour la découverte, ainsi que le modèle d’authentification temps réel par ticket.

J’ai implémenté

  • Les 11 domaines Django, leurs APIs, tâches de fond, et le pattern d’adaptateur piloté par ADR câblé à la racine de composition.
  • Le pipeline de vérification face au jeu de données ouvert ESR, le pipeline de modération et sanctions, et la détection automatisée de mineurs.
  • Le pipeline CI en 12 étapes : lint, typage strict, import-linter, scan de sécurité, seuils de couverture, contrôle des migrations et détection de rupture OpenAPI.

J’ai collaboré sur

  • Le comportement produit du client Flutter consommant ces APIs, et la façon dont les états temps réel et de vérification s’affichent aux utilisateurs.
  • Les décisions de politique de confiance et sécurité traduites dans les règles du domaine modération.

03

Objectifs

Objectifs

Confiance

Rattacher l’accès produit à une inscription vérifiée face à un registre externe faisant autorité.

Frontières

Garder 11 domaines testables indépendamment et imposer l’isolation comme un contrat vérifié en CI.

Temps réel

Livrer la messagerie sur des sockets persistants sans exposer d’identifiants longue durée à la connexion.

Sécurité

Combiner modération manuelle et détection automatisée pour les cas à plus haut risque.

04

Architecture système

Architecture système

01Client

Flutter · iOS · Android

02API & temps réel

DRF · Channels/WebSockets · auth par ticket

03Cœur métier

11 domaines délimités · services · ports

04Runtime & externe

PostgreSQL/PostGIS · Redis · Celery · ESR · RevenueCat

Le client Flutter, les APIs temps réel et requête, le cœur à 11 domaines et les services externes restent séparés afin qu’aucune couche n’ait besoin de connaître les détails internes d’une autre.

Stack technique

Application

Django 5 · Django REST Framework · drf-spectacular · ASGI/Daphne

Temps réel & asynchrone

Channels · channels-redis · Celery · Redis

Données & stockage

PostgreSQL · PostGIS · S3-compatible storage

Intégrations & exploitation

RevenueCat · Sentry · Prometheus · structlog · ESR open dataset

05

Modèle métier

Modèle métier

Le modèle de données garde distincts l’identité vérifiée, le graphe social et la couche de sécurité. Une école est validée face à un registre externe avant de pouvoir ancrer une vérification, les connexions et conversations dépendent de cette identité vérifiée, et la modération agit sur la même identité sans se mêler aux tables produit.

01

École (vérifiée registre)

Synchronisée depuis le jeu de données ouvert ESR et rapprochée par similarité de nom normalisé.

02

Compte & vérification

Identité locale plus un enregistrement et un état de vérification d’inscription indépendants.

03

Profil & disponibilité découverte

Média, localisation approximative et conditions de visibilité avant l’entrée en mise en relation.

04

Connexion

Demandes d’ami et blocages rattachés à des comptes vérifiés.

05

Conversation & message

Messagerie directe et de groupe livrée via des sockets temps réel authentifiés.

06

Communauté & événement

Groupes avec rôles, et événements avec participation rattachée à l’appartenance.

07

Dossier de modération

Signalements, preuves, sanctions et appels se rattachent à l’identité vérifiée, pas à une ligne utilisateur générique.

06

Modèle d’états

Modèle d’états

Vérification et confiance forment un seul cycle : une inscription déclarée ne devient un accès qu’après une preuve externe, et les événements de sécurité ultérieurs agissent sur cette même identité vérifiée plutôt que sur un concept de compte séparé.

01

Inscription déclarée

L’utilisateur soumet une école et une déclaration d’identité.

02

Registre rapproché

La déclaration est normalisée et rapprochée du catalogue école ESR.

03

Vérifié

Le compte obtient un accès complet une fois l’inscription confirmée.

04

Confiance maintenue

Signalements et sanctions se rattachent ensuite à cette même identité vérifiée.

Transitions alternatives

Incohérence de vérification

Une incohérence registre est orientée vers une revue plutôt qu’acceptée ou rejetée silencieusement.

Mineur détecté

Le compte est auto-suspendu et les sessions révoquées en attente de revue, indépendamment de la modération manuelle.

Vérification et confiance forment un seul cycle : l’accès suit une preuve externe, et les événements de sécurité agissent sur cette même identité vérifiée plutôt que sur un concept parallèle.

07

Défis d’ingénierie

Défis d’ingénierie

01

Vérifier de vrais étudiants sans devenir une autorité de registre

Problème

Une inscription auto-rapportée ne donne aucun signal de confiance défendable, mais la plateforme ne peut pas posséder elle-même un registre étudiant faisant autorité.

Solution

Synchroniser et normaliser le jeu de données ouvert du Ministère de l’Enseignement Supérieur, rapprocher les déclarations par similarité de nom, et orienter les incohérences vers une revue et une relance plutôt qu’une décision automatique.

Compromis

La vérification dépend de la fraîcheur des données externes et d’une revue manuelle occasionnelle, mais l’accès repose sur une preuve défendable plutôt que sur la seule confiance en l’utilisateur.

Si c’est mal géré

Si l’inscription n’est que déclarée, la promesse d’identité vérifiée s’effondre et des acteurs malveillants peuvent se faire passer pour des étudiants librement.

02

Des frontières de domaines qui survivent à la croissance

Problème

Onze domaines partageant un même code sont à un import pratique de s’emmêler à mesure que les fonctionnalités s’accumulent.

Solution

Imposer des contrats import-linter en CI, documenter chaque exception inter-domaines légitime comme un adaptateur justifié par ADR enregistré à une racine de composition unique, et faire transiter les faits inter-domaines par un outbox transactionnel.

Compromis

Chaque interaction inter-domaines coûte plus de cérémonie qu’un appel direct, mais les domaines restent testables et remplaçables indépendamment.

Si c’est mal géré

Sans imposition, la pression de livraison érode les frontières import par import jusqu’à ce que les domaines ne puissent plus évoluer indépendamment.

03

Messagerie temps réel sans identifiant longue durée sur le socket

Problème

Exposer un token d’accès standard directement à une connexion WebSocket persistante étend sa fenêtre d’exposition bien au-delà d’une requête normale.

Solution

Échanger un ticket temps réel de courte durée pour la poignée de main socket, et suivre les sessions au niveau appareil indépendamment de l’authentification HTTP.

Compromis

Le client a besoin d’un aller-retour supplémentaire pour obtenir un ticket avant de se connecter, en échange d’un identifiant borné sur le socket.

Si c’est mal géré

Un token longue durée compromis donnerait sinon un accès prolongé à un flux de conversation en direct plutôt qu’une fenêtre courte et révocable.

08

Modes d’échec & mitigation

Modes d’échec & mitigation

Incohérence de registre pendant la vérification

Une incohérence de nom normalisé est orientée vers une revue et une relance plutôt qu’acceptée ou rejetée silencieusement.

Utilisateur mineur détecté

Le compte est automatiquement suspendu et ses sessions révoquées en attente de revue, indépendamment de la file de modération manuelle.

Événement inter-domaines non encore livré

L’outbox transactionnel persiste le fait durablement et permet un rejeu plutôt que de le perdre en cas d’échec en aval.

Ticket temps réel invalide ou expiré

La connexion socket est rejetée explicitement, forçant un nouvel échange de ticket plutôt qu’une dégradation silencieuse.

09

Décisions techniques

Décisions techniques

01

Des ports, pas des imports, entre domaines

Les lectures inter-domaines passent par des adaptateurs enregistrés à la racine de composition, import-linter imposant la frontière comme un contrat vérifié en CI plutôt qu’une convention.

02

Un outbox transactionnel pour les faits inter-domaines

Les événements de domaine sont persistés durablement et rejouables plutôt qu’émis puis oubliés, afin qu’un domaine en aval ne manque jamais un fait silencieusement.

03

Une confiance fondée sur une preuve externe

L’inscription est vérifiée face au registre ESR plutôt que d’accepter une déclaration, les incohérences étant orientées vers une revue plutôt qu’acceptées ou rejetées silencieusement.

10

Sécurité & exploitation

Sécurité & exploitation

Frontières d’architecture imposées par la CI

Les contrats import-linter et les exceptions documentées par ADR conditionnent chaque fusion, au-delà de la seule discipline de revue.

Configuration production fail-fast

La validation au démarrage refuse le mode debug, les hôtes joker, les cookies non sécurisés et les secrets par défaut au lieu de les accepter silencieusement.

Rotation de clés et secrets chiffrés

Les clés de signature JWT tournent avec plusieurs clés de vérification acceptées, et les secrets OTP sont chiffrés Fernet au repos.

Webhooks de facturation vérifiés

Les webhooks RevenueCat sont validés par signature HMAC avant l’octroi de tout droit d’accès.

  • Seuils de couverture 85% lignes et 80% branches imposés en CI.
  • Un pipeline en 12 étapes couvrant scan de sécurité, fraîcheur des migrations et détection de rupture OpenAPI.
  • Logs structurés, Sentry et métriques Prometheus pour la visibilité opérationnelle.

11

Résultat livré

Résultat livré

Résultats d’implémentation — aucune métrique commerciale non vérifiée.

Une frontière de confiance défendable

L’accès repose sur une inscription vérifiée au registre plutôt que sur une simple déclaration.

Une isolation imposée, pas supposée

11 domaines restent testables indépendamment car c’est la CI, et non la convention, qui impose leurs frontières.

Un pipeline de sécurité auditable

Signalements, sanctions et appels opèrent sur la même identité vérifiée avec des parcours manuels et automatiques.

Du temps réel sans perdre le contrôle de session

La messagerie s’exécute sur des sockets persistants tandis que les identifiants restent courts et révocables.

Ce que j’en retiens

“Les frontières d’architecture ne tiennent que si la CI les impose mécaniquement — les conventions seules s’érodent sous la pression de livraison. Et la confiance dans un produit social doit reposer sur une preuve externe, pas une simple déclaration.”
Étude suivanteAssaliz