# API : products

4 opérations REST du groupe products.

Base : `/api/v1`. [Conventions](/documentation/api-conventions/) · [Toutes les ressources](/documentation/api-reference/)

- GET /products : Lister les produits du catalogue (hors corbeille)
- POST /products : Créer un produit avec ses tarifs (≥ 1)
- GET /products/{id} : Détail d'un produit (tarifs inclus)
- PATCH /products/{id} : Modifier un produit - `prices` fourni = l'ensemble des tarifs est remplacé
## GET /products

```json
{
  "summary": "Lister les produits du catalogue (hors corbeille)",
  "tags": [
    "Produits"
  ],
  "parameters": [
    {
      "name": "cursor",
      "in": "query",
      "required": false,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "description": "Curseur opaque de la page précédente",
        "type": "string"
      }
    },
    {
      "name": "limit",
      "in": "query",
      "required": false,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "description": "Taille de page - défaut 50, max 200 (clampé)",
        "type": "integer",
        "minimum": 1,
        "maximum": 9007199254740991
      }
    },
    {
      "name": "updatedSince",
      "in": "query",
      "required": false,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "description": "ISO 8601 - objets modifiés depuis (inclusif), le filtre des syncs incrémentales",
        "type": "string"
      }
    },
    {
      "name": "ids",
      "in": "query",
      "required": false,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "description": "Répétable - restriction à une liste d'ids (max 200)",
        "type": "string"
      }
    },
    {
      "name": "q",
      "in": "query",
      "required": false,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "description": "Recherche sur le nom ou la référence",
        "type": "string"
      }
    },
    {
      "name": "businessUnitId",
      "in": "query",
      "required": false,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "string"
      }
    },
    {
      "name": "active",
      "in": "query",
      "required": false,
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "string",
        "enum": [
          "true",
          "false"
        ]
      }
    }
  ],
  "security": [
    {
      "oauth2": [
        "products:read"
      ]
    },
    {
      "userSession": []
    }
  ],
  "responses": {
    "200": {
      "description": "Page de produits",
      "content": {
        "application/json": {
          "schema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "name": {
                      "type": "string"
                    },
                    "code": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "businessUnitId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "capacity": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "saleMode": {
                      "type": "string",
                      "enum": [
                        "per_cycle",
                        "one_off"
                      ],
                      "description": "T-1412 : par cycle ou ponctuel"
                    },
                    "active": {
                      "type": "boolean"
                    },
                    "prices": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "label": {
                            "type": "string"
                          },
                          "unitPrice": {
                            "type": "string",
                            "description": "HT, chaîne décimale à 2 décimales"
                          },
                          "vatRate": {
                            "description": "Fraction stockée (0.20000) - null : taux du déploiement",
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "quantityTiers": {
                            "anyOf": [
                              {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "minQuantity": {
                                      "type": "integer",
                                      "minimum": -9007199254740991,
                                      "maximum": 9007199254740991
                                    },
                                    "unitPrice": {
                                      "type": "number"
                                    },
                                    "discountPercent": {
                                      "type": "number"
                                    }
                                  },
                                  "required": [
                                    "minQuantity"
                                  ],
                                  "additionalProperties": false
                                }
                              },
                              {
                                "type": "null"
                              }
                            ],
                            "description": "#761 : paliers par quantité triés par seuil - null : aucun"
                          },
                          "sortOrder": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "active": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "label",
                          "unitPrice",
                          "vatRate",
                          "description",
                          "quantityTiers",
                          "sortOrder",
                          "active"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "code",
                    "businessUnitId",
                    "capacity",
                    "saleMode",
                    "active",
                    "prices",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                }
              },
              "nextCursor": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "data",
              "nextCursor"
            ],
            "additionalProperties": false
          }
        }
      }
    },
    "default": {
      "description": "Erreur - enveloppe problem+json (RFC 9457)",
      "content": {
        "application/problem+json": {
          "schema": {
            "$ref": "#/components/schemas/Problem"
          }
        }
      }
    }
  }
}
```

## POST /products

