Chaque source suit le même pipeline documenté. Traçabilité, reproductibilité, indice de confiance par enregistrement.
Récupération programmée depuis les API et miroirs publics. Versioning par millésime source.
Typage strict, normalisation adresses via BAN, déduplication, rejet des enregistrements aberrants.
Liaison inter-sources par ban_id, code_insee, id_parcelle. Scoring de la qualité du match.
Indicateurs dérivés, vues statistiques, journal d'audit public, mise à jour incrémentale.
Les données sources sont récupérées en continu via des edge functions dédiées. Chaque source a son propre orchestrateur et sa propre queue de téléchargement. Les millésimes sont conservés afin de pouvoir rejouer l'historique si nécessaire.
Les enregistrements bruts passent par une série de filtres :
| Filtre | Action | Sources concernées |
|---|---|---|
| Types stricts | Cast numérique, date ISO, booléens uniformes | Toutes |
| Valeurs manquantes | Rejet si champs critiques absents | DVF, DPE |
| Ventes groupées | Flag is_vente_groupee exclu du prix/m² | DVF |
| Surface aberrante | Rejet si < 9 m² ou > 500 m² en résidentiel | DVF, DPE |
| Prix aberrant | Rejet si hors 3σ de la distribution commune | DVF |
| Déduplication | Conservation du plus récent par clé unique | Toutes |
Le cœur du projet : rattacher chaque enregistrement à un ban_id, identifiant d'adresse pérenne qui sert de pivot universel.
Pour chaque paire (enregistrement source, adresse BAN candidate), un score est calculé à partir de quatre signaux : similarité trigram du nom de voie, égalité du numéro, égalité du code commune, distance géodésique.
| Niveau | Score | Critères |
|---|---|---|
| exact | 100 | numéro ✓, voie sim ≥ 0,95, commune ✓, dist ≤ 20 m |
| high | 85 | numéro ✓, voie sim ≥ 0,80, commune ✓, dist ≤ 50 m |
| good | 70 | voie sim ≥ 0,70, commune ✓, dist ≤ 100 m |
| medium | 55 | voie sim ≥ 0,55, commune ✓, dist ≤ 150 m |
| low | 40 | voie sim ≥ 0,40 ou dist ≤ 250 m |
| weak | 20 | tous autres cas — candidat à purge |
Le score est stocké dans la colonne ban_match_score de chaque table, aux côtés de ban_match_method et ban_match_scored_at. Les enregistrements sous seuil (< 40) voient leur lien ban_id remis à NULL automatiquement, puis un nouveau matching est tenté avec une recherche élargie.
Les indicateurs dérivés sont calculés à partir des données croisées :
Un journal d'audit consigne chaque correction automatique : ré-attribution d'un ban_id suite à un score insuffisant, purge d'enregistrement aberrant, transition d'état d'un cron de reconcile.
L'ensemble de la méthodologie est documenté en SQL dans le dépôt technique. Les seuils, les règles de filtrage, les fonctions de scoring sont ouverts à la revue.