{
  "openapi": "3.1.0",
  "info": {
    "title": "Tekshelf · API du tenant",
    "version": "0.4.0-draft",
    "description": "Documentation des appels pour intégrer les bacs promo dans No Waste. Les schémas détaillés manquants sont signalés. Les choix encore ouverts sont regroupés dans le guide « Points à confirmer ». Cet aperçu ne permet pas d’exécuter des requêtes métier."
  },
  "servers": [
    {
      "url": "https://tenant.example.invalid",
      "description": "Domaine fictif : remplacer par l’origine fournie pour chaque tenant."
    }
  ],
  "tags": [
    {
      "name": "Bacs promo",
      "description": "Consulter et gérer la représentation métier du bac."
    },
    {
      "name": "Produits",
      "description": "Rechercher et gérer les fiches locales autorisées."
    },
    {
      "name": "Associations",
      "description": "Distinguer produits affichés et produit de comptage."
    },
    {
      "name": "Dispositifs",
      "description": "Consulter le dispositif associé au bac."
    },
    {
      "name": "Maintenance",
      "description": "État logiciel et prise en compte matérielle à distinguer."
    },
    {
      "name": "Événements",
      "description": "Consulter les mouvements et leur historique."
    }
  ],
  "paths": {
    "/api/furnitures": {
      "get": {
        "tags": [
          "Bacs promo"
        ],
        "summary": "Lister les meubles d’une pharmacie",
        "description": "Liste les meubles du magasin. Les bacs promo portent le type `promo_bin`. Utiliser `storeId` pour cibler la pharmacie et `zoneId` pour limiter la liste à une zone.",
        "operationId": "get_api_furnitures",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "example": {},
                        "additionalProperties": true,
                        "description": "Schéma détaillé non renseigné."
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "description": "Liste paginée. Le schéma détaillé des éléments reste à renseigner.",
                  "example": {
                    "items": [],
                    "total": 0,
                    "page": 1,
                    "limit": 20
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "storeId",
            "in": "query",
            "required": false,
            "description": "Identifiant du magasin autorisé.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "zoneId",
            "in": "query",
            "required": false,
            "description": "Filtre optionnel de zone.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Numéro de page, à partir de 1.",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Nombre d’éléments par page.",
            "schema": {
              "type": "integer",
              "default": 100,
              "minimum": 1,
              "maximum": 100
            }
          }
        ]
      },
      "post": {
        "tags": [
          "Bacs promo"
        ],
        "summary": "Créer la représentation logicielle d’un bac",
        "description": "Crée la représentation logicielle d’un bac dans une zone existante. Le type `promo_bin` possède un seul niveau. Cette création ne provisionne pas le dispositif physique. L’ouverture de cette action à No Waste fait partie des choix de gestion à arrêter.",
        "operationId": "post_api_furnitures",
        "responses": {
          "201": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          },
          "400": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "zoneId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name": {
                    "type": "string"
                  },
                  "type": {
                    "type": "string",
                    "const": "promo_bin"
                  },
                  "levelCount": {
                    "type": "integer",
                    "const": 1
                  }
                },
                "additionalProperties": true
              }
            }
          }
        }
      }
    },
    "/api/furnitures/map": {
      "get": {
        "tags": [
          "Bacs promo"
        ],
        "summary": "Consulter la vue enrichie des bacs",
        "description": "Vue enrichie des meubles, niveaux et données de stock : `currentCount`, `status`, `lastUpdateAt`, `fillPercent` et `fillStatus`. Certains comptages absents sont convertis en zéro dans cette vue : vérifier la fraîcheur et la validité avant de présenter une rupture. Le schéma détaillé reste à renseigner.",
        "operationId": "get_api_furnitures_map",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "example": {},
                    "additionalProperties": true,
                    "description": "Schéma détaillé non renseigné."
                  }
                }
              }
            }
          },
          "400": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "storeId",
            "in": "query",
            "required": true,
            "description": "Identifiant du magasin autorisé.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/api/furnitures/{furnitureId}": {
      "get": {
        "tags": [
          "Bacs promo"
        ],
        "summary": "Consulter le détail d’un bac",
        "description": "Retourne le meuble et ses niveaux. Un bac promo est un meuble de type `promo_bin`.",
        "operationId": "get_api_furnitures_furnitureId",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          },
          "404": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "furnitureId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      },
      "put": {
        "tags": [
          "Bacs promo"
        ],
        "summary": "Modifier le nom ou l’emplacement métier",
        "description": "Modifie le nom ou la zone du bac. Le déplacement doit rester dans le périmètre du magasin autorisé. Les champs ouverts à No Waste sont définis avec les droits de gestion.",
        "operationId": "put_api_furnitures_furnitureId",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          },
          "400": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "furnitureId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "zoneId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "additionalProperties": false,
                "description": "Sous-ensemble proposé pour No Waste, pas une preuve des restrictions actuellement actives."
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Bacs promo"
        ],
        "summary": "Modifier le nom ou l’emplacement métier",
        "description": "Modifie le nom ou la zone du bac. Le déplacement doit rester dans le périmètre du magasin autorisé. Les champs ouverts à No Waste sont définis avec les droits de gestion.",
        "operationId": "patch_api_furnitures_furnitureId",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          },
          "400": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "furnitureId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "zoneId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "additionalProperties": false,
                "description": "Sous-ensemble proposé pour No Waste, pas une preuve des restrictions actuellement actives."
              }
            }
          }
        }
      }
    },
    "/api/products": {
      "get": {
        "tags": [
          "Produits"
        ],
        "summary": "Rechercher les produits",
        "description": "Recherche les produits du tenant. `ean` recherche un code exact dans EAN, master CIP et CIP13 ; il prend la priorité sur `search`. La réponse est paginée.",
        "operationId": "get_api_products",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "example": {},
                        "additionalProperties": true,
                        "description": "Schéma détaillé non renseigné."
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "description": "Liste paginée. Le schéma détaillé des éléments reste à renseigner.",
                  "example": {
                    "items": [],
                    "total": 0,
                    "page": 1,
                    "limit": 20
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "ean",
            "in": "query",
            "required": false,
            "description": "Code exact EAN ou CIP.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Recherche textuelle.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "section",
            "in": "query",
            "required": false,
            "description": "Filtre de section.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Numéro de page, à partir de 1.",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Nombre d’éléments par page ; maximum 100.",
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          }
        ]
      },
      "post": {
        "tags": [
          "Produits"
        ],
        "summary": "Créer un produit local",
        "description": "Crée une fiche produit locale. Le corps de création reste à renseigner. Les règles de création et de rapprochement des produits sont à arrêter dans le périmètre de gestion.",
        "operationId": "post_api_products",
        "responses": {
          "201": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "example": {},
                "additionalProperties": true,
                "description": "Schéma détaillé non renseigné."
              }
            }
          }
        }
      }
    },
    "/api/products/{productId}": {
      "get": {
        "tags": [
          "Produits"
        ],
        "summary": "Consulter un produit",
        "description": "Retourne la fiche produit identifiée par `productId`.",
        "operationId": "get_api_products_productId",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          },
          "404": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      },
      "put": {
        "tags": [
          "Produits"
        ],
        "summary": "Modifier un produit local",
        "description": "Modifie une fiche produit locale. Une fiche peut servir à plusieurs emplacements. Les champs autorisés et le changement du poids unitaire sont à arrêter dans le périmètre de gestion.",
        "operationId": "put_api_products_productId",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "example": {},
                "additionalProperties": true,
                "description": "Schéma détaillé non renseigné."
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "Produits"
        ],
        "summary": "Modifier un produit local",
        "description": "Modifie une fiche produit locale. Une fiche peut servir à plusieurs emplacements. Les champs autorisés et le changement du poids unitaire sont à arrêter dans le périmètre de gestion.",
        "operationId": "patch_api_products_productId",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "productId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "example": {},
                "additionalProperties": true,
                "description": "Schéma détaillé non renseigné."
              }
            }
          }
        }
      }
    },
    "/api/furnitures/{furnitureId}/display-products": {
      "put": {
        "tags": [
          "Associations"
        ],
        "summary": "Remplacer les produits affichés dans un bac",
        "description": "Remplace intégralement la liste des produits affichés. `[]` vide la liste déclarative ; il ne vide pas physiquement le bac. Chaque produit doit exister, ne pas être supprimé et n’apparaître qu’une fois. Les positions sont normalisées après tri. Rejouer la même liste produit le même état. Cette action ne modifie pas l’association de comptage par poids.",
        "operationId": "put_api_furnitures_furnitureId_display_products",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          },
          "400": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "furnitureId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "maxItems": 100,
                "items": {
                  "type": "object",
                  "required": [
                    "productId"
                  ],
                  "properties": {
                    "productId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "position": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": false
                },
                "example": [
                  {
                    "productId": "11111111-1111-4111-8111-111111111111",
                    "position": 0
                  },
                  {
                    "productId": "22222222-2222-4222-8222-222222222222",
                    "position": 1
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/api/devices/{deviceId}": {
      "get": {
        "tags": [
          "Dispositifs"
        ],
        "summary": "Consulter le dispositif peseur",
        "description": "Retourne le dispositif peseur associé au bac. Le dispositif est distinct du meuble qui représente le bac dans le magasin.",
        "operationId": "get_api_devices_deviceId",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          },
          "404": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/api/devices/{deviceId}/scales/{scaleIndex}/product": {
      "put": {
        "tags": [
          "Associations"
        ],
        "summary": "Associer le produit de comptage",
        "description": "Associe un produit à un emplacement de mesure. Le changement réinitialise le comptage et les références liées à l’ancien produit. La réponse `{\"ok\":true}` confirme l’association logicielle ; elle ne garantit pas qu’une nouvelle mesure physique soit déjà disponible.",
        "operationId": "put_api_devices_deviceId_scales_scaleIndex_product",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "example": {
                    "ok": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "410": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "scaleIndex",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "productId"
                ],
                "properties": {
                  "productId": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "example": {
                  "productId": "11111111-1111-4111-8111-111111111111"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Associations"
        ],
        "summary": "Retirer l’association de comptage",
        "description": "Retire l’association du produit à l’emplacement de mesure. Ne supprime ni le produit, ni le bac, ni son historique.",
        "operationId": "delete_api_devices_deviceId_scales_scaleIndex_product",
        "responses": {
          "204": {
            "description": "Association retirée. Aucun corps de réponse."
          },
          "404": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "scaleIndex",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ]
      }
    },
    "/api/furnitures/{furnitureId}/maintenance": {
      "post": {
        "tags": [
          "Maintenance"
        ],
        "summary": "Déclarer le début d’une maintenance",
        "description": "Déclare la maintenance des dispositifs du meuble dans le logiciel. La durée est exprimée en secondes. Le réveil d’un bac autonome en sommeil et le délai avant une nouvelle mesure font partie des points ouverts sur l’installation et la maintenance.",
        "operationId": "post_api_furnitures_furnitureId_maintenance",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "example": {},
                  "additionalProperties": true,
                  "description": "Schéma détaillé non renseigné."
                }
              }
            }
          },
          "404": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erreur de la requête.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string"
                    },
                    "status": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "example": {
                    "error": "Message d’erreur (exemple fictif)"
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "furnitureId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "const": "start",
                    "default": "start"
                  },
                  "duration": {
                    "type": "integer",
                    "minimum": 60,
                    "maximum": 86400,
                    "default": 900,
                    "description": "Durée en secondes."
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 255
                  }
                },
                "example": {
                  "action": "start",
                  "duration": 900,
                  "reason": "Changement de produits"
                }
              }
            }
          }
        }
      }
    },
    "/api/events": {
      "get": {
        "tags": [
          "Événements"
        ],
        "summary": "Récupérer l’historique",
        "description": "Historique paginé, filtrable par magasin, dispositif et produit. Avec `from` et `to`, le début est inclus et la fin exclue. Une période nommée prend la priorité sur ces dates. `excludePositive=true` retire les événements dont `differenceProduct > 0` ; ce n’est pas un filtre de ventes. La reprise de synchronisation doit gérer les événements arrivant pendant la pagination.",
        "operationId": "get_api_events",
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "example": {},
                        "additionalProperties": true,
                        "description": "Schéma détaillé non renseigné."
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true,
                  "description": "Liste paginée. Le schéma détaillé des éléments reste à renseigner.",
                  "example": {
                    "items": [],
                    "total": 0,
                    "page": 1,
                    "limit": 20
                  }
                }
              }
            }
          }
        },
        "x-allowed-use": "Gestion des bacs promo, selon les droits du partenaire.",
        "parameters": [
          {
            "name": "storeId",
            "in": "query",
            "required": false,
            "description": "Magasin autorisé.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "deviceId",
            "in": "query",
            "required": false,
            "description": "Dispositif concerné.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "productId",
            "in": "query",
            "required": false,
            "description": "Produit concerné.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "scaleIndex",
            "in": "query",
            "required": false,
            "description": "Index de balance.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Type d’événement ; valeurs à valider.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Début inclus. Utiliser une date avec fuseau explicite.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Fin exclue. Utiliser une date avec fuseau explicite.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "period",
            "in": "query",
            "required": false,
            "description": "Période prédéfinie ; ne pas combiner avec from/to.",
            "schema": {
              "type": "string",
              "enum": [
                "today",
                "yesterday",
                "last7Days",
                "last30Days",
                "thisWeek",
                "thisMonth"
              ]
            }
          },
          {
            "name": "excludePositive",
            "in": "query",
            "required": false,
            "description": "Exclure les mouvements strictement positifs.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Champ de tri.",
            "schema": {
              "type": "string",
              "default": "createdAt",
              "enum": [
                "createdAt",
                "type",
                "differenceProduct"
              ]
            }
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "description": "Ordre du tri.",
            "schema": {
              "type": "string",
              "default": "DESC",
              "enum": [
                "ASC",
                "DESC"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Numéro de page, à partir de 1.",
            "schema": {
              "type": "integer",
              "default": 1,
              "minimum": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Nombre d’éléments par page ; maximum 100.",
            "schema": {
              "type": "integer",
              "default": 20,
              "minimum": 1,
              "maximum": 100
            }
          }
        ]
      }
    }
  },
  "x-draft": true,
  "x-authentication-status": "Non spécifié : aucun mécanisme d’authentification n’est garanti par cet export."
}