```json
{
  "summary": "Créer un produit avec ses tarifs (≥ 1)",
  "tags": [
    "Produits"
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "businessUnitId": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            },
            "code": {
              "anyOf": [
                {
                  "type": "null"
                },
                {
                  "type": "string",
                  "maxLength": 60
                }
              ]
            },
            "capacity": {
              "anyOf": [
                {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991
                },
                {
                  "type": "null"
                }
              ]
            },
            "saleMode": {
              "description": "T-1412 : par cycle (défaut) ou ponctuel, vendu à une date de prestation",
              "type": "string",
              "enum": [
                "per_cycle",
                "one_off"
              ]
            },
            "active": {
              "type": "boolean"
            },
            "prices": {
              "minItems": 1,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Présent = mise à jour du tarif, absent = création",
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "label": {
                    "type": "string",
                    "minLength": 1
                  },
                  "unitPrice": {
                    "type": "number",
                    "minimum": 0
                  },
                  "vatRatePercent": {
                    "description": "En POURCENT (20, 5.5) - null : taux du déploiement",
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "description": {
                    "anyOf": [
                      {
                        "type": "null"
                      },
                      {
                        "type": "string",
                        "maxLength": 500
                      }
                    ]
                  },
                  "active": {
                    "type": "boolean"
                  },
                  "quantityTiers": {
                    "description": "#761 : paliers par quantité [{ minQuantity ≥ 2, unitPrice | discountPercent }] ; absent : grille gardée, null ou [] : aucun palier",
                    "anyOf": [
                      {
                        "maxItems": 20,
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "minQuantity": {
                              "type": "integer",
                              "minimum": 2,
                              "maximum": 1000000
                            },
                            "unitPrice": {
                              "type": "number",
                              "exclusiveMinimum": 0,
                              "maximum": 9999999999
                            },
                            "discountPercent": {
                              "type": "number",
                              "exclusiveMinimum": 0,
                              "maximum": 100
                            }
                          },
                          "required": [
                            "minQuantity"
                          ],
                          "additionalProperties": false
                        }
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "label",
                  "unitPrice"
                ],
                "additionalProperties": false
              }
            }
          },
          "required": [
            "name",
            "businessUnitId",
            "prices"
          ],
          "additionalProperties": false
        }
      }
    }
  },
  "security": [
    {
      "oauth2": [
        "products:write"
      ]
    },
    {
      "userSession": []
    }
  ],
  "responses": {
    "201": {
      "description": "Produit créé",
      "content": {
        "application/json": {
          "schema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "name": {
                "type": "string"
              },
              "code": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "businessUnitId": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "capacity": {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "saleMode": {
                "type": "string",
                "enum": [
                  "per_cycle",
                  "one_off"
                ],
                "description": "T-1412 : par cycle ou ponctuel"
              },
              "active": {
                "type": "boolean"
              },
              "prices": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "label": {
                      "type": "string"
                    },
                    "unitPrice": {
                      "type": "string",
                      "description": "HT, chaîne décimale à 2 décimales"
                    },
                    "vatRate": {
                      "description": "Fraction stockée (0.20000) - null : taux du déploiement",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "description": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "quantityTiers": {
                      "anyOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "minQuantity": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "unitPrice": {
                                "type": "number"
                              },
                              "discountPercent": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "minQuantity"
                            ],
                            "additionalProperties": false
                          }
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "#761 : paliers par quantité triés par seuil - null : aucun"
                    },
                    "sortOrder": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "active": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "label",
                    "unitPrice",
                    "vatRate",
                    "description",
                    "quantityTiers",
                    "sortOrder",
                    "active"
                  ],
                  "additionalProperties": false
                }
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
              }
            },
            "required": [
              "id",
              "name",
              "code",
              "businessUnitId",
              "capacity",
              "saleMode",
              "active",
              "prices",
              "updatedAt"
            ],
            "additionalProperties": false
          }
        }
      }
    },
    "default": {
      "description": "Erreur - enveloppe problem+json (RFC 9457)",
      "content": {
        "application/problem+json": {
          "schema": {
            "$ref": "#/components/schemas/Problem"
          }
        }
      }
    }
  }
}
```

## GET /products/{id}

```json
{
  "summary": "Détail d'un produit (tarifs inclus)",
  "tags": [
    "Produits"
  ],
  "security": [
    {
      "oauth2": [
        "products:read"
      ]
    },
    {
      "userSession": []
    }
  ],
  "responses": {
    "200": {
      "description": "Produit",
      "content": {
        "application/json": {
          "schema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "name": {
                "type": "string"
              },
              "code": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "businessUnitId": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "capacity": {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "saleMode": {
                "type": "string",
                "enum": [
                  "per_cycle",
                  "one_off"
                ],
                "description": "T-1412 : par cycle ou ponctuel"
              },
              "active": {
                "type": "boolean"
              },
              "prices": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "label": {
                      "type": "string"
                    },
                    "unitPrice": {
                      "type": "string",
                      "description": "HT, chaîne décimale à 2 décimales"
                    },
                    "vatRate": {
                      "description": "Fraction stockée (0.20000) - null : taux du déploiement",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "description": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "quantityTiers": {
                      "anyOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "minQuantity": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "unitPrice": {
                                "type": "number"
                              },
                              "discountPercent": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "minQuantity"
                            ],
                            "additionalProperties": false
                          }
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "#761 : paliers par quantité triés par seuil - null : aucun"
                    },
                    "sortOrder": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "active": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "label",
                    "unitPrice",
                    "vatRate",
                    "description",
                    "quantityTiers",
                    "sortOrder",
                    "active"
                  ],
                  "additionalProperties": false
                }
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
              }
            },
            "required": [
              "id",
              "name",
              "code",
              "businessUnitId",
              "capacity",
              "saleMode",
              "active",
              "prices",
              "updatedAt"
            ],
            "additionalProperties": false
          }
        }
      }
    },
    "default": {
      "description": "Erreur - enveloppe problem+json (RFC 9457)",
      "content": {
        "application/problem+json": {
          "schema": {
            "$ref": "#/components/schemas/Problem"
          }
        }
      }
    }
  }
}
```

