Public Programme & Property Browsing

Summary

Browsing is the entry point of the acheteur journey. No authentication is required. Visitors can search and filter new-build programmes (neuf) and resale/rental properties (ancien), view them on an interactive map, and open individual detail pages. Lot-level data (individual units within a programme) is also accessible publicly. All data is served read-only; write operations (favorites, contact requests) require the acheteur to be authenticated or to fill a public contact form.

State Diagram

stateDiagram-v2
    state "Liste des programmes" as Listing
    state "Résultats filtrés" as Filtered
    state "Vue carte" as MapView
    state "Fiche programme" as ProgrammeDetail
    state "Fiche lot" as LotDetail
    state "Formulaire contact" as ContactForm
    state "Ajout favori" as FavoriteAction
    state "Fiche Express" as FicheExpress
    state "Liste des annonces" as PropertyListing
    state "Fiche bien" as PropertyDetail
    [*] --> Listing: visitor loads /programmes or /proprietes
    Listing --> Filtered: applies city, price, surface, type filters
    Filtered --> Listing: clears filters
    Listing --> MapView: switches to map view (/programmes/geo endpoint)
    MapView --> ProgrammeDetail: clicks map pin or card
    Listing --> ProgrammeDetail: clicks programme card
    ProgrammeDetail --> LotDetail: opens individual lot
    ProgrammeDetail --> ContactForm: clicks "Contacter" (public form)
    ProgrammeDetail --> FavoriteAction: clicks heart icon (requires auth)
    LotDetail --> FicheExpress: views Fiche Express (tax, charges estimates)
    [*] --> PropertyListing: visitor loads /annonces
    PropertyListing --> PropertyDetail: clicks property card
    PropertyDetail --> ContactForm: clicks "Contacter" (public form)
    PropertyDetail --> FavoriteAction: clicks heart icon (requires auth)

Steps

1. Browse Programme Listing (Actor: acheteur)

GET /programmes accepts filters via query string: ville (partial/multi-city), price_min, price_max, surface_min, surface_max, types (comma-separated lot types), rooms_min, promoteur, statuses (comma-separated programme statuses). Pagination via cursor (nextCursor). Only lots with status: disponible and isComplete: true are counted.

Smart city search: values that look like postal codes (2-5 digits) use startsWith on postalCode; otherwise partial match on both ville and programme name.

Outcome: Paginated list of programmes with lot count summaries.

2. Browse Map View (Actor: acheteur)

GET /programmes/geo returns lightweight GeoJSON-compatible data (slug, name, latitude, longitude, prixMin, prixMax, first photo) for all non-retired programmes. Powers the Leaflet map. No pagination — full dataset returned.

Outcome: All visible programme locations for map rendering.

3. View Programme Detail (Actor: acheteur)

GET /programmes/:slug returns a programme’s full data including all lots. Lots are filtered by available status and completeness. The route also computes:

  • Pinel zone and max rent estimates (getPinelZone, computePinelRent)
  • Taxe fonciere estimate (estimateTaxeFonciere)
  • Default charges per sqm (DEFAULT_CHARGES_PER_SQM)
  • Max floor for the programme (getMaxEtageForProgramme)

Photos are normalized via normalizePhotos().

Outcome: Full programme page data.

4. Browse Lots (Actor: acheteur)

GET /lots supports filtering by programmeId, type, price_min, price_max, surface_min, surface_max, rooms_min. Only disponible + isComplete lots returned.

Outcome: Filtered lot list.

5. Browse Property Listing (Actor: acheteur)

GET /properties returns active resale/rental listings with filters: type, transactionType, city, price_min, price_max, surface_min, surface_max, rooms_min. Cursor-paginated.

Outcome: Paginated property list.

6. View Property Detail (Actor: acheteur)

GET /properties/:slug returns a single active property with all fields.

Outcome: Full property page data.

Error States

  • Programme slug not found → 404
  • Property slug not found → 404
  • Invalid filter values → silently ignored (filters parsed with safe type coercion)