{
  "components": {
    "schemas": {
      "BatchUpsertRequest": {
        "properties": {
          "products": {
            "description": "Liste de produits à upsert (max 500)",
            "items": {
              "$ref": "#/components/schemas/ProductBatchItemSchema"
            },
            "title": "Products",
            "type": "array"
          }
        },
        "required": [
          "products"
        ],
        "title": "BatchUpsertRequest",
        "type": "object"
      },
      "ChampsIgnoresFiche": {
        "description": "Une fiche d'un lot qui portait des clés inconnues (ignorées).",
        "properties": {
          "champs": {
            "description": "Clés ignorées de cette fiche, triées",
            "items": {
              "type": "string"
            },
            "title": "Champs",
            "type": "array"
          },
          "ean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "EAN de la fiche, tel que reçu",
            "title": "Ean"
          },
          "index": {
            "description": "Position de la fiche dans le lot reçu (à partir de 0)",
            "title": "Index",
            "type": "integer"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Référence WinDev de la fiche (`/windev/products/sync`)",
            "title": "Reference"
          }
        },
        "required": [
          "index",
          "champs"
        ],
        "title": "ChampsIgnoresFiche",
        "type": "object"
      },
      "ErrorDetail": {
        "description": "Objet `error` interne, commun aux 5 gestionnaires de `error_handlers.py`.",
        "properties": {
          "code": {
            "description": "Code HTTP",
            "title": "Code",
            "type": "integer"
          },
          "details": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "description": "Détails additionnels ; liste de ValidationErrorField sur un 422",
            "title": "Details"
          },
          "error_code": {
            "description": "Code d'erreur normalisé (ex. VALIDATION_FAILED, PERMISSION_DENIED)",
            "title": "Error Code",
            "type": "string"
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "items": {},
                "type": "array"
              }
            ],
            "description": "Message lisible — ou objet structuré si le handler a levé HTTPException(detail={...})",
            "title": "Message"
          },
          "path": {
            "description": "Chemin de la requête",
            "title": "Path",
            "type": "string"
          },
          "request_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifiant de requête, aussi renvoyé en en-tête X-Request-ID",
            "title": "Request Id"
          },
          "timestamp": {
            "description": "Horodatage ISO 8601 (UTC)",
            "title": "Timestamp",
            "type": "string"
          },
          "type": {
            "description": "Famille d'erreur (validation_error, not_found, rate_limit_exceeded…)",
            "title": "Type",
            "type": "string"
          }
        },
        "required": [
          "code",
          "error_code",
          "type",
          "message",
          "path",
          "timestamp"
        ],
        "title": "ErrorDetail",
        "type": "object"
      },
      "ErrorResponse": {
        "description": "Enveloppe d'erreur normalisée — forme n°1 (dominante).\n\n```json\n{\"error\": {\"code\": 404, \"error_code\": \"SYSTEM_INTERNAL_ERROR\",\n           \"type\": \"not_found\", \"message\": \"Product not found\",\n           \"details\": null, \"path\": \"/api/v1/products/xxx\",\n           \"request_id\": \"abc-123\", \"timestamp\": \"2026-08-18T12:00:00+00:00\"}}\n```",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        },
        "required": [
          "error"
        ],
        "title": "ErrorResponse",
        "type": "object"
      },
      "ExtBatchError": {
        "description": "Détail d'erreur d'un item dans un upsert batch.",
        "properties": {
          "ean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "EAN de l'item en erreur",
            "title": "Ean"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Message d'erreur",
            "title": "Error"
          },
          "index": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Index de l'item en erreur",
            "title": "Index"
          }
        },
        "title": "ExtBatchError",
        "type": "object"
      },
      "ExtBatchResponse": {
        "description": "Enveloppe de `POST /ext/products/batch`.",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "champs_ignores_par_fiche": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChampsIgnoresFiche"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures en lot : une entrée par fiche qui portait des clés ignorées (aucune : liste vide)",
            "title": "Champs Ignores Par Fiche"
          },
          "data": {
            "$ref": "#/components/schemas/ExtBatchResult"
          },
          "errors": {
            "items": {},
            "title": "Errors",
            "type": "array"
          },
          "meta": {
            "$ref": "#/components/schemas/ExtMeta"
          },
          "success": {
            "default": true,
            "title": "Success",
            "type": "boolean"
          }
        },
        "title": "ExtBatchResponse",
        "type": "object"
      },
      "ExtBatchResult": {
        "description": "Payload de `POST /ext/products/batch` (résumé de l'upsert batch).",
        "properties": {
          "brands_unresolved": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre de fiches enregistrées dont `brand_name` ne désigne aucune marque du référentiel (inconnue, ambiguë ou désactivée) : le nom est gardé, sans marque rattachée ; aucune marque n'est créée",
            "title": "Brands Unresolved"
          },
          "created": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre de produits créés",
            "title": "Created"
          },
          "error_details": {
            "items": {
              "$ref": "#/components/schemas/ExtBatchError"
            },
            "title": "Error Details",
            "type": "array"
          },
          "errors": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre d'erreurs",
            "title": "Errors"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total d'items traités",
            "title": "Total"
          },
          "updated": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre de produits mis à jour",
            "title": "Updated"
          }
        },
        "title": "ExtBatchResult",
        "type": "object"
      },
      "ExtFabricant": {
        "description": "Fabricant RÉSOLU d'un produit (surcharge du produit, sinon celui de sa marque) — vague CHAMPS-P0, lot GPSR.",
        "properties": {
          "adresse_ligne1": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Adresse postale, ligne 1",
            "title": "Adresse Ligne1"
          },
          "adresse_ligne2": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Adresse postale, ligne 2",
            "title": "Adresse Ligne2"
          },
          "code_postal": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Code postal",
            "title": "Code Postal"
          },
          "courriel": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Adresse électronique de contact",
            "title": "Courriel"
          },
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifiant de la fiche (UUID)",
            "title": "Id"
          },
          "nom_commercial": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nom commercial ou marque déposée",
            "title": "Nom Commercial"
          },
          "pays": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pays, ISO 3166-1 alpha-2",
            "title": "Pays"
          },
          "personne_responsable": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExtOperateur"
              },
              {
                "type": "null"
              }
            ],
            "description": "Personne responsable dans l'Union (fabricant établi hors de l'Union, art. 16)"
          },
          "provenance": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "`produit` (surcharge) ou `marque` (fabricant de la marque)",
            "title": "Provenance"
          },
          "raison_sociale": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nom légal",
            "title": "Raison Sociale"
          },
          "site_web": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Site ou formulaire de contact",
            "title": "Site Web"
          },
          "telephone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Téléphone",
            "title": "Telephone"
          },
          "ville": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ville",
            "title": "Ville"
          }
        },
        "title": "ExtFabricant",
        "type": "object"
      },
      "ExtMeta": {
        "description": "Métadonnées de l'enveloppe `_ok()` (pagination + timestamp).",
        "properties": {
          "page": {
            "default": 1,
            "description": "Numéro de page (1-indexée)",
            "title": "Page",
            "type": "integer"
          },
          "page_size": {
            "default": 50,
            "description": "Nombre d'éléments par page",
            "title": "Page Size",
            "type": "integer"
          },
          "total": {
            "default": 0,
            "description": "Nombre total de résultats",
            "title": "Total",
            "type": "integer"
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Timestamp de la réponse (ISO 8601)",
            "title": "Updated At"
          }
        },
        "title": "ExtMeta",
        "type": "object"
      },
      "ExtOperateur": {
        "description": "Opérateur économique (GPSR, règlement (UE) 2023/988) : fabricant ou personne responsable dans l'Union.",
        "properties": {
          "adresse_ligne1": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Adresse postale, ligne 1",
            "title": "Adresse Ligne1"
          },
          "adresse_ligne2": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Adresse postale, ligne 2",
            "title": "Adresse Ligne2"
          },
          "code_postal": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Code postal",
            "title": "Code Postal"
          },
          "courriel": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Adresse électronique de contact",
            "title": "Courriel"
          },
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifiant de la fiche (UUID)",
            "title": "Id"
          },
          "nom_commercial": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nom commercial ou marque déposée",
            "title": "Nom Commercial"
          },
          "pays": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pays, ISO 3166-1 alpha-2",
            "title": "Pays"
          },
          "raison_sociale": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nom légal",
            "title": "Raison Sociale"
          },
          "site_web": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Site ou formulaire de contact",
            "title": "Site Web"
          },
          "telephone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Téléphone",
            "title": "Telephone"
          },
          "ville": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Ville",
            "title": "Ville"
          }
        },
        "title": "ExtOperateur",
        "type": "object"
      },
      "ExtProduct": {
        "description": "Représentation d'un produit telle que renvoyée par\n`services.external_api_service._product_to_dict`.\n\nAligné sur le schéma `Product` de `docs/external-api/openapi.yaml`.",
        "properties": {
          "asin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "ASIN Amazon",
            "title": "Asin"
          },
          "avertissements_securite": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Avertissements et informations de sécurité par langue ISO 639-1 (GPSR)",
            "title": "Avertissements Securite"
          },
          "brand_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nom de la marque",
            "title": "Brand Name"
          },
          "category_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Toujours null : l'ancien arbre `categories` est retiré (catalog/228). Champ gardé au contrat v1.",
            "title": "Category Id"
          },
          "completeness_score": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Score de complétude (0-100)",
            "title": "Completeness Score"
          },
          "condition": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "État du produit : new | refurbished | used (null : non renseigné)",
            "title": "Condition"
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Date de création (ISO 8601)",
            "title": "Created At"
          },
          "depth": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Profondeur en cm",
            "title": "Depth"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Description longue",
            "title": "Description"
          },
          "ean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "EAN-13 ou code équivalent",
            "title": "Ean"
          },
          "external_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifiant externe (ERP, WinDev)",
            "title": "External Id"
          },
          "fabricant": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExtFabricant"
              },
              {
                "type": "null"
              }
            ],
            "description": "Fabricant résolu (GPSR) avec sa provenance et sa personne responsable ; null : aucun"
          },
          "gross_weight": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Poids brut en kg, emballage compris",
            "title": "Gross Weight"
          },
          "gtin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "GTIN",
            "title": "Gtin"
          },
          "height": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hauteur en cm",
            "title": "Height"
          },
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifiant unique du produit (UUID)",
            "title": "Id"
          },
          "is_active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Produit actif ou non",
            "title": "Is Active"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nom / titre du produit",
            "title": "Name"
          },
          "net_content": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Contenu net (prix à l'unité)",
            "title": "Net Content"
          },
          "net_content_unit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unité du contenu net : ml | cl | l | g | kg | cm | m | m2 | m3 | unite",
            "title": "Net Content Unit"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Référence fabricant",
            "title": "Reference"
          },
          "short_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Description courte",
            "title": "Short Description"
          },
          "sku": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Référence interne (SKU) du produit, unique par tenant",
            "title": "Sku"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Statut (active | inactive | archived)",
            "title": "Status"
          },
          "supplier_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Code fournisseur (import_source)",
            "title": "Supplier Code"
          },
          "unit_of_measure": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unité de mesure",
            "title": "Unit Of Measure"
          },
          "upc": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Code UPC",
            "title": "Upc"
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Date de dernière modification (ISO 8601)",
            "title": "Updated At"
          },
          "url_slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Slug URL pour SEO",
            "title": "Url Slug"
          },
          "weight": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Poids net en kg",
            "title": "Weight"
          },
          "width": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Largeur en cm",
            "title": "Width"
          }
        },
        "title": "ExtProduct",
        "type": "object"
      },
      "ExtProductListResponse": {
        "description": "Enveloppe des listes de produits (`GET /ext/products`, `GET /ext/products/delta`).",
        "properties": {
          "data": {
            "items": {
              "$ref": "#/components/schemas/ExtProduct"
            },
            "title": "Data",
            "type": "array"
          },
          "errors": {
            "items": {},
            "title": "Errors",
            "type": "array"
          },
          "meta": {
            "$ref": "#/components/schemas/ExtMeta"
          },
          "success": {
            "default": true,
            "title": "Success",
            "type": "boolean"
          }
        },
        "title": "ExtProductListResponse",
        "type": "object"
      },
      "ExtProductResponse": {
        "description": "Enveloppe d'un produit unique (`GET /ext/products/{ean}`, `PUT`, `PATCH`).",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "data": {
            "$ref": "#/components/schemas/ExtProduct"
          },
          "errors": {
            "items": {},
            "title": "Errors",
            "type": "array"
          },
          "meta": {
            "$ref": "#/components/schemas/ExtMeta"
          },
          "success": {
            "default": true,
            "title": "Success",
            "type": "boolean"
          }
        },
        "title": "ExtProductResponse",
        "type": "object"
      },
      "ExtStatusData": {
        "description": "Payload de `GET /ext/status` (champ `data`).",
        "properties": {
          "api_key_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nom de la clé API appelante",
            "title": "Api Key Name"
          },
          "api_key_scopes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Scopes de la clé API",
            "title": "Api Key Scopes"
          },
          "api_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Version MAJEURE du contrat public (même valeur que l'en-tête `API-Version`)",
            "title": "Api Version"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "État de l'API ('ok')",
            "title": "Status"
          },
          "timestamp": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Horodatage serveur (ISO 8601)",
            "title": "Timestamp"
          },
          "version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Valeur historique figée ('1.0'), conservée pour compatibilité ; lire `api_version`",
            "title": "Version"
          }
        },
        "title": "ExtStatusData",
        "type": "object"
      },
      "ExtStatusResponse": {
        "description": "Enveloppe de `GET /ext/status`.",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/ExtStatusData"
          },
          "errors": {
            "items": {},
            "title": "Errors",
            "type": "array"
          },
          "meta": {
            "$ref": "#/components/schemas/ExtMeta"
          },
          "success": {
            "default": true,
            "title": "Success",
            "type": "boolean"
          }
        },
        "title": "ExtStatusResponse",
        "type": "object"
      },
      "ExtUpsertResponse": {
        "description": "Enveloppe de `POST /ext/products`.",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "data": {
            "$ref": "#/components/schemas/ExtUpsertResult"
          },
          "errors": {
            "items": {},
            "title": "Errors",
            "type": "array"
          },
          "meta": {
            "$ref": "#/components/schemas/ExtMeta"
          },
          "success": {
            "default": true,
            "title": "Success",
            "type": "boolean"
          }
        },
        "title": "ExtUpsertResponse",
        "type": "object"
      },
      "ExtUpsertResult": {
        "description": "Payload de `POST /ext/products` (résultat d'un upsert unitaire).",
        "properties": {
          "created": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "True si le produit a été créé",
            "title": "Created"
          },
          "ean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "EAN du produit",
            "title": "Ean"
          },
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "UUID du produit",
            "title": "Id"
          },
          "product": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExtProduct"
              },
              {
                "type": "null"
              }
            ],
            "description": "Représentation complète du produit"
          }
        },
        "title": "ExtUpsertResult",
        "type": "object"
      },
      "ProductBatchItemSchema": {
        "description": "Une fiche d'un lot — contre-revue du train 9 : une mesure hors plage n'invalide pas le LOT entier (422) ;\nelle est refusée PAR FICHE par `batch_upsert_products` (motif nommé), les autres passent. Même règle pour un\n`url_slug` de plus de 255 caractères.",
        "properties": {
          "asin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Asin"
          },
          "brand_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Brand Name"
          },
          "depth": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Depth"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "ean": {
            "description": "EAN-13 ou code équivalent (obligatoire)",
            "title": "Ean",
            "type": "string"
          },
          "external_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Id"
          },
          "gtin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Gtin"
          },
          "height": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Height"
          },
          "is_active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Active"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nom / titre du produit",
            "title": "Name"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Référence fabricant",
            "title": "Reference"
          },
          "short_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Short Description"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "active | inactive | archived",
            "title": "Status"
          },
          "supplier_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Code fournisseur (import_source)",
            "title": "Supplier Code"
          },
          "unit_of_measure": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Of Measure"
          },
          "upc": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Upc"
          },
          "url_slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Slug d'URL (fin de l'adresse, 255 caractères au plus). Plus long : la fiche est refusée SEULE (`error_details`). Porteur d'un schéma (`javascript:`…) : la requête entière est refusée (422).",
            "title": "Url Slug"
          },
          "weight": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Weight"
          },
          "width": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Width"
          }
        },
        "required": [
          "ean"
        ],
        "title": "ProductBatchItemSchema",
        "type": "object"
      },
      "ProductPatchSchema": {
        "properties": {
          "asin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Asin"
          },
          "brand_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Brand Name"
          },
          "depth": {
            "anyOf": [
              {
                "exclusiveMaximum": 100000000.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Depth"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "external_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Id"
          },
          "gtin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Gtin"
          },
          "height": {
            "anyOf": [
              {
                "exclusiveMaximum": 100000000.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Height"
          },
          "is_active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Active"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference"
          },
          "short_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Short Description"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status"
          },
          "supplier_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Supplier Code"
          },
          "unit_of_measure": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Of Measure"
          },
          "upc": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Upc"
          },
          "url_slug": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url Slug"
          },
          "weight": {
            "anyOf": [
              {
                "exclusiveMaximum": 10000000.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Weight"
          },
          "width": {
            "anyOf": [
              {
                "exclusiveMaximum": 100000000.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Width"
          }
        },
        "title": "ProductPatchSchema",
        "type": "object"
      },
      "ProductWriteSchema": {
        "description": "Écriture UNITAIRE (création, remplacement) : mêmes champs qu'une fiche de lot, mesures et slug bornés à\nl'entrée (slug : 422 `VALIDATION_URL_SLUG_TOO_LONG` au-delà de 255 caractères, `VALIDATION_URL_SLUG_SCHEME` s'il\nporte un schéma).",
        "properties": {
          "asin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Asin"
          },
          "brand_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Brand Name"
          },
          "depth": {
            "anyOf": [
              {
                "exclusiveMaximum": 100000000.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Depth"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "ean": {
            "description": "EAN-13 ou code équivalent (obligatoire)",
            "title": "Ean",
            "type": "string"
          },
          "external_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Id"
          },
          "gtin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Gtin"
          },
          "height": {
            "anyOf": [
              {
                "exclusiveMaximum": 100000000.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Height"
          },
          "is_active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Active"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nom / titre du produit",
            "title": "Name"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Référence fabricant",
            "title": "Reference"
          },
          "short_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Short Description"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "active | inactive | archived",
            "title": "Status"
          },
          "supplier_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Code fournisseur (import_source)",
            "title": "Supplier Code"
          },
          "unit_of_measure": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Of Measure"
          },
          "upc": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Upc"
          },
          "url_slug": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url Slug"
          },
          "weight": {
            "anyOf": [
              {
                "exclusiveMaximum": 10000000.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Weight"
          },
          "width": {
            "anyOf": [
              {
                "exclusiveMaximum": 100000000.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Width"
          }
        },
        "required": [
          "ean"
        ],
        "title": "ProductWriteSchema",
        "type": "object"
      },
      "RateLimitErrorResponse": {
        "description": "Erreur de limitation de débit (429) — forme n°2, **divergente**.\n\nProduite par `core/rate_limit.py::rate_limit_exceeded_handler` (slowapi),\nqui court-circuite l'enveloppe commune. ⚠ `error` est ici une **chaîne**,\npas un objet : le code appelant qui lit `error.code` sur un 429 obtient\n`undefined`. Modélisée telle qu'elle est émise — l'unifier sur\n`ErrorResponse` est une décision de rupture de contrat, pas un nettoyage.",
        "example": {
          "detail": "5 per 15 minute",
          "error": "rate_limit_exceeded",
          "message": "Too many requests. Please try again later.",
          "retry_after": "Please wait before making more requests"
        },
        "properties": {
          "detail": {
            "description": "Limite dépassée, format slowapi (ex. « 5 per 15 minute »)",
            "title": "Detail",
            "type": "string"
          },
          "error": {
            "description": "Constante « rate_limit_exceeded »",
            "title": "Error",
            "type": "string"
          },
          "message": {
            "description": "Message lisible",
            "title": "Message",
            "type": "string"
          },
          "retry_after": {
            "description": "Consigne d'attente (texte libre, PAS un délai)",
            "title": "Retry After",
            "type": "string"
          }
        },
        "required": [
          "error",
          "message",
          "detail",
          "retry_after"
        ],
        "title": "RateLimitErrorResponse",
        "type": "object"
      },
      "ValidationErrorResponse": {
        "description": "Erreur de validation (422) — même enveloppe, `error.details` peuplé.\n\n⚠ À ne pas confondre avec le `HTTPValidationError` de FastAPI\n(`{\"detail\":[{loc,msg,type}]}`) que le contrat déclare aujourd'hui : cette\nforme-là n'est **jamais** émise, `validation_exception_handler` la remplace.",
        "example": {
          "error": {
            "code": 422,
            "details": [
              {
                "field": "body.name",
                "message": "Field required",
                "type": "missing"
              }
            ],
            "error_code": "VALIDATION_FAILED",
            "message": "Request validation failed",
            "path": "/api/v1/products",
            "request_id": "abc-123",
            "timestamp": "2026-08-18T12:00:00+00:00",
            "type": "validation_error"
          }
        },
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        },
        "required": [
          "error"
        ],
        "title": "ValidationErrorResponse",
        "type": "object"
      },
      "WinDevCategory": {
        "additionalProperties": true,
        "description": "Catégorie plate WinDev — forme gardée au contrat v1 ; `GET /windev/categories` (dépréciée) rend une liste VIDE\ndepuis le retrait de l'ancien arbre `categories` (catalog/228).",
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Id"
          },
          "is_active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Active"
          },
          "level": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Level"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "parent_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Id"
          },
          "path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Path"
          },
          "product_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product Count"
          },
          "slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Slug"
          }
        },
        "required": [
          "id",
          "name",
          "slug",
          "parent_id",
          "level",
          "path",
          "is_active",
          "product_count"
        ],
        "title": "WinDevCategory",
        "type": "object"
      },
      "WinDevCategoryListEnvelope": {
        "description": "`GET /windev/categories` — DÉPRÉCIÉE (catalog/228) : liste toujours vide, retrait au terme du préavis.",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "champs_ignores_par_fiche": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChampsIgnoresFiche"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures en lot : une entrée par ligne qui portait des clés ignorées (aucune : liste vide)",
            "title": "Champs Ignores Par Fiche"
          },
          "code": {
            "default": 200,
            "description": "Code HTTP applicatif",
            "title": "Code",
            "type": "integer"
          },
          "count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre d'éléments dans `data`",
            "title": "Count"
          },
          "data": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/WinDevCategory"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Toujours vide (ancien arbre `categories` retiré)",
            "title": "Data"
          },
          "limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taille de page (endpoints de liste)",
            "title": "Limit"
          },
          "message": {
            "default": "OK",
            "description": "Message lisible",
            "title": "Message",
            "type": "string"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Page courante (endpoints de liste)",
            "title": "Page"
          },
          "pages": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de pages (endpoints de liste)",
            "title": "Pages"
          },
          "success": {
            "default": true,
            "description": "True si code < 400",
            "title": "Success",
            "type": "boolean"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de résultats (endpoints de liste)",
            "title": "Total"
          }
        },
        "title": "WinDevCategoryListEnvelope",
        "type": "object"
      },
      "WinDevPriceEnvelope": {
        "description": "`POST /windev/prices/update`.",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "champs_ignores_par_fiche": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChampsIgnoresFiche"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures en lot : une entrée par ligne qui portait des clés ignorées (aucune : liste vide)",
            "title": "Champs Ignores Par Fiche"
          },
          "code": {
            "default": 200,
            "description": "Code HTTP applicatif",
            "title": "Code",
            "type": "integer"
          },
          "count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre d'éléments dans `data`",
            "title": "Count"
          },
          "data": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/WinDevPriceResult"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Un résultat par ligne reçue",
            "title": "Data"
          },
          "limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taille de page (endpoints de liste)",
            "title": "Limit"
          },
          "message": {
            "default": "OK",
            "description": "Message lisible",
            "title": "Message",
            "type": "string"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Page courante (endpoints de liste)",
            "title": "Page"
          },
          "pages": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de pages (endpoints de liste)",
            "title": "Pages"
          },
          "success": {
            "default": true,
            "description": "True si code < 400",
            "title": "Success",
            "type": "boolean"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de résultats (endpoints de liste)",
            "title": "Total"
          }
        },
        "title": "WinDevPriceEnvelope",
        "type": "object"
      },
      "WinDevPriceItem": {
        "description": "Item de mise à jour de prix.",
        "properties": {
          "ean": {
            "description": "EAN du produit",
            "title": "Ean",
            "type": "string"
          },
          "price_ht": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Prix de VENTE hors taxes (EUR) — enregistré comme prix de vente HT du produit (⚖ 26/10/2026 : avant, il était enregistré comme coût d'achat)",
            "title": "Price Ht"
          },
          "price_ttc": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Prix TTC (EUR) — JAMAIS enregistré : seul (sans price_ht), l'article est refusé (WINDEV_PRICE_TTC_ONLY) ; avec price_ht, il est cité dans champs_ignores",
            "title": "Price Ttc"
          }
        },
        "required": [
          "ean"
        ],
        "title": "WinDevPriceItem",
        "type": "object"
      },
      "WinDevPriceResult": {
        "additionalProperties": true,
        "description": "Résultat par ligne de `POST /windev/prices/update` (`services.windev_service.update_prices_batch`).",
        "properties": {
          "ean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "EAN reçu (normalisé s'il est valide)",
            "title": "Ean"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Présent si status = not_found ou error",
            "title": "Error"
          },
          "error_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Refus NOMMÉ de la ligne (rien n'est écrit pour elle) : `WINDEV_PRODUCT_IN_TRASH` (le produit est dans la corbeille ; le restaurer d'abord), `WINDEV_REFERENCE_AMBIGUOUS` (plusieurs produits vivants portent cet EAN ou cette référence ; corriger le doublon d'abord) ou `WINDEV_PRICE_TTC_ONLY` (price_ttc sans price_ht)",
            "title": "Error Code"
          },
          "price_ht": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Prix de vente HT enregistré (présent si status = updated)",
            "title": "Price Ht"
          },
          "price_ttc": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Absent depuis le 26/10/2026 : aucun prix TTC n'est enregistré (champ conservé au contrat)",
            "title": "Price Ttc"
          },
          "status": {
            "description": "updated | not_found | error",
            "title": "Status",
            "type": "string"
          },
          "updated": {
            "description": "Prix écrit",
            "title": "Updated",
            "type": "boolean"
          }
        },
        "required": [
          "ean",
          "status",
          "updated"
        ],
        "title": "WinDevPriceResult",
        "type": "object"
      },
      "WinDevProduct": {
        "description": "Produit envoyé depuis WinDev pour synchronisation batch (POST /products/sync).",
        "properties": {
          "brand": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Marque",
            "title": "Brand"
          },
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Catégorie, par son NOM (ou son identifiant) : rattachée à la catégorie existante qui porte ce nom (casse, accents et ponctuation ignorés) ; aucune catégorie n'est créée. Nom inconnu ou porté par plusieurs catégories : produit enregistré sans toucher sa catégorie, et l'article porte category_unresolved",
            "title": "Category"
          },
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Color"
          },
          "country_of_origin": {
            "anyOf": [
              {
                "maxLength": 2,
                "minLength": 2,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country Of Origin"
          },
          "dangerous_goods": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dangerous Goods"
          },
          "depth": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Depth"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "ean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "EAN/GTIN",
            "title": "Ean"
          },
          "external_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Id"
          },
          "gtin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Gtin"
          },
          "height": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Height"
          },
          "hs_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Hs Code"
          },
          "lead_time_days": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Délai de livraison du PRODUIT en jours (products.lead_time_days) — distinct du délai d'un FOURNISSEUR, que porte l'import de fichier (supplier_products.lead_time_days)",
            "title": "Lead Time Days"
          },
          "material": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Material"
          },
          "min_order_quantity": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Quantité minimale de VENTE du produit (products.min_order_quantity) — distincte du minimum d'ACHAT chez un fournisseur, que porte l'import de fichier (supplier_products.moq)",
            "title": "Min Order Quantity"
          },
          "name": {
            "description": "Nom du produit",
            "title": "Name",
            "type": "string"
          },
          "package_quantity": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Package Quantity"
          },
          "package_weight": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Poids colis (grammes)",
            "title": "Package Weight"
          },
          "price_ht": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Prix de VENTE hors taxes (EUR) — enregistré comme prix de vente HT du produit (⚖ 26/10/2026 : avant, il était enregistré comme coût d'achat)",
            "title": "Price Ht"
          },
          "price_ttc": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Prix TTC (EUR) — JAMAIS enregistré : seul (sans price_ht), l'article est refusé (WINDEV_PRICE_TTC_ONLY) ; avec price_ht, il est cité dans champs_ignores",
            "title": "Price Ttc"
          },
          "reference": {
            "description": "Référence interne WinDev (clé d'identification)",
            "title": "Reference",
            "type": "string"
          },
          "short_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Short Description"
          },
          "size": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size"
          },
          "stock": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Stock"
          },
          "supplier_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Supplier Code"
          },
          "tax_rate": {
            "anyOf": [
              {
                "maximum": 100.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Rate"
          },
          "unit_of_measure": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Of Measure"
          },
          "upc": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Upc"
          },
          "warranty_duration": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Garantie (mois)",
            "title": "Warranty Duration"
          },
          "weight": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Weight"
          },
          "width": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Width"
          }
        },
        "required": [
          "reference",
          "name"
        ],
        "title": "WinDevProduct",
        "type": "object"
      },
      "WinDevProductEnvelope": {
        "description": "`GET`/`PATCH /windev/products/{ref}`, `POST …/activate`, `POST …/deactivate`.",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "champs_ignores_par_fiche": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChampsIgnoresFiche"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures en lot : une entrée par ligne qui portait des clés ignorées (aucune : liste vide)",
            "title": "Champs Ignores Par Fiche"
          },
          "code": {
            "default": 200,
            "description": "Code HTTP applicatif",
            "title": "Code",
            "type": "integer"
          },
          "count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre d'éléments dans `data`",
            "title": "Count"
          },
          "data": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WinDevProductRead"
              },
              {
                "type": "null"
              }
            ],
            "description": "Produit"
          },
          "limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taille de page (endpoints de liste)",
            "title": "Limit"
          },
          "message": {
            "default": "OK",
            "description": "Message lisible",
            "title": "Message",
            "type": "string"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Page courante (endpoints de liste)",
            "title": "Page"
          },
          "pages": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de pages (endpoints de liste)",
            "title": "Pages"
          },
          "success": {
            "default": true,
            "description": "True si code < 400",
            "title": "Success",
            "type": "boolean"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de résultats (endpoints de liste)",
            "title": "Total"
          }
        },
        "title": "WinDevProductEnvelope",
        "type": "object"
      },
      "WinDevProductListEnvelope": {
        "description": "`GET /windev/products`, `GET /windev/products/since/{timestamp}` (paginés).",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "champs_ignores_par_fiche": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChampsIgnoresFiche"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures en lot : une entrée par ligne qui portait des clés ignorées (aucune : liste vide)",
            "title": "Champs Ignores Par Fiche"
          },
          "code": {
            "default": 200,
            "description": "Code HTTP applicatif",
            "title": "Code",
            "type": "integer"
          },
          "count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre d'éléments dans `data`",
            "title": "Count"
          },
          "data": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/WinDevProductRead"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Produits de la page",
            "title": "Data"
          },
          "limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taille de page (endpoints de liste)",
            "title": "Limit"
          },
          "message": {
            "default": "OK",
            "description": "Message lisible",
            "title": "Message",
            "type": "string"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Page courante (endpoints de liste)",
            "title": "Page"
          },
          "pages": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de pages (endpoints de liste)",
            "title": "Pages"
          },
          "success": {
            "default": true,
            "description": "True si code < 400",
            "title": "Success",
            "type": "boolean"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de résultats (endpoints de liste)",
            "title": "Total"
          }
        },
        "title": "WinDevProductListEnvelope",
        "type": "object"
      },
      "WinDevProductRead": {
        "additionalProperties": true,
        "description": "Produit complet WinDev-friendly tel que renvoyé par\n`services.windev_service._product_to_dict` (72 clés, TOUJOURS présentes, valeur éventuellement nulle).\n\nOrdre des champs = ordre du sérialiseur (la réponse JSON garde l'ordre des clés à l'octet).\n`technical_specs` / `compatibility` : JSON libre (colonne JSON, forme non garantie).",
        "properties": {
          "asin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Asin"
          },
          "availability_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Availability Date"
          },
          "backorder_allowed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Backorder Allowed"
          },
          "brand": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Brand"
          },
          "carbon_footprint_kg": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Carbon Footprint Kg"
          },
          "ce_marked": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ce Marked"
          },
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Color"
          },
          "color_secondary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Color Secondary"
          },
          "compatibility": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Compatibility"
          },
          "completeness_score": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Completeness Score"
          },
          "country_of_origin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country Of Origin"
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At"
          },
          "dangerous_goods": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dangerous Goods"
          },
          "dangerous_goods_class": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dangerous Goods Class"
          },
          "depth": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Depth"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description"
          },
          "discontinued": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discontinued"
          },
          "ean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ean"
          },
          "eco_friendly": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Eco Friendly"
          },
          "end_of_life_date": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Of Life Date"
          },
          "energy_class": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Energy Class"
          },
          "export_restricted": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Export Restricted"
          },
          "external_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Id"
          },
          "finish": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finish"
          },
          "gtin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Gtin"
          },
          "height": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Height"
          },
          "hs_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Hs Code"
          },
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Id"
          },
          "installation_required": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Installation Required"
          },
          "is_active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Active"
          },
          "is_b2b_only": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is B2B Only"
          },
          "lead_time_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Délai de livraison du PRODUIT (jours)",
            "title": "Lead Time Days"
          },
          "lifecycle_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lifecycle Status"
          },
          "manufacturer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Manufacturer Reference"
          },
          "material": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Material"
          },
          "max_order_quantity": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Order Quantity"
          },
          "min_order_quantity": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Quantité minimale de VENTE du produit",
            "title": "Min Order Quantity"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          },
          "order_increment": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Increment"
          },
          "package_height": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Package Height"
          },
          "package_length": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Package Length"
          },
          "package_quantity": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Package Quantity"
          },
          "package_weight": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Package Weight"
          },
          "package_width": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Package Width"
          },
          "pattern": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pattern"
          },
          "preorder_available": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Preorder Available"
          },
          "price_ht": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Prix de vente HORS TAXES (avant le 26/10/2026 : le coût d'achat)",
            "title": "Price Ht"
          },
          "price_ttc": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Prix de vente TTC CALCULÉ : price_ht × (1 + tax_rate / 100), au centime ; null sans tax_rate",
            "title": "Price Ttc"
          },
          "promotional_text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Promotional Text"
          },
          "reach_compliant": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reach Compliant"
          },
          "recyclable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Recyclable"
          },
          "requires_quote": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Requires Quote"
          },
          "return_allowed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Return Allowed"
          },
          "return_policy_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Return Policy Days"
          },
          "rohs_compliant": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rohs Compliant"
          },
          "seasonal": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Seasonal"
          },
          "short_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Short Description"
          },
          "size": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size"
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status"
          },
          "stock": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Stock"
          },
          "style": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Style"
          },
          "tax_rate": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Rate"
          },
          "technical_specs": {
            "anyOf": [
              {},
              {
                "type": "null"
              }
            ],
            "title": "Technical Specs"
          },
          "unit_of_measure": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Of Measure"
          },
          "upc": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Upc"
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At"
          },
          "url_slug": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url Slug"
          },
          "warranty_duration": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warranty Duration"
          },
          "warranty_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warranty Type"
          },
          "weee_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Weee Category"
          },
          "weight": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Weight"
          },
          "width": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Width"
          }
        },
        "required": [
          "id",
          "ean",
          "asin",
          "upc",
          "gtin",
          "external_id",
          "manufacturer_reference",
          "url_slug",
          "name",
          "brand",
          "status",
          "is_active",
          "lifecycle_status",
          "discontinued",
          "description",
          "short_description",
          "promotional_text",
          "weight",
          "width",
          "height",
          "depth",
          "unit_of_measure",
          "package_length",
          "package_width",
          "package_height",
          "package_weight",
          "package_quantity",
          "min_order_quantity",
          "max_order_quantity",
          "order_increment",
          "lead_time_days",
          "backorder_allowed",
          "preorder_available",
          "availability_date",
          "requires_quote",
          "is_b2b_only",
          "tax_rate",
          "hs_code",
          "country_of_origin",
          "dangerous_goods",
          "dangerous_goods_class",
          "reach_compliant",
          "rohs_compliant",
          "ce_marked",
          "weee_category",
          "energy_class",
          "recyclable",
          "eco_friendly",
          "carbon_footprint_kg",
          "warranty_duration",
          "warranty_type",
          "return_policy_days",
          "return_allowed",
          "color",
          "color_secondary",
          "size",
          "material",
          "finish",
          "style",
          "pattern",
          "seasonal",
          "export_restricted",
          "installation_required",
          "technical_specs",
          "compatibility",
          "end_of_life_date",
          "completeness_score",
          "price_ttc",
          "price_ht",
          "stock",
          "created_at",
          "updated_at"
        ],
        "title": "WinDevProductRead",
        "type": "object"
      },
      "WinDevProductUpdate": {
        "description": "Tous les champs modifiables d'un produit via PATCH /products/{ref}.",
        "properties": {
          "asin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "ASIN Amazon",
            "title": "Asin"
          },
          "availability_date": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Date de disponibilité",
            "title": "Availability Date"
          },
          "backorder_allowed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Commande en rupture autorisée",
            "title": "Backorder Allowed"
          },
          "brand": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Marque (brand_name)",
            "title": "Brand"
          },
          "carbon_footprint_kg": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Empreinte carbone (kg CO2)",
            "title": "Carbon Footprint Kg"
          },
          "ce_marked": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Marquage CE",
            "title": "Ce Marked"
          },
          "color": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Couleur principale",
            "title": "Color"
          },
          "color_secondary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Couleur secondaire",
            "title": "Color Secondary"
          },
          "compatibility": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Compatibilité produits (JSON)",
            "title": "Compatibility"
          },
          "country_of_origin": {
            "anyOf": [
              {
                "maxLength": 2,
                "minLength": 2,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Pays d'origine (ISO 3166-1 alpha-2)",
            "title": "Country Of Origin"
          },
          "dangerous_goods": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Marchandises dangereuses",
            "title": "Dangerous Goods"
          },
          "dangerous_goods_class": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Classe matières dangereuses",
            "title": "Dangerous Goods Class"
          },
          "depth": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Profondeur (cm)",
            "title": "Depth"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Description longue",
            "title": "Description"
          },
          "discontinued": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Produit discontinué",
            "title": "Discontinued"
          },
          "ean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "EAN/GTIN",
            "title": "Ean"
          },
          "eco_friendly": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Éco-responsable",
            "title": "Eco Friendly"
          },
          "end_of_life_date": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Date de fin de vie",
            "title": "End Of Life Date"
          },
          "energy_class": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Classe énergétique (A+++, A++, A+, A, B, C, D, E, F, G)",
            "title": "Energy Class"
          },
          "export_restricted": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Export restreint",
            "title": "Export Restricted"
          },
          "external_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "ID système externe",
            "title": "External Id"
          },
          "finish": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Finition",
            "title": "Finish"
          },
          "gtin": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Global Trade Item Number (14 chiffres)",
            "title": "Gtin"
          },
          "height": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hauteur (cm)",
            "title": "Height"
          },
          "hs_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Code douanier harmonisé",
            "title": "Hs Code"
          },
          "installation_required": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Installation requise",
            "title": "Installation Required"
          },
          "is_active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Produit actif",
            "title": "Is Active"
          },
          "is_b2b_only": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Réservé B2B uniquement",
            "title": "Is B2B Only"
          },
          "lead_time_days": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Délai de livraison du PRODUIT en jours (products.lead_time_days) — distinct du délai d'un FOURNISSEUR, que porte l'import de fichier (supplier_products.lead_time_days)",
            "title": "Lead Time Days"
          },
          "lifecycle_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "active|end_of_life|discontinued|development",
            "title": "Lifecycle Status"
          },
          "material": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Matériau principal",
            "title": "Material"
          },
          "max_order_quantity": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Quantité maximale de commande",
            "title": "Max Order Quantity"
          },
          "min_order_quantity": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Quantité minimale de VENTE du produit (products.min_order_quantity) — distincte du minimum d'ACHAT chez un fournisseur, que porte l'import de fichier (supplier_products.moq)",
            "title": "Min Order Quantity"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nom du produit",
            "title": "Name"
          },
          "order_increment": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Incrément de commande",
            "title": "Order Increment"
          },
          "package_height": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Hauteur colis (cm)",
            "title": "Package Height"
          },
          "package_length": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Longueur colis (cm)",
            "title": "Package Length"
          },
          "package_quantity": {
            "anyOf": [
              {
                "minimum": 1.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Quantité par colis",
            "title": "Package Quantity"
          },
          "package_weight": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Poids colis (grammes)",
            "title": "Package Weight"
          },
          "package_width": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Largeur colis (cm)",
            "title": "Package Width"
          },
          "pattern": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Motif",
            "title": "Pattern"
          },
          "preorder_available": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Précommande disponible",
            "title": "Preorder Available"
          },
          "price_ht": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Prix de VENTE hors taxes (EUR) — enregistré comme prix de vente HT du produit (⚖ 26/10/2026 : avant, il était enregistré comme coût d'achat)",
            "title": "Price Ht"
          },
          "price_ttc": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Prix TTC (EUR) — JAMAIS enregistré : seul (sans price_ht), l'article est refusé (WINDEV_PRICE_TTC_ONLY) ; avec price_ht, il est cité dans champs_ignores",
            "title": "Price Ttc"
          },
          "promotional_text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Texte promotionnel",
            "title": "Promotional Text"
          },
          "reach_compliant": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Conformité REACH",
            "title": "Reach Compliant"
          },
          "recyclable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Recyclable",
            "title": "Recyclable"
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Référence fabricant (manufacturer_reference)",
            "title": "Reference"
          },
          "requires_quote": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nécessite un devis",
            "title": "Requires Quote"
          },
          "return_allowed": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Retours autorisés",
            "title": "Return Allowed"
          },
          "return_policy_days": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Délai de retour (jours)",
            "title": "Return Policy Days"
          },
          "rohs_compliant": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Conformité RoHS",
            "title": "Rohs Compliant"
          },
          "seasonal": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "description": "Produit saisonnier",
            "title": "Seasonal"
          },
          "short_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Description courte",
            "title": "Short Description"
          },
          "size": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taille / format",
            "title": "Size"
          },
          "stock": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Stock",
            "title": "Stock"
          },
          "style": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Style / design",
            "title": "Style"
          },
          "supplier_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Code fournisseur pour le stock",
            "title": "Supplier Code"
          },
          "tax_rate": {
            "anyOf": [
              {
                "maximum": 100.0,
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taux de TVA (%)",
            "title": "Tax Rate"
          },
          "technical_specs": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "description": "Spécifications techniques (JSON)",
            "title": "Technical Specs"
          },
          "unit_of_measure": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Unité (unit, pack, m, kg...)",
            "title": "Unit Of Measure"
          },
          "upc": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Universal Product Code",
            "title": "Upc"
          },
          "url_slug": {
            "anyOf": [
              {
                "maxLength": 255,
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Slug URL",
            "title": "Url Slug"
          },
          "warranty_duration": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Durée de garantie (mois)",
            "title": "Warranty Duration"
          },
          "warranty_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Type de garantie (manufacturer, extended...)",
            "title": "Warranty Type"
          },
          "weee_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Catégorie DEEE/WEEE",
            "title": "Weee Category"
          },
          "weight": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Poids (kg)",
            "title": "Weight"
          },
          "width": {
            "anyOf": [
              {
                "minimum": 0.0,
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "description": "Largeur (cm)",
            "title": "Width"
          }
        },
        "title": "WinDevProductUpdate",
        "type": "object"
      },
      "WinDevStatusData": {
        "additionalProperties": true,
        "description": "Charge de `GET /windev/status` (`routers.windev.windev_status`).",
        "properties": {
          "api": {
            "description": "Nom de l'API",
            "title": "Api",
            "type": "string"
          },
          "api_version": {
            "description": "Version MAJEURE du contrat public (même valeur que l'en-tête `API-Version`)",
            "title": "Api Version",
            "type": "string"
          },
          "endpoints": {
            "description": "Opérations de la famille, « MÉTHODE chemin »",
            "items": {
              "type": "string"
            },
            "title": "Endpoints",
            "type": "array"
          },
          "timestamp": {
            "description": "Horodatage serveur (ISO 8601)",
            "title": "Timestamp",
            "type": "string"
          },
          "version": {
            "description": "Valeur historique figée ('1.1'), conservée pour compatibilité ; lire `api_version`",
            "title": "Version",
            "type": "string"
          }
        },
        "required": [
          "api",
          "version",
          "api_version",
          "timestamp",
          "endpoints"
        ],
        "title": "WinDevStatusData",
        "type": "object"
      },
      "WinDevStatusEnvelope": {
        "description": "`GET /windev/status`.",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "champs_ignores_par_fiche": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChampsIgnoresFiche"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures en lot : une entrée par ligne qui portait des clés ignorées (aucune : liste vide)",
            "title": "Champs Ignores Par Fiche"
          },
          "code": {
            "default": 200,
            "description": "Code HTTP applicatif",
            "title": "Code",
            "type": "integer"
          },
          "count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre d'éléments dans `data`",
            "title": "Count"
          },
          "data": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WinDevStatusData"
              },
              {
                "type": "null"
              }
            ],
            "description": "Statut de l'API"
          },
          "limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taille de page (endpoints de liste)",
            "title": "Limit"
          },
          "message": {
            "default": "OK",
            "description": "Message lisible",
            "title": "Message",
            "type": "string"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Page courante (endpoints de liste)",
            "title": "Page"
          },
          "pages": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de pages (endpoints de liste)",
            "title": "Pages"
          },
          "success": {
            "default": true,
            "description": "True si code < 400",
            "title": "Success",
            "type": "boolean"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de résultats (endpoints de liste)",
            "title": "Total"
          }
        },
        "title": "WinDevStatusEnvelope",
        "type": "object"
      },
      "WinDevStockEnvelope": {
        "description": "`POST /windev/stock/update`.",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "champs_ignores_par_fiche": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChampsIgnoresFiche"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures en lot : une entrée par ligne qui portait des clés ignorées (aucune : liste vide)",
            "title": "Champs Ignores Par Fiche"
          },
          "code": {
            "default": 200,
            "description": "Code HTTP applicatif",
            "title": "Code",
            "type": "integer"
          },
          "count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre d'éléments dans `data`",
            "title": "Count"
          },
          "data": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/WinDevStockResult"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Un résultat par ligne reçue",
            "title": "Data"
          },
          "limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taille de page (endpoints de liste)",
            "title": "Limit"
          },
          "message": {
            "default": "OK",
            "description": "Message lisible",
            "title": "Message",
            "type": "string"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Page courante (endpoints de liste)",
            "title": "Page"
          },
          "pages": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de pages (endpoints de liste)",
            "title": "Pages"
          },
          "success": {
            "default": true,
            "description": "True si code < 400",
            "title": "Success",
            "type": "boolean"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de résultats (endpoints de liste)",
            "title": "Total"
          }
        },
        "title": "WinDevStockEnvelope",
        "type": "object"
      },
      "WinDevStockItem": {
        "description": "Item de mise à jour de stock.",
        "properties": {
          "ean": {
            "description": "EAN du produit",
            "title": "Ean",
            "type": "string"
          },
          "stock": {
            "description": "Nouvelle quantité en stock",
            "minimum": 0.0,
            "title": "Stock",
            "type": "integer"
          },
          "supplier_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Code fournisseur",
            "title": "Supplier Code"
          }
        },
        "required": [
          "ean",
          "stock"
        ],
        "title": "WinDevStockItem",
        "type": "object"
      },
      "WinDevStockResult": {
        "additionalProperties": true,
        "description": "Résultat par ligne de `POST /windev/stock/update` (`services.windev_service.update_stock_batch`).",
        "properties": {
          "ean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "EAN reçu (normalisé s'il est valide)",
            "title": "Ean"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Présent si status = not_found ou error",
            "title": "Error"
          },
          "error_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Refus NOMMÉ de la ligne (rien n'est écrit pour elle) : `WINDEV_PRODUCT_IN_TRASH` (le produit est dans la corbeille ; le restaurer d'abord), `WINDEV_REFERENCE_AMBIGUOUS` (plusieurs produits vivants portent cet EAN ou cette référence ; corriger le doublon d'abord) ou `WINDEV_PRICE_TTC_ONLY` (price_ttc sans price_ht)",
            "title": "Error Code"
          },
          "status": {
            "description": "updated | not_found | error",
            "title": "Status",
            "type": "string"
          },
          "updated": {
            "description": "Stock écrit",
            "title": "Updated",
            "type": "boolean"
          }
        },
        "required": [
          "ean",
          "status",
          "updated"
        ],
        "title": "WinDevStockResult",
        "type": "object"
      },
      "WinDevSupplier": {
        "additionalProperties": true,
        "description": "Fournisseur plat WinDev (`services.windev_service._supplier_to_dict`) — clés toujours présentes.",
        "properties": {
          "code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code"
          },
          "contact_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Email"
          },
          "contact_phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Phone"
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country"
          },
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Id"
          },
          "is_active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Active"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name"
          }
        },
        "required": [
          "id",
          "code",
          "name",
          "is_active",
          "contact_email",
          "contact_phone",
          "country"
        ],
        "title": "WinDevSupplier",
        "type": "object"
      },
      "WinDevSupplierListEnvelope": {
        "description": "`GET /windev/suppliers`.",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "champs_ignores_par_fiche": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChampsIgnoresFiche"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures en lot : une entrée par ligne qui portait des clés ignorées (aucune : liste vide)",
            "title": "Champs Ignores Par Fiche"
          },
          "code": {
            "default": 200,
            "description": "Code HTTP applicatif",
            "title": "Code",
            "type": "integer"
          },
          "count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre d'éléments dans `data`",
            "title": "Count"
          },
          "data": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/WinDevSupplier"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Fournisseurs actifs",
            "title": "Data"
          },
          "limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taille de page (endpoints de liste)",
            "title": "Limit"
          },
          "message": {
            "default": "OK",
            "description": "Message lisible",
            "title": "Message",
            "type": "string"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Page courante (endpoints de liste)",
            "title": "Page"
          },
          "pages": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de pages (endpoints de liste)",
            "title": "Pages"
          },
          "success": {
            "default": true,
            "description": "True si code < 400",
            "title": "Success",
            "type": "boolean"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de résultats (endpoints de liste)",
            "title": "Total"
          }
        },
        "title": "WinDevSupplierListEnvelope",
        "type": "object"
      },
      "WinDevSyncEnvelope": {
        "description": "`POST /windev/products/sync`.",
        "properties": {
          "champs_ignores": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures : clés reçues que l'opération ne connaît pas, IGNORÉES (rien n'en est écrit) — triées ; vide si aucune. Sur un lot : union des clés ignorées de toutes les fiches (détail dans `champs_ignores_par_fiche`). Lectures : null.",
            "title": "Champs Ignores"
          },
          "champs_ignores_par_fiche": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ChampsIgnoresFiche"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Écritures en lot : une entrée par ligne qui portait des clés ignorées (aucune : liste vide)",
            "title": "Champs Ignores Par Fiche"
          },
          "code": {
            "default": 200,
            "description": "Code HTTP applicatif",
            "title": "Code",
            "type": "integer"
          },
          "count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre d'éléments dans `data`",
            "title": "Count"
          },
          "data": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/WinDevSyncResult"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "description": "Un résultat par produit reçu",
            "title": "Data"
          },
          "limit": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Taille de page (endpoints de liste)",
            "title": "Limit"
          },
          "message": {
            "default": "OK",
            "description": "Message lisible",
            "title": "Message",
            "type": "string"
          },
          "page": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Page courante (endpoints de liste)",
            "title": "Page"
          },
          "pages": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de pages (endpoints de liste)",
            "title": "Pages"
          },
          "success": {
            "default": true,
            "description": "True si code < 400",
            "title": "Success",
            "type": "boolean"
          },
          "total": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Nombre total de résultats (endpoints de liste)",
            "title": "Total"
          }
        },
        "title": "WinDevSyncEnvelope",
        "type": "object"
      },
      "WinDevSyncResult": {
        "additionalProperties": true,
        "description": "Résultat par produit de `POST /windev/products/sync` (`services.windev_service.sync_products`).",
        "properties": {
          "brand_unresolved": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Présent si `brand` ne désigne aucune marque du référentiel : `inconnue`, `ambigue` (plusieurs marques portent ce nom) ou `inactive` (marque désactivée). Le nom est gardé, sans marque rattachée ; aucune marque n'est créée",
            "title": "Brand Unresolved"
          },
          "category_unresolved": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Présent si `category` ne désigne aucune catégorie existante : `inconnue` ou `ambigue` (plusieurs catégories portent ce nom). La catégorie du produit n'est pas touchée ; aucune catégorie n'est créée",
            "title": "Category Unresolved"
          },
          "ean": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "EAN du produit",
            "title": "Ean"
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Présent si status = error",
            "title": "Error"
          },
          "error_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Refus NOMMÉ de la ligne (rien n'est écrit pour elle) : `WINDEV_PRODUCT_IN_TRASH` (le produit est dans la corbeille ; le restaurer d'abord), `WINDEV_REFERENCE_AMBIGUOUS` (plusieurs produits vivants portent cet EAN ou cette référence ; corriger le doublon d'abord) ou `WINDEV_PRICE_TTC_ONLY` (price_ttc sans price_ht)",
            "title": "Error Code"
          },
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Identifiant du produit (null en erreur)",
            "title": "Id"
          },
          "ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Référence WinDev reçue",
            "title": "Ref"
          },
          "status": {
            "description": "created | updated | error",
            "title": "Status",
            "type": "string"
          },
          "warning": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "description": "Présent si le code fournisseur est inconnu",
            "title": "Warning"
          }
        },
        "required": [
          "ref",
          "status",
          "id",
          "ean"
        ],
        "title": "WinDevSyncResult",
        "type": "object"
      }
    },
    "securitySchemes": {
      "APIKeyHeader": {
        "description": "Clé d'API (Réglages › Intégrations › Clés API), avec les scopes de la famille.",
        "in": "header",
        "name": "X-API-Key",
        "type": "apiKey"
      }
    }
  },
  "info": {
    "description": "Contrat PUBLIC, version majeure 1 : familles `/api/v1/ext` et `/api/v1/windev`, appelées avec une clé d'API (en-tête `X-API-Key`). Chaque réponse porte `API-Version: 1`. Politique de compatibilité et de dépréciation (préavis d'au moins 180 jours) : https://apidoc.pixeepim.com/changelog.",
    "title": "PixeePIM — API publique",
    "version": "1"
  },
  "openapi": "3.1.0",
  "paths": {
    "/api/v1/ext/products": {
      "get": {
        "description": "Retourne une liste paginée de produits avec filtres optionnels.",
        "operationId": "list_products_endpoint_api_v1_ext_products_get",
        "parameters": [
          {
            "description": "Filtrer par code fournisseur",
            "in": "query",
            "name": "supplier_code",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filtrer par code fournisseur",
              "title": "Supplier Code"
            }
          },
          {
            "description": "ISO 8601 — produits modifiés depuis cette date",
            "in": "query",
            "name": "updated_since",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "ISO 8601 — produits modifiés depuis cette date",
              "title": "Updated Since"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "title": "Page",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "page_size",
            "required": false,
            "schema": {
              "default": 50,
              "maximum": 500,
              "minimum": 1,
              "title": "Page Size",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtProductListResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Lister les produits",
        "tags": [
          "External API",
          "External API"
        ]
      },
      "post": {
        "description": "Crée un produit ou met à jour un produit existant par EAN.\nSi l'EAN n'existe pas : crée (`name` obligatoire).\nSi l'EAN existe déjà : met à jour les champs non-null fournis.",
        "operationId": "create_or_upsert_product_api_v1_ext_products_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductWriteSchema"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtUpsertResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Créer ou mettre à jour un produit par EAN",
        "tags": [
          "External API",
          "External API"
        ]
      }
    },
    "/api/v1/ext/products/batch": {
      "post": {
        "description": "Upsert en batch de N produits (max 500). Les erreurs individuelles sont collectées sans interrompre le batch.\n\nUn `url_slug` de plus de 255 caractères, ou une création au-delà du plafond de produits de la formule, refusent la\nFICHE seule (`error_details`, motif nommé) ; les autres fiches du lot sont écrites. Une erreur imprévue sur une\nfiche la refuse seule, avec un motif et une référence à transmettre au support.\n\nLimite : un `url_slug` qui ressemble à une adresse complète (« : » avant le premier « / », comme `javascript:`,\ny compris sous une forme encodée : `&#58;`, `&colon;`, deux-points pleine chasse) dans UNE fiche refuse la requête ENTIÈRE dès l'entrée (422 `VALIDATION_URL_SLUG_SCHEME`) : aucune fiche du lot\nn'est enregistrée. Envoyez seulement la fin de l'adresse (`mon-produit-42`), puis renvoyez le lot.",
        "operationId": "batch_upsert_products_endpoint_api_v1_ext_products_batch_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchUpsertRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtBatchResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Upsert en batch (max 500 produits)",
        "tags": [
          "External API",
          "External API"
        ]
      }
    },
    "/api/v1/ext/products/delta": {
      "get": {
        "description": "Retourne tous les produits mis à jour depuis la date `since`. Utile pour sync incrémentale.",
        "operationId": "get_products_delta_api_v1_ext_products_delta_get",
        "parameters": [
          {
            "description": "Date ISO 8601 (ex: 2026-01-01T00:00:00Z)",
            "in": "query",
            "name": "since",
            "required": true,
            "schema": {
              "description": "Date ISO 8601 (ex: 2026-01-01T00:00:00Z)",
              "title": "Since",
              "type": "string"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "title": "Page",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "page_size",
            "required": false,
            "schema": {
              "default": 100,
              "maximum": 500,
              "minimum": 1,
              "title": "Page Size",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtProductListResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Produits modifiés depuis une date",
        "tags": [
          "External API",
          "External API"
        ]
      }
    },
    "/api/v1/ext/products/{ean}": {
      "get": {
        "description": "Retourne les détails d'un produit identifié par son EAN.",
        "operationId": "get_product_by_ean_endpoint_api_v1_ext_products__ean__get",
        "parameters": [
          {
            "in": "path",
            "name": "ean",
            "required": true,
            "schema": {
              "title": "Ean",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtProductResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Récupérer un produit par EAN",
        "tags": [
          "External API",
          "External API"
        ]
      },
      "patch": {
        "description": "Mise à jour partielle (PATCH) : seuls les champs non-null fournis sont mis à jour.",
        "operationId": "patch_product_by_ean_api_v1_ext_products__ean__patch",
        "parameters": [
          {
            "in": "path",
            "name": "ean",
            "required": true,
            "schema": {
              "title": "Ean",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductPatchSchema"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtProductResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Mise à jour partielle d'un produit par EAN",
        "tags": [
          "External API",
          "External API"
        ]
      },
      "put": {
        "description": "Mise à jour complète (PUT) d'un produit existant identifié par son EAN. Retourne 404 si inexistant.",
        "operationId": "put_product_by_ean_api_v1_ext_products__ean__put",
        "parameters": [
          {
            "in": "path",
            "name": "ean",
            "required": true,
            "schema": {
              "title": "Ean",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductWriteSchema"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtProductResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Mise à jour complète d'un produit par EAN",
        "tags": [
          "External API",
          "External API"
        ]
      }
    },
    "/api/v1/ext/status": {
      "get": {
        "description": "Health-check pour les applications externes.",
        "operationId": "get_status_api_v1_ext_status_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtStatusResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Statut de l'API externe",
        "tags": [
          "External API",
          "External API"
        ]
      }
    },
    "/api/v1/windev/categories": {
      "get": {
        "description": "DÉPRÉCIÉE (lot n56-categories-retrait-table, ⚖ CAT-ANCIEN-ARBRE = A) : servait l'ancien arbre `categories`,\nretiré par catalog/228 — rend une liste VIDE, forme inchangée, jusqu'à son retrait au terme du préavis\n(`core/api_publique.py::DEPRECIATIONS`, en-têtes `Deprecation` / `Sunset`). La catégorie envoyée par\n`POST /sync/products` est rangée dans le Category Manager (arbre de rangement).",
        "operationId": "get_categories_api_v1_windev_categories_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevCategoryListEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Get Categories",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    },
    "/api/v1/windev/prices/update": {
      "post": {
        "description": "Met à jour les prix en batch.\nprice_ht → prix de vente HT ; price_ttc jamais enregistré (seul : ligne refusée, WINDEV_PRICE_TTC_ONLY).",
        "operationId": "update_prices_api_v1_windev_prices_update_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "items": {
                  "$ref": "#/components/schemas/WinDevPriceItem"
                },
                "title": "Items",
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevPriceEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Update Prices",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    },
    "/api/v1/windev/products": {
      "get": {
        "description": "Liste paginée de tous les produits PM.\nUtile pour la synchronisation initiale WinDev (quand aucun timestamp de référence n'existe).",
        "operationId": "list_products_api_v1_windev_products_get",
        "parameters": [
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "title": "Page",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 100,
              "maximum": 500,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          },
          {
            "description": "Recherche dans nom / référence",
            "in": "query",
            "name": "search",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Recherche dans nom / référence",
              "title": "Search"
            }
          },
          {
            "description": "Filtre exact par EAN",
            "in": "query",
            "name": "ean",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Filtre exact par EAN",
              "title": "Ean"
            }
          },
          {
            "description": "Produits actifs uniquement",
            "in": "query",
            "name": "active_only",
            "required": false,
            "schema": {
              "default": true,
              "description": "Produits actifs uniquement",
              "title": "Active Only",
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevProductListEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "List Products",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    },
    "/api/v1/windev/products/since/{timestamp}": {
      "get": {
        "description": "Retourne les produits créés ou modifiés depuis le timestamp Unix donné.\nExemple : GET /api/v1/windev/products/since/1709730000",
        "operationId": "get_products_since_api_v1_windev_products_since__timestamp__get",
        "parameters": [
          {
            "in": "path",
            "name": "timestamp",
            "required": true,
            "schema": {
              "title": "Timestamp",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "page",
            "required": false,
            "schema": {
              "default": 1,
              "minimum": 1,
              "title": "Page",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 100,
              "maximum": 500,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevProductListEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Get Products Since",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    },
    "/api/v1/windev/products/sync": {
      "post": {
        "description": "Synchronise un batch de produits WinDev vers Pixee PIM.\nCherche par EAN (prioritaire) puis par référence interne.",
        "operationId": "sync_products_api_v1_windev_products_sync_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "items": {
                  "$ref": "#/components/schemas/WinDevProduct"
                },
                "title": "Items",
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevSyncEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Sync Products",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    },
    "/api/v1/windev/products/{ref}": {
      "get": {
        "description": "Récupère un produit par référence interne WinDev (manufacturer_reference) ou par EAN/GTIN.",
        "operationId": "get_product_by_ref_api_v1_windev_products__ref__get",
        "parameters": [
          {
            "in": "path",
            "name": "ref",
            "required": true,
            "schema": {
              "title": "Ref",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevProductEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Get Product By Ref",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      },
      "patch": {
        "description": "Met à jour les champs d'un produit identifié par EAN ou référence fabricant.\n\nSeuls les champs fournis sont modifiés (PATCH sémantique).\nGère aussi les prix et stocks inline si fournis.",
        "operationId": "patch_product_api_v1_windev_products__ref__patch",
        "parameters": [
          {
            "in": "path",
            "name": "ref",
            "required": true,
            "schema": {
              "title": "Ref",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WinDevProductUpdate"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevProductEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Patch Product",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    },
    "/api/v1/windev/products/{ref}/activate": {
      "post": {
        "description": "Réactive un produit (is_active=True, status='active').\nIdentifié par EAN ou référence fabricant.",
        "operationId": "activate_product_api_v1_windev_products__ref__activate_post",
        "parameters": [
          {
            "in": "path",
            "name": "ref",
            "required": true,
            "schema": {
              "title": "Ref",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevProductEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Activate Product",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    },
    "/api/v1/windev/products/{ref}/deactivate": {
      "post": {
        "description": "Désactive un produit (is_active=False, status='inactive').\nIdentifié par EAN ou référence fabricant.",
        "operationId": "deactivate_product_api_v1_windev_products__ref__deactivate_post",
        "parameters": [
          {
            "in": "path",
            "name": "ref",
            "required": true,
            "schema": {
              "title": "Ref",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevProductEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Deactivate Product",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    },
    "/api/v1/windev/status": {
      "get": {
        "description": "Health check public pour WinDev. Retourne le statut de l'API sans authentification.",
        "operationId": "windev_status_api_v1_windev_status_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevStatusEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "summary": "Windev Status",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    },
    "/api/v1/windev/stock/update": {
      "post": {
        "description": "Met à jour les stocks en batch.\nSi supplier_code est fourni : MAJ dans supplier_products.\nSinon : MAJ dans product_stocks (stock générique).",
        "operationId": "update_stock_api_v1_windev_stock_update_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "items": {
                  "$ref": "#/components/schemas/WinDevStockItem"
                },
                "title": "Items",
                "type": "array"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevStockEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Update Stock",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    },
    "/api/v1/windev/suppliers": {
      "get": {
        "description": "Retourne la liste des fournisseurs actifs triée par nom.",
        "operationId": "get_suppliers_api_v1_windev_suppliers_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinDevSupplierListEnvelope"
                }
              }
            },
            "description": "Successful Response"
          },
          "401": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Unauthorized"
          },
          "403": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Forbidden"
          },
          "404": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Not Found"
          },
          "409": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Conflict"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              }
            },
            "description": "Unprocessable Entity"
          },
          "429": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitErrorResponse"
                }
              }
            },
            "description": "Too Many Requests"
          },
          "500": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            },
            "description": "Internal Server Error"
          }
        },
        "security": [
          {
            "APIKeyHeader": []
          }
        ],
        "summary": "Get Suppliers",
        "tags": [
          "WinDev Integration",
          "WinDev Integration"
        ]
      }
    }
  }
}
