> ## 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

# 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)

| 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 :

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è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 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`** : `type` ∈ `POINT | LINE_STRING | POLYGON | MULTI_POINT | MULTI_LINE_STRING` + `coordinates` (LatLng\[]) + `relation` ∈ `WITHIN | 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

| 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 :

```yaml theme={null}
---
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

| 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` + 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

| 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 :

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

| 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)                             |

→ **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

| 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 UNIQUE
  * `ALERT_MATCH_ADVERT_EVENT` : webhook reçoit `event_type` ∈ `PRICE | 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 interne | HTTP    | Sens                      |
| ------------ | ------- | ------------------------- |
| `10001`      | 408/500 | HTTP request timeout (ES) |
| `10002`      | 400     | Validation error (DTO)    |
| `10003`      | 500     | Unexpected                |

Format réponse erreur :

```json theme={null}
{ "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 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             |