## PATCH /products/{id}

```json
{
  "summary": "Modifier un produit - `prices` fourni = l'ensemble des tarifs est remplacé",
  "description": "Patch partiel sur les champs du produit. Le tableau `prices`, s'il est fourni, devient l'ensemble complet (id présent = mise à jour, absent = création, manquant = retrait - refusé 409 si le tarif est référencé par un devis).",
  "tags": [
    "Produits"
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$schema": "https://json-schema.org/draft/2020-12/schema",
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "businessUnitId": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            },
            "code": {
              "anyOf": [
                {
                  "type": "null"
                },
                {
                  "type": "string",
                  "maxLength": 60
                }
              ]
            },
            "capacity": {
              "anyOf": [
                {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991
                },
                {
                  "type": "null"
                }
              ]
            },
            "saleMode": {
              "description": "T-1412 : par cycle (défaut) ou ponctuel, vendu à une date de prestation",
              "type": "string",
              "enum": [
                "per_cycle",
                "one_off"
              ]
            },
            "active": {
              "type": "boolean"
            },
            "prices": {
              "minItems": 1,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Présent = mise à jour du tarif, absent = création",
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "label": {
                    "type": "string",
                    "minLength": 1
                  },
                  "unitPrice": {
                    "type": "number",
                    "minimum": 0
                  },
                  "vatRatePercent": {
                    "description": "En POURCENT (20, 5.5) - null : taux du déploiement",
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "description": {
                    "anyOf": [
                      {
                        "type": "null"
                      },
                      {
                        "type": "string",
                        "maxLength": 500
                      }
                    ]
                  },
                  "active": {
                    "type": "boolean"
                  },
                  "quantityTiers": {
                    "description": "#761 : paliers par quantité [{ minQuantity ≥ 2, unitPrice | discountPercent }] ; absent : grille gardée, null ou [] : aucun palier",
                    "anyOf": [
                      {
                        "maxItems": 20,
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "minQuantity": {
                              "type": "integer",
                              "minimum": 2,
                              "maximum": 1000000
                            },
                            "unitPrice": {
                              "type": "number",
                              "exclusiveMinimum": 0,
                              "maximum": 9999999999
                            },
                            "discountPercent": {
                              "type": "number",
                              "exclusiveMinimum": 0,
                              "maximum": 100
                            }
                          },
                          "required": [
                            "minQuantity"
                          ],
                          "additionalProperties": false
                        }
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "label",
                  "unitPrice"
                ],
                "additionalProperties": false
              }
            }
          },
          "additionalProperties": false
        }
      }
    }
  },
  "security": [
    {
      "oauth2": [
        "products:write"
      ]
    },
    {
      "userSession": []
    }
  ],
  "responses": {
    "200": {
      "description": "Produit modifié",
      "content": {
        "application/json": {
          "schema": {
            "$schema": "https://json-schema.org/draft/2020-12/schema",
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "name": {
                "type": "string"
              },
              "code": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "businessUnitId": {
                "type": "string",
                "format": "uuid",
                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
              },
              "capacity": {
                "anyOf": [
                  {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "saleMode": {
                "type": "string",
                "enum": [
                  "per_cycle",
                  "one_off"
                ],
                "description": "T-1412 : par cycle ou ponctuel"
              },
              "active": {
                "type": "boolean"
              },
              "prices": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "label": {
                      "type": "string"
                    },
                    "unitPrice": {
                      "type": "string",
                      "description": "HT, chaîne décimale à 2 décimales"
                    },
                    "vatRate": {
                      "description": "Fraction stockée (0.20000) - null : taux du déploiement",
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "description": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "quantityTiers": {
                      "anyOf": [
                        {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "minQuantity": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "unitPrice": {
                                "type": "number"
                              },
                              "discountPercent": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "minQuantity"
                            ],
                            "additionalProperties": false
                          }
                        },
                        {
                          "type": "null"
                        }
                      ],
                      "description": "#761 : paliers par quantité triés par seuil - null : aucun"
                    },
                    "sortOrder": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "active": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "label",
                    "unitPrice",
                    "vatRate",
                    "description",
                    "quantityTiers",
                    "sortOrder",
                    "active"
                  ],
                  "additionalProperties": false
                }
              },
              "updatedAt": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
              }
            },
            "required": [
              "id",
              "name",
              "code",
              "businessUnitId",
              "capacity",
              "saleMode",
              "active",
              "prices",
              "updatedAt"
            ],
            "additionalProperties": false
          }
        }
      }
    },
    "default": {
      "description": "Erreur - enveloppe problem+json (RFC 9457)",
      "content": {
        "application/problem+json": {
          "schema": {
            "$ref": "#/components/schemas/Problem"
          }
        }
      }
    }
  }
}
```
