Skip to main content

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 Mintlify doc.fluximmo.io. ⚠️ Scope de cette session : production UNIQUEMENT du fichier RECOMMENDATION_IMPROVE_DOC.md à la racine. Aucune modification des .mdx ni de mint.json n’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 :
  1. 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”.
  2. 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.mdx synthétique copiable/collable + activation du standard llms.txt/llms-full.txt Mintlify.
  3. Supériorité perçue : design premium face à Casafari/Melo, identity visuelle modernisée (couleurs, hero, illustrations, diagrammes).
  4. DX par l’exemple : privilégier exemples concrets > texte brut. Pas d’usine à gaz.

2. État des lieux (synthèse)

DomaineConstat
Navigation75 .mdx, ~61 orphelins/non référencés, doublons (market-analytics x2, properties-analytics x2, estimations x2)
Onboarding0 quickstart, 0 playbook, 0 FAQ, 0 troubleshooting, 0 errors, 0 rate-limits, 0 changelog
Friction3 mentions Calendly (intro, auth, baas). Clé test gratuite my.fluximmo.io non mentionnée. Sample endpoints (no-auth) enterrés
ConceptsProperty vs Advert expliqué partiellement. Cycle de vie alerte (perte historique sur recreate) jamais évoqué. Match types non détaillés
API ReferenceOpenAPI exhaustif côté swagger, mais .mdx minimalistes — aucune prose, aucun exemple, aucun lien croisé
AI / GEO16 endpoints quasi non documentés en prose
Composants MintlifySous-utilisés : 0 Card/CardGroup, 0 Tabs, 0 CodeGroup, 0 Steps, 0 Mermaid, 0 Warning

3. Décisions confirmées (Q&A)

