Une carte qui ne dit pas où vous habitez

Une carte qui ne dit pas où vous habitez
Montrer qu'il y a du monde autour de vous sans jamais révéler d'adresse. Cet épisode raconte un déplacement de code de dix lignes qui change tout : sortir le calcul de distance du navigateur.
Après l'architecture et le Débriefing, voici le sujet qui a le plus changé de forme depuis le début du projet : la géographie. Une app de rencontre a besoin de la distance — c'est le premier filtre que tout le monde utilise. Et la distance, mal implémentée, est une adresse.
La faute qu'on a commise, puis corrigée
La première version de l'écran d'invitation faisait ce que fait n'importe quel prototype : elle demandait à la base la liste des profils avec leurs coordonnées GPS, puis calculait les distances en JavaScript, dans le navigateur de l'hôte. Ça fonctionne parfaitement. C'est aussi une fuite : pour afficher « ~12 km », on avait téléchargé la latitude et la longitude exactes de tout le monde sur un appareil qu'on ne contrôle pas. Le chiffre affiché était flou ; la donnée transmise ne l'était pas.
La migration 005 du dépôt existe pour effacer ça. Une fonction de base de données prend l'identifiant de la soirée, calcule les distances côté serveur, et ne renvoie qu'une liste de couples profil → kilomètres arrondis. Les coordonnées brutes ne quittent plus jamais le serveur. Le navigateur reçoit un entier — impossible de remonter à un point sur une carte à partir d'un rayon unique.
La bonne question n'est pas « qu'est-ce que j'affiche ? » mais « qu'est-ce que j'envoie ? ». Ce n'est pas la même réponse.
La fonction est doublement gardée : elle refuse un appel non authentifié, et elle vérifie que l'appelant est bien l'hôte de la soirée — ou son partenaire. Exactement la même règle que celle appliquée à l'écran, mais cette fois du bon côté de la frontière, comme dans le premier épisode.
Nous utilisons la formule de Haversine : la distance « à vol d'oiseau » sur une sphère de 6 371 km de rayon. Elle ignore les routes, les montagnes et les embouteillages — c'est voulu. Un rayon exact au mètre près serait à la fois plus lourd à calculer et plus indiscret.
Et quand il n'y a pas de coordonnées ?
Un cas limite plus intéressant qu'il n'y paraît. Une soirée sans adresse géolocalisée ne peut produire aucune distance. La fonction pourrait lever une erreur ; elle retourne un résultat vide, et l'écran affiche simplement un tiret. Un défaut de données n'a pas à devenir un message d'erreur pour la personne qui organise sa soirée.
Même logique côté tri : un profil ou une soirée sans coordonnées ne disparaît pas de la liste — il passe en dernier. Sans coordonnées, la distance vaut une valeur volontairement énorme, ce qui le range à la fin sans jamais l'exclure. C'est un détail d'une ligne, et c'est la différence entre « pas encore localisé » et « inexistant ».
Deux distances, deux niveaux d'exigence
Toutes les distances ne sont pas également sensibles, et nous ne les traitons donc pas de la même façon. Sur la liste publique des soirées, le calcul reste côté navigateur : il compare votre position à celle de lieux d'événements déjà rendus visibles, et il n'y a rien à protéger. Sur l'écran d'invitation, où l'hôte parcourt des personnes, tout passe par le serveur. La règle est simple : dès qu'un point sur la carte est un domicile, il ne sort pas de la base.
Cette distinction se voit aussi dans le vocabulaire de l'app : votre localisation sert à « calculer votre distance avec les soirées et les hôtes qui vous recherchent, et à vous positionner sur la carte ». Elle ne sert jamais à vous rendre trouvable à une adresse.
La carte, et son sabotage préféré : le réseau
La carte elle-même est en Leaflet, chargée à la demande — elle n'existe pas tant que vous n'ouvrez pas l'onglet, parce qu'une bibliothèque de cartographie est lourde et n'a rien à faire dans le chargement initial de l'app.
Ce chargement à la demande a un coût, et nous l'avons découvert en usage réel : dans l'app installée sur l'écran d'accueil, qui redémarre souvent avec une connexion encore hésitante, un morceau de la carte peut ne jamais arriver. Résultat, un écran blanc, qui ne se répare qu'en rafraîchissant plusieurs fois à la main. Personne ne fait ça — on quitte l'app.
Le correctif reconnaît spécifiquement cette panne-là et relance une seule fois, automatiquement. Une fois, parce qu'une relance automatique non bornée sur une connexion morte, c'est une boucle infinie doublée d'une batterie vide. Si la seconde tentative échoue aussi, on affiche « Carte indisponible » et un bouton Réessayer. Dire honnêtement qu'on a échoué vaut mieux qu'un écran vide qui tourne.
Le petit code postal qui devine les villes
Dernier détail, presque amusant : pour afficher « Paris » plutôt que « 12 rue Machin, 75000 Paris », une fonction cherche un code postal à cinq chiffres et prend ce qui suit. Si elle ne trouve rien, elle prend le dernier fragment de l'adresse ; en dernier recours, elle affiche « Ville non précisée ». Ce n'est pas de la géolocalisation, c'est de la lecture d'adresse française — et ça restera fragile pour les adresses étrangères. On l'assume tant que le Cercle est en France, et c'est écrit dans le code plutôt que dans nos têtes.
Ce que ça vous garantit
Votre position sert à calculer des rayons, et rien d'autre. Un hôte voit « ~12 km » ; il ne voit pas un point, ni une rue, ni une ville s'il ne l'a pas obtenue autrement. Un membre qui n'a pas renseigné sa position reste visible, simplement plus bas dans les listes. Et un rayon arrondi n'est pas réversible : c'est la seule forme sous laquelle la géographie a le droit de circuler.
Prochain épisode : le moteur de réputation, palier par palier — comment une note devient un droit d'accès, et pourquoi nous refusons qu'un algorithme le décide seul.
Questions fréquentes sur la géolocalisation et la carte
Amphitryon affiche-t-il jamais une adresse exacte sur la carte ?
Non. Le calcul de distance se fait côté serveur et ne renvoie qu'un nombre de kilomètres arrondi ("~12 km") ; les coordonnées GPS exactes ne quittent jamais la base, il est donc impossible de remonter à un point précis à partir de ce rayon.
Pourquoi la distance est-elle arrondie et précédée d'un tilde ?
Pour signaler explicitement qu'il s'agit d'une approximation (distance à vol d'oiseau) et non d'un repérage exact, et pour qu'aucune décimale ne puisse être recoupée avec d'autres informations pour deviner un lieu précis.
Que voit-on si un profil n'a pas renseigné sa localisation ?
Il reste visible dans les listes, simplement classé en dernier grâce à une valeur de distance volontairement énorme : l'absence de coordonnées n'exclut jamais un profil, elle le range juste plus bas.
Le calcul de distance est-il fait de la même façon partout dans l'application ?
Non. Sur la liste publique des soirées, le calcul reste côté navigateur car il ne compare que des lieux déjà publics. Sur l'écran d'invitation, où l'hôte parcourt des personnes, tout passe par le serveur dès qu'un point correspond à un domicile.


