Documentation Index
Fetch the complete documentation index at: https://doc.fluximmo.io/llms.txt
Use this file to discover all available pages before exploring further.
RECOMMENDATION_IMPROVE_DOC — Plan de refonte doc Fluximmo
Document destiné à devenir/RECOMMENDATION_IMPROVE_DOC.mdà la racine du repo une fois validé. Audience : Tim (CEO/Tech Fluximmo) + équipe doc/produit. Objectif : refonte UX/DX de la doc Mintlifydoc.fluximmo.io. ⚠️ Scope de cette session : production UNIQUEMENT du fichierRECOMMENDATION_IMPROVE_DOC.mdà la racine. Aucune modification des.mdxni demint.jsonn’est entreprise dans cette session — la refonte effective sera planifiée en sprints séparés (cf §11).
1. Contexte
Fluximmo est un acteur historique (depuis 2017) de l’API d’intelligence immobilière FR. La doc actuelle souffre de friction d’onboarding (3 mentions Calendly), d’absence de quickstart/playbooks/FAQ, de nombreux fichiers.mdx orphelins, et de pages API référence quasi-vides (1 ligne openapi: ref). Les concepts critiques (Property vs Advert, cycle de vie alerte, match types) sont sous-documentés ou éparpillés.
Objectifs primaires de la refonte :
- Autonomie totale : un client doit pouvoir intégrer l’API de bout en bout sans appel ni email, juste avec la doc + sample no-auth + clé test gratuite. Métrique : ratio “tickets posés vs comptes créés”.
- Compatibilité LLM : en 2026 la majorité des clients passent par ChatGPT/Claude pour générer leurs payloads. Vu la complexité (filtres nested, geo, match types), les LLMs échouent souvent → les clients accusent l’API. Nouvelle exigence : page
llms-context.mdxsynthétique copiable/collable + activation du standardllms.txt/llms-full.txtMintlify. - Supériorité perçue : design premium face à Casafari/Melo, identity visuelle modernisée (couleurs, hero, illustrations, diagrammes).
- DX par l’exemple : privilégier exemples concrets > texte brut. Pas d’usine à gaz.
2. État des lieux (synthèse)
| Domaine | Constat |
|---|---|
| Navigation | 75 .mdx, ~61 orphelins/non référencés, doublons (market-analytics x2, properties-analytics x2, estimations x2) |
| Onboarding | 0 quickstart, 0 playbook, 0 FAQ, 0 troubleshooting, 0 errors, 0 rate-limits, 0 changelog |
| Friction | 3 mentions Calendly (intro, auth, baas). Clé test gratuite my.fluximmo.io non mentionnée. Sample endpoints (no-auth) enterrés |
| Concepts | Property vs Advert expliqué partiellement. Cycle de vie alerte (perte historique sur recreate) jamais évoqué. Match types non détaillés |
| API Reference | OpenAPI exhaustif côté swagger, mais .mdx minimalistes — aucune prose, aucun exemple, aucun lien croisé |
| AI / GEO | 16 endpoints quasi non documentés en prose |
| Composants Mintlify | Sous-utilisés : 0 Card/CardGroup, 0 Tabs, 0 CodeGroup, 0 Steps, 0 Mermaid, 0 Warning |
3. Décisions confirmées (Q&A)
| Sujet | Décision |
|---|---|
| Calendly / appel intro | Mention discrète conservée + CTAs Mintlify gardés. Mais retirer des intros + valoriser self-serve |
| Personas cibles | 4 : chasseurs (alertes ADVERT temps réel), marketplaces (réplication BDD), analytics/fintech (search PROPERTIES), AVM (estimations) |
| Scope endpoints | Search/Alerts, Sample/Auth/Quickstart, AI, GEO, et “Sur demande” (capabilities descriptives) |
| Structure | 5 sections : Démarrer / Concepts / Playbooks / API Reference / Ressources |
| Match types (vérité code) | Adverts : ALERT_MATCH_CREATED (nouvelle advert matchée 1x) + ALERT_MATCH_ADVERT_EVENT (event sur advert historiquement matchée) · Properties : ALERT_MATCH_CREATED + ALERT_MATCH_MERGED (= property existante mise à jour, nom legacy au niveau worker = ALERT_PROPERTIES_MATCH_UPDATED) · UNKNOWN legacy. Pas de backfill à la création. |
| Endpoints sur demande | Page unique Capabilities descriptive (pas de schéma OpenAPI exposé) |
| Langue | FR uniquement |
| Exemples payloads | Mix : webhook live /v2/sample/webhook/* + request bodies curated par cas d’usage |
| Doc style | Privilégier exemples > texte brut. Pas d’usine à gaz. Tabs/CodeGroup/Cards systématiquement |
4. User journeys cibles
Avant de penser endpoints, on pense parcours utilisateur. 8 journeys prioritaires :- Découverte sans clé → samples no-auth + visualisation Property/Advert/webhook payload
- Onboarding 5 min → clé test gratuite my.fluximmo.io → premier appel curl → première recherche
- Alerte ADVERT temps réel → créer alerte achat appartement département → recevoir webhook → traiter events (prix, dépub/repub)
- Recherche analytique PROPERTIES → filtrer Paris achat appartement avec
meta.isTotallyOffline=false+ range prix m² + paginer par cursor - ★ Recherche géographique avancée → filtrer par
geoBoundingBox(carte),geoDistance(rayon autour d’un point), polygone GeoJSON (zone dessinée), polygones administratifs (IRIS, canton, commune…) - Réplication BDD adverts → alerte ADVERT large + persistance locale + sync continue via events
- Estimation d’un bien → AI lite estimation → exploitation des price ranges
- Géocodage → résoudre une adresse FR → utiliser l’output dans un filtre
locationsearch
5. Décision matrix — ADVERT vs PROPERTY
| Critère | ADVERT | PROPERTY |
|---|---|---|
| Définition | Annonce individuelle sur un portail (1 URL = 1 advert) | Bien physique unique = agrégation de plusieurs adverts (déduplication multi-portails) |
| Identifiant | flxId (advert) + propertyFlxId (parent) | flxId (property) + adverts[] (constituants) |
| API Search | POST /v2/protected/adverts/search — flux brut, doublons inter-portails | POST /v2/protected/properties/search — vue unique du bien, déduplication |
| Filtre clé spécifique | isOnline, isPro, isExclusive, source, seller[] | meta.isTotallyOffline, filtre nested adverts.* |
| Webhook payload | Payload COMPLET de chaque advert + events | IDs uniquement → refetch obligatoire via GET /v2/protected/properties/{flxId} |
| Events supportés | ✅ OUI : changement prix, online/offline, republication (ALERT_MATCH_ADVERT_EVENT) | ❌ NON : seulement CREATED et MERGED (fusion ex-post) |
| Cas d’usage idéal | Monitoring temps réel, alertes chasseurs, réplication BDD, tracking source-par-source | Recherche analytique, déduplication, valorisation, market intel |
| Anti-pattern | Utiliser pour analytics agrégés (doublons inter-portails) | Utiliser pour suivre les changements de prix d’une annonce précise |
| Coût/perf | Volume plus élevé (toutes les annonces) | Volume réduit, fetch supplémentaire si webhook |
⚠️ Cycle de vie alerte (concept critique non documenté aujourd’hui) : les events d’une alerte ne couvrent QUE les adverts historiquement matchées par cette même alerte. Supprimer + recréer une alerte = perte d’historique (l’alerte recréée ne recevra plus les events des annonces matchées par l’ancienne). À documenter en gras.
⚠️ Pas de backfill à la création (vérifié dans les workers) : une alerte ne match QUE les adverts/properties traitées après sa création. Les annonces antérieures qualifiantes ne seront jamais émises. → Toujours expliquer comment combinersearch(one-shot pour le rétro) +alert(continuous).
⚠️ Events ADVERT exhaustifs réels (workers) :PRICE(toute variation, même 1 €),REPUBLISHED(status passe à online après offline),UNPUBLISHED(status passe à offline).CHECK(vérification sans changement) ne déclenche pas de webhook.
6. Navigation Mintlify proposée
Onglets Mintlify (tabs) à conserver pour navigation rapide par domaine, mais avec la sidebar au-dessus comme source de vérité.
7. Recommandations par endpoint (Search & Alerts)
Pour chaque endpoint : but business · ce qu’il faut documenter · exemples de payloads à créer (filtres, pas JSON) · priorité.7.1 POST /v2/protected/properties/search
- But : recherche analytique avec déduplication (1 ligne = 1 bien physique).
- À documenter : tous les filtres (
locationavec ses 4+ modes géographiques — cf §7.27 ★,offer,price,habitation,land,parking,type,meta.isTotallyOffline,meta.firstSeenAt/lastSeenAt,tags,process,hasAnomaly,isUrgent, nestedadverts.*) ; pagination cursor (searchAfterHash) ; sortBy (5 valeurs) + orderBy ;countsemantics ; usage typique vslite. - Exemples prod-driven (cf Annexe D) — ordre par fréquence d’usage réel :
- ★★ Combo standard dominant : Paris (
postalCodeouinseeCode, pascityqui est ignoré) achat appartement, types[FLAT, HOUSE, PROGRAM], prix 100-350k€, surface 30-110m², 1-3 chambres,isTotallyOffline=false, sortFIRST_SEEN_AT DESC, size 100 - ★ Avec
geoDistancerayon 20 km autour d’une adresse géocodée (20% prod, cas investisseur) - Variante achat avec range prix m² (ex: Paris 8-15k€/m²)
- Bouches-du-Rhône location maison surface ≥ 80 m² 3+ chambres (cas exhaustivité non-prod)
- ★ Investisseur terrains : combo standard + filtre
land - ★
geoBoundingBoxcarte interactive (feature distinctive sous-utilisée à promouvoir) geoShapePOLYGON quartier custom (feature distinctive)- Multi-zones via
location: [...](Paris + 92/93/94) - Pagination cursor
searchAfterHashsur 5 000 résultats
- ★★ Combo standard dominant : Paris (
- Priorité : P0
7.2 POST /v2/protected/properties/search/lite
- But : variante allégée, perf plus rapide, schéma de réponse réduit.
- À documenter : différences vs full (filtres absents :
advertsnested,parking,process,tags,hasAnomaly,isUrgent) ; quand utiliser (UI temps réel, mobile, autocomplete). - Exemples : 1 même cas que full pour comparer · 1 cas mobile/autocomplete.
- Priorité : P1
7.3 POST /v2/protected/properties/search/lite/similar
- But : trouver des biens similaires (à clarifier : similar à un flxId ? à un payload ?).
- À documenter : input attendu, distance/scoring, cas d’usage (recommandation, AVM peer comparison).
- Exemples : 1 cas peer comparison.
- Priorité : P3 (sur demande / capability)
7.4 POST /v2/protected/adverts/search
- But : recherche brute annonces, avec filtres source-spécifiques.
- À documenter : filtres communs + spécifiques adverts (
isOnline,isPro,isExclusive,isAuction,source,seller[],firstSeenAt,lastModifiedAt,propertyFlxId,mainPropertyAdFlxId,scope,currency) ; mêmelocationriche (geoBoundingBox/geoDistance/polygon) — cf §7.27 ★ ; pagination + sorting ; quand préférer à properties search. - Exemples :
- Achat appartement département (idem playbook chasseur)
- ★
geoDistancerayon autour d’une station de métro (chasseur urbain) - Adverts d’un seller spécifique (agence)
- Adverts d’une property donnée (
propertyFlxId) - Adverts pro vs particulier (
isPro)
- Priorité : P0
7.5 PUT /v2/protected/adverts/search/alerts (CREATE)
- But : créer une alerte ADVERT → réception webhook temps réel.
- À documenter : body (
search_query= même schéma que search ·webhook_url·matchenum ·search_name·context) ; comportement à la création (back-fill ? non, uniquement nouveaux matches) ; ⚠️ les events ne s’appliquent qu’aux adverts historiquement matchées ; activate/deactivate vs delete (perte historique). - Exemples :
- Achat appartement département
match=ALERT_MATCH_CREATED(use case #1) - Achat + events
match=ALERT_MATCH_ADVERT_EVENT - Multi-départements via array
- Range prix + surface + chambres
- Achat appartement département
- Priorité : P0
7.6 PUT /v2/protected/adverts/search/alerts/many (BULK CREATE)
- But : créer N alertes en un appel.
- À documenter : limite max, atomicité, cas d’usage (multi-territoires).
- Exemples : 1 cas multi-départements.
- Priorité : P2
7.7 GET /v2/protected/adverts/search/alerts/all (LIST)
- À documenter : pas de pagination visible, format réponse.
- Priorité : P1
7.8 GET /v2/protected/adverts/search/alerts/{alertId} (READ)
- À documenter : utilité (réinspecter config), réponse complète.
- Priorité : P2
7.9 PATCH /v2/protected/adverts/search/alerts/{alertId} (UPDATE)
- À documenter : ⚠️ modifier l’alerte conserve l’historique (≠ delete + recreate), champs modifiables.
- Exemples : 1 changement webhook url · 1 ajout filtre prix.
- Priorité : P1
7.10 DELETE /v2/protected/adverts/search/alerts/{alertId} (DEACTIVATE)
- À documenter : sémantique réelle (deactivate vs hard delete) ; impact sur historique events.
- Priorité : P1
7.11 GET /v2/protected/adverts/search/alerts/{alertId}/activate (REACTIVATE)
- À documenter : pourquoi GET (legacy), comportement post-réactivation (events repris ?).
- Priorité : P2
7.12 GET /v2/protected/adverts/search/alerts/history/{flxId} (HISTORY)
- À documenter : que retourne ce endpoint ? historique des matches d’une alerte ; pagination offset (skip/take, ⚠️ incohérence vs cursor du search) ; cas d’usage (rejouer un backlog).
- Exemples : 1 fetch backlog 30 derniers jours.
- Priorité : P1
7.13–7.20 Properties alerts (CREATE, MANY, LIST, GET, PATCH, DELETE, ACTIVATE, HISTORY)
- Structure miroir des adverts alerts. Même grille de doc.
- Différence clé à mettre en gras : webhook = IDs only · pas d’events sur changement de prix ·
matchenum =CREATED | MERGED | UNKNOWN(pasADVERT_EVENT). Combo prod par défaut :match=[CREATED, MERGED]. - Exemples spécifiques (cf Annexe D — patterns prod) :
- ★★ Combo standard 88% prod : alerte ville+CP achat
[FLAT, HOUSE, PROGRAM]prix 100-350k€isTotallyOffline=falsematch=[CREATED, MERGED] - Properties alert sur département +
meta.isTotallyOffline=false+ refetch IDs reçus - Use case fintech : alerte properties analytics (Paris achat) → fetch périodique pour stats
- ★★ Combo standard 88% prod : alerte ville+CP achat
- Priorité : P0 (CREATE + LIST), P1 (UPDATE, DELETE, HISTORY), P2 (autres)
7.21 GET /v2/protected/adverts/{flxId} & /v2/protected/adverts/by-url
- But : refetch unitaire d’une advert.
- À documenter : codes 404 (advert supprimée du portail), différence by-id vs by-url.
- Priorité : P1
7.22 GET /v2/protected/properties/{flxId} & /by-url & /bulk & /by-advert
- But : refetch après webhook properties (IDs only).
- À documenter :
bulk= batch fetch (taille max, perf) ; quand utiliserby-advert; lien direct webhook → refetch. - Exemples : 1 batch fetch 50 IDs après webhook · 1 cas by-advert.
- Priorité : P0 (bulk + by-id), P1 (autres)
7.23 Sample endpoints (GET /v2/sample/properties|adverts|webhook/properties|webhook/adverts)
- But : visualisation publique sans auth.
- À documenter : ★ mettre en avant fortement dans Démarrer ; usage : tester structure avant d’avoir une clé, debug local, fixtures de tests.
- Priorité : P0
7.24 AI : POST /v2/protected/estimate/property/lite & /v2/protected/experimental/estimate
- À documenter : input (location, habitation, type, offer), output (price, priceRange, confidence/metadata), différence lite vs experimental, cas d’usage AVM.
- Exemples : 1 estimation appartement Paris · 1 estimation maison province.
- Priorité : P1
7.25 GEO : /search, /reverse, /search/csv, /reverse/csv, async projects
- Nature : ⚠️ C’est le BAN / BANO du gouvernement français (api-adresse.data.gouv.fr) que Fluximmo déploie/proxy — pas une brique propriétaire. À assumer franchement dans la doc : “service public BAN/BANO opéré pour vous, sans rate limit gouv”. Évite de survendre.
- À documenter : origine BAN/BANO (transparence + crédibilité) ; usage typique (résoudre adresse → injecter dans
locationsearch Fluximmo) ; index (address, parcel, poi) ; format GeoJSON ; batch CSV sync vs async ; lien externe vers la spec officielle BAN. - Exemples : 1 search “Tour Eiffel” · 1 reverse via lat/lon · 1 batch CSV 10k adresses.
- Priorité : P1
7.26 Capabilities sur demande (DPE/DVF, similar, market analytics, properties analytics, agences, consumption)
- Page descriptive unique : présenter la capability + valeur métier + CTA “Activer” (email contact).
- Pas d’exposition OpenAPI.
- Priorité : P2
7.26.A ★ Page comparative “DVF vs Fluximmo”
- Pourquoi : DVF (gouv) est l’alternative gratuite la plus citée par les startups qui hésitent. Une page comparative honnête désamorce la question avant qu’elle ne devienne un blocage commercial.
- Contenu cible :
- DVF — forces : prix de vente réels (pas de prix annonce), géolocalisation parcellaire précise, gratuit, donnée notariale fiable.
- DVF — limites : aucun temps réel (publication trimestrielle avec lag de 6+ mois), pas de caractéristiques détaillées du bien (pas de photos, pas de description, pas de filtres surface/chambres/équipements précis), pas de webhooks, pas de cycle de vie de l’annonce.
- Fluximmo — forces : temps réel (webhooks adverts/properties), caractéristiques riches (habitation, climat, équipements, photos, full-text), événements (PRICE/REPUBLISHED/UNPUBLISHED), filtres avancés et géo riche, multi-portails dédupliqués.
- Fluximmo — limites : prix = prix annonce (pas prix de vente notarial), couverture marketplace (ce qui est publié uniquement).
- Quand choisir lequel : matrice “Si tu veux X → utilise Y”.
- Combinaison gagnante : Fluximmo (temps réel + caractéristiques) + DVF (prix de vente notariaux historiques) = stack complet. → DVF est dès aujourd’hui disponible chez Fluximmo en capability sur-demande : un seul fournisseur, un seul contrat, pas de double intégration. (Endpoints OpenAPI publics arriveront ensuite.)
- CTA : “Activer DVF sur votre clé” → email contact.
- Format : tableau comparatif côte-à-côte + diagramme Mermaid de complémentarité + 1-2 cas d’usage concrets (“AVM” / “compliance scoring”).
- Path :
concepts/dvf-vs-fluximmo.mdx - Priorité : P1
7.27.A ★★ Page LLM-ready (llms-context.mdx + llms.txt / llms-full.txt)
- Pourquoi : objectif primaire #2. Les clients passent par ChatGPT/Claude. Les payloads complexes (FilterLocation imbriqué, filtres nested, match types) font échouer les LLMs → accusations injustes. Solution : fournir un bloc de contexte compact que le client copie-colle dans son LLM avant de demander un payload.
- 2 livrables complémentaires :
/llms-context.mdx(page humaine + lien “Copier pour LLM”) : version condensée et lisible, accessible depuis la sidebar Démarrer + bouton flottant “Copier pour ChatGPT/Claude” (composant Mintlify clipboard)./llms.txt+/llms-full.txt(servis à la racine, standard llms.txt natif Mintlify) : versions plain-text optimisées pour l’ingestion automatique des LLMs (un index court + une version full).
- Contenu cible (synthétique mais suffisant) :
- Identité Fluximmo en 3 lignes + URL doc + URL sample no-auth (pour que le LLM puisse vérifier).
- Décision matrix Property vs Advert ultra-condensée (5 lignes max).
- Schémas TypeScript-like des principaux DTOs :
FilterProperty,FilterAdvert,FilterLocation(4 modes géo + 4 champs administratifs),FilterPrice,FilterTypeHabitation,FilterMeta,SaveSearchPropertiesPayload,SaveSearchAdvertsPayload. - Enums clés littéraux :
EnumPropertyOfferType,EnumPropertyClass,EnumSearchRequestSortBy,EnumPropertyAlertMatch,EnumAdvertAlertMatch,EnumPricingScope,EnumCurrency. - Limites strictes (size 25/100, max keywords 20, distance > 0, bbox topLeft.lat > bottomRight.lat).
- Match types & events :
CREATED/MERGED(= UPDATED côté worker) /ADVERT_EVENT/ eventsPRICE/REPUBLISHED/UNPUBLISHED. Pas de backfill à la création. - 8-10 archetypes de payloads (texte uniquement, format JSON minifié) couvrant : alerte ADVERT département, search PROPERTIES Paris, geoBoundingBox, geoDistance, geoShape POLYGON, multi-zones INSEE, filtres prix m², refetch bulk properties.
- Anti-patterns critiques (1 paragraphe) : ne pas mocker, ne pas mixer GeoJSON
[lon,lat]avec API{lat,lon}, ne pas reposer sur backfill. - Lien vers la doc complète et les sample endpoints no-auth.
- Contraintes de format :
- Cible 2 000–4 000 tokens max (= ~5-10 K caractères) pour tenir dans une fenêtre prompt LLM standard.
- Pas de fluff marketing. Notation type schémas TS / JSON / Markdown brut.
- Mintlify : utiliser
<RequestExample>ou bloc<CodeGroup>contenant un<copy>button explicite.
- Maintenance :
- Générer (semi-)automatiquement à partir des DTOs (
api_fluximmo_v2/src/modules/app/dto/) — script Node ou Python qui parse les classes class-validator/decorators et émet le contexte. Sinon mise à jour manuelle bimensuelle. - Versionnée (timestamp en bas) pour que les LLMs sachent la fraîcheur.
- Générer (semi-)automatiquement à partir des DTOs (
- Bonus DX :
- Endpoint
GET /llms.txtetGET /llms-full.txtcôté Mintlify déclaré dansmint.json(feature native). - Lien direct dans le footer de chaque page : ”🤖 Copier le contexte LLM”.
- Endpoint
- Priorité : P0 (blocant pour l’objectif autonomie #2)
7.26.B ★ Page “Recevoir des webhooks à fort volume — bonnes pratiques”
- Pourquoi : un client mal préparé qui prend tout en synchrone perd des webhooks (timeout, 5xx, surcharge) et accuse l’API. Mécaniser les bonnes pratiques en amont réduit massivement le support.
- Contenu cible :
- Architecture recommandée : endpoint webhook → ack rapide (200 < 1s) → push vers queue → worker consume async.
- Outils suggérés : RabbitMQ, AWS SQS, Google Pub/Sub, Redis Streams, Kafka (par ordre de complexité). Pour 80% des clients : SQS standard ou RabbitMQ suffit.
- Règles de base :
- Ne jamais traiter en synchrone dans le handler webhook (DB write, fetch externe, ML inference)
- Idempotence : utiliser
flxId + event_type + timestampcomme clé de dédup - Validation
x-webhook-key(cf §C.3) avant ack - Réponse 2xx rapide (Fluximmo retry 2× + DLX 10× × 5min sinon DROP — cf §C.3)
- Persister les payloads bruts dans une table
webhook_inboxavant ack (audit + replay) - Dimensionner la queue : SLO Fluximmo 30-50s, batch max 20 adverts → pic possible
- Anti-patterns : retourner 200 sans persister, ack avant validation, traitement bloquant en handler, pas de queue dead-letter côté client.
- Diagramme Mermaid : flow webhook → queue → workers → DB.
- Snippets : exemple Node Express + SQS, exemple Python Flask + Celery/RabbitMQ.
- Path :
playbooks/webhook-volume-architecture.mdx(joint àconcepts/webhooks.mdx) - Priorité : P1
7.27 ★ Filtres géographiques avancés (transverses search + alerts)
- Pourquoi un focus dédié : argument distinctif Fluximmo très demandé. Aujourd’hui éparpillé/sous-documenté. Doit être un point d’entrée premium dans Concepts + playbook autonome.
- Vérité code (cf elasticimmo Go) : 4 modes natifs ES + champs administratifs indexés + multi-zones via
repeated location(OR avecminimum_should_match=1). Champ index :location(geo_point WGS84). DistanceType =Plane(à signaler pour longues distances). - Modes réels à documenter (tous dans
FilterLocation[]du payload search/alerts) :- Champs administratifs indexés :
inseeCode(commune),irisCode(quartier),postalCode,department. ⚠️ L’INSEE commune fait l’objet d’une lookup vers centroïde (3 686 communes mappées). Pas de support dédiéregionCode/cantonCode/arrondissementCodeau niveau du DTO API actuel — à valider avec produit si on étend. geoBoundingBox:topLeft+bottomRight(LatLng). Cas type : carte interactive “search in this map area”.geoDistance:pin(LatLng) +distanceKm. Cas type : “à X km d’une adresse / station”.geoInseeCodeDistance:inseeCode(commune) +distanceKm. Lookup centroïde → distance. Cas type : “à 10 km de Bordeaux centre”.geoShape:type∈POINT | LINE_STRING | POLYGON | MULTI_POINT | MULTI_LINE_STRING+coordinates(LatLng[]) +relation∈WITHIN | CONTAINS | DISJOINT | INTERSECTS. Cas type : zone dessinée à la main.- Multi-zones :
location: [zone1, zone2, ...]→ OR (matching ≥1 zone). Mix bbox + distance + shape autorisé dans la même requête.
- Champs administratifs indexés :
- Contraintes & anti-patterns (réels code) :
distanceKm > 0strict (rejetInvalidArgument)topLeft.lat > bottomRight.lat(latitudes décroissantes N→S)- DistanceType Plane (euclidien) → erreur > ~50 km, à signaler
- Polygons : ES default ≈ 10 000 vertices max (silencieux)
- bbox immenses : ES tronque silencieusement
- Coords WGS84, ordre GeoJSON
[lon, lat]au stockage interne (l’API reçoit{lat, lon})
- À documenter aussi :
- Combinaison filtres : geoDistance + price + propertyType (cas chasseur typique)
- Pipeline complet : geocoding BAN/BANO → coords →
geoDistanceougeoShape→ search Fluximmo - Performance : impact pagination cursor, sortBy=RELEVANCE est BM25 + boosts title^2/description^3 (pas distance), recommandation bbox vs polygon
- Exemples à créer :
- ★
geoBoundingBoxParis zoom 14 (carte interactive SeLoger-like) - ★
geoDistance1.5 km autour adresse (chaîné après BAN) - ★
geoInseeCodeDistance10 km autour commune (cas province) - ★
geoShapePOLYGON quartier custom (Le Marais) - ★ Multi-zones :
inseeCodeParis + departement92/93/94 - ★ Multi-polygones (3 secteurs d’une agence)
- ★ geoDistance + price m² + isTotallyOffline=false (chasseur typique)
- ★
- Endpoints concernés : properties search (full + lite + similar), adverts search, properties alerts CREATE/UPDATE, adverts alerts CREATE/UPDATE.
- Livrables doc :
- Page concept
concepts/recherche-geographique.mdx(P0) - Playbook
playbooks/recherche-geographique-avancee.mdx(P0) - Mention systématique avec lien depuis chaque endpoint search/alert
- Page concept
- Priorité : P0
7.30 ★ Page “Pour les startups & sur-mesure” (positionnement commercial discret)
- Pourquoi : les startups early-stage hésitent face à un acteur “B2B mature”. Une page dédiée + discount + flexibilité signale l’ouverture, sans surfacer Calendly partout.
- Contenu cible :
- Engagement explicite : on accompagne les startups, on est ouverts aux collaborations sur-mesure, modalités flexibles.
- Discount early-stage mentionné clairement (sans afficher de prix — invite à contacter pour qualif).
- Solutions sur-mesure : endpoints non publics, formats de données customs, alertes complexes multi-territoires, intégrations dédiées.
- Crédibilité : “nous alimentons aujourd’hui les principaux acteurs de l’immo en France” (sans noms).
- Confidentialité clients (point critique) : nous ne communiquons jamais publiquement les noms de nos clients sauf autorisation explicite. Références et études de cas disponibles sur demande dans un cadre commercial confidentiel.
- Cas d’usage typiques que nous accompagnons : réplication BDD marketplaces, scoring fintech, AVM banques/assurances, alertes chasseurs immo, market intelligence, CRM agences.
- CTA discret : email contact + lien
my.fluximmo.io(clé test gratuite 1 semaine).
- Path :
ressources/startups-et-sur-mesure.mdx(visible dans Ressources, pas dans le path d’onboarding pour ne pas alourdir) - Bonus : insérer une bannière discrète (“Vous êtes une startup early-stage ? Discount + collaboration sur-mesure →”) en pied de page de l’introduction et du quickstart.
- Priorité : P1
7.31 ★ Confidentialité clients & références sur demande (transverse)
- Règle absolue : aucun nom client public dans toute la doc. Pas de logos clients, pas de testimonials nominatifs, pas de “they trust us”.
- À la place : tournures factuelles “leaders du marché immobilier français”, “marketplaces, banques, fintechs, scoring”, références disponibles sur demande.
- À mentionner brièvement dans :
introduction.mdx,ressources/startups-et-sur-mesure.mdx, FAQ (“Qui sont vos clients ?”). - Priorité : P1 (consigne éditoriale plus que livrable séparé)
7.32 Nettoyage des @TODO existants
| Fichier | Ligne | Action |
|---|---|---|
authentification.mdx:5 | ”@TODO PAS D’APPEL MIS EN AVANT” | Aligné avec objectif autonomie #1 — réécrire la page sans Calendly proéminent dans P0. |
doc/main-concepts/baas.mdx:12 | Phrase tronquée “filtres @TODO” | Réécrire la phrase, lier vers concepts/filtres-communs.mdx. P0. |
swagger-api-geocoding.json:945,950 | Token XXXXXX / Bearer XXXXXX | Faux positif (placeholder dans description swagger BAN/BANO) — ignorer. |
todo.md (racine) | Méta-fichier instructions | Hors scope — fichier de pilotage, pas de doc publique. |
7.29 ★ Override des titres OpenAPI dans les pages MDX
Problème actuel :https://doc.fluximmo.io/api-v2-reference/properties/get-a-property-by-its-flx_id affiche un titre auto-généré du swagger collé au nom du tag (PropertiesGet a property by it's flx_id) — illisible.
Solution Mintlify confirmée : on peut override directement dans le frontmatter du .mdx, sans toucher au swagger :
STABLE / BETA / DEPRECATED).
Alternative (si on préfère central) : x-mint: { metadata: { title, sidebarTitle, description } } dans le swagger source. Recommandation : frontmatter MDX pour la flexibilité (la doc équipe édite côté MDX, pas côté swagger qui est auto-généré par NestJS).
Priorité : P0 (massive amélioration UX/SEO immédiate, ~2h pour tous les endpoints).
7.28 ★ Refonte UI/UX Mintlify (identité visuelle premium)
Objectif : doc qui transpire la maturité (acteur 2017+) et inspire confiance face à Casafari/Melo. Pas un facelift cosmétique — un signal de sérieux et de modernité.Capacités Mintlify à exploiter
- Background décoratif :
"background": { "decoration": "gradient", "color": { "light": "#…", "dark": "#…" } }→ ambiance premium discrète. - Theme-aware colors :
light/darkpaire par paire pour chaque variable. - Custom CSS (Tailwind via composants JSX inline) : hero cards, badges custom.
- Mode dark/light : ergonomie attendue par les devs.
- Hero React custom sur la landing (composant
<HeroCard>JSX). - Mermaid diagrams natifs (workflows webhook, Property↔Adverts).
- API Playground interactif (intégré OpenAPI Mintlify) : bouton “Try it” sur chaque endpoint avec edition live du payload.
<Frame>pour captures d’écran my.fluximmo.io.- AI search assistant Mintlify (built-in, à activer) : un autre chemin pour atténuer la friction “je ne trouve pas ma réponse”.
- Reusable snippets (Mintlify) : pour la décision matrix, le LLM banner, le footer contact — déduplication systématique.
Direction artistique
- Décision : rebrand complet de la palette (palette actuelle
#ED0040rouge +#7274E4violet → abandonnée). Le rouge dominant n’est plus aligné avec le positionnement “API d’intelligence immobilière mature B2B”. - Direction recommandée à valider en atelier brand :
- Primary :
#1E40AFindigo profond (confiance, FR, données) — ou variante#0F172Aslate très foncé pour un look encore plus premium/data-driven - Secondary/accent :
#10B981emerald (succès, signal “live data”) OU#F59E0Bamber (insight, valorisation) — un seul accent fort, choix à valider - Neutres : tons gris/slate Tailwind (
#F8FAFClight →#0F172Adark) - Background : gradient discret depuis le primary (light:
linear-gradient(135deg, #F8FAFC 0%, #EEF2FF 100%); dark:linear-gradient(135deg, #0F172A 0%, #1E293B 100%))
- Primary :
- Livraison palette : 1 atelier brand (1h) → Figma palette → application progressive. Livrer la doc avec un placeholder palette neutre (slate-only) et appliquer la palette finale en P2.
- Cohérence brand global : prévenir l’équipe que ce rebrand peut/devrait remonter au site marketing (
fluximmo.io) pour cohérence — décision au-delà du périmètre doc. - Typographie : Mintlify default (Inter) suffit, ne pas surcharger.
- Illustrations : 3-5 spots SVG sur landing + 1 par section (Démarrer / Concepts / Playbooks / API Reference / Ressources). Style “minimal isometric” ou “abstract gradient” — éviter les stock photos. Source : commande illustrateur freelance (Figma / Storyset payant) ou génération AI cohérente.
- Diagrammes Mermaid systématiques pour :
- Flow ingestion → indexation → match → webhook
- Decision tree Property vs Advert
- Lifecycle d’une alerte (create → match → event → delete)
- Pipeline geocoding → search Fluximmo
- Retry/DLX webhook (avec timeline)
- Hero landing : phrase d’accroche forte (“L’API d’intelligence immobilière FR, depuis 2017”), 3 cards d’entrée (Découvrir / Démarrer en 5 min / Référence API), illustration de fond gradient.
Détails Mintlify config (mint.json)
- Activer :
"theme","appearance": { "default": "system" },"background": { "decoration": "gradient" },"navigation": { ... }propre. - Activer API playground sur tous les endpoints documentés.
- Activer Mintlify search AI (clé Mintlify Pro requise — à confirmer plan).
- Activer llms.txt natif (
"llms_txt": trueou équivalent — cf §7.27.A). - Topbar : conserver “Mon compte” (CTA fort), retirer ou minimiser “Réserver un appel” (cf objectif autonomie).
Priorité
- P1 pour la palette + background + Mermaid systématique + API playground
- P2 pour les illustrations sur-mesure + Hero landing custom
8. Composants Mintlify à introduire
| Composant | Usage prévu |
|---|---|
<Card> / <CardGroup> | Landing pages (Démarrer, Concepts, Playbooks) — choix de chemin |
<Tabs> | Code samples curl/Python/Node sur chaque exemple |
<CodeGroup> | Multi-langages dans une seule fenêtre de code |
<Steps> | Quickstart, playbooks |
<Note> / <Tip> / <Warning> | Subtilités (cycle de vie alerte, refetch obligatoire) |
<Accordion> | Filtres avancés, FAQ |
<Mermaid> | Diagrammes Property/Advert/Webhook flow |
<Frame> | Captures my.fluximmo.io |
9. Tableau 1 — Endpoint × Documentation × Exemples × Priorité
| Endpoint | Doc à produire | Exemples payloads (filtres) | Prio |
|---|---|---|---|
POST /properties/search | Filtres complets (★ city deprecated/ignoré → utiliser postalCode/inseeCode/department), ★ filtres géo avancés (bbox/distance/polygon/INSEE), cursor, sortBy, lite vs full, count semantics | Combo standard postalCode achat · département entier · geoDistance rayon · geoBoundingBox carte · polygone GeoJSON · multi-zones · isExclusive nested · pagination | P0 |
POST /properties/search/lite | Diff vs full, cas mobile/UI, mêmes modes géo | Idem full · cas autocomplete · ★ bbox temps réel | P1 |
POST /properties/search/lite/similar | Input/output, scoring | Peer comparison AVM | P3 |
POST /adverts/search | Filtres adverts-specific, source/seller, ★ filtres géo avancés | Achat appart dpt · ★ geoDistance autour métro · seller agence · propertyFlxId · isPro | P0 |
PUT /adverts/search/alerts | matchType ADVERT_EVENT, cycle de vie, webhook payload | Alerte chasseur dpt · alerte + events · multi-dpt · range complet | P0 |
PUT /adverts/search/alerts/many | Limite, atomicité | Multi-dpt | P2 |
GET /adverts/search/alerts/all | Format, pas de pagination | — | P1 |
GET /adverts/search/alerts/{id} | Réinspecter config | — | P2 |
PATCH /adverts/search/alerts/{id} | Préserve historique vs delete+create | Maj webhook url · maj filtres | P1 |
DELETE /adverts/search/alerts/{id} | Deactivate vs delete, impact events | — | P1 |
GET /adverts/search/alerts/{id}/activate | Sémantique GET legacy | — | P2 |
GET /adverts/search/alerts/history/{flxId} | Pagination skip/take, replay backlog | Backlog 30j | P1 |
PUT /properties/search/alerts | matchType MERGED, webhook IDs only, refetch | Alerte dpt analytics · isTotallyOffline · multi-dpt | P0 |
PUT /properties/search/alerts/many | Bulk | Multi-dpt | P2 |
GET /properties/search/alerts/all | Format | — | P1 |
GET/PATCH/DELETE /properties/search/alerts/{id} | Idem adverts | Idem adverts | P1/P2 |
GET /properties/search/alerts/{id}/activate | Idem adverts | — | P2 |
GET /properties/search/alerts/history/{flxId} | Idem adverts | Backlog | P1 |
GET /adverts/{flxId} /by-url | Refetch unitaire, 404 | — | P1 |
GET /properties/{flxId} | Refetch unitaire post-webhook | — | P0 |
GET /properties/bulk | Batch fetch post-webhook properties (taille max) | Batch 50 IDs | P0 |
GET /properties/by-url /by-advert | Cas d’usage | — | P1 |
GET /v2/sample/* (4 endpoints, no auth) | ★ Valorisation forte, fixtures | — | P0 |
POST /estimate/property/lite | Input/output AVM, confidence | Appart Paris · maison province | P1 |
POST /experimental/estimate | Diff vs lite, instabilité experimental | — | P2 |
GEO /search /reverse /csv | ⚠️ Origine BAN/BANO Gouv assumée + usage typique → injecter dans search location | Tour Eiffel · reverse coords · batch CSV | P1 |
| GEO async projects (7 endpoints) | Workflow batch async (BAN/BANO) | 1 cas batch async 100k adresses | P2 |
| Capabilities sur demande (DPE, DVF, similar, market/properties analytics, agences, consumption) | Page descriptive, CTA contact | — | P2 |
| ★ Filtres géo avancés (transverse) | Concept + playbook dédié, modes bbox/distance/polygon/INSEE/multi-zones, contraintes, anti-patterns | bbox carte · rayon adresse · polygone custom · multi-zones petite couronne · multi-polygones agence · combo prix+geo | P0 |
10. Tableau 2 — MDX × Goal × Priorité × Dépendances
| MDX (path proposé) | Goal | Prio | Dépend de |
|---|---|---|---|
introduction.mdx (réécrit) | Vision FR-first, supériorité 2017+, supprimer Calendly proéminent | P0 | — |
demarrer/quickstart.mdx | 5 min sans appel : sample → clé test → 1er search | P0 | sample, auth |
demarrer/sample-data.mdx | ★ valoriser endpoints no-auth (4) | P0 | — |
authentification.mdx (réécrit) | Clé test gratuite + clé prod, sans imposer Calendly | P0 | — |
demarrer/limites-rate-limits.mdx | Quotas, headers, backoff | P1 | — |
concepts/property-vs-advert.mdx | Decision matrix (cf §5) | P0 | — |
concepts/webhooks.mdx (refondu) | Archi, retry, signature, déploiement, IDs vs payload | P0 | property-vs-advert |
concepts/filtres-communs.mdx | Référentiel filtres location/offer/price/habitation | P0 | — |
concepts/match-types-cycle-alerte.mdx | ★ MERGED, ADVERT_EVENT, perte historique sur recreate | P0 | property-vs-advert |
concepts/recherche-geographique.mdx | ★ Modes géo (INSEE, bbox, distance, polygon, multi-zones), schémas JSON, contraintes, anti-patterns | P0 | filtres-communs |
llms-context.mdx (+ llms.txt + llms-full.txt) | ★★ Page LLM-ready copiable/collable + standards llms.txt natifs Mintlify | P0 | concepts, modèles, filtres |
concepts/baas.mdx (allégé) | Vue d’ensemble moteurs | P2 | — |
playbooks/alerte-advert-departement.mdx | Use case #1 chasseur immo | P0 | adverts/search/alerts, webhooks |
playbooks/search-properties-analytique.mdx | Use case #2 analytics Paris | P0 | properties/search, filtres |
playbooks/replicate-bdd-adverts.mdx | Sync continue marketplace | P1 | adverts alerts, webhooks |
playbooks/track-price-changes.mdx | Events ADVERT temps réel | P1 | adverts alerts, match types |
playbooks/estimer-un-bien.mdx | AVM AI lite | P1 | AI |
playbooks/geocoder-pour-search.mdx | GEO (BAN/BANO Gouv) → injection location filter | P1 | GEO, properties/search |
playbooks/recherche-geographique-avancee.mdx | ★ Cas concrets bbox/rayon/polygon/multi-zones, chaîne BAN→search | P0 | recherche-geographique, properties/search, adverts/search |
api-reference/... (existant) | Enrichir chaque .mdx OpenAPI avec prose + 2-3 exemples curated | P0 (search/alerts), P1 (AI/GEO), P2 (autres) | concepts, playbooks |
api-reference/_models/property.mdx (réécrit) | Champs + décisions + lien decision matrix | P0 | property-vs-advert |
api-reference/_models/advert.mdx (réécrit) | Idem | P0 | property-vs-advert |
api-reference/capabilities-sur-demande.mdx | DPE, DVF, similar, market analytics, agences, consumption | P2 | — |
ressources/faq.mdx | Top 15 questions (auth, webhooks, refetch, pagination, alertes) | P1 | concepts |
ressources/codes-erreur.mdx | Codes HTTP + métier (10001/10002/10003), exemples body erreur | P1 | — |
ressources/webhooks-livraison.mdx | Headers (x-webhook-key), pas de signature HMAC, retry 2+10×5min, DROP après ~50min, codes 200-205, SLO 30-50s | P1 | webhooks |
ressources/bonnes-pratiques.mdx | Pagination, retry, idempotence, refetch, validation webhook par x-webhook-key | P1 | concepts, webhooks-livraison |
ressources/changelog.mdx | Versions v2.x | P2 | — |
ressources/contact.mdx | Email + Calendly discret | P2 | — |
ressources/startups-et-sur-mesure.mdx | Engagement startups, discount early-stage, sur-mesure, références sur demande, pas de noms clients publics | P1 | — |
concepts/dvf-vs-fluximmo.mdx | Comparatif honnête DVF vs Fluximmo + complémentarité | P1 | property-vs-advert |
playbooks/webhook-volume-architecture.mdx | Architecture queue (RMQ/SQS), idempotence, ack rapide, anti-patterns | P1 | webhooks, webhooks-livraison |
11. Roadmap priorisée
P0 — Foundation (livraison sprint 1, ~5-7j)
- Nettoyer mint.json (orphelins, doublons), nouvelle structure 5 sections
- ★★ Désactiver/minimiser tous les CTAs Calendly (objectif autonomie #1)
- Nettoyage des @TODO existants (authentification, baas)
- Réécrire
introduction,authentification,quickstart,sample-data - Décision matrix Property vs Advert + page concepts associée
- Refonte
webhooks.mdx+ page Match types & cycle de vie alerte - Page filtres communs
- ★ Page concept Recherche géographique (4 modes + multi-zones + INSEE commune)
- ★★ Page LLM-ready
llms-context.mdx+ activationllms.txt/llms-full.txtMintlify - ★ Override frontmatter title/sidebarTitle/description sur tous les .mdx OpenAPI (~2h)
- Enrichir 6 endpoints Search/Alerts P0 (properties search, adverts search, properties alert CREATE, adverts alert CREATE, properties bulk, properties get)
- 3 playbooks fondateurs : Alerte ADVERT département + Search PROPERTIES analytique + ★ Recherche géographique avancée
- Modèles Property et Advert réécrits
P1 — Coverage + UI/UX (sprint 2, ~5-7j)
- Tous les autres endpoints alerts (LIST, UPDATE, DELETE, HISTORY)
- Adverts get + properties by-url/by-advert
- AI (estimations) + GEO (search/reverse) avec prose et exemples
- 5 playbooks : Réplication BDD, Track price changes, Estimer un bien, Géocoder, Webhook architecture haut volume (queue)
- Page comparative DVF vs Fluximmo
- Page Startups & sur-mesure + bannière discrète early-stage + consigne éditoriale “pas de noms clients publics”
- FAQ, Codes erreur, Bonnes pratiques, Limites/rate limits, Webhooks-livraison
- ★ Refonte UI/UX Mintlify : nouvelle palette validée, background gradient, dark mode, Mermaid diagrammes systématiques (5 diagrammes clés), API playground activé, AI search activé (si plan le permet)
P2 — Polish (sprint 3, ~3-5j)
- Bulk alerts CREATE many (properties + adverts)
- Activate endpoints
- GEO async batch
- Capabilities sur demande (DPE, DVF, similar, market analytics, agences, consumption)
- Experimental estimate
- Changelog, Contact, BaaS allégé
- Illustrations sur-mesure (5-10 SVG) + Hero landing custom (composant React)
- Snippets Mintlify réutilisables (décision matrix, footer, banners)
- Script de génération automatique du
llms-context.mdxà partir des DTOs (CI/CD)
P3 — Nice-to-have
properties/search/lite/similar(sur demande)- Mermaid diagrammes (workflow Property/Advert/Webhook)
- Dark mode visuels, captures my.fluximmo.io
- Exemples SDK (Python, Node) si lib officielle livrée
12. Indicateurs de succès (post-livraison)
- Autonomie : ratio “tickets / nouveaux comptes” divisé par 2 sur 3 mois
- Time-to-first-call < 5 min (depuis landing)
- CTA Calendly absent avant la 3ᵉ page profondeur
- Couverture exemples : tout endpoint P0/P1 a ≥ 2 exemples curated + 1 lien playbook
- Decision matrix Property vs Advert accessible en ≤ 2 clics
- FAQ couvre les 15 top questions support actuelles (à collecter auprès du support)
- LLM accuracy : tester
llms-context.mdxen demandant à GPT-5 / Claude de générer 5 payloads variés → ≥ 4/5 valides au premier essai - UI : score Lighthouse Performance ≥ 90, Accessibility ≥ 95, dark mode fluide
15. Questions ouvertes / décisions à prendre
| Sujet | Question | Recommandation |
|---|---|---|
Filtre city | Garder dans le DTO API (silent-ignore) ou retirer / déprécier ? | À court terme : marquer @deprecated dans le swagger + warning de validation côté API si fourni seul (sans postalCode/inseeCode/department). À long terme : retirer du DTO. |
ALERT_MATCH_MERGED naming | Garder le terme “MERGED” public alors que côté worker c’est “UPDATED” ? | Garder MERGED public (breaking change sinon), mais expliquer dans Concepts que sémantiquement = property mise à jour. |
| Niveaux INSEE étendus | Étendre inseeCode aux niveaux département/région/IRIS ? | À discuter produit — actuellement commune-only via lookup. Fort impact UX si étendu (vrai pouvoir géo administratif). |
| AI search Mintlify | Plan tarifaire requis ? | Vérifier si le plan actuel inclut l’AI search built-in. Si non, calculer le ROI. |
| Rebrand couleur | Atelier brand 1h pour valider la palette finale | Bloquer un créneau avec design/marketing avant P1. |
13. Vérification end-to-end
Une fois la refonte livrée :- Lancer
mintlify devlocalement → vérifier 0 lien cassé, navigation cohérente - Tester journey “découverte” : depuis introduction, atteindre un sample no-auth en ≤ 2 clics
- Tester journey “quickstart” : suivre le quickstart from scratch sur clé test → premier search OK
- Lancer un appel curl sur chaque sample endpoint depuis la doc (copier-coller doit marcher)
- Vérifier que chaque endpoint P0/P1 a au moins 1 exemple, 1 cas d’erreur, 1 lien croisé concept/playbook
- Search interne (Mintlify) : “alerte département” → playbook chasseur en top 3 résultats
Annexe A — Fichiers clés à modifier
| Path | Action |
|---|---|
mint.json | Refonte complète navigation (groupes, ordre, tabs) |
introduction.mdx | Réécriture (vision FR-first, supprimer Calendly) |
authentification.mdx | Réécriture (clé test gratuite proéminente) |
doc/main-concepts/baas.mdx | Allégé, déplacé en Concepts |
doc/main-concepts/properties-adverts.mdx | Étendu en concepts/property-vs-advert.mdx (decision matrix) |
doc/main-concepts/webhooks.mdx | Refonte (signature, retry, déploiement, samples webhook) |
api-v2-reference/_api-models/property.mdx | Étendu (champs + décisions) |
api-v2-reference/_api-models/advert.mdx | Idem |
api-v2-reference/{properties-search,adverts-search}/*.mdx | Enrichir avec prose + exemples curated |
api-v2-reference/{properties-alerts,adverts-alerts}/*.mdx | Idem + cycle de vie |
api-v2-reference/sample-{adverts,properties}/*.mdx | Valoriser, lier depuis Démarrer |
| Nouveaux fichiers | Tous les playbooks, FAQ, codes erreur, bonnes pratiques, limites, capabilities sur demande, quickstart |
Annexe D — Patterns d’usage réels (analyse échantillon récent prod)
Source :/__samples/{adverts_alerts.csv, properties_alerts.csv, requests.csv}.
⚠️ Lecture précautionneuse : ces CSV sont un échantillon récent (requêtes/alertes des dernières semaines), non exhaustifs et non représentatifs en volume global. Les pourcentages cités ci-dessous donnent une tendance qualitative (quels combos existent et lesquels semblent fréquents), pas une distribution prod officielle. À utiliser pour calibrer les archétypes d’exemples, pas pour des assertions chiffrées dans la doc publique.
D.1 Top filtres réellement utilisés
- Properties (88% des cas) — combo standard :
price+offer+location+type+meta+habitation+adverts.isOnline. C’est l’exemple #1 à mettre partout. - Properties (8.8%) : combo standard +
land(investisseurs terrains). - Adverts (54% — bruit) :
source-only (probablement tests / monitoring brut). Les clients sérieux passent par Properties. - Adverts (12% — sérieux) :
type+offer+location+habitation+process.
D.2 Modes géo réels (vs feature distinctive)
⚠️ CRITICAL : le champ city (string) ne filtre PAS réellement (désactivé côté code à cause de la non-normalisation des noms de villes — “Paris” / “PARIS” / “paris 1er” / “Paris 75001”…). Il est silencieusement ignoré. À documenter en gras comme deprecated / ignoré + masquer dans les exemples + question ouverte (cf §15) : faut-il le retirer du DTO ou afficher un warning de validation ?
→ Les clients qui mettent { "city": "Paris", "postalCode": "75001" } filtrent en réalité uniquement par postalCode. Les % ci-dessous reflètent le filtre utile.
| Mode | Usage échantillon | Doc |
|---|---|---|
postalCode (seul ou avec city ignoré) | dominant | ★ Exemple par défaut #1 |
geoDistance (rayon, médiane 20 km, plage 5-50) | ~20% | ★ Exemple #2 |
inseeCode (commune) | rare en échantillon, mais recommandé vs city | À promouvoir comme alternative robuste à city |
department (code 2 chiffres) | présent | ★ Exemple #3 (cas chasseur département entier) |
irisCode | rare | Documenter pour cas urbain fin |
geoBoundingBox | absent en échantillon | Documenter (cas carte interactive — feature distinctive à promouvoir) |
geoShape POLYGON | absent en échantillon | Documenter brièvement (capability distinctive) |
| Multi-zones (array) | présent ponctuellement | Documenter (cas agence multi-territoires) |
postalCode / inseeCode / department / geoDistance comme modes primaires. city est marqué “non utilisé pour le filtrage” + retiré des exemples. Les modes avancés (geoBoundingBox, geoShape, multi-zones) restent documentés en P0/P1 comme features distinctives.
D.3 Enums dominants
offer.type=OFFER_BUY100% (RENT quasi-nul). → Exemples primaires en achat, location en exemple secondaire pour exhaustivité.type=CLASS_FLAT85% +CLASS_HOUSE98% +CLASS_PROGRAM66% (neuf très utilisé). → Toujours inclurePROGRAMdans les exemples par défaut.meta.isTotallyOffline=false100%. → Best practice à documenter en gras : c’est le filtre clé pour qualité prod.
D.4 Ranges réels (à utiliser dans les exemples)
- Prix : médiane 200 k€, p75 358 k€, p95 900 k€. Range typique : 100-350 k€.
- Surface : médiane 110 m², p95 295 m².
- Rooms min : médiane 2-3.
- Rayon
geoDistance: médiane 20 km, plage 5-50.
D.5 Pagination réelle
size=100 (60% des requêtes), 80 (26%) → utiliser size=100 dans tous les exemples search.sortBy=FIRST_SEEN_ATDESC(62%) → défaut canonique dans la doc.LAST_SEEN_AT DESC(26%) → cas “monitoring activité”.
D.6 Match types réels (alerts properties)
- Combos fréquents :
[CREATED, MERGED]est le défaut prod recommandé. - → Documenter ce combo en exemple primaire.
D.7 À déprioriser dans la doc (peu utilisé en prod)
keywords/fullTexts(1 cas / 154) — mention brève uniquement.process,tags,hasAnomaly,isUrgent— pas en exemple primaire.- Filtre
climate.epcEnergy“toutes classes” — non-restrictif, pédagogique seulement.
D.8 Anti-patterns prod observés à signaler
- ★★
city(string) est silencieusement ignoré — utiliserpostalCode,inseeCode, oudepartmentà la place. À mettre en gras dans la doc Concepts/filtres-communs. - Adverts source-only : sans valeur métier pour la plupart des cas, signaler comme “test only”.
filterPropertyvide → renvoie tout le catalogue, danger perf + facturation.- Webhook URL non-HTTPS : rejetée à la création (cf §C.3).
D.9 Implication concrète sur la roadmap
- Les 10 archétypes prod identifiés deviennent les 10 exemples curated obligatoires à livrer en P0/P1 (cf §7 et tableau §9).
- 80% des clients sont couverts par : combo standard properties + city/postalCode + size=100 + sortBy=FIRST_SEEN_AT DESC + isTotallyOffline=false + match=[CREATED,MERGED] + offer=BUY + types=[FLAT,HOUSE,PROGRAM].
Annexe C — Vérités code à intégrer dans la doc (deltas vs OpenAPI)
Issu de l’exploration des reposapi_fluximmo_v2 (NestJS), elasticimmo (Go), prod_fluximmo/v2/_workers (Python).
C.1 Limites & contraintes réelles
| Endpoint | Champ | Limite réelle code |
|---|---|---|
POST /properties/search | size | 1–25 (max 25) |
POST /properties/search/lite | size | 1–25 |
POST /properties/search/lite/similar | size | 1–100 |
POST /adverts/search | size | 1–100 |
| Search (tous) | keywords[], fullTexts[] | Max 20 items chacun |
| Webhooks adverts | batch | 20 adverts par delivery (MAX_BATCH_SIZE=20) |
geoDistance.distanceKm | — | Strictement > 0 sinon rejet |
geoBoundingBox | — | topLeft.lat > bottomRight.lat requis |
geoShape polygon | vertices | ≈ 10 000 max (limite ES, silencieuse) |
C.2 Match types & events (corrigés vs OpenAPI)
- Adverts :
ALERT_MATCH_CREATED: 1× par couple (alert, advert) — dédup garantie via contrainte UNIQUEALERT_MATCH_ADVERT_EVENT: webhook reçoitevent_type∈PRICE | REPUBLISHED | UNPUBLISHED
- Properties :
ALERT_MATCH_CREATED: nouvelle propertyALERT_MATCH_MERGED: property existante mise à jour (côté worker =ALERT_PROPERTIES_MATCH_UPDATED). Le nom “MERGED” est l’API publique, à expliquer pour éviter la confusion.
C.3 Webhook delivery (à documenter en P1)
- Headers envoyés :
Content-Type: application/json,x-webhook-key: <client_token>,x-api-key(legacy duplicate). Pas de signature HMAC, pas de timestamp. Le client doit valider sur la valeur statique dex-webhook-key. - Retry : 2 retries internes + 30 s timeout + 10 s sleep entre. Puis DLX : 10 tentatives × 5 min de delay. Total worst case ≈ 50 minutes, ensuite DROP silencieux (pas de notification client).
- SLO normal : 30–50 s entre match et delivery. À documenter clairement (pas de “temps réel sub-seconde”).
- Codes succès acceptés : 200–205 (inclus 203, 204, 205 — atypique).
C.4 Codes erreur API (vérité code)
| Code interne | HTTP | Sens |
|---|---|---|
10001 | 408/500 | HTTP request timeout (ES) |
10002 | 400 | Validation error (DTO) |
10003 | 500 | Unexpected |
C.5 Pas de rate limiting exposé
Aucun headerX-RateLimit-* retourné par l’API publique. Documenter neutralement : “Si vous rencontrez des throttling, contactez-nous” (sans surpromettre des limites publiques).
C.6 Sample no-auth confirmés
GET /v2/sample/propertiesGET /v2/sample/advertsGET /v2/sample/webhook/propertiesGET /v2/sample/webhook/advertsGET /portals(no auth, liste portails sources réels)GET /version,GET /healthz(no auth, util DX)
C.7 Schémas DTO clés à cristalliser dans la doc Concepts
FilterLocation: 4 modes géo + 4 champs administratifs (cf §7.27)FilterPrice(properties) :initial/latest/highest/lowest+scope[]+currency[]+variation[]+isAuctionFilterAdvertPrice:currentPrice.value+currentPrice.valuePerAreaFilterMeta(properties only) :firstSeenAt/lastSeenAt/lastUpdatedAt/lastPublishedAt/isTotallyOfflineFilterTypeHabitation: surface (total/habitable), roomCount, bedroomCount, bathroomCount, type T1-T5+, characteristics, climate (EPC), heatFilterAdvert-only :isOnline,isPro,isExclusive,isAuction,source,seller[],firstSeenAt,lastModifiedAt,propertyFlxId- Enums :
EnumPropertyOfferTypeDto(BUY/RENT/AUCTION/LIFE_ANNUITY_SALE/LEASE_BACK/BUSINESS_TAKE_OVER/HOLIDAYS),EnumPropertyClassDto(HOUSE/FLAT/PROGRAM/SHOP/PREMISES/OFFICE/LAND/BUILDING/PARKING/ROOM/OTHER),EnumSearchRequestSortByDto(FIRST_SEEN_AT/PRICE/LAST_UPDATED_AT/LAST_SEEN_AT/RELEVANCE) - Scoring
RELEVANCE= BM25 + boosts (title^2,description^3, n-gram, fuzziness 1) → à expliquer pour éviter “pourquoi le tri RELEVANCE n’est pas par distance ?”
C.8 Endpoints publics non encore listés
GET /portals(no auth)GET /version,GET /healthz(no auth)- v1 legacy :
GET /v1/adverts/search,GET /v1/adverts/urls,GET /v1/analytics/...→ à mentionner brièvement comme legacy (sans encourager)
Annexe B — Concurrents inspirations retenues
| Source | À reprendre |
|---|---|
| Casafari API docs | Hiérarchie claire Concepts / Reference / FAQ, badges visuels |
Melo /api-reference/concepts | Format des concepts (court, comparatifs, exemples mini) |
Melo /api-reference/faq | Format FAQ avec accordéons par thème |
| Stripe docs | Tabs code curl/Python/Node, recipes/playbooks orientés use case |
| Mintlify guidelines | Cards landing, Steps quickstart, Mermaid diagrammes |

