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¶
- La donnée d'analyse (manifeste, semi-structuré) vit en JSONB sur Neon, pas dans une base séparée.
- RAG hybride assumé : structuré (JSON/Neon) + vectoriel (Qdrant), avec un agent qui choisit l'outil (+ vérification/fallback car non-déterministe).
- Qdrant : passage à une recherche filtrée par
project_id(aujourd'hui similarité sans filtre → mélange de lots, chunks hors contexte). - 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_idsysté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¶
- ADR-024 Stack Python IA / TS web
- ADR-030 Isolation DB Python × API TS (amende la greffe mono-base)
- ADR-026 Refactoring progressif + LangChain/LangGraph
- ADR-013 Activation ordre de précédence des sources
Sources¶
- Source migrée :
bricks-os/wiki/architecture/ADR-025-persistance-postgres-neon-qdrant.md - Catalogue des sources legacy