Portrait de Patrice GADEGBEPatrice GADEGBE

Encheria

Encheria est une application mobile consacrée aux enchères judiciaires immobilières en France : elle réunit les annonces, attribue à chacune un score, simule les frais d’acquisition et le rendement locatif, et alerte l’utilisateur lorsqu’un bien correspond à ses critères.

Rôle
Auteur de l’application mobile ; sur le serveur, écrit par un associé, j’ai apporté les abonnements, la connexion, les liens et le déploiement
Période
De mai 2026 à aujourd’hui
État
En développement. En développement, diffusée en recette seulement
Technologies
Flutter, flutter_bloc, Spring Boot 4, PostgreSQL et PostGIS, Redis
Dépôts
Deux, ainsi qu’un backoffice
Architecture d’EncheriaL’application Flutter appelle une API Spring Boot à travers nginx, qui sert aussi les fichiers des liens universels. L’API s’appuie sur PostgreSQL et PostGIS. Les abonnements sont achetés dans les magasins d’applications.ApplicationFlutter, flutter_bloc33 pagesnginxliens universelset proxyAPISpring Boot 4, Java 2173 points d’accèsHTTPS, jeton JWTMagasinsachats intégrésPostgreSQL 16PostGIS43 migrations
Figure 1. Architecture d’Encheria. Les magasins d’applications détiennent les abonnements, que le serveur vérifie de son côté.

Contexte

Encheria s’adresse à des particuliers qui investissent dans l’immobilier par la voie des ventes judiciaires. Le serveur, dont le cœur a été écrit par mon associé, collecte chaque jour des annonces publiques, les croise avec les données ouvertes de l’État sur les transactions et sur les loyers, puis calcule un score et les frais d’une acquisition. L’application mobile, que j’ai écrite, présente ces biens sur une carte et dans un radar, porte les simulateurs et gère les alertes ainsi que l’abonnement.

Cette étude s’en tient à ce que j’ai réalisé, à savoir l’application et, sur le serveur, les abonnements, la connexion par Google et par Apple, les liens universels et le déploiement.

Problème

Trois difficultés de l’application sont retenues ici. Le choix d’une zone de recherche, qu’il s’agisse d’une région, d’un département ou d’une commune, devait fonctionner sans réseau tout en aboutissant à une seule requête. Un lien vers un bien, partagé par un utilisateur, devait ouvrir l’application chez son destinataire, ce que le serveur d’application refusait de servir. Un abonnement payé dans un magasin, enfin, ne devait pas être perdu lorsqu’une notification de ce magasin n’arrivait pas.

Réponse apportée

Une géographie embarquée

L’application embarque la géographie de la France, soit 18 régions, 101 départements et 34 875 communes, dans un fichier de 2,6 mégaoctets produit par un script à partir des données publiques, les coordonnées y étant conservées sous la forme d’entiers. La sélection se fait donc sans appel au serveur. L’API accepte de son côté jusqu’à vingt cercles, qu’elle combine entre eux ; lorsqu’un cercle dépasserait deux cents kilomètres de rayon, ou qu’il en faudrait plus de vingt, l’application renonce aux cercles et renvoie l’ensemble de la sélection sous la forme de codes exacts.

List<LocationCircle>? searchCirclesFor(
  Iterable<LocationRef> refs,
  GeoIndex index,
) {
  final circles = <LocationCircle>[];
  for (final ref in refs) {
    final circle = locationCircleFor(ref, index);
    if (circle == null || circle.radiusKm > maxCircleRadiusKm) return null;
    if (circles.contains(circle)) continue;
    circles.add(circle);
  }
  if (circles.isEmpty || circles.length > maxSearchZones) return null;
  return circles;
}
Extrait 1. Tous les lieux en cercles, ou aucun : la fonction rend une valeur nulle dès qu’un seul lieu ne s’y prête pas.

Des liens servis par nginx

Les fichiers d’association qu’exigent iOS et Android, ainsi que la page de repli d’un bien partagé, sont servis par le conteneur nginx et non par l’application Spring, avec un jeu de fichiers par environnement. Dans l’application, un garde refuse tout lien dont l’hôte n’est pas celui de la variante installée, et met la destination de côté jusqu’à ce que l’utilisateur soit connecté.

Des abonnements rapprochés à la lecture

Les achats sont vérifiés par le serveur auprès des magasins. Une notification perdue figeait cependant la date de fin de période et aurait ramené un abonné payant à l’offre gratuite. Le rapprochement se fait donc à la lecture : le serveur n’interroge le magasin que pour un abonnement qui paraît échu, au plus une fois par quart d’heure, et une panne du magasin n’empêche jamais la lecture d’aboutir. Aucun balayage planifié n’est nécessaire.

Limites et perspectives

L’application n’est pas publiée : une cinquantaine de versions de recette ont été envoyées aux magasins, et le domaine de production n’est pas encore servi. Aucun pipeline n’exécute les tests, qui sont lancés depuis le poste ; l’application en compte environ sept cents, mais la dernière mesure locale ne donne que 38,6 % de lignes couvertes, sans seuil imposé.

Un biais connu du simulateur de rendement reste par ailleurs à corriger, l’application transmettant un prix qui inclut déjà des frais que le serveur calcule de nouveau. Deux écrans ne sont pas terminés, à savoir l’analyse de marché, qui n’est pas reliée à la navigation, et l’export des données personnelles. Le backoffice, enfin, n’est pas encore versionné.

Retour aux réalisations