Aller au contenu

ADR-025 — Persistance : rester Postgres/Neon (mono-base greffée) + Qdrant pour le vectoriel

Statut Accepted — amendé par ADR-030 sur la partie « mono-base greffée »
Date 26/06/2026 (call archi) — confirmé 29/06 (point Néon)
Décideurs Denis Mludek (CTO), Dimitri Hertz, Romain BAZIL
Origine Synchro archi 26/06 §2 + DMO 29/06 §1-2
Amendé par ADR-030 (20/07/2026) — ownership bases : 2 BDD + API TS pour le métier partagé
Nature Ratification du statu quo (no-change ADR) — confirme Postgres/Neon + Qdrant et écarte Mongo/PG Vector. ⚠️ La greffe mono-base (Python écrit dans le Neon TS) est remplacée par ADR-030. Le point non tranché (source de vérité des projets post-EF) reste hors scope, cf. § Point ouvert.

Contexte

Dimitri reprend l'ownership technique de la partie IA et doit poser la stack de persistance, structurante pour la suite. Deux questions ouvertes : (1) faut-il introduire MongoDB pour stocker le manifeste et la donnée semi-structurée en JSON, ou Postgres suffit ? (2) faut-il garder Qdrant (base vectorielle dédiée) ou se rabattre sur PG Vector pour n'avoir qu'un seul moteur ? Aujourd'hui l'IA Python n'a pas de DB propre : elle écrit dans le Neon (Postgres) de l'outil d'analyse en fin de cycle ; le vectoriel est sur Qdrant.

Décision

Données structurées + semi-structurées (JSONB)  →  Postgres / Neon existant (greffe, pas de nouvelle base)
Recherche vectorielle / similarité               →  Qdrant (collection unique + filtre project_id)
MongoDB                                           →  écarté (sauf besoin réellement justifié)

Dimitri greffe ses tables (manifeste en JSONB + tables semi-structurées bien/financier) sur le Neon existant plutôt que d'ajouter une base. Migrations gérées via Drizzle côté TS, à reprendre/aligner côté Python.

Rationale

  • Postgres sait filtrer dans le JSON : Denis confirme que parcourir / filtrer des champs JSONB est natif et déjà utilisé sur le monorepo → pas besoin de Mongo pour ce cas.
  • Coût de maintenance : éviter d'ajouter une techno (Mongo) à maintenir alors que PG couvre le besoin — règle Denis : « je veux juste que ça soit justifié ».
  • Qdrant > PG Vector à l'échelle : Qdrant applique les filtres a priori (avant la recherche vectorielle), PG Vector a posteriori (recherche puis filtre) → bien moins efficace à gros volume, et nécessite des index compliqués selon la donnée.
  • Mono-base = mapping simple : greffer sur le Neon existant évite la complexité de synchroniser plusieurs bases pour la donnée d'analyse.

Conséquences

Ce qui change

  1. La donnée d'analyse (manifeste, semi-structuré) vit en JSONB sur Neon, pas dans une base séparée.
  2. RAG hybride assumé : structuré (JSON/Neon) + vectoriel (Qdrant), avec un agent qui choisit l'outil (+ vérification/fallback car non-déterministe).
  3. Qdrant : passage à une recherche filtrée par project_id (aujourd'hui similarité sans filtre → mélange de lots, chunks hors contexte).
  4. Migrations Python à formaliser (schéma aujourd'hui quasi inexistant côté Python).

Ce qu'il faut faire

  • Définir le schéma des tables greffées (manifeste JSONB + semi-structuré) et reprendre la gestion des migrations côté Python.
  • Ajouter le filtre project_id systématique sur les recherches Qdrant ; granulariser en collections seulement si nécessaire.
  • Intégrer la devise dans le data model (bug vicieux franc/€ identifié le 29/06).

Ce qu'il faut éviter

  • Ajouter MongoDB sans besoin que PG ne couvre pas.
  • PG Vector comme moteur vectoriel principal vu le volume cible.
  • Multiplier les collections Qdrant prématurément (types de documents en entrée trop hétérogènes pour figer une découpe).

Alternatives écartées

  • MongoDB pour le semi-structuré : non justifié, PG/JSONB fait le travail ; éviterait juste un parcours JSON déjà natif en PG.
  • PG Vector (un seul moteur) : simplicité d'avoir « un seul truc à gérer », mais filtres a posteriori + index complexes + perf dégradée à l'échelle.
  • Nouvelle base dédiée à l'analyse : complexité de mapping/synchro supérieure au gain ; on greffe sur l'existant.

Point ouvert (hors scope de cet ADR)

La source de vérité des projets va bouger : avec la refonte de l'Espace Financement, la table projet vivra dans la DB de l'EF, pas dans le Neon de l'analyse. Mapping (get continu vs réplication) non tranché — à reprendre Denis × Romain (× William, Benoît).

Verbatims

« Tu peux parcourir le JSON, faire des filtres dessus, etc. Aucun souci, on le fait nous aussi. Je veux juste que ça soit justifié. » — Denis (PG vs Mongo)

« Qdrant fait des filtres a priori. PG Vector va d'abord faire une recherche vectorielle puis appliquer les filtres — beaucoup moins efficace sur gros volumes. » — Dimitri

« Si tu as juste un Neon pour le dashboard, je vais greffer mes données dessus pour éviter d'avoir trop de bases à gérer. » — Dimitri

Voir aussi

Sources