{
  "openapi": "3.1.0",
  "info": {
    "title": "API du socle commun HPD",
    "version": "1.1.0",
    "description": "Contrat API du socle HPD One 1.21.0. API v1 conservée ; extensions additives projets, santé, carte et pagination. Contrôles côté serveur, UUID stables, versions, idempotence et périmètres. Les mutations par cookies exigent X-HPD-CSRF. Ce document couvre les routes listées ; les opérations spécialisées météo et reprise sont détaillées dans docs/ARCHITECTURE_CURRENT.md et docs/WEATHER_DISPLAY_SCHEDULE.md. Flyers et campagnes : voir docs/GEOPROSPECT_16_4_0.md."
  },
  "servers": [
    {
      "url": "/",
      "description": "Même origine que le serveur HPD"
    }
  ],
  "paths": {
    "/api/v1/health": {
      "get": {
        "summary": "État de disponibilité de la base",
        "security": [],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/status": {
      "get": {
        "summary": "État d’initialisation du socle",
        "security": [],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/setup": {
      "post": {
        "summary": "Créer une seule fois le premier administrateur",
        "security": [],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    },
                    "csrf": {
                      "type": "string"
                    },
                    "accessExpiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "refreshExpiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "accessToken": {
                      "type": "string",
                      "description": "Uniquement pour transport natif sans Origin."
                    },
                    "refreshToken": {
                      "type": "string",
                      "description": "Uniquement pour transport natif sans Origin."
                    }
                  },
                  "required": [
                    "user",
                    "csrf"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-HPD-Setup-Token",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Nécessaire sur le serveur autonome. Sur le site privé, propriétaire connecté."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "username": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "transport": {
                    "type": "string",
                    "enum": [
                      "web",
                      "native"
                    ]
                  },
                  "displayName": {
                    "type": "string",
                    "maxLength": 100
                  }
                },
                "required": [
                  "username",
                  "displayName",
                  "password"
                ]
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/login": {
      "post": {
        "summary": "Connexion HPD par identifiant et mot de passe",
        "security": [],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    },
                    "csrf": {
                      "type": "string"
                    },
                    "accessExpiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "refreshExpiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "accessToken": {
                      "type": "string",
                      "description": "Uniquement pour transport natif sans Origin."
                    },
                    "refreshToken": {
                      "type": "string",
                      "description": "Uniquement pour transport natif sans Origin."
                    }
                  },
                  "required": [
                    "user",
                    "csrf"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "username": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string",
                    "maxLength": 128
                  },
                  "transport": {
                    "type": "string",
                    "enum": [
                      "web",
                      "native"
                    ]
                  }
                },
                "required": [
                  "username",
                  "password"
                ]
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/refresh": {
      "post": {
        "summary": "Renouveler une session et faire tourner ses jetons",
        "security": [],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    },
                    "csrf": {
                      "type": "string"
                    },
                    "accessExpiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "refreshExpiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "accessToken": {
                      "type": "string",
                      "description": "Uniquement pour transport natif sans Origin."
                    },
                    "refreshToken": {
                      "type": "string",
                      "description": "Uniquement pour transport natif sans Origin."
                    }
                  },
                  "required": [
                    "user",
                    "csrf"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "refreshToken": {
                    "type": "string"
                  },
                  "transport": {
                    "type": "string",
                    "enum": [
                      "web",
                      "native"
                    ]
                  }
                },
                "required": []
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/me": {
      "get": {
        "summary": "Compte, droits et namespace du cache",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    },
                    "csrf": {
                      "type": "string"
                    },
                    "cacheScope": {
                      "type": "string"
                    },
                    "applications": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/logout": {
      "post": {
        "summary": "Déconnecter et révoquer la session ainsi que l’appareil lié",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/password": {
      "post": {
        "summary": "Changer son mot de passe et révoquer les autres sessions",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    },
                    "csrf": {
                      "type": "string"
                    },
                    "accessExpiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "refreshExpiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "accessToken": {
                      "type": "string",
                      "description": "Uniquement pour transport natif sans Origin."
                    },
                    "refreshToken": {
                      "type": "string",
                      "description": "Uniquement pour transport natif sans Origin."
                    }
                  },
                  "required": [
                    "user",
                    "csrf"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "currentPassword": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string",
                    "minLength": 12,
                    "maxLength": 128
                  },
                  "transport": {
                    "type": "string",
                    "enum": [
                      "web",
                      "native"
                    ]
                  }
                },
                "required": [
                  "currentPassword",
                  "password"
                ]
              }
            }
          }
        }
      }
    },
    "/api/v1/clients": {
      "get": {
        "summary": "Lire les fiches dans le périmètre du compte",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "clients": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Client"
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "description": ""
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read"
        ]
      },
      "post": {
        "summary": "Créer une fiche avec un UUID indépendant de la carte",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "201": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "client": {
                      "$ref": "#/components/schemas/Client"
                    }
                  },
                  "required": []
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Clé stable de l’opération, conservée lors d’une reprise réseau."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "data": {
                    "$ref": "#/components/schemas/ClientData"
                  },
                  "ownerUserId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": []
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read",
          "clients.write"
        ]
      }
    },
    "/api/v1/clients/{id}": {
      "get": {
        "summary": "Lire une fiche et sa version ETag",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "client": {
                      "$ref": "#/components/schemas/Client"
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read"
        ]
      },
      "patch": {
        "summary": "Modifier les champs transmis ; attribution réservée aux administrateurs",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "client": {
                      "$ref": "#/components/schemas/Client"
                    }
                  },
                  "required": []
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Clé stable de l’opération, conservée lors d’une reprise réseau."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Version attendue, par exemple \"3\". Obligatoire sur une modification sauf si version est transmise dans le JSON."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "data": {
                    "$ref": "#/components/schemas/ClientData"
                  },
                  "ownerUserId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": []
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read",
          "clients.write"
        ]
      },
      "delete": {
        "summary": "Archiver une fiche en conservant ses données et photos",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Clé stable de l’opération, conservée lors d’une reprise réseau."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Version attendue, par exemple \"3\". Obligatoire sur une modification sauf si version est transmise dans le JSON."
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read",
          "clients.delete"
        ]
      }
    },
    "/api/v1/clients/{id}/restore": {
      "post": {
        "summary": "Restaurer une fiche archivée avec le même UUID",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Clé stable de l’opération, conservée lors d’une reprise réseau."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Version attendue, par exemple \"3\". Obligatoire sur une modification sauf si version est transmise dans le JSON."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "version": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": []
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read",
          "clients.write",
          "users.manage"
        ]
      }
    },
    "/api/v1/sync/changes": {
      "get": {
        "summary": "Changements, suppressions et retraits de périmètre depuis un curseur",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": ""
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read"
        ]
      }
    },
    "/api/v1/admin/users": {
      "get": {
        "summary": "Lister les comptes, rôles et permissions",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.admin",
          "users.manage"
        ]
      },
      "post": {
        "summary": "Créer un compte avec un mot de passe provisoire",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "201": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "username": {
                    "type": "string",
                    "pattern": "^[a-z0-9][a-z0-9._-]{2,63}$"
                  },
                  "displayName": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "responsable",
                      "prospecteur",
                      "lecteur"
                    ]
                  },
                  "scope": {
                    "type": "string",
                    "enum": [
                      "all",
                      "assigned"
                    ]
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "permissions": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "boolean"
                    }
                  },
                  "password": {
                    "type": "string",
                    "minLength": 12,
                    "maxLength": 128
                  },
                  "version": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": []
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.admin",
          "users.manage"
        ]
      }
    },
    "/api/v1/admin/users/{id}": {
      "patch": {
        "summary": "Modifier un compte avec sa version, sans retirer le dernier administrateur",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "username": {
                    "type": "string",
                    "pattern": "^[a-z0-9][a-z0-9._-]{2,63}$"
                  },
                  "displayName": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "responsable",
                      "prospecteur",
                      "lecteur"
                    ]
                  },
                  "scope": {
                    "type": "string",
                    "enum": [
                      "all",
                      "assigned"
                    ]
                  },
                  "enabled": {
                    "type": "boolean"
                  },
                  "permissions": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "boolean"
                    }
                  },
                  "password": {
                    "type": "string",
                    "minLength": 12,
                    "maxLength": 128
                  },
                  "version": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": []
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.admin",
          "users.manage"
        ]
      }
    },
    "/api/v1/admin/users/{id}/password": {
      "post": {
        "summary": "Réinitialiser le mot de passe et révoquer toutes les sessions du compte",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "password": {
                    "type": "string",
                    "minLength": 12,
                    "maxLength": 128
                  }
                },
                "required": [
                  "password"
                ]
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.admin",
          "users.manage"
        ]
      }
    },
    "/api/v1/admin/sessions": {
      "get": {
        "summary": "Lister les 200 dernières connexions, sans leurs jetons",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.admin",
          "sessions.manage"
        ]
      },
      "post": {
        "summary": "Révoquer toutes les connexions d’un compte",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "userId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "userId"
                ]
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.admin",
          "sessions.manage"
        ]
      }
    },
    "/api/v1/admin/audit": {
      "get": {
        "summary": "Lire les 200 derniers événements du journal",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.admin",
          "audit.read"
        ]
      }
    },
    "/api/v1/admin/summary": {
      "get": {
        "summary": "Compteurs du pilote et applications disponibles",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.admin",
          "users.manage"
        ]
      }
    },
    "/api/v1/admin/backup": {
      "post": {
        "summary": "Exporter une sauvegarde chiffrée avec les fichiers",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "currentPassword": {
                    "type": "string"
                  },
                  "password": {
                    "type": "string",
                    "minLength": 16,
                    "maxLength": 128
                  }
                },
                "required": [
                  "currentPassword",
                  "password"
                ]
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.admin",
          "backups.manage"
        ]
      }
    },
    "/api/v1/admin/import-geoprospect": {
      "post": {
        "summary": "Vérifier puis importer atomiquement un export GeoProspect sans photos",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "currentPassword": {
                    "type": "string"
                  },
                  "snapshot": {
                    "type": "object"
                  },
                  "dryRun": {
                    "type": "boolean",
                    "default": true
                  }
                },
                "required": [
                  "currentPassword",
                  "snapshot"
                ]
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.admin",
          "backups.manage",
          "clients.read",
          "clients.write",
          "tours.write"
        ]
      }
    },
    "/api/prospects": {
      "get": {
        "summary": "Façade GeoProspect GET",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read"
        ],
        "parameters": [
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            }
          },
          {
            "in": "query",
            "name": "after",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "description": "Avec limit ou after : prospects, nextCursor, generatedAt, apiVersion=2. Sans ces paramètres : format historique apiVersion=1 transmis en flux ; préférer les pages."
      },
      "post": {
        "summary": "Façade GeoProspect POST",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Clé stable de l’opération, conservée lors d’une reprise réseau."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Version attendue, par exemple \"3\". Obligatoire sur une modification sauf si version est transmise dans le JSON."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read",
          "clients.write"
        ]
      },
      "patch": {
        "summary": "Façade GeoProspect PATCH",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Clé stable de l’opération, conservée lors d’une reprise réseau."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Version attendue, par exemple \"3\". Obligatoire sur une modification sauf si version est transmise dans le JSON."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read",
          "clients.write"
        ]
      },
      "delete": {
        "summary": "Façade GeoProspect DELETE",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100
            },
            "description": "Clé stable de l’opération, conservée lors d’une reprise réseau."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Version attendue, par exemple \"3\". Obligatoire sur une modification sauf si version est transmise dans le JSON."
          },
          {
            "name": "buildingKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": ""
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read",
          "clients.delete"
        ]
      }
    },
    "/api/prospects/export": {
      "get": {
        "summary": "Export CSV des fiches autorisées",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "CSV UTF-8",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.geoprospect",
          "clients.read",
          "clients.export"
        ]
      }
    },
    "/api/tours": {
      "get": {
        "summary": "Tournées et passages GeoProspect",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.geoprospect",
          "tours.read"
        ]
      },
      "post": {
        "summary": "Tournées et passages GeoProspect",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.geoprospect",
          "tours.write"
        ]
      }
    },
    "/api/photos": {
      "get": {
        "summary": "Photo privée ou liste de photos",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "clientKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": ""
          },
          {
            "name": "photoId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect",
          "photos.read"
        ]
      },
      "delete": {
        "summary": "Photo privée ou liste de photos",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "clientKey",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": ""
          },
          {
            "name": "photoId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": ""
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect",
          "photos.write"
        ]
      },
      "post": {
        "summary": "Ajouter une photo idempotente par uploadId",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-hpd-permissions": [
          "app.geoprospect",
          "photos.write"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "clientKey": {
                    "type": "string"
                  },
                  "uploadId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "photo": {
                    "type": "string",
                    "format": "binary"
                  },
                  "addedAt": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "label": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "parcelReference": {
                    "type": "string"
                  }
                },
                "required": [
                  "clientKey",
                  "uploadId",
                  "photo",
                  "addedAt"
                ]
              }
            }
          }
        }
      }
    },
    "/api/v1/auth/device-session": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    },
                    "accessToken": {
                      "type": "string"
                    },
                    "refreshToken": {
                      "type": "string"
                    },
                    "csrf": {
                      "type": "string"
                    },
                    "accessExpiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "refreshExpiresAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "user",
                    "accessToken",
                    "refreshToken"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false
              }
            }
          }
        },
        "description": "Appel natif sans en-tête Origin. Une requête Web ou des cookies seuls sont refusés. La connexion ouvre la suite HPD One et ne requiert pas le droit GéoProspect. Les API métier conservent leurs contrôles de droits propres.",
        "summary": "Activer une session d’appareil Android protégée"
      },
      "delete": {
        "summary": "Désactiver le déverrouillage Android en conservant la connexion Web courante",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Révoque la session d’appareil et les autres connexions liées. Exige CSRF avec les cookies."
      }
    },
    "/api/v1/auth/browser-session": {
      "post": {
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Réponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "$ref": "#/components/schemas/User"
                    },
                    "csrf": {
                      "type": "string"
                    },
                    "cacheScope": {
                      "type": "string"
                    },
                    "applications": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": []
                }
              }
            },
            "headers": {
              "Set-Cookie": {
                "description": "__Host-hpd-access et __Host-hpd-refresh, HttpOnly ; ne pas exposer au JavaScript.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Requête invalide",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Connexion ou renouvellement nécessaire",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Droits, origine ou CSRF refusés",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Conflit de version ou de clé d’opération",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "428": {
            "description": "Version attendue manquante",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false
              }
            }
          }
        },
        "description": "Appel natif sans en-tête Origin. Une requête Web ou des cookies seuls sont refusés. Le Bearer doit appartenir à une session d’appareil. La réponse ne contient aucun jeton ; deux cookies HttpOnly Secure SameSite=Strict sont fournis. La connexion ouvre la suite HPD One et ne requiert pas le droit GéoProspect. Les API métier conservent leurs contrôles de droits propres.",
        "summary": "Ouvrir une connexion Web liée depuis une session d’appareil"
      }
    },
    "/api/v1/projects": {
      "get": {
        "summary": "Lire le portefeuille, ses itemVersions et sa progression",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "app.dashboard",
          "projects.read"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "since",
            "schema": {
              "type": "integer",
              "minimum": 0
            },
            "description": "Retour unchanged si la version globale correspond."
          }
        ]
      }
    },
    "/api/v1/projects/mutations": {
      "post": {
        "summary": "Modifier un projet ou une étape, avec idempotence et version attendue",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "app.dashboard",
          "projects.read",
          "projects.write"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          },
          "409": {
            "description": "Conflit de version, dépendance ou clé ; saisie à conserver"
          },
          "428": {
            "description": "Version globale nécessaire"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "version",
                  "action",
                  "data"
                ],
                "properties": {
                  "version": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "itemVersion": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Pour project.update/task.update ; lu dans itemVersions. Une modification du même élément provoque 409."
                  },
                  "action": {
                    "type": "string",
                    "enum": [
                      "project.create",
                      "project.update",
                      "task.create",
                      "task.update",
                      "template.hpd"
                    ]
                  },
                  "data": {
                    "type": "object",
                    "description": "Création : champs ; mise à jour : {id,data:{champs}}. Voir public/active-pilot-core.mjs."
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          }
        ]
      }
    },
    "/api/v1/projects/history": {
      "get": {
        "summary": "Lire les 200 derniers événements du suivi",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "app.dashboard",
          "projects.read"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        }
      }
    },
    "/api/v1/projects/export": {
      "get": {
        "summary": "Exporter le suivi et ses métadonnées",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "app.dashboard",
          "projects.read",
          "projects.export"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        }
      }
    },
    "/api/v1/projects/assistant": {
      "get": {
        "summary": "Lire le réglage d’accès de l’assistant",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "app.dashboard",
          "projects.read"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        }
      },
      "put": {
        "summary": "Autoriser ou révoquer l’assistant",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "app.dashboard",
          "projects.read",
          "projects.write",
          "users.manage"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "enabled"
                ],
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/admin/health": {
      "get": {
        "summary": "Santé du cœur, stockage configuré et pipeline météo",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "users.manage"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        }
      }
    },
    "/api/v1/weather/collection-status": {
      "get": {
        "summary": "Files display:v1, fraîcheur, retards et travailleur",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "users.manage"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        }
      }
    },
    "/api/map-data": {
      "get": {
        "summary": "Lire une révision cartographique ; 404 de repli distinct du 503",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        },
        "parameters": [
          {
            "in": "query",
            "name": "file",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "revision",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/api/map-data-status": {
      "get": {
        "summary": "Statut des données cartographiques",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        }
      },
      "post": {
        "summary": "Vérifier les sources de données cartographiques",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect",
          "mapdata.manage"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "force": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Appliquer une révision cartographique",
        "security": [
          {
            "cookieAuth": []
          },
          {
            "bearerAuth": []
          }
        ],
        "x-hpd-permissions": [
          "app.geoprospect",
          "mapdata.manage"
        ],
        "responses": {
          "200": {
            "description": "Résultat de l’opération"
          },
          "400": {
            "description": "Paramètres invalides"
          },
          "401": {
            "description": "Connexion nécessaire"
          },
          "403": {
            "description": "Droits ou CSRF refusés"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "sourceId",
                  "revision"
                ],
                "properties": {
                  "sourceId": {
                    "type": "string"
                  },
                  "revision": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/flyers": {
      "get": {
        "summary": "Bibliothèque de flyers ou fichier original authentifié",
        "parameters": [
          {
            "in": "query",
            "name": "id",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "cursor",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "in": "query",
            "name": "download",
            "schema": {
              "type": "string",
              "enum": [
                "1"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Catalogue paginé ou octets du fichier"
          },
          "404": {
            "description": "Flyer absent du périmètre"
          }
        }
      },
      "post": {
        "summary": "Importer un flyer PDF/JPEG/PNG/WebP (12 Mio maximum)",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file",
                  "label",
                  "uploadId"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "label": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "uploadId": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Flyer créé"
          },
          "200": {
            "description": "Import déjà enregistré"
          },
          "413": {
            "description": "Fichier trop volumineux"
          },
          "415": {
            "description": "Format refusé"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "cookieAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Host-hpd-access"
      },
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "username": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": [
              "admin",
              "responsable",
              "prospecteur",
              "lecteur"
            ]
          },
          "enabled": {
            "type": "boolean"
          },
          "scope": {
            "type": "string",
            "enum": [
              "all",
              "assigned"
            ]
          },
          "permissions": {
            "type": "object",
            "additionalProperties": {
              "type": "boolean"
            }
          },
          "effectivePermissions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "mustChangePassword": {
            "type": "boolean"
          },
          "version": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "username",
          "role",
          "effectivePermissions",
          "version"
        ]
      },
      "ClientData": {
        "type": "object",
        "properties": {
          "buildingKey": {
            "type": "string",
            "maxLength": 80
          },
          "communeCode": {
            "type": "string",
            "maxLength": 10
          },
          "communeName": {
            "type": "string",
            "maxLength": 80
          },
          "contactName": {
            "type": "string",
            "maxLength": 120
          },
          "contactFirstName": {
            "type": "string",
            "maxLength": 120
          },
          "phone": {
            "type": "string",
            "maxLength": 40
          },
          "email": {
            "type": "string",
            "maxLength": 160
          },
          "propertyAddress": {
            "type": "string",
            "maxLength": 240
          },
          "notes": {
            "type": "string",
            "maxLength": 3000
          },
          "longitude": {
            "type": "string",
            "maxLength": 30
          },
          "latitude": {
            "type": "string",
            "maxLength": 30
          },
          "status": {
            "type": "string",
            "enum": [
              "a_contacter",
              "flyer_depose",
              "contacte",
              "rendez_vous",
              "devis_envoye",
              "devis_en_cours",
              "a_facturer",
              "client_gagne",
              "a_relancer"
            ]
          },
          "priority": {
            "type": "string",
            "enum": [
              "basse",
              "normale",
              "haute"
            ]
          },
          "buildingType": {
            "type": "string",
            "enum": [
              "habitation",
              "entreprise",
              "autre",
              "inconnu"
            ]
          },
          "entityType": {
            "type": "string",
            "enum": [
              "building",
              "parcel"
            ]
          },
          "buildingNumber": {
            "type": "integer",
            "minimum": 0
          },
          "dwellings": {
            "type": "integer",
            "minimum": 0
          },
          "nextActionDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "flyerDate": {
            "type": [
              "string",
              "null"
            ],
            "format": "date"
          },
          "parcelReference": {
            "type": [
              "string",
              "null"
            ]
          },
          "parcelMeasurements": {
            "type": [
              "object",
              "null"
            ]
          },
          "clientParcels": {
            "type": "array",
            "maxItems": 32,
            "items": {
              "type": "object"
            }
          },
          "manualMeasurements": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "type": "object"
            }
          },
          "extensions": {
            "type": "object"
          }
        },
        "required": [],
        "additionalProperties": false
      },
      "Client": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "data": {
            "$ref": "#/components/schemas/ClientData"
          },
          "version": {
            "type": "integer",
            "minimum": 1
          },
          "ownerUserId": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "deletedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "data",
          "version",
          "ownerUserId"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "server": {
            "$ref": "#/components/schemas/Client"
          },
          "prospect": {
            "type": "object"
          }
        },
        "required": [
          "error",
          "code"
        ]
      }
    }
  }
}