SujetDécision
Calendly / appel introMention discrète conservée + CTAs Mintlify gardés. Mais retirer des intros + valoriser self-serve
Personas cibles4 : chasseurs (alertes ADVERT temps réel), marketplaces (réplication BDD), analytics/fintech (search PROPERTIES), AVM (estimations)
Scope endpointsSearch/Alerts, Sample/Auth/Quickstart, AI, GEO, et “Sur demande” (capabilities descriptives)
Structure5 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 demandePage unique Capabilities descriptive (pas de schéma OpenAPI exposé)
LangueFR uniquement
Exemples payloadsMix : webhook live /v2/sample/webhook/* + request bodies curated par cas d’usage
Doc stylePrivilé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 :
  1. Découverte sans clé → samples no-auth + visualisation Property/Advert/webhook payload
  2. Onboarding 5 min → clé test gratuite my.fluximmo.io → premier appel curl → première recherche
  3. Alerte ADVERT temps réel → créer alerte achat appartement département → recevoir webhook → traiter events (prix, dépub/repub)
  4. Recherche analytique PROPERTIES → filtrer Paris achat appartement avec meta.isTotallyOffline=false + range prix m² + paginer par cursor
  5. ★ 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…)
  6. Réplication BDD adverts → alerte ADVERT large + persistance locale + sync continue via events
  7. Estimation d’un bien → AI lite estimation → exploitation des price ranges
  8. Géocodage → résoudre une adresse FR → utiliser l’output dans un filtre location search
Chaque journey aura son playbook dédié (cf §7).

5. Décision matrix — ADVERT vs PROPERTY

CritèreADVERTPROPERTY
DéfinitionAnnonce individuelle sur un portail (1 URL = 1 advert)Bien physique unique = agrégation de plusieurs adverts (déduplication multi-portails)
IdentifiantflxId (advert) + propertyFlxId (parent)flxId (property) + adverts[] (constituants)
API SearchPOST /v2/protected/adverts/search — flux brut, doublons inter-portailsPOST /v2/protected/properties/search — vue unique du bien, déduplication
Filtre clé spécifiqueisOnline, isPro, isExclusive, source, seller[]meta.isTotallyOffline, filtre nested adverts.*
Webhook payloadPayload COMPLET de chaque advert + eventsIDs 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éalMonitoring temps réel, alertes chasseurs, réplication BDD, tracking source-par-sourceRecherche analytique, déduplication, valorisation, market intel
Anti-patternUtiliser pour analytics agrégés (doublons inter-portails)Utiliser pour suivre les changements de prix d’une annonce précise
Coût/perfVolume 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 combiner search (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

Démarrer
├── Introduction (vision, depuis 2017, FR-first, supériorité)
├── Quickstart (5 min, sans appel)
├── Données d'exemple (sample, no-auth) ★ valorisé
├── Authentification (clé test gratuite + clé prod)
└── Limites & rate limits

Concepts principaux
├── Property vs Advert (decision matrix)
├── Webhooks (architecture, retry, signature, déploiement)
├── Filtres communs (location, offer, price, habitation…)
├── Match types & cycle de vie d'une alerte ★ critique
└── BaaS — vue d'ensemble des moteurs

Playbooks
├── Recevoir une alerte ADVERT par département
├── Rechercher des PROPERTIES analytiques (Paris, achat appartement)
├── Répliquer la BDD adverts chez le client
├── Suivre les changements de prix en temps réel
├── Estimer un bien via l'API AI
└── Géocoder une adresse pour filtrer une recherche

API Reference
├── Search & Alerts
│   ├── Properties (search, search lite, alerts CRUD)
│   └── Adverts (search, alerts CRUD, get by id/url, raise issue)
├── AI (estimations lite + experimental)
├── GEO (search, reverse, batch sync, batch async)
├── Modèles
│   ├── Property
│   └── Advert
└── Capabilities sur demande (DPE, DVF prochainement, similar, market analytics, properties analytics, agences, consumption)

Ressources
├── FAQ
├── Codes d'erreur
├── Bonnes pratiques (pagination, retry, idempotence, refetch)
├── Changelog
└── Contact
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 (location avec ses 4+ modes géographiques — cf §7.27 ★, offer, price, habitation, land, parking, type, meta.isTotallyOffline, meta.firstSeenAt/lastSeenAt, tags, process, hasAnomaly, isUrgent, nested adverts.*) ; pagination cursor (searchAfterHash) ; sortBy (5 valeurs) + orderBy ; count semantics ; usage typique vs lite.
  • Exemples prod-driven (cf Annexe D) — ordre par fréquence d’usage réel :
    1. ★★ Combo standard dominant : Paris (postalCode ou inseeCode, pas city qui est ignoré) achat appartement, types [FLAT, HOUSE, PROGRAM], prix 100-350k€, surface 30-110m², 1-3 chambres, isTotallyOffline=false, sort FIRST_SEEN_AT DESC, size 100
    2. ★ Avec geoDistance rayon 20 km autour d’une adresse géocodée (20% prod, cas investisseur)
    3. Variante achat avec range prix m² (ex: Paris 8-15k€/m²)
    4. Bouches-du-Rhône location maison surface ≥ 80 m² 3+ chambres (cas exhaustivité non-prod)
    5. ★ Investisseur terrains : combo standard + filtre land
    6. geoBoundingBox carte interactive (feature distinctive sous-utilisée à promouvoir)
    7. geoShape POLYGON quartier custom (feature distinctive)
    8. Multi-zones via location: [...] (Paris + 92/93/94)
    9. Pagination cursor searchAfterHash sur 5 000 résultats
  • 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 : adverts nested, 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ême location riche (geoBoundingBox/geoDistance/polygon) — cf §7.27 ★ ; pagination + sorting ; quand préférer à properties search.
  • Exemples :
    1. Achat appartement département (idem playbook chasseur)
    2. geoDistance rayon autour d’une station de métro (chasseur urbain)
    3. Adverts d’un seller spécifique (agence)
    4. Adverts d’une property donnée (propertyFlxId)
    5. 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 · match enum · 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 :
    1. Achat appartement département match=ALERT_MATCH_CREATED (use case #1)
    2. Achat + events match=ALERT_MATCH_ADVERT_EVENT
    3. Multi-départements via array
    4. Range prix + surface + chambres
  • 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 · match enum = CREATED | MERGED | UNKNOWN (pas ADVERT_EVENT). Combo prod par défaut : match=[CREATED, MERGED].
  • Exemples spécifiques (cf Annexe D — patterns prod) :
    1. ★★ Combo standard 88% prod : alerte ville+CP achat [FLAT, HOUSE, PROGRAM] prix 100-350k€ isTotallyOffline=false match=[CREATED, MERGED]
    2. Properties alert sur département + meta.isTotallyOffline=false + refetch IDs reçus
    3. Use case fintech : alerte properties analytics (Paris achat) → fetch périodique pour stats
  • 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 utiliser by-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 location search 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 :
    1. /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).
    2. /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) :
    1. Identité Fluximmo en 3 lignes + URL doc + URL sample no-auth (pour que le LLM puisse vérifier).
    2. Décision matrix Property vs Advert ultra-condensée (5 lignes max).
    3. Schémas TypeScript-like des principaux DTOs : FilterProperty, FilterAdvert, FilterLocation (4 modes géo + 4 champs administratifs), FilterPrice, FilterTypeHabitation, FilterMeta, SaveSearchPropertiesPayload, SaveSearchAdvertsPayload.
    4. Enums clés littéraux : EnumPropertyOfferType, EnumPropertyClass, EnumSearchRequestSortBy, EnumPropertyAlertMatch, EnumAdvertAlertMatch, EnumPricingScope, EnumCurrency.
    5. Limites strictes (size 25/100, max keywords 20, distance > 0, bbox topLeft.lat > bottomRight.lat).
    6. Match types & events : CREATED / MERGED (= UPDATED côté worker) / ADVERT_EVENT / events PRICE / REPUBLISHED / UNPUBLISHED. Pas de backfill à la création.
    7. 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.
    8. Anti-patterns critiques (1 paragraphe) : ne pas mocker, ne pas mixer GeoJSON [lon,lat] avec API {lat,lon}, ne pas reposer sur backfill.
    9. 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.
  • Bonus DX :
    • Endpoint GET /llms.txt et GET /llms-full.txt côté Mintlify déclaré dans mint.json (feature native).
    • Lien direct dans le footer de chaque page : ”🤖 Copier le contexte LLM”.
  • 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 :
      1. Ne jamais traiter en synchrone dans le handler webhook (DB write, fetch externe, ML inference)
      2. Idempotence : utiliser flxId + event_type + timestamp comme clé de dédup
      3. Validation x-webhook-key (cf §C.3) avant ack
      4. Réponse 2xx rapide (Fluximmo retry 2× + DLX 10× × 5min sinon DROP — cf §C.3)
      5. Persister les payloads bruts dans une table webhook_inbox avant ack (audit + replay)
      6. 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 avec minimum_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) :
    1. 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/arrondissementCode au niveau du DTO API actuel — à valider avec produit si on étend.
    2. geoBoundingBox : topLeft + bottomRight (LatLng). Cas type : carte interactive “search in this map area”.
    3. geoDistance : pin (LatLng) + distanceKm. Cas type : “à X km d’une adresse / station”.
    4. geoInseeCodeDistance : inseeCode (commune) + distanceKm. Lookup centroïde → distance. Cas type : “à 10 km de Bordeaux centre”.
    5. geoShape : typePOINT | LINE_STRING | POLYGON | MULTI_POINT | MULTI_LINE_STRING + coordinates (LatLng[]) + relationWITHIN | CONTAINS | DISJOINT | INTERSECTS. Cas type : zone dessinée à la main.
    6. Multi-zones : location: [zone1, zone2, ...] → OR (matching ≥1 zone). Mix bbox + distance + shape autorisé dans la même requête.
  • Contraintes & anti-patterns (réels code) :
    • distanceKm > 0 strict (rejet InvalidArgument)
    • 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 → geoDistance ou geoShape → search Fluximmo
    • Performance : impact pagination cursor, sortBy=RELEVANCE est BM25 + boosts title^2/description^3 (pas distance), recommandation bbox vs polygon
  • Exemples à créer :
    1. geoBoundingBox Paris zoom 14 (carte interactive SeLoger-like)
    2. geoDistance 1.5 km autour adresse (chaîné après BAN)
    3. geoInseeCodeDistance 10 km autour commune (cas province)
    4. geoShape POLYGON quartier custom (Le Marais)
    5. ★ Multi-zones : inseeCode Paris + departement 92/93/94
    6. ★ Multi-polygones (3 secteurs d’une agence)
    7. ★ 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
  • 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

FichierLigneAction
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:12Phrase tronquée “filtres @TODO”Réécrire la phrase, lier vers concepts/filtres-communs.mdx. P0.
swagger-api-geocoding.json:945,950Token XXXXXX / Bearer XXXXXXFaux positif (placeholder dans description swagger BAN/BANO) — ignorer.
todo.md (racine)Méta-fichier instructionsHors 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 :
---
title: "Récupérer une property par son flx_id"
sidebarTitle: "Get by flx_id"
description: "Retourne une property unique. Utile en post-webhook pour refetch après réception d'un ID."
icon: "magnifying-glass"
tag: "STABLE"
openapi: "/swagger-api-v2.json GET /v2/protected/properties/{flxId}"
---
Action : passer en revue tous les fichiers OpenAPI MDX et ajouter un frontmatter complet (title FR, sidebarTitle court, description orientée cas d’usage, icon Lucide/Font Awesome cohérent par groupe, tag 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/dark paire 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 #ED0040 rouge + #7274E4 violet → 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 : #1E40AF indigo profond (confiance, FR, données) — ou variante #0F172A slate très foncé pour un look encore plus premium/data-driven
    • Secondary/accent : #10B981 emerald (succès, signal “live data”) OU #F59E0B amber (insight, valorisation) — un seul accent fort, choix à valider
    • Neutres : tons gris/slate Tailwind (#F8FAFC light → #0F172A dark)
    • Background : gradient discret depuis le primary (light: linear-gradient(135deg, #F8FAFC 0%, #EEF2FF 100%) ; dark: linear-gradient(135deg, #0F172A 0%, #1E293B 100%))
  • 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": true ou é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

ComposantUsage 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é

EndpointDoc à produireExemples payloads (filtres)Prio
POST /properties/searchFiltres complets (★ city deprecated/ignoré → utiliser postalCode/inseeCode/department), ★ filtres géo avancés (bbox/distance/polygon/INSEE), cursor, sortBy, lite vs full, count semanticsCombo standard postalCode achat · département entier · geoDistance rayon · geoBoundingBox carte · polygone GeoJSON · multi-zones · isExclusive nested · paginationP0
POST /properties/search/liteDiff vs full, cas mobile/UI, mêmes modes géoIdem full · cas autocomplete · ★ bbox temps réelP1
POST /properties/search/lite/similarInput/output, scoringPeer comparison AVMP3
POST /adverts/searchFiltres adverts-specific, source/seller, ★ filtres géo avancésAchat appart dpt · ★ geoDistance autour métro · seller agence · propertyFlxId · isProP0
PUT /adverts/search/alertsmatchType ADVERT_EVENT, cycle de vie, webhook payloadAlerte chasseur dpt · alerte + events · multi-dpt · range completP0
PUT /adverts/search/alerts/manyLimite, atomicitéMulti-dptP2
GET /adverts/search/alerts/allFormat, pas de paginationP1
GET /adverts/search/alerts/{id}Réinspecter configP2
PATCH /adverts/search/alerts/{id}Préserve historique vs delete+createMaj webhook url · maj filtresP1
DELETE /adverts/search/alerts/{id}Deactivate vs delete, impact eventsP1
GET /adverts/search/alerts/{id}/activateSémantique GET legacyP2
GET /adverts/search/alerts/history/{flxId}Pagination skip/take, replay backlogBacklog 30jP1
PUT /properties/search/alertsmatchType MERGED, webhook IDs only, refetchAlerte dpt analytics · isTotallyOffline · multi-dptP0
PUT /properties/search/alerts/manyBulkMulti-dptP2
GET /properties/search/alerts/allFormatP1
GET/PATCH/DELETE /properties/search/alerts/{id}Idem advertsIdem advertsP1/P2
GET /properties/search/alerts/{id}/activateIdem advertsP2
GET /properties/search/alerts/history/{flxId}Idem advertsBacklogP1
GET /adverts/{flxId} /by-urlRefetch unitaire, 404P1
GET /properties/{flxId}Refetch unitaire post-webhookP0
GET /properties/bulkBatch fetch post-webhook properties (taille max)Batch 50 IDsP0
GET /properties/by-url /by-advertCas d’usageP1
GET /v2/sample/* (4 endpoints, no auth)★ Valorisation forte, fixturesP0
POST /estimate/property/liteInput/output AVM, confidenceAppart Paris · maison provinceP1
POST /experimental/estimateDiff vs lite, instabilité experimentalP2
GEO /search /reverse /csv⚠️ Origine BAN/BANO Gouv assumée + usage typique → injecter dans search locationTour Eiffel · reverse coords · batch CSVP1
GEO async projects (7 endpoints)Workflow batch async (BAN/BANO)1 cas batch async 100k adressesP2
Capabilities sur demande (DPE, DVF, similar, market/properties analytics, agences, consumption)Page descriptive, CTA contactP2
★ Filtres géo avancés (transverse)Concept + playbook dédié, modes bbox/distance/polygon/INSEE/multi-zones, contraintes, anti-patternsbbox carte · rayon adresse · polygone custom · multi-zones petite couronne · multi-polygones agence · combo prix+geoP0

10. Tableau 2 — MDX × Goal × Priorité × Dépendances

MDX (path proposé)GoalPrioDépend de
introduction.mdx (réécrit)Vision FR-first, supériorité 2017+, supprimer Calendly proéminentP0
demarrer/quickstart.mdx5 min sans appel : sample → clé test → 1er searchP0sample, auth
demarrer/sample-data.mdx★ valoriser endpoints no-auth (4)P0
authentification.mdx (réécrit)Clé test gratuite + clé prod, sans imposer CalendlyP0
demarrer/limites-rate-limits.mdxQuotas, headers, backoffP1
concepts/property-vs-advert.mdxDecision matrix (cf §5)P0
concepts/webhooks.mdx (refondu)Archi, retry, signature, déploiement, IDs vs payloadP0property-vs-advert
concepts/filtres-communs.mdxRéférentiel filtres location/offer/price/habitationP0
concepts/match-types-cycle-alerte.mdx★ MERGED, ADVERT_EVENT, perte historique sur recreateP0property-vs-advert
concepts/recherche-geographique.mdx★ Modes géo (INSEE, bbox, distance, polygon, multi-zones), schémas JSON, contraintes, anti-patternsP0filtres-communs
llms-context.mdx (+ llms.txt + llms-full.txt)★★ Page LLM-ready copiable/collable + standards llms.txt natifs MintlifyP0concepts, modèles, filtres
concepts/baas.mdx (allégé)Vue d’ensemble moteursP2
playbooks/alerte-advert-departement.mdxUse case #1 chasseur immoP0adverts/search/alerts, webhooks
playbooks/search-properties-analytique.mdxUse case #2 analytics ParisP0properties/search, filtres
playbooks/replicate-bdd-adverts.mdxSync continue marketplaceP1adverts alerts, webhooks
playbooks/track-price-changes.mdxEvents ADVERT temps réelP1adverts alerts, match types
playbooks/estimer-un-bien.mdxAVM AI liteP1AI
playbooks/geocoder-pour-search.mdxGEO (BAN/BANO Gouv) → injection location filterP1GEO, properties/search
playbooks/recherche-geographique-avancee.mdx★ Cas concrets bbox/rayon/polygon/multi-zones, chaîne BAN→searchP0recherche-geographique, properties/search, adverts/search
api-reference/... (existant)Enrichir chaque .mdx OpenAPI avec prose + 2-3 exemples curatedP0 (search/alerts), P1 (AI/GEO), P2 (autres)concepts, playbooks
api-reference/_models/property.mdx (réécrit)Champs + décisions + lien decision matrixP0property-vs-advert
api-reference/_models/advert.mdx (réécrit)IdemP0property-vs-advert
api-reference/capabilities-sur-demande.mdxDPE, DVF, similar, market analytics, agences, consumptionP2
ressources/faq.mdxTop 15 questions (auth, webhooks, refetch, pagination, alertes)P1concepts
ressources/codes-erreur.mdxCodes HTTP + métier (10001/10002/10003), exemples body erreurP1
ressources/webhooks-livraison.mdxHeaders (x-webhook-key), pas de signature HMAC, retry 2+10×5min, DROP après ~50min, codes 200-205, SLO 30-50sP1webhooks
ressources/bonnes-pratiques.mdxPagination, retry, idempotence, refetch, validation webhook par x-webhook-keyP1concepts, webhooks-livraison
ressources/changelog.mdxVersions v2.xP2
ressources/contact.mdxEmail + Calendly discretP2
ressources/startups-et-sur-mesure.mdxEngagement startups, discount early-stage, sur-mesure, références sur demande, pas de noms clients publicsP1
concepts/dvf-vs-fluximmo.mdxComparatif honnête DVF vs Fluximmo + complémentaritéP1property-vs-advert
playbooks/webhook-volume-architecture.mdxArchitecture queue (RMQ/SQS), idempotence, ack rapide, anti-patternsP1webhooks, 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 + activation llms.txt/llms-full.txt Mintlify
  • 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.mdx en 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

SujetQuestionRecommandation
Filtre cityGarder 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 namingGarder 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 MintlifyPlan tarifaire requis ?Vérifier si le plan actuel inclut l’AI search built-in. Si non, calculer le ROI.
Rebrand couleurAtelier brand 1h pour valider la palette finaleBloquer un créneau avec design/marketing avant P1.

13. Vérification end-to-end

Une fois la refonte livrée :
  1. Lancer mintlify dev localement → vérifier 0 lien cassé, navigation cohérente
  2. Tester journey “découverte” : depuis introduction, atteindre un sample no-auth en ≤ 2 clics
  3. Tester journey “quickstart” : suivre le quickstart from scratch sur clé test → premier search OK
  4. Lancer un appel curl sur chaque sample endpoint depuis la doc (copier-coller doit marcher)
  5. Vérifier que chaque endpoint P0/P1 a au moins 1 exemple, 1 cas d’erreur, 1 lien croisé concept/playbook
  6. Search interne (Mintlify) : “alerte département” → playbook chasseur en top 3 résultats

Annexe A — Fichiers clés à modifier

PathAction
mint.jsonRefonte complète navigation (groupes, ordre, tabs)
introduction.mdxRéécriture (vision FR-first, supprimer Calendly)
authentification.mdxRéécriture (clé test gratuite proéminente)
doc/main-concepts/baas.mdxAllégé, déplacé en Concepts
doc/main-concepts/properties-adverts.mdxÉtendu en concepts/property-vs-advert.mdx (decision matrix)
doc/main-concepts/webhooks.mdxRefonte (signature, retry, déploiement, samples webhook)
api-v2-reference/_api-models/property.mdxÉtendu (champs + décisions)
api-v2-reference/_api-models/advert.mdxIdem
api-v2-reference/{properties-search,adverts-search}/*.mdxEnrichir avec prose + exemples curated
api-v2-reference/{properties-alerts,adverts-alerts}/*.mdxIdem + cycle de vie
api-v2-reference/sample-{adverts,properties}/*.mdxValoriser, lier depuis Démarrer
Nouveaux fichiersTous 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.
ModeUsage échantillonDoc
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)
irisCoderareDocumenter pour cas urbain fin
geoBoundingBoxabsent en échantillonDocumenter (cas carte interactive — feature distinctive à promouvoir)
geoShape POLYGONabsent en échantillonDocumenter brièvement (capability distinctive)
Multi-zones (array)présent ponctuellementDocumenter (cas agence multi-territoires)
Décision : la doc met en avant 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_BUY 100% (RENT quasi-nul). → Exemples primaires en achat, location en exemple secondaire pour exhaustivité.
  • type = CLASS_FLAT 85% + CLASS_HOUSE 98% + CLASS_PROGRAM 66% (neuf très utilisé). → Toujours inclure PROGRAM dans les exemples par défaut.
  • meta.isTotallyOffline = false 100%. → 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_AT DESC (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é — utiliser postalCode, inseeCode, ou department à 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”.
  • filterProperty vide → 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 repos api_fluximmo_v2 (NestJS), elasticimmo (Go), prod_fluximmo/v2/_workers (Python).

C.1 Limites & contraintes réelles

EndpointChampLimite réelle code
POST /properties/searchsize1–25 (max 25)
POST /properties/search/litesize1–25
POST /properties/search/lite/similarsize1–100
POST /adverts/searchsize1–100
Search (tous)keywords[], fullTexts[]Max 20 items chacun
Webhooks advertsbatch20 adverts par delivery (MAX_BATCH_SIZE=20)
geoDistance.distanceKmStrictement > 0 sinon rejet
geoBoundingBoxtopLeft.lat > bottomRight.lat requis
geoShape polygonvertices≈ 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 UNIQUE
    • ALERT_MATCH_ADVERT_EVENT : webhook reçoit event_typePRICE | REPUBLISHED | UNPUBLISHED
  • Properties :
    • ALERT_MATCH_CREATED : nouvelle property
    • ALERT_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 de x-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 interneHTTPSens
10001408/500HTTP request timeout (ES)
10002400Validation error (DTO)
10003500Unexpected
Format réponse erreur :
{ "error": { "message": "...", "code": 10003 } }

C.5 Pas de rate limiting exposé

Aucun header X-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/properties
  • GET /v2/sample/adverts
  • GET /v2/sample/webhook/properties
  • GET /v2/sample/webhook/adverts
  • GET /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[] + isAuction
  • FilterAdvertPrice : currentPrice.value + currentPrice.valuePerArea
  • FilterMeta (properties only) : firstSeenAt / lastSeenAt / lastUpdatedAt / lastPublishedAt / isTotallyOffline
  • FilterTypeHabitation : surface (total/habitable), roomCount, bedroomCount, bathroomCount, type T1-T5+, characteristics, climate (EPC), heat
  • FilterAdvert-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 docsHiérarchie claire Concepts / Reference / FAQ, badges visuels
Melo /api-reference/conceptsFormat des concepts (court, comparatifs, exemples mini)
Melo /api-reference/faqFormat FAQ avec accordéons par thème
Stripe docsTabs code curl/Python/Node, recipes/playbooks orientés use case
Mintlify guidelinesCards landing, Steps quickstart, Mermaid diagrammes