{
  "openapi": "3.1.0",
  "info": {
    "title": "API SATELICA",
    "version": "0.1.0",
    "summary": "API métier de la plateforme de distribution B2B SATELICA (CYBASTION, Starlink official reseller).",
    "description": "API métier de **SATELICA**, la plateforme de distribution B2B de CYBASTION pour la connectivité Internet par satellite Starlink.\n\n## S'authentifier\n\nChaque appel porte un **jeton d'accès** (JWT) dans l'en-tête `Authorization: Bearer <jeton>`. Le jeton s'obtient auprès du service d'authentification, par adresse e-mail et mot de passe :\n\n```\nPOST https://<supabase>/auth/v1/token?grant_type=password\napikey: <clé publique>\nContent-Type: application/json\n\n{ \"email\": \"…\", \"password\": \"…\" }\n```\n\nLa réponse contient `access_token` (valable une heure) et `refresh_token` pour le renouveler (`grant_type=refresh_token`). Les adresses et la clé publique de chaque environnement sont communiquées avec les comptes de test.\n\n## Conventions\n\n- **Listes paginées** : `?page=1&taille=20` (au plus 100). Réponse `{ donnees: [...], pagination: { page, taille, total, pages } }`.\n- **Erreurs** : toujours `{ code, message, details? }`, avec un code stable (`requete_invalide`, `authentification_requise`, `jeton_invalide`, `compte_inactif`, `permission_refusee`, `introuvable`, `conflit`, `debit_depasse`, `erreur_interne`, `service_indisponible`) et un message en français.\n- **Dates** : ISO 8601 ; un jour seul s'écrit `AAAA-MM-JJ`.\n- **Montants** : en francs CFA (XOF), nombres décimaux.\n- **Cloisonnement** : chaque opération indique ce que l'appelant peut voir. Un partenaire ne voit que son portefeuille ; une même adresse renvoie donc des résultats différents selon le compte.\n- **Débit** : au plus 300 requêtes par minute et par compte ; au-delà, 429.\n- **Idempotence** : les créations qui l'acceptent prennent une `cle_idempotence` ; rejouer la même clé ne crée rien de plus.\n\n## Webhooks\n\nSATELICA prévient vos systèmes de lui-même, à chaque événement métier : client enregistré, devis signé, paiement validé, facture émise, ordre d'installation, mise en service, commission, versement, transfert. Déclarez une adresse HTTPS avec `POST /api/v1/webhooks` (compte CYBASTION) ; chaque message est un `POST` JSON signé (HMAC SHA-256, en-tête `Satelica-Signature`), livré au moins une fois, avec relances pendant 45 heures. Le catalogue complet et le format de chaque message sont dans la section **Webhooks** de cette référence.",
    "contact": {
      "name": "CYBASTION",
      "url": "https://satelica.com"
    },
    "license": {
      "name": "Propriétaire — CYBASTION. Usage réservé aux intégrations autorisées.",
      "url": "https://satelica.com"
    }
  },
  "servers": [
    {
      "url": "https://preprod-api.satelica.com",
      "description": "Préproduction — données fictives, pour les essais"
    },
    {
      "url": "https://api.satelica.com",
      "description": "Production — données réelles ; les comptes d’essai n’y existent pas"
    }
  ],
  "tags": [
    {
      "name": "Authentification",
      "description": "Connexion, renouvellement et fermeture de session, auprès du service d’authentification de chaque environnement (adresse distincte de l’API). Voir aussi le guide du bac à sable."
    },
    {
      "name": "Santé",
      "description": "État du service, sans authentification."
    },
    {
      "name": "Mon compte",
      "description": "Profil et droits de l'appelant."
    },
    {
      "name": "Partenaires",
      "description": "Référencement, dossier, pièces et comptes des partenaires distributeurs."
    },
    {
      "name": "Clients",
      "description": "Fiches clients, sites, contacts, pièces et accès."
    },
    {
      "name": "Ventes",
      "description": "Opportunités, devis, signature et conversion en commande."
    },
    {
      "name": "Commandes et contrats",
      "description": "Commandes, échéanciers et contrats."
    },
    {
      "name": "Paiements et factures",
      "description": "Factures, paiements en ligne et hors ligne, avoirs, crédit."
    },
    {
      "name": "Commissions",
      "description": "Commissions des partenaires et demandes de versement."
    },
    {
      "name": "Opérations",
      "description": "Ordres d'installation, procès-verbaux, activations et techniciens."
    },
    {
      "name": "Catalogue",
      "description": "Produits, offres, tarifs et règles de commission."
    },
    {
      "name": "Espace partenaire",
      "description": "Vues propres à l'espace d'un partenaire."
    },
    {
      "name": "Actions et suivi",
      "description": "File de travail, actions, historique."
    },
    {
      "name": "Support",
      "description": "Tickets de support et échanges."
    },
    {
      "name": "Transferts de partenaire",
      "description": "Cession du portefeuille d’un client d’un partenaire à un autre."
    },
    {
      "name": "Notifications",
      "description": "Notifications des comptes et relances des factures impayées."
    },
    {
      "name": "Fichiers",
      "description": "Dépôt et lecture des fichiers (pièces, justificatifs, PV)."
    },
    {
      "name": "Administration",
      "description": "Paramètres, utilisateurs, rôles et référentiels."
    },
    {
      "name": "Référentiels",
      "description": "Listes de valeurs : zones, secteurs, types de pièces…"
    },
    {
      "name": "Pilotage",
      "description": "Tableaux de bord et indicateurs."
    },
    {
      "name": "Webhooks : adresses de réception",
      "description": "Déclarer les adresses qui reçoivent les événements (Odoo…), renouveler leur secret, les essayer, suivre et rejouer les livraisons. Le format de chaque message est dans la section Webhooks."
    },
    {
      "name": "Site public",
      "description": "Formulaires du site satelica.com."
    }
  ],
  "paths": {
    "/auth/v1/token": {
      "post": {
        "servers": [
          {
            "url": "https://preprod-api.satelica.com",
            "description": "Préproduction — la même adresse que l’API"
          },
          {
            "url": "https://supabase.satelica.com",
            "description": "Production — authentification"
          }
        ],
        "operationId": "authObtenirJeton",
        "tags": [
          "Authentification"
        ],
        "summary": "Se connecter, ou renouveler la session",
        "description": "Deux usages, choisis par `grant_type` :\n\n- `password` : connexion par e-mail et mot de passe. Rend une session : le jeton d’accès (valable **1 heure**) et un jeton de renouvellement.\n- `refresh_token` : renouvellement, **sans redemander le mot de passe**, avant ou après l’expiration du jeton d’accès. Le jeton de renouvellement est à usage unique : conserver celui que rend chaque réponse.\n\nLe jeton d’accès se place ensuite dans `Authorization: Bearer <jeton>` de chaque appel à l’API (`/api/v1/…`). Le rôle et les permissions du compte se lisent sur `GET /api/v1/moi`.\n\n**En-tête requis** : `apikey`, la clé publique de l’environnement (fournie avec les comptes d’essai ; préremplie dans le portail de préproduction).",
        "parameters": [
          {
            "name": "grant_type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "password",
                "refresh_token"
              ]
            },
            "description": "`password` pour se connecter, `refresh_token` pour renouveler."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "title": "Connexion (grant_type=password)",
                    "type": "object",
                    "required": [
                      "email",
                      "password"
                    ],
                    "properties": {
                      "email": {
                        "type": "string",
                        "format": "email"
                      },
                      "password": {
                        "type": "string",
                        "format": "password"
                      }
                    }
                  },
                  {
                    "title": "Renouvellement (grant_type=refresh_token)",
                    "type": "object",
                    "required": [
                      "refresh_token"
                    ],
                    "properties": {
                      "refresh_token": {
                        "type": "string"
                      }
                    }
                  }
                ]
              },
              "examples": {
                "connexion": {
                  "summary": "Connexion (grant_type=password)",
                  "value": {
                    "email": "odoo.partenaire@preprod.satelica.test",
                    "password": "‹mot de passe transmis à part›"
                  }
                },
                "renouvellement": {
                  "summary": "Renouvellement (grant_type=refresh_token)",
                  "value": {
                    "refresh_token": "‹refresh_token de la réponse précédente›"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session ouverte.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "access_token",
                    "token_type",
                    "expires_in",
                    "refresh_token",
                    "user"
                  ],
                  "properties": {
                    "access_token": {
                      "type": "string",
                      "description": "Jeton d’accès (JWT signé ES256), à placer dans `Authorization: Bearer …` de chaque appel à l’API."
                    },
                    "token_type": {
                      "type": "string",
                      "enum": [
                        "bearer"
                      ]
                    },
                    "expires_in": {
                      "type": "integer",
                      "description": "Durée de validité du jeton d’accès, en secondes (3 600)."
                    },
                    "expires_at": {
                      "type": "integer",
                      "description": "Instant d’expiration, en secondes depuis le 1er janvier 1970 (UTC)."
                    },
                    "refresh_token": {
                      "type": "string",
                      "description": "Jeton de renouvellement, à usage unique : chaque renouvellement en rend un nouveau."
                    },
                    "user": {
                      "type": "object",
                      "required": [
                        "id",
                        "email",
                        "role"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Identifiant du compte : le même que `utilisateur.id` de `GET /api/v1/moi`."
                        },
                        "aud": {
                          "type": "string"
                        },
                        "role": {
                          "type": "string",
                          "description": "Toujours `authenticated` : le rôle métier se lit sur `GET /api/v1/moi`."
                        },
                        "email": {
                          "type": "string",
                          "format": "email"
                        },
                        "phone": {
                          "type": "string",
                          "description": "Vide : les comptes SATELICA se connectent par e-mail."
                        },
                        "email_confirmed_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "confirmed_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "last_sign_in_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "app_metadata": {
                          "type": "object"
                        },
                        "user_metadata": {
                          "type": "object"
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "is_anonymous": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6Ij…‹jeton d’accès, 1 h›",
                  "token_type": "bearer",
                  "expires_in": 3600,
                  "expires_at": 1791903539,
                  "refresh_token": "‹jeton de renouvellement›",
                  "user": {
                    "id": "6638b260-1677-410c-ac1f-abefadfd0390",
                    "aud": "authenticated",
                    "role": "authenticated",
                    "email": "odoo.client@preprod.satelica.test",
                    "email_confirmed_at": "2026-10-12T19:06:53.459276Z",
                    "phone": "",
                    "confirmed_at": "2026-10-12T19:06:53.459276Z",
                    "last_sign_in_at": "2026-10-13T13:58:59.412147Z",
                    "app_metadata": {
                      "provider": "email",
                      "providers": [
                        "email"
                      ]
                    },
                    "user_metadata": {
                      "email_verified": true
                    },
                    "created_at": "2026-10-12T19:06:53.449458Z",
                    "updated_at": "2026-10-13T13:58:59.415949Z",
                    "is_anonymous": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Identifiants incorrects, ou jeton de renouvellement inconnu, déjà employé ou révoqué.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "description": "Statut HTTP."
                    },
                    "error_code": {
                      "type": "string",
                      "description": "Code stable du service d’authentification."
                    },
                    "msg": {
                      "type": "string",
                      "description": "Message, en anglais."
                    },
                    "weak_password": {
                      "type": "object",
                      "description": "Pour un mot de passe refusé : les raisons (`reasons`)."
                    }
                  }
                },
                "examples": {
                  "identifiants": {
                    "summary": "E-mail ou mot de passe incorrect",
                    "value": {
                      "code": 400,
                      "error_code": "invalid_credentials",
                      "msg": "Invalid login credentials"
                    }
                  },
                  "renouvellement": {
                    "summary": "Jeton de renouvellement refusé",
                    "value": {
                      "code": 400,
                      "error_code": "validation_failed",
                      "msg": "Refresh token is not valid"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "En-tête `apikey` absent ou faux : le service répond `Unauthorized`, sans corps JSON."
          },
          "429": {
            "description": "Trop de tentatives en peu de temps : le service limite les connexions. Patienter avant de réessayer.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "description": "Statut HTTP."
                    },
                    "error_code": {
                      "type": "string",
                      "description": "Code stable du service d’authentification."
                    },
                    "msg": {
                      "type": "string",
                      "description": "Message, en anglais."
                    },
                    "weak_password": {
                      "type": "object",
                      "description": "Pour un mot de passe refusé : les raisons (`reasons`)."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "cleApi": []
          }
        ]
      }
    },
    "/auth/v1/user": {
      "get": {
        "servers": [
          {
            "url": "https://preprod-api.satelica.com",
            "description": "Préproduction — la même adresse que l’API"
          },
          {
            "url": "https://supabase.satelica.com",
            "description": "Production — authentification"
          }
        ],
        "operationId": "authLireCompte",
        "tags": [
          "Authentification"
        ],
        "summary": "Lire le compte de la session",
        "description": "Le compte d’authentification derrière le jeton : identifiant, e-mail, dates de connexion. Pour le rôle, l’organisation et les permissions métier, appeler `GET /api/v1/moi`.\n\n**En-têtes requis** : `apikey` et `Authorization: Bearer <jeton>`.",
        "responses": {
          "200": {
            "description": "Le compte.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "email",
                    "role"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Identifiant du compte : le même que `utilisateur.id` de `GET /api/v1/moi`."
                    },
                    "aud": {
                      "type": "string"
                    },
                    "role": {
                      "type": "string",
                      "description": "Toujours `authenticated` : le rôle métier se lit sur `GET /api/v1/moi`."
                    },
                    "email": {
                      "type": "string",
                      "format": "email"
                    },
                    "phone": {
                      "type": "string",
                      "description": "Vide : les comptes SATELICA se connectent par e-mail."
                    },
                    "email_confirmed_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "confirmed_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "last_sign_in_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "app_metadata": {
                      "type": "object"
                    },
                    "user_metadata": {
                      "type": "object"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "is_anonymous": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "aud": "authenticated",
                  "role": "authenticated",
                  "email": "odoo.client@preprod.satelica.test",
                  "email_confirmed_at": "2026-10-12T19:06:53.459276Z",
                  "phone": "",
                  "confirmed_at": "2026-10-12T19:06:53.459276Z",
                  "last_sign_in_at": "2026-10-13T13:58:59.412147Z",
                  "app_metadata": {
                    "provider": "email",
                    "providers": [
                      "email"
                    ]
                  },
                  "user_metadata": {
                    "email_verified": true
                  },
                  "created_at": "2026-10-12T19:06:53.449458Z",
                  "updated_at": "2026-10-13T13:58:59.415949Z",
                  "is_anonymous": false
                }
              }
            }
          },
          "401": {
            "description": "En-tête `apikey` absent ou faux : le service répond `Unauthorized`, sans corps JSON."
          },
          "403": {
            "description": "Jeton expiré ou invalide.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "description": "Statut HTTP."
                    },
                    "error_code": {
                      "type": "string",
                      "description": "Code stable du service d’authentification."
                    },
                    "msg": {
                      "type": "string",
                      "description": "Message, en anglais."
                    },
                    "weak_password": {
                      "type": "object",
                      "description": "Pour un mot de passe refusé : les raisons (`reasons`)."
                    }
                  }
                },
                "example": {
                  "code": 403,
                  "error_code": "bad_jwt",
                  "msg": "invalid JWT: unable to parse or verify signature, token is malformed: …"
                }
              }
            }
          }
        },
        "security": [
          {
            "cleApi": [],
            "jetonAcces": []
          }
        ]
      },
      "put": {
        "servers": [
          {
            "url": "https://preprod-api.satelica.com",
            "description": "Préproduction — la même adresse que l’API"
          },
          {
            "url": "https://supabase.satelica.com",
            "description": "Production — authentification"
          }
        ],
        "operationId": "authChoisirMotDePasse",
        "tags": [
          "Authentification"
        ],
        "summary": "Choisir un nouveau mot de passe",
        "description": "Dernière étape d’un lien d’accès (bienvenue ou mot de passe oublié) : après `POST /auth/v1/verify`, la session obtenue fixe le mot de passe du compte. Le service exige six caractères au moins ; l’écran du back-office en demande huit.\n\n**En-têtes requis** : `apikey` et `Authorization: Bearer <jeton>`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "password"
                ],
                "properties": {
                  "password": {
                    "type": "string",
                    "format": "password",
                    "minLength": 6
                  }
                }
              },
              "example": {
                "password": "‹nouveau mot de passe›"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mot de passe enregistré ; le compte est rendu.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "email",
                    "role"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Identifiant du compte : le même que `utilisateur.id` de `GET /api/v1/moi`."
                    },
                    "aud": {
                      "type": "string"
                    },
                    "role": {
                      "type": "string",
                      "description": "Toujours `authenticated` : le rôle métier se lit sur `GET /api/v1/moi`."
                    },
                    "email": {
                      "type": "string",
                      "format": "email"
                    },
                    "phone": {
                      "type": "string",
                      "description": "Vide : les comptes SATELICA se connectent par e-mail."
                    },
                    "email_confirmed_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "confirmed_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "last_sign_in_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "app_metadata": {
                      "type": "object"
                    },
                    "user_metadata": {
                      "type": "object"
                    },
                    "created_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updated_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "is_anonymous": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "aud": "authenticated",
                  "role": "authenticated",
                  "email": "odoo.client@preprod.satelica.test",
                  "email_confirmed_at": "2026-10-12T19:06:53.459276Z",
                  "phone": "",
                  "confirmed_at": "2026-10-12T19:06:53.459276Z",
                  "last_sign_in_at": "2026-10-13T13:58:59.412147Z",
                  "app_metadata": {
                    "provider": "email",
                    "providers": [
                      "email"
                    ]
                  },
                  "user_metadata": {
                    "email_verified": true
                  },
                  "created_at": "2026-10-12T19:06:53.449458Z",
                  "updated_at": "2026-10-13T13:58:59.415949Z",
                  "is_anonymous": false
                }
              }
            }
          },
          "401": {
            "description": "En-tête `apikey` absent ou faux : le service répond `Unauthorized`, sans corps JSON."
          },
          "422": {
            "description": "Mot de passe trop faible.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "description": "Statut HTTP."
                    },
                    "error_code": {
                      "type": "string",
                      "description": "Code stable du service d’authentification."
                    },
                    "msg": {
                      "type": "string",
                      "description": "Message, en anglais."
                    },
                    "weak_password": {
                      "type": "object",
                      "description": "Pour un mot de passe refusé : les raisons (`reasons`)."
                    }
                  }
                },
                "example": {
                  "code": 422,
                  "error_code": "weak_password",
                  "msg": "Password should be at least 6 characters.",
                  "weak_password": {
                    "reasons": [
                      "length"
                    ]
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "cleApi": [],
            "jetonAcces": []
          }
        ]
      }
    },
    "/auth/v1/verify": {
      "post": {
        "servers": [
          {
            "url": "https://preprod-api.satelica.com",
            "description": "Préproduction — la même adresse que l’API"
          },
          {
            "url": "https://supabase.satelica.com",
            "description": "Production — authentification"
          }
        ],
        "operationId": "authOuvrirLienAcces",
        "tags": [
          "Authentification"
        ],
        "summary": "Ouvrir un lien d’accès reçu par e-mail",
        "description": "Le courriel de bienvenue ou de mot de passe oublié (`POST /api/v1/public/mot-de-passe/lien`) contient un lien porteur de `token_hash` et de `type`. L’échanger ici ouvre une session, avec laquelle `PUT /auth/v1/user` fixe le mot de passe. Un lien est valable **20 minutes**, ne sert qu’une fois, et seul le dernier demandé fonctionne.\n\n**En-tête requis** : `apikey`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "token_hash"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "recovery",
                      "invite",
                      "magiclink"
                    ],
                    "description": "Repris tel quel du lien reçu."
                  },
                  "token_hash": {
                    "type": "string",
                    "description": "Repris tel quel du lien reçu."
                  }
                }
              },
              "example": {
                "type": "recovery",
                "token_hash": "‹token_hash du lien›"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Session ouverte.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "access_token",
                    "token_type",
                    "expires_in",
                    "refresh_token",
                    "user"
                  ],
                  "properties": {
                    "access_token": {
                      "type": "string",
                      "description": "Jeton d’accès (JWT signé ES256), à placer dans `Authorization: Bearer …` de chaque appel à l’API."
                    },
                    "token_type": {
                      "type": "string",
                      "enum": [
                        "bearer"
                      ]
                    },
                    "expires_in": {
                      "type": "integer",
                      "description": "Durée de validité du jeton d’accès, en secondes (3 600)."
                    },
                    "expires_at": {
                      "type": "integer",
                      "description": "Instant d’expiration, en secondes depuis le 1er janvier 1970 (UTC)."
                    },
                    "refresh_token": {
                      "type": "string",
                      "description": "Jeton de renouvellement, à usage unique : chaque renouvellement en rend un nouveau."
                    },
                    "user": {
                      "type": "object",
                      "required": [
                        "id",
                        "email",
                        "role"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid",
                          "description": "Identifiant du compte : le même que `utilisateur.id` de `GET /api/v1/moi`."
                        },
                        "aud": {
                          "type": "string"
                        },
                        "role": {
                          "type": "string",
                          "description": "Toujours `authenticated` : le rôle métier se lit sur `GET /api/v1/moi`."
                        },
                        "email": {
                          "type": "string",
                          "format": "email"
                        },
                        "phone": {
                          "type": "string",
                          "description": "Vide : les comptes SATELICA se connectent par e-mail."
                        },
                        "email_confirmed_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "confirmed_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "last_sign_in_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "app_metadata": {
                          "type": "object"
                        },
                        "user_metadata": {
                          "type": "object"
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "is_anonymous": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "access_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6Ij…‹jeton d’accès, 1 h›",
                  "token_type": "bearer",
                  "expires_in": 3600,
                  "expires_at": 1791903539,
                  "refresh_token": "‹jeton de renouvellement›",
                  "user": {
                    "id": "6638b260-1677-410c-ac1f-abefadfd0390",
                    "aud": "authenticated",
                    "role": "authenticated",
                    "email": "odoo.client@preprod.satelica.test",
                    "email_confirmed_at": "2026-10-12T19:06:53.459276Z",
                    "phone": "",
                    "confirmed_at": "2026-10-12T19:06:53.459276Z",
                    "last_sign_in_at": "2026-10-13T13:58:59.412147Z",
                    "app_metadata": {
                      "provider": "email",
                      "providers": [
                        "email"
                      ]
                    },
                    "user_metadata": {
                      "email_verified": true
                    },
                    "created_at": "2026-10-12T19:06:53.449458Z",
                    "updated_at": "2026-10-13T13:58:59.415949Z",
                    "is_anonymous": false
                  }
                }
              }
            }
          },
          "401": {
            "description": "En-tête `apikey` absent ou faux : le service répond `Unauthorized`, sans corps JSON."
          },
          "403": {
            "description": "Lien expiré, déjà employé, ou remplacé par un lien plus récent.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "description": "Statut HTTP."
                    },
                    "error_code": {
                      "type": "string",
                      "description": "Code stable du service d’authentification."
                    },
                    "msg": {
                      "type": "string",
                      "description": "Message, en anglais."
                    },
                    "weak_password": {
                      "type": "object",
                      "description": "Pour un mot de passe refusé : les raisons (`reasons`)."
                    }
                  }
                },
                "example": {
                  "code": 403,
                  "error_code": "otp_expired",
                  "msg": "Email link is invalid or has expired"
                }
              }
            }
          },
          "429": {
            "description": "Trop de tentatives en peu de temps : le service limite les connexions. Patienter avant de réessayer.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "description": "Statut HTTP."
                    },
                    "error_code": {
                      "type": "string",
                      "description": "Code stable du service d’authentification."
                    },
                    "msg": {
                      "type": "string",
                      "description": "Message, en anglais."
                    },
                    "weak_password": {
                      "type": "object",
                      "description": "Pour un mot de passe refusé : les raisons (`reasons`)."
                    }
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "cleApi": []
          }
        ]
      }
    },
    "/auth/v1/logout": {
      "post": {
        "servers": [
          {
            "url": "https://preprod-api.satelica.com",
            "description": "Préproduction — la même adresse que l’API"
          },
          {
            "url": "https://supabase.satelica.com",
            "description": "Production — authentification"
          }
        ],
        "operationId": "authSeDeconnecter",
        "tags": [
          "Authentification"
        ],
        "summary": "Se déconnecter",
        "description": "Révoque les jetons de renouvellement : la session ne peut plus être prolongée. `scope=local` ferme cette session, `global` (par défaut) toutes celles du compte, `others` toutes sauf celle-ci.\n\n**Le jeton d’accès déjà émis reste accepté jusqu’à son expiration (une heure au plus)** : l’API le vérifie par sa signature, sans interroger le service à chaque appel. Pour couper un accès sur-le-champ, CYBASTION désactive le compte (`PATCH /api/v1/utilisateurs/{id}`) : l’API refuse alors tout appel (`403 compte_inactif`).\n\n**En-têtes requis** : `apikey` et `Authorization: Bearer <jeton>`.",
        "parameters": [
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "global",
                "local",
                "others"
              ],
              "default": "global"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Session fermée. Aucun corps."
          },
          "401": {
            "description": "En-tête `apikey` absent ou faux : le service répond `Unauthorized`, sans corps JSON."
          },
          "403": {
            "description": "Jeton expiré ou invalide.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "description": "Statut HTTP."
                    },
                    "error_code": {
                      "type": "string",
                      "description": "Code stable du service d’authentification."
                    },
                    "msg": {
                      "type": "string",
                      "description": "Message, en anglais."
                    },
                    "weak_password": {
                      "type": "object",
                      "description": "Pour un mot de passe refusé : les raisons (`reasons`)."
                    }
                  }
                },
                "example": {
                  "code": 403,
                  "error_code": "bad_jwt",
                  "msg": "invalid JWT: unable to parse or verify signature, token is malformed: …"
                }
              }
            }
          }
        },
        "security": [
          {
            "cleApi": [],
            "jetonAcces": []
          }
        ]
      }
    },
    "/api/v1/sante": {
      "get": {
        "operationId": "getSante",
        "tags": [
          "Santé"
        ],
        "summary": "Vérifier l'état du service",
        "description": "Répond sans authentification. `statut` vaut `operationnel` quand la base répond, `degrade` sinon ; `environnement` dit sur quelle plateforme on se trouve (`preproduction`, `exploitation`). `raccordements` indique ce qui est branché (paiement en ligne et son mode, stockage) sans rien divulguer de la configuration.\n\n**Permission requise** : Aucune : route ouverte, sans jeton.\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statut": {
                      "type": "string"
                    },
                    "environnement": {
                      "type": "string"
                    },
                    "base": {
                      "type": "string"
                    },
                    "base_duree_ms": {
                      "type": "integer"
                    },
                    "raccordements": {
                      "type": "object",
                      "properties": {
                        "paiement_en_ligne": {
                          "type": "boolean"
                        },
                        "paiement_mode": {
                          "type": "string"
                        },
                        "stockage": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "paiement_en_ligne",
                        "paiement_mode",
                        "stockage"
                      ]
                    },
                    "horodatage": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "statut",
                    "environnement",
                    "base",
                    "base_duree_ms",
                    "raccordements",
                    "horodatage"
                  ]
                },
                "example": {
                  "statut": "operationnel",
                  "environnement": "preproduction",
                  "base": "disponible",
                  "base_duree_ms": 1,
                  "raccordements": {
                    "paiement_en_ligne": true,
                    "paiement_mode": "bac_a_sable",
                    "stockage": true
                  },
                  "horodatage": "2026-10-19T10:44:39.354Z"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [],
        "x-satelica-permission": null,
        "x-satelica-cloisonnement": "sans_objet"
      }
    },
    "/api/v1/moi": {
      "get": {
        "operationId": "getMoi",
        "tags": [
          "Mon compte"
        ],
        "summary": "Lire le profil de l'appelant",
        "description": "Le compte connecté, son organisation (CYBASTION, partenaire ou client), son rôle et la liste de ses permissions. Premier appel à faire après la connexion : les permissions disent quelles opérations ce compte peut appeler.\n\n**Permission requise** : Être connecté (aucune permission particulière).\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        },
                        "double_authentification": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email",
                        "double_authentification"
                      ]
                    },
                    "organisation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string"
                        },
                        "partenaire_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "uuid"
                        },
                        "client_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "uuid"
                        },
                        "logo_adresse": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "nom",
                        "type",
                        "partenaire_id",
                        "client_id",
                        "logo_adresse"
                      ]
                    },
                    "role": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "libelle": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "libelle"
                      ]
                    },
                    "permissions": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "utilisateur",
                    "organisation",
                    "role",
                    "permissions"
                  ]
                },
                "example": {
                  "utilisateur": {
                    "id": "edcb444f-7e37-4cc7-b2e1-bf5c8bef0cb4",
                    "prenom": "ZZ Recette",
                    "nom": "Partenaire A 60446FF3",
                    "email": "zz.recette.60446ff3@exemple.invalide",
                    "double_authentification": false
                  },
                  "organisation": {
                    "id": "577e5e61-ff7e-46c7-8a92-b6f71f3bb9a2",
                    "nom": "ZZ Recette Partenaire A 60446FF3",
                    "type": "partenaire",
                    "partenaire_id": "2bf838df-d511-4a0c-a1e2-7f76064e3e3d",
                    "client_id": null,
                    "logo_adresse": null
                  },
                  "role": {
                    "code": "partenaire_administrateur",
                    "libelle": "Administrateur partenaire"
                  },
                  "permissions": [
                    "catalogue.consulter",
                    "clients.consulter"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "connecte",
        "x-satelica-cloisonnement": "sans_objet"
      }
    },
    "/api/v1/produits": {
      "get": {
        "operationId": "getProduits",
        "tags": [
          "Catalogue"
        ],
        "summary": "Lister les produits du catalogue",
        "description": "Les produits (équipement, installation, forfait data), triés par type de ligne puis libellé, avec leur code, leur marque et l'indicateur `sur_devis` (produit sans tarif, dont le prix se saisit sur chaque devis). Filtrables par type et par état actif ; `a_la_date` est accepté sans effet ici. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : L'une de : `catalogue.consulter`, `besoins.exprimer`, `devis.accepter`.\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "parameters": [
          {
            "name": "a_la_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          },
          {
            "name": "type_ligne",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "equipement",
                "installation",
                "forfait_data"
              ]
            }
          },
          {
            "name": "actif",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "type_ligne": {
                            "type": "string"
                          },
                          "marque": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "description": {
                            "type": "null"
                          },
                          "sur_devis": {
                            "type": "boolean"
                          },
                          "actif": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "code",
                          "libelle",
                          "type_ligne",
                          "marque",
                          "description",
                          "sur_devis",
                          "actif"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "b2ab5056-253e-4edb-b7ef-caad969dcf94",
                      "code": "ANTENNE-STANDARD",
                      "libelle": "Antenne Starlink standard",
                      "type_ligne": "equipement",
                      "marque": "Starlink",
                      "description": null,
                      "sur_devis": false,
                      "actif": true
                    },
                    {
                      "id": "48baa089-c3c4-40ea-9fc5-728d9e3a46bf",
                      "code": "INSTALLATION-COMPLEXE",
                      "libelle": "Installation complexe",
                      "type_ligne": "installation",
                      "marque": null,
                      "description": null,
                      "sur_devis": false,
                      "actif": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "catalogue.consulter",
          "besoins.exprimer",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "sans_objet"
      },
      "post": {
        "operationId": "postProduits",
        "tags": [
          "Catalogue"
        ],
        "summary": "Créer un produit",
        "description": "Ajoute un produit au catalogue : code (majuscules, chiffres, tirets), libellé, type de ligne et description. Le code ne se modifie plus ensuite. Refusé si le code est déjà celui d'un autre produit. La création est inscrite au journal d'audit.\n\n**Permission requise** : `catalogue.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 60,
                    "pattern": "^[A-Z0-9-]+$"
                  },
                  "libelle": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 200
                  },
                  "type_ligne": {
                    "type": "string",
                    "enum": [
                      "equipement",
                      "installation",
                      "forfait_data"
                    ]
                  },
                  "description": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 1000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "code",
                  "libelle",
                  "type_ligne"
                ]
              },
              "example": {
                "code": "ZZ-RECETTE-D861D8",
                "libelle": "ZZ Recette Produit D861D8",
                "type_ligne": "forfait_data"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "code": {
                      "type": "string"
                    },
                    "libelle": {
                      "type": "string"
                    },
                    "type_ligne": {
                      "type": "string"
                    },
                    "actif": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "code",
                    "libelle",
                    "type_ligne",
                    "actif"
                  ]
                },
                "example": {
                  "id": "ba2e1cba-ce98-4348-85a4-1ac4078c55a9",
                  "code": "ZZ-RECETTE-D861D8",
                  "libelle": "ZZ Recette Produit D861D8",
                  "type_ligne": "forfait_data",
                  "actif": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Code déjà utilisé par un autre produit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "catalogue.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/offres": {
      "get": {
        "operationId": "getOffres",
        "tags": [
          "Catalogue"
        ],
        "summary": "Lister les offres du catalogue",
        "description": "Les offres, triées par volume puis période, avec leurs cinq paramètres (volume, période, débit, nombre d'appareils et d'accès), `produit_id` et le produit résumé. Filtrables par produit, période, volume et état actif. Les prix ne figurent pas ici : ils se lisent sur `/tarifs`.\n\n**Permission requise** : L'une de : `catalogue.consulter`, `besoins.exprimer`, `devis.accepter`.\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "produit_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "periode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "hebdomadaire",
                "mensuelle",
                "trimestrielle",
                "semestrielle",
                "annuelle"
              ]
            }
          },
          {
            "name": "volume_go",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "actif",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 12 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "produit_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "volume_go": {
                            "type": "integer"
                          },
                          "periode": {
                            "type": "string"
                          },
                          "debit": {
                            "type": "string"
                          },
                          "nb_appareils": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "nb_acces": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "actif": {
                            "type": "boolean"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "produit": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "type_ligne": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "type_ligne"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "produit_id",
                          "code",
                          "libelle",
                          "volume_go",
                          "periode",
                          "debit",
                          "nb_appareils",
                          "nb_acces",
                          "actif",
                          "cree_le",
                          "modifie_le",
                          "produit"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                      "produit_id": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                      "code": "DATA-50GO-HEBDO",
                      "libelle": "Forfait 50 Go hebdomadaire",
                      "volume_go": 50,
                      "periode": "hebdomadaire",
                      "debit": "Selon capacité",
                      "nb_appareils": null,
                      "nb_acces": null,
                      "actif": true,
                      "cree_le": "2026-10-12T13:18:08.116Z",
                      "modifie_le": "2026-10-12T13:18:08.116Z",
                      "produit": {
                        "id": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                        "code": "FORFAIT-DATA",
                        "libelle": "Forfait data",
                        "type_ligne": "forfait_data"
                      }
                    },
                    {
                      "id": "e72f888e-db00-48b3-883e-858058b529ce",
                      "produit_id": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                      "code": "DATA-50GO-MENS",
                      "libelle": "Forfait 50 Go mensuel",
                      "volume_go": 50,
                      "periode": "mensuelle",
                      "debit": "Selon capacité",
                      "nb_appareils": null,
                      "nb_acces": null,
                      "actif": true,
                      "cree_le": "2026-10-12T13:18:08.116Z",
                      "modifie_le": "2026-10-12T13:18:08.116Z",
                      "produit": {
                        "id": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                        "code": "FORFAIT-DATA",
                        "libelle": "Forfait data",
                        "type_ligne": "forfait_data"
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 26,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "catalogue.consulter",
          "besoins.exprimer",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "sans_objet"
      },
      "post": {
        "operationId": "postOffres",
        "tags": [
          "Catalogue"
        ],
        "summary": "Créer une offre et son premier prix",
        "description": "Crée l'offre et, dans la même transaction, son premier tarif `prix_ht` à partir de `valide_du` (aujourd'hui par défaut, jamais plus tard). Le prix est exigé, sauf sur un produit « sur devis », où il est refusé. Refusée si le produit est retiré du catalogue ou si le code est déjà pris. Renvoie l'offre et son `tarif_courant`.\n\n**Permission requise** : `catalogue.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "produit_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "code": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 60,
                    "pattern": "^[A-Z0-9-]+$"
                  },
                  "libelle": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 200
                  },
                  "volume_go": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1000000
                  },
                  "periode": {
                    "type": "string",
                    "enum": [
                      "hebdomadaire",
                      "mensuelle",
                      "trimestrielle",
                      "semestrielle",
                      "annuelle"
                    ]
                  },
                  "debit": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 120
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "nb_appareils": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "nb_acces": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "prix_ht": {
                    "anyOf": [
                      {
                        "type": "number",
                        "exclusiveMinimum": 0,
                        "maximum": 1000000000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "valide_du": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  }
                },
                "required": [
                  "produit_id",
                  "code",
                  "libelle",
                  "volume_go",
                  "periode"
                ]
              },
              "example": {
                "produit_id": "ba2e1cba-ce98-4348-85a4-1ac4078c55a9",
                "code": "ZZ-OFFRE-D861D8",
                "libelle": "ZZ Recette Offre D861D8",
                "volume_go": 150,
                "periode": "mensuelle",
                "debit": "50 Mbit/s",
                "nb_appareils": 5,
                "nb_acces": 25,
                "prix_ht": 120000,
                "valide_du": "2026-10-13"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "produit_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "code": {
                      "type": "string"
                    },
                    "libelle": {
                      "type": "string"
                    },
                    "volume_go": {
                      "type": "integer"
                    },
                    "periode": {
                      "type": "string"
                    },
                    "debit": {
                      "type": "string"
                    },
                    "nb_appareils": {
                      "type": "integer"
                    },
                    "nb_acces": {
                      "type": "integer"
                    },
                    "actif": {
                      "type": "boolean"
                    },
                    "tarif_courant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "produit_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "offre_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prix_ht": {
                          "type": "integer"
                        },
                        "valide_du": {
                          "type": "string",
                          "format": "date"
                        },
                        "valide_au": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "produit_id",
                        "offre_id",
                        "prix_ht",
                        "valide_du",
                        "valide_au"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "produit_id",
                    "code",
                    "libelle",
                    "volume_go",
                    "periode",
                    "debit",
                    "nb_appareils",
                    "nb_acces",
                    "actif",
                    "tarif_courant"
                  ]
                },
                "example": {
                  "id": "eb7d57a7-c0b0-4e34-839b-4c7c8ffc5216",
                  "produit_id": "ba2e1cba-ce98-4348-85a4-1ac4078c55a9",
                  "code": "ZZ-OFFRE-D861D8",
                  "libelle": "ZZ Recette Offre D861D8",
                  "volume_go": 150,
                  "periode": "mensuelle",
                  "debit": "50 Mbit/s",
                  "nb_appareils": 5,
                  "nb_acces": 25,
                  "actif": true,
                  "tarif_courant": {
                    "id": "0e74c5f0-7f7d-4ecc-aeb5-e9e81af8164f",
                    "produit_id": "ba2e1cba-ce98-4348-85a4-1ac4078c55a9",
                    "offre_id": "eb7d57a7-c0b0-4e34-839b-4c7c8ffc5216",
                    "prix_ht": 120000,
                    "valide_du": "2026-10-13",
                    "valide_au": null
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Produit retiré du catalogue, ou code déjà utilisé.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "catalogue.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/tarifs": {
      "get": {
        "operationId": "getTarifs",
        "tags": [
          "Catalogue"
        ],
        "summary": "Lister les tarifs datés",
        "description": "Les prix HT par produit ou par offre, du plus récent au plus ancien. Par défaut, seuls ceux en vigueur à `a_la_date` (aujourd'hui si elle est absente) ; `historique=true` les renvoie tous. Réponse `{ donnees: [...], a_la_date }`, non paginée.\n\n**Permission requise** : L'une de : `catalogue.consulter`, `besoins.exprimer`, `devis.accepter`.\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "parameters": [
          {
            "name": "a_la_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          },
          {
            "name": "produit_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "offre_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "historique",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "produit_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "offre_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "prix_ht": {
                            "type": "integer"
                          },
                          "valide_du": {
                            "type": "string",
                            "format": "date"
                          },
                          "valide_au": {
                            "type": "null"
                          }
                        },
                        "required": [
                          "id",
                          "produit_id",
                          "offre_id",
                          "prix_ht",
                          "valide_du",
                          "valide_au"
                        ]
                      }
                    },
                    "a_la_date": {
                      "type": "string",
                      "format": "date"
                    }
                  },
                  "required": [
                    "donnees",
                    "a_la_date"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "900d0114-354f-43cc-ae55-d714ba5723f7",
                      "produit_id": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                      "offre_id": "5040696b-c729-4a66-9a0b-946199f9fe1f",
                      "prix_ht": 120000,
                      "valide_du": "2026-09-25",
                      "valide_au": null
                    },
                    {
                      "id": "110a29e5-3da2-46ee-bd65-8135ce7c6989",
                      "produit_id": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                      "offre_id": "e72f888e-db00-48b3-883e-858058b529ce",
                      "prix_ht": 60000,
                      "valide_du": "2026-09-01",
                      "valide_au": null
                    }
                  ],
                  "a_la_date": "2026-10-19"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "catalogue.consulter",
          "besoins.exprimer",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "sans_objet"
      },
      "post": {
        "operationId": "postTarifs",
        "tags": [
          "Catalogue"
        ],
        "summary": "Poser un tarif daté",
        "description": "Un tarif ne se modifie pas : on en pose un nouveau à partir de `valide_du` (aujourd'hui par défaut), et celui qui court pour le même produit et la même offre est clos la veille. L'offre doit appartenir au produit. Refusé si un tarif du même couple commence déjà ce jour-là. Renvoie le tarif posé et celui qu’il remplace (`remplace`).\n\n**Permission requise** : `catalogue.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "produit_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "offre_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "prix_ht": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 1000000000
                  },
                  "valide_du": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  }
                },
                "required": [
                  "produit_id",
                  "prix_ht"
                ]
              },
              "example": {
                "produit_id": "ba2e1cba-ce98-4348-85a4-1ac4078c55a9",
                "offre_id": "eb7d57a7-c0b0-4e34-839b-4c7c8ffc5216",
                "prix_ht": 135000,
                "valide_du": "2026-10-14"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "produit_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "offre_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "prix_ht": {
                      "type": "integer"
                    },
                    "valide_du": {
                      "type": "string",
                      "format": "date"
                    },
                    "valide_au": {
                      "type": "null"
                    },
                    "remplace": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prix_ht": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "id",
                        "prix_ht"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "produit_id",
                    "offre_id",
                    "prix_ht",
                    "valide_du",
                    "valide_au",
                    "remplace"
                  ]
                },
                "example": {
                  "id": "492e5927-8e78-45dc-be10-7982022ece35",
                  "produit_id": "ba2e1cba-ce98-4348-85a4-1ac4078c55a9",
                  "offre_id": "eb7d57a7-c0b0-4e34-839b-4c7c8ffc5216",
                  "prix_ht": 135000,
                  "valide_du": "2026-10-14",
                  "valide_au": null,
                  "remplace": {
                    "id": "0e74c5f0-7f7d-4ecc-aeb5-e9e81af8164f",
                    "prix_ht": 120000
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Un tarif commence déjà à cette date.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "catalogue.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/regles-tva": {
      "get": {
        "operationId": "getReglesTva",
        "tags": [
          "Catalogue"
        ],
        "summary": "Lister les règles de TVA en vigueur",
        "description": "Les taux de TVA par type de ligne en vigueur à `a_la_date` (aujourd'hui si elle est absente), avec l'exonération et sa mention. Seuls `type_ligne` et `a_la_date` filtrent cette liste. Réponse `{ donnees: [...], a_la_date }`, non paginée.\n\n**Permission requise** : L'une de : `catalogue.consulter`, `besoins.exprimer`, `devis.accepter`.\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "parameters": [
          {
            "name": "a_la_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          },
          {
            "name": "type_ligne",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "equipement",
                "installation",
                "forfait_data"
              ]
            }
          },
          {
            "name": "partenaire_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "rang_vente",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "toutes",
                "premiere_vente",
                "renouvellement"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type_ligne": {
                            "type": "string"
                          },
                          "taux": {
                            "type": "integer"
                          },
                          "exoneration": {
                            "type": "boolean"
                          },
                          "mention_exoneration": {
                            "type": "null"
                          },
                          "valide_du": {
                            "type": "string",
                            "format": "date"
                          },
                          "valide_au": {
                            "type": "null"
                          }
                        },
                        "required": [
                          "id",
                          "type_ligne",
                          "taux",
                          "exoneration",
                          "mention_exoneration",
                          "valide_du",
                          "valide_au"
                        ]
                      }
                    },
                    "a_la_date": {
                      "type": "string",
                      "format": "date"
                    }
                  },
                  "required": [
                    "donnees",
                    "a_la_date"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "05148dae-e917-4c7d-8898-288ac88fb0d0",
                      "type_ligne": "equipement",
                      "taux": 18,
                      "exoneration": false,
                      "mention_exoneration": null,
                      "valide_du": "2026-09-01",
                      "valide_au": null
                    },
                    {
                      "id": "e6056158-c86e-4c09-838d-1113ffe99361",
                      "type_ligne": "installation",
                      "taux": 18,
                      "exoneration": false,
                      "mention_exoneration": null,
                      "valide_du": "2026-09-01",
                      "valide_au": null
                    }
                  ],
                  "a_la_date": "2026-10-19"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "catalogue.consulter",
          "besoins.exprimer",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "sans_objet"
      }
    },
    "/api/v1/regles-commission": {
      "get": {
        "operationId": "getReglesCommission",
        "tags": [
          "Catalogue"
        ],
        "summary": "Lister les règles de commission en vigueur",
        "description": "Les règles en vigueur à `a_la_date` (aujourd'hui si elle est absente) : taux de base, taux majoré et seuil, plafond de remise. Avec `partenaire_id`, ses règles et les règles générales ; avec `rang_vente`, celles de ce rang et celles valant pour `toutes`. Les plus précises viennent en tête. Réponse `{ donnees: [...], a_la_date }`, non paginée.\n\n**Permission requise** : L'une de : `catalogue.consulter`, `besoins.exprimer`, `devis.accepter`.\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "parameters": [
          {
            "name": "a_la_date",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          },
          {
            "name": "type_ligne",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "equipement",
                "installation",
                "forfait_data"
              ]
            }
          },
          {
            "name": "partenaire_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "rang_vente",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "toutes",
                "premiere_vente",
                "renouvellement"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type_ligne": {
                            "type": "string"
                          },
                          "rang_vente": {
                            "type": "string"
                          },
                          "partenaire_id": {
                            "type": "null"
                          },
                          "offre_id": {
                            "type": "null"
                          },
                          "taux_base": {
                            "type": "integer"
                          },
                          "taux_majore": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "seuil_montant": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "base_seuil": {
                            "type": "string"
                          },
                          "periode_seuil": {
                            "type": "string"
                          },
                          "remise_max_pct": {
                            "type": "number"
                          },
                          "valide_du": {
                            "type": "string",
                            "format": "date"
                          },
                          "valide_au": {
                            "type": "null"
                          }
                        },
                        "required": [
                          "id",
                          "type_ligne",
                          "rang_vente",
                          "partenaire_id",
                          "offre_id",
                          "taux_base",
                          "taux_majore",
                          "seuil_montant",
                          "base_seuil",
                          "periode_seuil",
                          "remise_max_pct",
                          "valide_du",
                          "valide_au"
                        ]
                      }
                    },
                    "a_la_date": {
                      "type": "string",
                      "format": "date"
                    }
                  },
                  "required": [
                    "donnees",
                    "a_la_date"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "00376ce9-b379-44ae-bd01-99d9b600c746",
                      "type_ligne": "equipement",
                      "rang_vente": "toutes",
                      "partenaire_id": null,
                      "offre_id": null,
                      "taux_base": 5,
                      "taux_majore": 7,
                      "seuil_montant": 75000000,
                      "base_seuil": "ca_ht_encaisse",
                      "periode_seuil": "annee_civile",
                      "remise_max_pct": 2.5,
                      "valide_du": "2026-09-01",
                      "valide_au": null
                    },
                    {
                      "id": "6879ad1e-85f9-48ae-b676-16b0a85cdfcf",
                      "type_ligne": "installation",
                      "rang_vente": "toutes",
                      "partenaire_id": null,
                      "offre_id": null,
                      "taux_base": 0,
                      "taux_majore": null,
                      "seuil_montant": null,
                      "base_seuil": "ca_ht_encaisse",
                      "periode_seuil": "annee_civile",
                      "remise_max_pct": 0,
                      "valide_du": "2026-09-01",
                      "valide_au": null
                    }
                  ],
                  "a_la_date": "2026-10-19"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "catalogue.consulter",
          "besoins.exprimer",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "sans_objet"
      },
      "post": {
        "operationId": "postReglesCommission",
        "tags": [
          "Catalogue"
        ],
        "summary": "Poser une règle de commission datée",
        "description": "Pose une règle (type de ligne, rang de vente, partenaire et offre facultatifs) à partir de `valide_du` (aujourd'hui par défaut) ; celle qui court pour la même combinaison est close la veille. Le taux majoré et le seuil vont ensemble, et le taux majoré ne peut être inférieur au taux de base. Renvoie la règle et celle qu’elle remplace (`remplace`).\n\n**Permission requise** : `catalogue.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type_ligne": {
                    "type": "string",
                    "enum": [
                      "equipement",
                      "installation",
                      "forfait_data"
                    ]
                  },
                  "rang_vente": {
                    "default": "toutes",
                    "type": "string",
                    "enum": [
                      "toutes",
                      "premiere_vente",
                      "renouvellement"
                    ]
                  },
                  "partenaire_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "offre_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "taux_base": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100
                  },
                  "taux_majore": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 100
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "seuil_montant": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": 0,
                        "maximum": 1000000000000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "base_seuil": {
                    "default": "ca_ht_encaisse",
                    "type": "string",
                    "enum": [
                      "ca_ht_encaisse",
                      "ca_ht_vendu"
                    ]
                  },
                  "periode_seuil": {
                    "default": "annee_civile",
                    "type": "string",
                    "enum": [
                      "mois",
                      "trimestre",
                      "annee_civile"
                    ]
                  },
                  "remise_max_pct": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 100
                  },
                  "valide_du": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  }
                },
                "required": [
                  "type_ligne",
                  "taux_base",
                  "remise_max_pct"
                ]
              },
              "example": {
                "type_ligne": "forfait_data",
                "rang_vente": "premiere_vente",
                "offre_id": "eb7d57a7-c0b0-4e34-839b-4c7c8ffc5216",
                "taux_base": 18,
                "taux_majore": 21,
                "seuil_montant": 30000000,
                "remise_max_pct": 8,
                "valide_du": "2026-10-13"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type_ligne": {
                      "type": "string"
                    },
                    "rang_vente": {
                      "type": "string"
                    },
                    "partenaire_id": {
                      "type": "null"
                    },
                    "offre_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "taux_base": {
                      "type": "integer"
                    },
                    "taux_majore": {
                      "type": "integer"
                    },
                    "seuil_montant": {
                      "type": "integer"
                    },
                    "base_seuil": {
                      "type": "string"
                    },
                    "periode_seuil": {
                      "type": "string"
                    },
                    "remise_max_pct": {
                      "type": "integer"
                    },
                    "valide_du": {
                      "type": "string",
                      "format": "date"
                    },
                    "valide_au": {
                      "type": "null"
                    },
                    "remplace": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "taux_base": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "id",
                        "taux_base"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "type_ligne",
                    "rang_vente",
                    "partenaire_id",
                    "offre_id",
                    "taux_base",
                    "taux_majore",
                    "seuil_montant",
                    "base_seuil",
                    "periode_seuil",
                    "remise_max_pct",
                    "valide_du",
                    "valide_au",
                    "remplace"
                  ]
                },
                "example": {
                  "id": "8672af22-3d7b-499c-8a04-ad29c079978b",
                  "type_ligne": "forfait_data",
                  "rang_vente": "premiere_vente",
                  "partenaire_id": null,
                  "offre_id": "eb7d57a7-c0b0-4e34-839b-4c7c8ffc5216",
                  "taux_base": 18,
                  "taux_majore": 21,
                  "seuil_montant": 30000000,
                  "base_seuil": "ca_ht_encaisse",
                  "periode_seuil": "annee_civile",
                  "remise_max_pct": 8,
                  "valide_du": "2026-10-13",
                  "valide_au": null,
                  "remplace": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Une règle de la même combinaison commence déjà à cette date.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "catalogue.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/produits/{id}": {
      "patch": {
        "operationId": "patchProduitsParId",
        "tags": [
          "Catalogue"
        ],
        "summary": "Modifier un produit",
        "description": "Modifie le libellé, la description ou l'état actif d'un produit ; le code et le type de ligne ne se modifient pas. `actif: false` le retire du catalogue. Au moins un champ est exigé. La modification est inscrite au journal d'audit.\n\n**Permission requise** : `catalogue.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "libelle": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 200
                  },
                  "description": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 1000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "actif": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "libelle": "ZZ Recette Produit D861D8 corrigé"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "code": {
                      "type": "string"
                    },
                    "libelle": {
                      "type": "string"
                    },
                    "type_ligne": {
                      "type": "string"
                    },
                    "description": {
                      "type": "null"
                    },
                    "actif": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "code",
                    "libelle",
                    "type_ligne",
                    "description",
                    "actif"
                  ]
                },
                "example": {
                  "id": "ba2e1cba-ce98-4348-85a4-1ac4078c55a9",
                  "code": "ZZ-RECETTE-D861D8",
                  "libelle": "ZZ Recette Produit D861D8 corrigé",
                  "type_ligne": "forfait_data",
                  "description": null,
                  "actif": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "catalogue.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "delete": {
        "operationId": "deleteProduitsParId",
        "tags": [
          "Catalogue"
        ],
        "summary": "Supprimer un produit",
        "description": "Efface un produit jamais utilisé. Refusé s’il figure sur un devis, porte une offre ou a été tarifé : il se retire alors du catalogue (`actif: false`). La suppression est inscrite au journal d'audit. Renvoie `{ supprime, libelle }`.\n\n**Permission requise** : `catalogue.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    },
                    "libelle": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "supprime",
                    "libelle"
                  ]
                },
                "example": {
                  "supprime": true,
                  "libelle": "ZZ Recette Produit D861D8 corrigé"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Produit déjà utilisé (devis, offre ou tarif) : à retirer plutôt.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "catalogue.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/offres/{id}": {
      "patch": {
        "operationId": "patchOffresParId",
        "tags": [
          "Catalogue"
        ],
        "summary": "Modifier une offre",
        "description": "Modifie le libellé, les paramètres ou l'état actif d'une offre ; le code et le produit ne se modifient pas. Repasser une offre retirée à `actif: true` est refusé si elle n'a aucun prix en vigueur ce jour (sauf produit « sur devis »). Au moins un champ est exigé. La modification est inscrite au journal d'audit.\n\n**Permission requise** : `catalogue.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "libelle": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 200
                  },
                  "volume_go": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1000000
                  },
                  "periode": {
                    "type": "string",
                    "enum": [
                      "hebdomadaire",
                      "mensuelle",
                      "trimestrielle",
                      "semestrielle",
                      "annuelle"
                    ]
                  },
                  "debit": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 120
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "nb_appareils": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "nb_acces": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 1,
                        "maximum": 100000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "actif": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "volume_go": 200,
                "nb_acces": 40
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "produit_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "code": {
                      "type": "string"
                    },
                    "libelle": {
                      "type": "string"
                    },
                    "volume_go": {
                      "type": "integer"
                    },
                    "periode": {
                      "type": "string"
                    },
                    "debit": {
                      "type": "string"
                    },
                    "nb_appareils": {
                      "type": "integer"
                    },
                    "nb_acces": {
                      "type": "integer"
                    },
                    "actif": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "produit_id",
                    "code",
                    "libelle",
                    "volume_go",
                    "periode",
                    "debit",
                    "nb_appareils",
                    "nb_acces",
                    "actif"
                  ]
                },
                "example": {
                  "id": "eb7d57a7-c0b0-4e34-839b-4c7c8ffc5216",
                  "produit_id": "ba2e1cba-ce98-4348-85a4-1ac4078c55a9",
                  "code": "ZZ-OFFRE-D861D8",
                  "libelle": "ZZ Recette Offre D861D8",
                  "volume_go": 200,
                  "periode": "mensuelle",
                  "debit": "50 Mbit/s",
                  "nb_appareils": 5,
                  "nb_acces": 40,
                  "actif": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Réactivation d'une offre sans prix en vigueur.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "catalogue.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "delete": {
        "operationId": "deleteOffresParId",
        "tags": [
          "Catalogue"
        ],
        "summary": "Supprimer une offre",
        "description": "Efface une offre qui n'a rien vendu, avec ses tarifs et ses règles de commission propres. Refusée si un contrat la porte, si un devis la nomme, ou si l’un de ses tarifs a déjà commencé à s'appliquer, sauf le jour même de sa création. La suppression est inscrite au journal d'audit. Renvoie `{ supprime, libelle }`.\n\n**Permission requise** : `catalogue.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    },
                    "libelle": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "supprime",
                    "libelle"
                  ]
                },
                "example": {
                  "supprime": true,
                  "libelle": "ZZ Recette Offre D861D8"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Offre portée par un contrat, nommée par un devis ou déjà vendue à son prix.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "catalogue.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/tarifs/{id}": {
      "delete": {
        "operationId": "deleteTarifsParId",
        "tags": [
          "Catalogue"
        ],
        "summary": "Annuler un tarif programmé",
        "description": "Efface un tarif qui n'a pas encore commencé à s'appliquer, et rouvre celui qu'il avait clos, jusqu’à la fin prévue du tarif annulé. Refusé pour un tarif en vigueur ou passé, et pour le dernier prix d’une offre active (hors produit « sur devis »). La suppression est inscrite au journal d'audit. Renvoie `{ supprime, prix_ht }`.\n\n**Permission requise** : `catalogue.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    },
                    "prix_ht": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "supprime",
                    "prix_ht"
                  ]
                },
                "example": {
                  "supprime": true,
                  "prix_ht": 135000
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Tarif déjà appliqué, ou dernier prix d'une offre active.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "catalogue.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/regles-commission/{id}": {
      "delete": {
        "operationId": "deleteReglesCommissionParId",
        "tags": [
          "Catalogue"
        ],
        "summary": "Annuler une règle de commission programmée",
        "description": "Efface une règle qui n'a pas encore commencé à s'appliquer et qu'aucune commission ne cite, puis rouvre celle qu’elle avait close, jusqu’à la fin prévue de la règle annulée. La suppression est inscrite au journal d'audit. Renvoie `{ supprime, taux_base }`.\n\n**Permission requise** : `catalogue.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    },
                    "taux_base": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "supprime",
                    "taux_base"
                  ]
                },
                "example": {
                  "supprime": true,
                  "taux_base": 20
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Règle déjà appliquée, ou citée par une commission.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "catalogue.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/fichiers": {
      "post": {
        "operationId": "postFichiers",
        "tags": [
          "Fichiers"
        ],
        "summary": "Déposer un fichier",
        "description": "Un seul fichier en `multipart/form-data`, avec un champ `bucket` facultatif (`kyc`, `devis`, `paiements`, `proces-verbaux`, `versements`, `depots` par défaut). Taille et types selon `fichier.taille_max_mo` (10 Mo à défaut) et `fichier.types_acceptes` (PDF, JPEG, PNG, WebP, HEIC à défaut) ; le contenu doit être du type déclaré, un PDF sans script ni fichier embarqué, et pages ou mégapixels sont bornés. Un fichier infecté est refusé ; si l'antivirus ne répond pas, il est gardé `en_attente` et n'est pas servi. Idempotent : le même contenu, redéposé par le même compte dans le même seau, renvoie le fichier existant.\n\n**Permission requise** : Être connecté (aucune permission particulière).\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "fichier"
                ],
                "properties": {
                  "fichier": {
                    "type": "string",
                    "format": "binary"
                  },
                  "bucket": {
                    "type": "string",
                    "enum": [
                      "kyc",
                      "devis",
                      "paiements",
                      "proces-verbaux",
                      "versements",
                      "depots"
                    ],
                    "description": "Destination du fichier : pièce KYC, devis, justificatif, procès-verbal…"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 55 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "bucket": {
                      "type": "string"
                    },
                    "nom_original": {
                      "type": "string"
                    },
                    "type_mime": {
                      "type": "string"
                    },
                    "taille_octets": {
                      "type": "integer"
                    },
                    "empreinte_sha256": {
                      "type": "string"
                    },
                    "statut_scan": {
                      "type": "string"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "bucket",
                    "nom_original",
                    "type_mime",
                    "taille_octets",
                    "empreinte_sha256",
                    "statut_scan",
                    "cree_le"
                  ]
                },
                "example": {
                  "id": "356b47bd-dd4a-4694-9064-918073156cc6",
                  "bucket": "kyc",
                  "nom_original": "client_photo-54587534.pdf",
                  "type_mime": "application/pdf",
                  "taille_octets": 215,
                  "empreinte_sha256": "7cbb9c5856896936333d9ec6e25f49997b611dfe5cb46acaa9f197b38539d51d",
                  "statut_scan": "sain",
                  "cree_le": "2026-10-19T10:44:15.497Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Limite de dépôts par heure, ou quota de stockage de l'organisation atteint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "connecte",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/fichiers/{id}": {
      "get": {
        "operationId": "getFichiersParId",
        "tags": [
          "Fichiers"
        ],
        "summary": "Obtenir l'adresse de lecture d'un fichier",
        "description": "Renvoie une adresse signée de courte durée (`fichier.signature_secondes`, 300 secondes à défaut) si le fichier a été déposé depuis l'organisation de l'appelant ou si un objet de son périmètre le référence (pièce KYC, devis, paiement, demande de versement, procès-verbal, contrat, facture, contrat-cadre). Un fichier que l’antivirus n’a pas déclaré sain n'est pas servi. Chaque lecture est inscrite au journal d'audit.\n\n**Permission requise** : Être connecté (aucune permission particulière).\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "nom_original": {
                      "type": "string"
                    },
                    "type_mime": {
                      "type": "string"
                    },
                    "adresse": {
                      "type": "string"
                    },
                    "expire_dans_secondes": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "nom_original",
                    "type_mime",
                    "adresse",
                    "expire_dans_secondes"
                  ]
                },
                "example": {
                  "id": "c34f6bb8-9e68-4d97-82bd-3f19f368766b",
                  "nom_original": "rccm.pdf",
                  "type_mime": "application/pdf",
                  "adresse": "/object/sign/kyc/2026/10/45498750-88ae-4f39-8b46-01900785999d.pdf?‹paramètres signés›",
                  "expire_dans_secondes": 300
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Fichier non déclaré sain par l'antivirus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "connecte",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/clients/{id}/suppression": {
      "get": {
        "operationId": "getClientsParIdSuppression",
        "tags": [
          "Clients"
        ],
        "summary": "Vérifier si un client peut être supprimé",
        "description": "Dit si le dossier du client peut être supprimé et, sinon, pourquoi : signature électronique, règlement, facture, procès-verbal, commission, contrat, commande ou devis signé. Quand c'est possible, renvoie l'inventaire de ce que la suppression emporterait. Ne modifie rien : à appeler avant `DELETE /clients/{id}`.\n\n**Permission requise** : `clients.supprimer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut"
                      ]
                    },
                    "possible": {
                      "type": "boolean"
                    },
                    "refus": {
                      "type": "null"
                    },
                    "inventaire": {
                      "type": "object",
                      "properties": {
                        "réservation": {
                          "type": "integer"
                        },
                        "affectation": {
                          "type": "integer"
                        },
                        "site": {
                          "type": "integer"
                        },
                        "contact": {
                          "type": "integer"
                        },
                        "pièces du dossier": {
                          "type": "integer"
                        },
                        "comptes d’accès": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "réservation",
                        "affectation",
                        "site",
                        "contact",
                        "pièces du dossier",
                        "comptes d’accès"
                      ]
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "client",
                    "possible",
                    "refus",
                    "inventaire",
                    "total"
                  ]
                },
                "example": {
                  "client": {
                    "id": "b7ec7eb5-20e9-4f57-9017-6026dc2f790c",
                    "raison_sociale": "Entreprise de démonstration Odoo",
                    "statut": "reserve"
                  },
                  "possible": true,
                  "refus": null,
                  "inventaire": {
                    "réservation": 1,
                    "affectation": 1,
                    "site": 1,
                    "contact": 1,
                    "pièces du dossier": 4,
                    "comptes d’accès": 2
                  },
                  "total": 10
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.supprimer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/clients/{id}": {
      "delete": {
        "operationId": "deleteClientsParId",
        "tags": [
          "Clients"
        ],
        "summary": "Supprimer un client et tout son dossier",
        "description": "Efface le client et tout ce qui en dépend, en une transaction. Exige un motif et la raison sociale recopiée à l'identique (`confirmation`). Refusé dès que le client a produit un fait (signature, règlement, facture, procès-verbal, commission, contrat, commande, devis signé). Le nom, le motif et l'inventaire effacé sont inscrits au journal d'audit.\n\n**Permission requise** : `clients.supprimer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "motif": {
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 500
                  },
                  "confirmation": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 300
                  }
                },
                "required": [
                  "motif",
                  "confirmation"
                ]
              },
              "example": {
                "motif": "Saisi en double par erreur.",
                "confirmation": "ZZ Recette Client B030E901"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "emporte": {
                      "type": "object",
                      "properties": {
                        "réservation": {
                          "type": "integer"
                        },
                        "site": {
                          "type": "integer"
                        },
                        "contact": {
                          "type": "integer"
                        },
                        "pièces du dossier": {
                          "type": "integer"
                        },
                        "fichiers déposés": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "réservation",
                        "site",
                        "contact",
                        "pièces du dossier",
                        "fichiers déposés"
                      ]
                    }
                  },
                  "required": [
                    "supprime",
                    "raison_sociale",
                    "emporte"
                  ]
                },
                "example": {
                  "supprime": true,
                  "raison_sociale": "ZZ Recette Client B030E901",
                  "emporte": {
                    "réservation": 1,
                    "site": 1,
                    "contact": 1,
                    "pièces du dossier": 4,
                    "fichiers déposés": 4
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Le client a produit un fait qui interdit sa suppression.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.supprimer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "get": {
        "operationId": "getClientsParId",
        "tags": [
          "Clients"
        ],
        "summary": "Lire la fiche d'un client",
        "description": "La fiche complète : contacts, sites, réservations (hors CYBASTION, seulement celles de l'appelant), affectations, les 20 derniers contrats, commandes, factures, devis et besoins, reste à payer, état du crédit, pièces exigées et déposées (dossier en vigueur), 50 derniers événements d'activité et état de l'accès du contact principal. Elle dit aussi ce que l'appelant peut faire : `peut_creer_devis`, `peut_demander_reservation` et `motif_reservation_impossible`.\n\n**Permission requise** : L'une de : `clients.consulter`, `besoins.exprimer`, `devis.accepter`, `pv.valider`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 19 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "forme_juridique": {
                      "type": "null"
                    },
                    "rccm": {
                      "type": "string"
                    },
                    "ncc": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "secteur_id": {
                      "type": "null"
                    },
                    "adresse_facturation": {
                      "type": "null"
                    },
                    "ville": {
                      "type": "string"
                    },
                    "zone_id": {
                      "type": "null"
                    },
                    "telephone": {
                      "type": "null"
                    },
                    "email": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "origine": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "statut_kyc": {
                      "type": "string"
                    },
                    "partenaire_actuel_id": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "credit_approuve": {
                      "type": "boolean"
                    },
                    "plafond_encours": {
                      "type": "null"
                    },
                    "credit_approuve_par": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "logo_fichier_id": {
                      "type": "null"
                    },
                    "mode_paiement_souhaite": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "sites": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "adresse": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "ville": {
                            "type": "string"
                          },
                          "zone_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "latitude": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "longitude": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "contact_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "zone": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              },
                              "parent_id": {
                                "type": "string",
                                "format": "uuid"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "type",
                              "parent_id"
                            ]
                          },
                          "contact": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "client_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "fonction": {
                                "type": "null"
                              },
                              "email": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "telephone": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "principal": {
                                "type": "boolean"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "client_id",
                              "prenom",
                              "nom",
                              "fonction",
                              "email",
                              "telephone",
                              "principal",
                              "cree_le",
                              "modifie_le"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "client_id",
                          "libelle",
                          "adresse",
                          "ville",
                          "zone_id",
                          "latitude",
                          "longitude",
                          "contact_id",
                          "statut",
                          "cree_le",
                          "modifie_le",
                          "zone",
                          "contact"
                        ]
                      }
                    },
                    "reservations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "demandee_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "doublons_detectes": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "items": {
                              "type": "object",
                              "properties": {
                                "niveau": {
                                  "type": "string"
                                },
                                "criteres": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "client_id": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "similarite": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "raison_sociale": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "niveau",
                                "criteres",
                                "client_id",
                                "similarite",
                                "raison_sociale"
                              ]
                            }
                          },
                          "motif_decision": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "traitee_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "traitee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut"
                            ]
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "ville",
                              "code_confidentiel"
                            ]
                          },
                          "demandeur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "traitee_par_utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "client_id",
                          "partenaire_id",
                          "demandee_par",
                          "statut",
                          "doublons_detectes",
                          "motif_decision",
                          "traitee_par",
                          "traitee_le",
                          "cree_le",
                          "modifie_le",
                          "client",
                          "partenaire",
                          "demandeur",
                          "traitee_par_utilisateur"
                        ]
                      }
                    },
                    "affectations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "origine": {
                            "type": "string"
                          },
                          "debut_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "fin_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "active": {
                            "type": "boolean"
                          },
                          "cree_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "code_confidentiel"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "client_id",
                          "partenaire_id",
                          "origine",
                          "debut_le",
                          "fin_le",
                          "active",
                          "cree_par",
                          "cree_le",
                          "partenaire"
                        ]
                      }
                    },
                    "contrats": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "date_debut": {
                            "type": "string",
                            "format": "date"
                          },
                          "date_fin": {
                            "type": "string",
                            "format": "date"
                          },
                          "active_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "offre": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle"
                            ]
                          },
                          "site": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "libelle",
                              "ville"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "statut",
                          "date_debut",
                          "date_fin",
                          "active_le",
                          "offre",
                          "site"
                        ]
                      }
                    },
                    "commandes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "total_ttc": {
                            "type": "integer"
                          },
                          "mode_paiement": {
                            "type": "string"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "statut",
                          "total_ttc",
                          "mode_paiement",
                          "cree_le"
                        ]
                      }
                    },
                    "factures": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "montant_paye": {
                            "type": "integer"
                          },
                          "date_emission": {
                            "type": "string",
                            "format": "date"
                          },
                          "date_echeance": {
                            "type": "string",
                            "format": "date"
                          },
                          "reste_a_payer": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "statut",
                          "montant_ttc",
                          "montant_paye",
                          "date_emission",
                          "date_echeance",
                          "reste_a_payer"
                        ]
                      }
                    },
                    "devis": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "total_ttc": {
                            "type": "string"
                          },
                          "valide_jusquau": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "signe_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "statut",
                          "total_ttc",
                          "valide_jusquau",
                          "signe_le",
                          "cree_le"
                        ]
                      }
                    },
                    "opportunites": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "description": {
                            "type": "string"
                          },
                          "type_transaction": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "besoin": {
                            "type": "null"
                          },
                          "eligibilite": {
                            "type": "string"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "description",
                          "type_transaction",
                          "statut",
                          "besoin",
                          "eligibilite",
                          "cree_le"
                        ]
                      }
                    },
                    "peut_creer_devis": {
                      "type": "boolean"
                    },
                    "peut_demander_reservation": {
                      "type": "boolean"
                    },
                    "motif_reservation_impossible": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "logo_adresse": {
                      "type": "null"
                    },
                    "partenaire_actuel": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "code_confidentiel"
                      ]
                    },
                    "zone": {
                      "type": "null"
                    },
                    "secteur": {
                      "type": "null"
                    },
                    "contact_principal": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "client_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "fonction": {
                          "type": "null"
                        },
                        "email": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "telephone": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "principal": {
                          "type": "boolean"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "modifie_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "client_id",
                        "prenom",
                        "nom",
                        "fonction",
                        "email",
                        "telephone",
                        "principal",
                        "cree_le",
                        "modifie_le"
                      ]
                    },
                    "nb_sites": {
                      "type": "integer"
                    },
                    "contacts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "prenom": {
                            "type": "string"
                          },
                          "nom": {
                            "type": "string"
                          },
                          "fonction": {
                            "type": "null"
                          },
                          "email": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "telephone": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "principal": {
                            "type": "boolean"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "client_id",
                          "prenom",
                          "nom",
                          "fonction",
                          "email",
                          "telephone",
                          "principal",
                          "cree_le",
                          "modifie_le"
                        ]
                      }
                    },
                    "reste_a_payer_total": {
                      "type": "integer"
                    },
                    "contrats_actifs": {
                      "type": "integer"
                    },
                    "credit": {
                      "type": "object",
                      "properties": {
                        "approuve": {
                          "type": "boolean"
                        },
                        "plafond_encours": {
                          "type": "null"
                        },
                        "demande": {
                          "type": "null"
                        },
                        "origine": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "approuve",
                        "plafond_encours",
                        "demande",
                        "origine"
                      ]
                    },
                    "pieces": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type_document": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "obligatoire": {
                                "type": "boolean"
                              },
                              "validite_mois": {
                                "type": "null"
                              },
                              "exigee_creation": {
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "obligatoire",
                              "validite_mois",
                              "exigee_creation"
                            ]
                          },
                          "document": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "type_document_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "motif": {
                                "type": "null"
                              },
                              "date_emission": {
                                "type": "null"
                              },
                              "date_expiration": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time"
                              },
                              "fichier": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "bucket": {
                                    "type": "string"
                                  },
                                  "chemin": {
                                    "type": "string"
                                  },
                                  "nom_original": {
                                    "type": "string"
                                  },
                                  "type_mime": {
                                    "type": "string"
                                  },
                                  "taille_octets": {
                                    "type": "integer"
                                  },
                                  "empreinte_sha256": {
                                    "type": "string"
                                  },
                                  "statut_scan": {
                                    "type": "string"
                                  },
                                  "depose_par": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "cree_le": {
                                    "type": "string",
                                    "format": "date-time"
                                  }
                                },
                                "required": [
                                  "id",
                                  "bucket",
                                  "chemin",
                                  "nom_original",
                                  "type_mime",
                                  "taille_octets",
                                  "empreinte_sha256",
                                  "statut_scan",
                                  "depose_par",
                                  "cree_le"
                                ]
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "type_document_id",
                              "statut",
                              "motif",
                              "date_emission",
                              "date_expiration",
                              "fichier",
                              "cree_le"
                            ]
                          },
                          "statut": {
                            "type": "string"
                          },
                          "jours_avant_expiration": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "type_document",
                          "document",
                          "statut",
                          "jours_avant_expiration"
                        ]
                      }
                    },
                    "documents_kyc": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type_document_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "fichier_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "date_emission": {
                            "type": "null"
                          },
                          "date_expiration": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "motif": {
                            "type": "null"
                          },
                          "verifie_par": {
                            "type": "null"
                          },
                          "verifie_le": {
                            "type": "null"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "type_document": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "cible": {
                                "type": "string"
                              },
                              "obligatoire": {
                                "type": "boolean"
                              },
                              "validite_mois": {
                                "type": "null"
                              },
                              "actif": {
                                "type": "boolean"
                              },
                              "exigee_creation": {
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "cible",
                              "obligatoire",
                              "validite_mois",
                              "actif",
                              "exigee_creation"
                            ]
                          },
                          "fichier": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "bucket": {
                                "type": "string"
                              },
                              "chemin": {
                                "type": "string"
                              },
                              "nom_original": {
                                "type": "string"
                              },
                              "type_mime": {
                                "type": "string"
                              },
                              "taille_octets": {
                                "type": "integer"
                              },
                              "empreinte_sha256": {
                                "type": "string"
                              },
                              "statut_scan": {
                                "type": "string"
                              },
                              "depose_par": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "bucket",
                              "chemin",
                              "nom_original",
                              "type_mime",
                              "taille_octets",
                              "empreinte_sha256",
                              "statut_scan",
                              "depose_par",
                              "cree_le"
                            ]
                          },
                          "titulaire": {
                            "type": "object",
                            "properties": {
                              "cible": {
                                "type": "string"
                              },
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "nom": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "cible",
                              "id",
                              "nom"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "organisation_id",
                          "type_document_id",
                          "fichier_id",
                          "date_emission",
                          "date_expiration",
                          "statut",
                          "motif",
                          "verifie_par",
                          "verifie_le",
                          "cree_le",
                          "modifie_le",
                          "type_document",
                          "fichier",
                          "titulaire"
                        ]
                      }
                    },
                    "acces_contact": {
                      "type": "object",
                      "properties": {
                        "email": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "email",
                        "statut"
                      ]
                    },
                    "historique": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "objet_type": {
                            "type": "string"
                          },
                          "objet_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "statut_avant": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "statut_apres": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "fichier_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "action_id": {
                            "type": "null"
                          },
                          "utilisateur_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "objet_type",
                          "objet_id",
                          "type",
                          "message",
                          "statut_avant",
                          "statut_apres",
                          "fichier_id",
                          "action_id",
                          "utilisateur_id",
                          "cree_le",
                          "utilisateur"
                        ]
                      }
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "raison_sociale",
                    "forme_juridique",
                    "rccm",
                    "ncc",
                    "secteur_id",
                    "adresse_facturation",
                    "ville",
                    "zone_id",
                    "telephone",
                    "email",
                    "origine",
                    "statut",
                    "statut_kyc",
                    "partenaire_actuel_id",
                    "credit_approuve",
                    "plafond_encours",
                    "credit_approuve_par",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "logo_fichier_id",
                    "mode_paiement_souhaite",
                    "sites",
                    "reservations",
                    "affectations",
                    "contrats",
                    "commandes",
                    "factures",
                    "devis",
                    "opportunites",
                    "peut_creer_devis",
                    "peut_demander_reservation",
                    "motif_reservation_impossible",
                    "logo_adresse",
                    "partenaire_actuel",
                    "zone",
                    "secteur",
                    "contact_principal",
                    "nb_sites",
                    "contacts",
                    "reste_a_payer_total",
                    "contrats_actifs",
                    "credit",
                    "pieces",
                    "documents_kyc",
                    "acces_contact",
                    "historique"
                  ]
                },
                "example": {
                  "id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                  "organisation_id": "7ecefe01-06fd-407d-8a43-3e04b7e5199d",
                  "raison_sociale": "ZZ Recette Client 54587534",
                  "forme_juridique": null,
                  "rccm": "CI-ZZC-54587534",
                  "ncc": "NCC-ZZC-54587534",
                  "secteur_id": null,
                  "adresse_facturation": null,
                  "ville": "Abidjan",
                  "zone_id": null,
                  "telephone": null,
                  "email": "contact.54587534@exemple.invalide",
                  "origine": "partenaire",
                  "statut": "reserve",
                  "statut_kyc": "en_verification",
                  "partenaire_actuel_id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                  "credit_approuve": false,
                  "plafond_encours": null,
                  "credit_approuve_par": null,
                  "cree_par": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                  "cree_le": "2026-10-19T10:44:16.127Z",
                  "modifie_le": "2026-10-19T10:44:16.306Z",
                  "logo_fichier_id": null,
                  "mode_paiement_souhaite": null,
                  "sites": [
                    {
                      "id": "83b0497e-9931-4957-a633-225afa68ab61",
                      "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                      "libelle": "Site 54587534",
                      "adresse": null,
                      "ville": "Abidjan",
                      "zone_id": null,
                      "latitude": null,
                      "longitude": null,
                      "contact_id": "ca08621c-d247-45e5-91dc-5abe247d7338",
                      "statut": "a_qualifier",
                      "cree_le": "2026-10-19T10:44:16.136Z",
                      "modifie_le": "2026-10-19T10:44:16.136Z",
                      "zone": null,
                      "contact": {
                        "id": "ca08621c-d247-45e5-91dc-5abe247d7338",
                        "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                        "prenom": "ZZ Recette",
                        "nom": "Contact 54587534",
                        "fonction": null,
                        "email": "contact.54587534@exemple.invalide",
                        "telephone": "+225 07 00 00 00 00",
                        "principal": true,
                        "cree_le": "2026-10-19T10:44:16.133Z",
                        "modifie_le": "2026-10-19T10:44:16.133Z"
                      }
                    }
                  ],
                  "reservations": [
                    {
                      "id": "95316f2f-30f5-4e98-8613-8cf8c7a9e5b5",
                      "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                      "partenaire_id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                      "demandee_par": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                      "statut": "validee",
                      "doublons_detectes": [
                        {
                          "niveau": "alerte",
                          "criteres": [
                            "raison_sociale_proche",
                            "telephone_identique"
                          ],
                          "client_id": "a0e7b70a-3e2d-4281-bfe1-b5e6b7fa501d",
                          "similarite": 0.76,
                          "raison_sociale": "ZZ Recette Client 585738DF"
                        },
                        {
                          "niveau": "alerte",
                          "criteres": [
                            "raison_sociale_proche",
                            "telephone_identique"
                          ],
                          "client_id": "4b4b7b6b-aae0-4c67-88c1-1f8f34abadc0",
                          "similarite": 0.72,
                          "raison_sociale": "ZZ Recette Client F31EF585"
                        }
                      ],
                      "motif_decision": "Fixture de recette.",
                      "traitee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "traitee_le": "2026-10-19T10:44:16.306Z",
                      "cree_le": "2026-10-19T10:44:16.139Z",
                      "modifie_le": "2026-10-19T10:44:16.306Z",
                      "client": {
                        "id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                        "raison_sociale": "ZZ Recette Client 54587534",
                        "statut": "reserve"
                      },
                      "partenaire": {
                        "id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                        "raison_sociale": "ZZ Recette Partenaire W 8E10C2F1",
                        "statut": "actif",
                        "ville": "Abidjan",
                        "code_confidentiel": "C-0070"
                      },
                      "demandeur": {
                        "id": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire W 8E10C2F1",
                        "email": "zz.recette.8e10c2f1@exemple.invalide"
                      },
                      "traitee_par_utilisateur": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction",
                        "email": "admin.cybastion@preprod.satelica.test"
                      }
                    }
                  ],
                  "affectations": [
                    {
                      "id": "4af70557-8a90-4eb9-bfd5-7ccb8d014911",
                      "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                      "partenaire_id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                      "origine": "reservation",
                      "debut_le": "2026-10-19T10:44:16.310Z",
                      "fin_le": null,
                      "active": true,
                      "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "cree_le": "2026-10-19T10:44:16.312Z",
                      "partenaire": {
                        "id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                        "raison_sociale": "ZZ Recette Partenaire W 8E10C2F1",
                        "statut": "actif",
                        "ville": "Abidjan",
                        "code_confidentiel": "C-0070"
                      }
                    }
                  ],
                  "contrats": [],
                  "commandes": [],
                  "factures": [],
                  "devis": [],
                  "opportunites": [],
                  "peut_creer_devis": false,
                  "peut_demander_reservation": false,
                  "motif_reservation_impossible": null,
                  "logo_adresse": null,
                  "partenaire_actuel": {
                    "id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                    "raison_sociale": "ZZ Recette Partenaire W 8E10C2F1",
                    "statut": "actif",
                    "ville": "Abidjan",
                    "code_confidentiel": "C-0070"
                  },
                  "zone": null,
                  "secteur": null,
                  "contact_principal": {
                    "id": "ca08621c-d247-45e5-91dc-5abe247d7338",
                    "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                    "prenom": "ZZ Recette",
                    "nom": "Contact 54587534",
                    "fonction": null,
                    "email": "contact.54587534@exemple.invalide",
                    "telephone": "+225 07 00 00 00 00",
                    "principal": true,
                    "cree_le": "2026-10-19T10:44:16.133Z",
                    "modifie_le": "2026-10-19T10:44:16.133Z"
                  },
                  "nb_sites": 1,
                  "contacts": [
                    {
                      "id": "ca08621c-d247-45e5-91dc-5abe247d7338",
                      "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                      "prenom": "ZZ Recette",
                      "nom": "Contact 54587534",
                      "fonction": null,
                      "email": "contact.54587534@exemple.invalide",
                      "telephone": "+225 07 00 00 00 00",
                      "principal": true,
                      "cree_le": "2026-10-19T10:44:16.133Z",
                      "modifie_le": "2026-10-19T10:44:16.133Z"
                    }
                  ],
                  "reste_a_payer_total": 0,
                  "contrats_actifs": 0,
                  "credit": {
                    "approuve": false,
                    "plafond_encours": null,
                    "demande": null,
                    "origine": null
                  },
                  "pieces": [
                    {
                      "type_document": {
                        "id": "65112411-529e-4bcd-908a-c87e88a601c8",
                        "code": "client_identifiant_fiscal",
                        "libelle": "Identifiant fiscal (NCC)",
                        "obligatoire": true,
                        "validite_mois": null,
                        "exigee_creation": false
                      },
                      "document": null,
                      "statut": "manquant",
                      "jours_avant_expiration": null
                    },
                    {
                      "type_document": {
                        "id": "bc37176b-726f-4a1a-9d83-06ff5c09eaa2",
                        "code": "client_pouvoir",
                        "libelle": "Pouvoir du signataire",
                        "obligatoire": false,
                        "validite_mois": null,
                        "exigee_creation": false
                      },
                      "document": null,
                      "statut": "manquant",
                      "jours_avant_expiration": null
                    }
                  ],
                  "documents_kyc": [
                    {
                      "id": "a5c46600-47bb-4d1e-8af6-d982bad73e16",
                      "organisation_id": "7ecefe01-06fd-407d-8a43-3e04b7e5199d",
                      "type_document_id": "5aeb6ee0-19e8-4ba1-977a-c2c9e532979c",
                      "fichier_id": "85e541dc-fe31-4889-9a6f-626fcc666dc0",
                      "date_emission": null,
                      "date_expiration": null,
                      "statut": "depose",
                      "motif": null,
                      "verifie_par": null,
                      "verifie_le": null,
                      "cree_le": "2026-10-19T10:44:16.167Z",
                      "modifie_le": "2026-10-19T10:44:16.167Z",
                      "type_document": {
                        "id": "5aeb6ee0-19e8-4ba1-977a-c2c9e532979c",
                        "code": "client_rccm",
                        "libelle": "Registre du commerce (RCCM)",
                        "cible": "client",
                        "obligatoire": true,
                        "validite_mois": null,
                        "actif": true,
                        "exigee_creation": true
                      },
                      "fichier": {
                        "id": "85e541dc-fe31-4889-9a6f-626fcc666dc0",
                        "bucket": "kyc",
                        "chemin": "kyc/2026/10/7bd805fe-b2c7-4779-9469-ce2da5b8a50f.pdf",
                        "nom_original": "client_rccm-54587534.pdf",
                        "type_mime": "application/pdf",
                        "taille_octets": 214,
                        "empreinte_sha256": "dff592acf1a195575ea1ade58f07cced84520e4968ee22d544ced5587f6d569c",
                        "statut_scan": "sain",
                        "depose_par": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                        "cree_le": "2026-10-19T10:44:15.991Z"
                      },
                      "titulaire": {
                        "cible": "client",
                        "id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                        "nom": "ZZ Recette Client 54587534"
                      }
                    },
                    {
                      "id": "ed16e112-dac1-4854-9c07-97ebf8fb1b76",
                      "organisation_id": "7ecefe01-06fd-407d-8a43-3e04b7e5199d",
                      "type_document_id": "c22f7087-1e0c-47bc-bab0-b2b791114ef5",
                      "fichier_id": "6649a7d7-a153-4911-ba5d-ee8feefeeb6a",
                      "date_emission": null,
                      "date_expiration": null,
                      "statut": "depose",
                      "motif": null,
                      "verifie_par": null,
                      "verifie_le": null,
                      "cree_le": "2026-10-19T10:44:16.162Z",
                      "modifie_le": "2026-10-19T10:44:16.162Z",
                      "type_document": {
                        "id": "c22f7087-1e0c-47bc-bab0-b2b791114ef5",
                        "code": "client_piece_identite_verso",
                        "libelle": "Pièce d'identité du signataire — verso",
                        "cible": "client",
                        "obligatoire": true,
                        "validite_mois": null,
                        "actif": true,
                        "exigee_creation": true
                      },
                      "fichier": {
                        "id": "6649a7d7-a153-4911-ba5d-ee8feefeeb6a",
                        "bucket": "kyc",
                        "chemin": "kyc/2026/10/bcc8a58c-b93a-473e-b4ef-dd35190f964d.pdf",
                        "nom_original": "client_piece_identite_verso-54587534.pdf",
                        "type_mime": "application/pdf",
                        "taille_octets": 230,
                        "empreinte_sha256": "5750aca32a41df5b728da1bae9bb1356953f69399ff20674acfae5e922fedcd6",
                        "statut_scan": "sain",
                        "depose_par": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                        "cree_le": "2026-10-19T10:44:15.826Z"
                      },
                      "titulaire": {
                        "cible": "client",
                        "id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                        "nom": "ZZ Recette Client 54587534"
                      }
                    }
                  ],
                  "acces_contact": {
                    "email": "contact.54587534@exemple.invalide",
                    "statut": "jamais_connecte"
                  },
                  "historique": [
                    {
                      "id": "fac246d1-7af8-4b6d-9497-fe8e8872065d",
                      "objet_type": "clients",
                      "objet_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                      "type": "changement_statut",
                      "message": "Client rattaché à ZZ Recette Partenaire W 8E10C2F1",
                      "statut_avant": "reservation_demandee",
                      "statut_apres": "reserve",
                      "fichier_id": null,
                      "action_id": null,
                      "utilisateur_id": "86ce3683-763a-4644-9b69-5412f153968f",
                      "cree_le": "2026-10-19T10:44:16.317Z",
                      "utilisateur": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction",
                        "email": "admin.cybastion@preprod.satelica.test"
                      }
                    },
                    {
                      "id": "8501dbac-f824-4ff7-a709-41fec62b141b",
                      "objet_type": "clients",
                      "objet_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                      "type": "note",
                      "message": "Client enregistré par ZZ Recette Partenaire W 8E10C2F1",
                      "statut_avant": null,
                      "statut_apres": "reservation_demandee",
                      "fichier_id": null,
                      "action_id": null,
                      "utilisateur_id": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                      "cree_le": "2026-10-19T10:44:16.143Z",
                      "utilisateur": {
                        "id": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire W 8E10C2F1",
                        "email": "zz.recette.8e10c2f1@exemple.invalide"
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "clients.consulter",
          "besoins.exprimer",
          "devis.accepter",
          "pv.valider"
        ],
        "x-satelica-cloisonnement": "applique"
      },
      "patch": {
        "operationId": "patchClientsParId",
        "tags": [
          "Clients"
        ],
        "summary": "Corriger la fiche d'un client",
        "description": "Modifie l'identité et les coordonnées du client : seuls les champs renseignés changent, un champ absent ou `null` est laissé tel quel. Le statut, le partenaire, le crédit et la conformité ne se modifient pas ici. Refusé si le RCCM ou le NCC est déjà celui d'un autre client ; une nouvelle raison sociale renomme aussi l'organisation. Passer `mode_paiement_souhaite` à `postpaye` ouvre une demande de crédit et prévient la Finance.\n\n**Permission requise** : `clients.creer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "raison_sociale": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 200
                  },
                  "logo_fichier_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "forme_juridique": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "rccm": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ncc": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "secteur_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "adresse_facturation": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 400
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ville": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "zone_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "telephone": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "email": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 200,
                        "format": "email",
                        "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "mode_paiement_souhaite": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "prepaye",
                          "postpaye"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              },
              "example": {
                "ville": "Bouaké",
                "adresse_facturation": "Quartier Commerce, Bouaké",
                "mode_paiement_souhaite": "postpaye"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "forme_juridique": {
                      "type": "null"
                    },
                    "rccm": {
                      "type": "string"
                    },
                    "ncc": {
                      "type": "string"
                    },
                    "secteur_id": {
                      "type": "null"
                    },
                    "adresse_facturation": {
                      "type": "string"
                    },
                    "ville": {
                      "type": "string"
                    },
                    "zone_id": {
                      "type": "null"
                    },
                    "telephone": {
                      "type": "null"
                    },
                    "email": {
                      "type": "string"
                    },
                    "mode_paiement_souhaite": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "raison_sociale",
                    "forme_juridique",
                    "rccm",
                    "ncc",
                    "secteur_id",
                    "adresse_facturation",
                    "ville",
                    "zone_id",
                    "telephone",
                    "email",
                    "mode_paiement_souhaite",
                    "statut",
                    "modifie_le"
                  ]
                },
                "example": {
                  "id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                  "raison_sociale": "ZZ Recette Client 62AAEFDF",
                  "forme_juridique": null,
                  "rccm": "CI-ZZC-62AAEFDF",
                  "ncc": "NCC-ZZC-62AAEFDF",
                  "secteur_id": null,
                  "adresse_facturation": "Quartier Commerce, Bouaké",
                  "ville": "Bouaké",
                  "zone_id": null,
                  "telephone": null,
                  "email": "contact.62aaefdf@exemple.invalide",
                  "mode_paiement_souhaite": "postpaye",
                  "statut": "reserve",
                  "modifie_le": "2026-10-19T10:44:57.074Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Ce RCCM ou ce NCC est déjà celui d'un autre client.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.creer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/clients/controle-doublon": {
      "post": {
        "operationId": "postClientsControleDoublon",
        "tags": [
          "Clients"
        ],
        "summary": "Contrôler les doublons avant de créer un client",
        "description": "Compare la saisie à tous les clients connus, quel que soit leur partenaire, et rend `aucun`, `doublon_potentiel` (raison sociale proche, téléphone ou e-mail identique) ou `bloquant` (RCCM ou NCC identique). Un partenaire ne reçoit que le niveau, les critères et la similarité de chaque correspondance, jamais le client en cause ; CYBASTION reçoit le rapport complet. N'écrit rien.\n\n**Permission requise** : `clients.creer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "raison_sociale": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "rccm": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ncc": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "telephone": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "email": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 200,
                        "format": "email",
                        "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "contact_telephone": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "contact_email": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 200,
                        "format": "email",
                        "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              },
              "example": {
                "raison_sociale": "ZZ Recette WNCYUQRHJW",
                "rccm": "CI-ZZ-WNCYUQRHJW"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "resultat": {
                      "type": "string"
                    },
                    "correspondances": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "niveau": {
                            "type": "string"
                          },
                          "criteres": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "similarite": {
                            "type": "null"
                          }
                        },
                        "required": [
                          "niveau",
                          "criteres",
                          "similarite"
                        ]
                      }
                    }
                  },
                  "required": [
                    "resultat",
                    "correspondances"
                  ]
                },
                "example": {
                  "resultat": "aucun",
                  "correspondances": []
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.creer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/clients": {
      "post": {
        "operationId": "postClients",
        "tags": [
          "Clients"
        ],
        "summary": "Créer un client",
        "description": "Crée en une transaction l'organisation, la fiche client, son contact principal, son premier site, une réservation pour le partenaire et les pièces jointes (le dossier passe alors en vérification). Un partenaire validé ou actif enregistre pour lui-même et doit joindre les pièces exigées à la création ; CYBASTION désigne `partenaire_id`, pièces facultatives. La réservation naît `conflit` si un doublon est signalé, `validee` si CYBASTION enregistre ou si le paramètre `reservation.validation_obligatoire` est levé (client `reserve`, accès envoyé au contact principal), `demandee` sinon. Refusé si le RCCM ou le NCC est déjà enregistré ; un souhait `postpaye` ouvre une demande de crédit et prévient la Finance.\n\n**Permission requise** : `clients.creer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "entreprise": {
                    "type": "object",
                    "properties": {
                      "raison_sociale": {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 200
                      },
                      "logo_fichier_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "forme_juridique": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "rccm": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "ncc": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "secteur_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "adresse_facturation": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 400
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "ville": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "zone_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "telephone": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "email": {
                        "anyOf": [
                          {
                            "type": "string",
                            "maxLength": 200,
                            "format": "email",
                            "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "raison_sociale"
                    ]
                  },
                  "contact": {
                    "type": "object",
                    "properties": {
                      "prenom": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "nom": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      "fonction": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "email": {
                        "anyOf": [
                          {
                            "type": "string",
                            "maxLength": 200,
                            "format": "email",
                            "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "telephone": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "prenom",
                      "nom"
                    ]
                  },
                  "site": {
                    "type": "object",
                    "properties": {
                      "libelle": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      "adresse": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 400
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "ville": {
                        "anyOf": [
                          {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "zone_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "latitude": {
                        "anyOf": [
                          {
                            "type": "number",
                            "minimum": -90,
                            "maximum": 90
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "longitude": {
                        "anyOf": [
                          {
                            "type": "number",
                            "minimum": -180,
                            "maximum": 180
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "libelle"
                    ]
                  },
                  "pieces": {
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "type_document_id": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        "fichier_id": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        "date_emission": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "date_expiration": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "type_document_id",
                        "fichier_id"
                      ]
                    }
                  },
                  "partenaire_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "mode_paiement_souhaite": {
                    "anyOf": [
                      {
                        "type": "string",
                        "enum": [
                          "prepaye",
                          "postpaye"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "entreprise",
                  "contact",
                  "site"
                ]
              },
              "example": {
                "pieces": [
                  {
                    "type_document_id": "17913663-439c-4d1a-a4f6-18a86763cd33",
                    "fichier_id": "356b47bd-dd4a-4694-9064-918073156cc6"
                  },
                  {
                    "type_document_id": "2671959b-8969-4ffd-83f8-2df0139ee3e4",
                    "fichier_id": "22e29dc8-b63f-4043-968c-b4bd67e55e89"
                  }
                ],
                "entreprise": {
                  "raison_sociale": "ZZ Recette Client 54587534",
                  "rccm": "CI-ZZC-54587534",
                  "ncc": "NCC-ZZC-54587534",
                  "ville": "Abidjan",
                  "email": "contact.54587534@exemple.invalide"
                },
                "contact": {
                  "prenom": "ZZ Recette",
                  "nom": "Contact 54587534",
                  "email": "contact.54587534@exemple.invalide",
                  "telephone": "+2250700000000"
                },
                "site": {
                  "libelle": "Site 54587534",
                  "ville": "Abidjan"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 8 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contact_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "reservation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut_reservation": {
                      "type": "string"
                    },
                    "doublon": {
                      "type": "string"
                    },
                    "acces": {
                      "type": "object",
                      "properties": {
                        "statut": {
                          "type": "string"
                        },
                        "email": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "utilisateur_id": {
                          "type": "null"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "statut",
                        "email",
                        "utilisateur_id",
                        "message"
                      ]
                    },
                    "pieces": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "type_document": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "statut",
                          "type_document"
                        ]
                      }
                    }
                  },
                  "required": [
                    "client_id",
                    "contact_id",
                    "site_id",
                    "reservation_id",
                    "statut_reservation",
                    "doublon",
                    "acces",
                    "pieces"
                  ]
                },
                "example": {
                  "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                  "contact_id": "ca08621c-d247-45e5-91dc-5abe247d7338",
                  "site_id": "83b0497e-9931-4957-a633-225afa68ab61",
                  "reservation_id": "95316f2f-30f5-4e98-8613-8cf8c7a9e5b5",
                  "statut_reservation": "conflit",
                  "doublon": "doublon_potentiel",
                  "acces": {
                    "statut": "en_attente",
                    "email": "contact.54587534@exemple.invalide",
                    "utilisateur_id": null,
                    "message": "L’accès du client partira à contact.54587534@exemple.invalide dès que CYBASTION aura validé la réservation."
                  },
                  "pieces": [
                    {
                      "id": "307efed9-eb77-4d73-a619-4617cef000b2",
                      "statut": "depose",
                      "type_document": {
                        "id": "17913663-439c-4d1a-a4f6-18a86763cd33",
                        "code": "client_photo",
                        "libelle": "Photo du client"
                      }
                    },
                    {
                      "id": "3dd10523-0c78-4c19-8453-a86aa6274489",
                      "statut": "depose",
                      "type_document": {
                        "id": "2671959b-8969-4ffd-83f8-2df0139ee3e4",
                        "code": "client_piece_identite",
                        "libelle": "Pièce d'identité du signataire — recto"
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "RCCM ou NCC déjà enregistré, ou partenaire suspendu ou non validé.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.creer",
        "x-satelica-cloisonnement": "applique"
      },
      "get": {
        "operationId": "getClients",
        "tags": [
          "Clients"
        ],
        "summary": "Lister les clients",
        "description": "Les clients, par raison sociale, avec partenaire actuel, zone, secteur, contact principal, nombre de sites, adresse du logo et la plus ancienne réservation en attente (hors CYBASTION, seulement celle de l'appelant). Filtres : statut (plusieurs valeurs, répétées ou séparées par des virgules), partenaire, zone, `sans_partenaire` (ni partenaire ni réservation en attente) et recherche sur la raison sociale, le RCCM, le NCC ou l'e-mail.\n\n**Permission requise** : `clients.consulter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "partenaire_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "zone_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "sans_partenaire",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "recherche",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 120
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 10 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "raison_sociale": {
                            "type": "string"
                          },
                          "forme_juridique": {
                            "type": "null"
                          },
                          "rccm": {
                            "type": "string"
                          },
                          "ncc": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "secteur_id": {
                            "type": "null"
                          },
                          "adresse_facturation": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "ville": {
                            "type": "string"
                          },
                          "zone_id": {
                            "type": "null"
                          },
                          "telephone": {
                            "type": "null"
                          },
                          "email": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "origine": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "statut_kyc": {
                            "type": "string"
                          },
                          "partenaire_actuel_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "credit_approuve": {
                            "type": "boolean"
                          },
                          "plafond_encours": {
                            "type": "null"
                          },
                          "credit_approuve_par": {
                            "type": "null"
                          },
                          "cree_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "logo_fichier_id": {
                            "type": "null"
                          },
                          "mode_paiement_souhaite": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "logo_adresse": {
                            "type": "null"
                          },
                          "partenaire_actuel": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "ville",
                              "code_confidentiel"
                            ]
                          },
                          "zone": {
                            "type": "null"
                          },
                          "secteur": {
                            "type": "null"
                          },
                          "contact_principal": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "client_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "fonction": {
                                "type": "null"
                              },
                              "email": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "telephone": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "principal": {
                                "type": "boolean"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "client_id",
                              "prenom",
                              "nom",
                              "fonction",
                              "email",
                              "telephone",
                              "principal",
                              "cree_le",
                              "modifie_le"
                            ]
                          },
                          "nb_sites": {
                            "type": "integer"
                          },
                          "reservation_en_attente": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "partenaire": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "raison_sociale": {
                                    "type": "string"
                                  },
                                  "statut": {
                                    "type": "string"
                                  },
                                  "ville": {
                                    "type": "string"
                                  },
                                  "code_confidentiel": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "raison_sociale",
                                  "statut",
                                  "ville",
                                  "code_confidentiel"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "statut",
                              "cree_le",
                              "partenaire"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "organisation_id",
                          "raison_sociale",
                          "forme_juridique",
                          "rccm",
                          "ncc",
                          "secteur_id",
                          "adresse_facturation",
                          "ville",
                          "zone_id",
                          "telephone",
                          "email",
                          "origine",
                          "statut",
                          "statut_kyc",
                          "partenaire_actuel_id",
                          "credit_approuve",
                          "plafond_encours",
                          "credit_approuve_par",
                          "cree_par",
                          "cree_le",
                          "modifie_le",
                          "logo_fichier_id",
                          "mode_paiement_souhaite",
                          "logo_adresse",
                          "partenaire_actuel",
                          "zone",
                          "secteur",
                          "contact_principal",
                          "nb_sites",
                          "reservation_en_attente"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                      "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc",
                      "raison_sociale": "ZZ Recette WNCYUQRHJW",
                      "forme_juridique": null,
                      "rccm": "CI-ZZ-WNCYUQRHJW",
                      "ncc": null,
                      "secteur_id": null,
                      "adresse_facturation": null,
                      "ville": "Abidjan",
                      "zone_id": null,
                      "telephone": null,
                      "email": "contact.wncyuqrhjw@recette.satelica.test",
                      "origine": "partenaire",
                      "statut": "reserve",
                      "statut_kyc": "en_verification",
                      "partenaire_actuel_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                      "credit_approuve": false,
                      "plafond_encours": null,
                      "credit_approuve_par": null,
                      "cree_par": "d60b33fd-8d32-4475-a107-5d4bd82d6f3f",
                      "cree_le": "2026-10-19T10:44:26.180Z",
                      "modifie_le": "2026-10-19T10:44:27.244Z",
                      "logo_fichier_id": null,
                      "mode_paiement_souhaite": null,
                      "logo_adresse": null,
                      "partenaire_actuel": {
                        "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                        "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                        "statut": "actif",
                        "ville": "Abidjan",
                        "code_confidentiel": "C-0071"
                      },
                      "zone": null,
                      "secteur": null,
                      "contact_principal": {
                        "id": "b21e4065-665c-40c9-9e58-b4d7a5a47a4d",
                        "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                        "prenom": "Awa",
                        "nom": "Koné",
                        "fonction": null,
                        "email": null,
                        "telephone": null,
                        "principal": true,
                        "cree_le": "2026-10-19T10:44:26.183Z",
                        "modifie_le": "2026-10-19T10:44:26.183Z"
                      },
                      "nb_sites": 1,
                      "reservation_en_attente": null
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 1,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.consulter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/clients/{id}/acces": {
      "post": {
        "operationId": "postClientsParIdAcces",
        "tags": [
          "Clients"
        ],
        "summary": "Envoyer son accès au contact principal d'un client",
        "description": "Ouvre un compte `client_validateur` au contact principal et lui envoie la bienvenue, ou la lui renvoie si son compte n'a jamais servi. Le client doit être rattaché à un partenaire (réservation validée) ; hors CYBASTION, seul le partenaire qui le détient peut l'appeler. Refusé si le contact n'a pas d'adresse e-mail, si elle appartient à un autre compte, si le compte est suspendu ou s'il s'est déjà connecté (il demande alors lui-même un nouveau mot de passe).\n\n**Permission requise** : L'une de : `clients.creer`, `utilisateurs.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statut": {
                      "type": "string"
                    },
                    "email": {
                      "type": "string"
                    },
                    "utilisateur_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "statut",
                    "email",
                    "utilisateur_id",
                    "message"
                  ]
                },
                "example": {
                  "statut": "envoye",
                  "email": "contact.62aaefdf@exemple.invalide",
                  "utilisateur_id": "db835906-ff07-402c-9249-0f079564129c",
                  "message": "Accès renvoyé à contact.62aaefdf@exemple.invalide : un courriel l’invite à choisir son mot de passe."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Réservation non validée, contact sans e-mail, compte déjà utilisé ou envoi échoué.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "clients.creer",
          "utilisateurs.gerer"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/clients/{id}/sites": {
      "post": {
        "operationId": "postClientsParIdSites",
        "tags": [
          "Clients"
        ],
        "summary": "Ajouter un site à un client",
        "description": "Crée un site au statut `a_qualifier` ; la ville et la zone non données reprennent celles du client, et la latitude et la longitude se donnent ensemble ou pas du tout. L'ajout est tracé sur la fiche du client et inscrit au journal d'audit.\n\n**Permission requise** : `clients.creer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "libelle": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "adresse": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 400
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ville": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "zone_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "latitude": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "longitude": {
                    "anyOf": [
                      {
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "libelle"
                ]
              },
              "example": {
                "libelle": "ZZ Recette Site Cocody 1792406757564",
                "ville": "Abidjan",
                "zone_id": "4eb92397-15f6-4d22-afdc-0a65f3b80ef3"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "libelle": {
                      "type": "string"
                    },
                    "adresse": {
                      "type": "null"
                    },
                    "ville": {
                      "type": "string"
                    },
                    "zone_id": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "latitude": {
                      "type": "null"
                    },
                    "longitude": {
                      "type": "null"
                    },
                    "contact_id": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "client_id",
                    "libelle",
                    "adresse",
                    "ville",
                    "zone_id",
                    "latitude",
                    "longitude",
                    "contact_id",
                    "statut",
                    "cree_le",
                    "modifie_le"
                  ]
                },
                "example": {
                  "id": "a0a74ce9-69ee-4ebb-92cc-e6f154950340",
                  "client_id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                  "libelle": "Entrepôt secondaire",
                  "adresse": null,
                  "ville": "Bouaké",
                  "zone_id": null,
                  "latitude": null,
                  "longitude": null,
                  "contact_id": null,
                  "statut": "a_qualifier",
                  "cree_le": "2026-10-19T10:44:57.571Z",
                  "modifie_le": "2026-10-19T10:44:57.571Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.creer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/sites/{id}": {
      "delete": {
        "operationId": "deleteSitesParId",
        "tags": [
          "Clients"
        ],
        "summary": "Supprimer un site qui n'a jamais servi",
        "description": "Refusé dès que le site est rattaché à un contrat, une commande, un ordre d'installation, une connexion, une activation, un équipement, un devis ou un besoin. La suppression est tracée sur la fiche du client et inscrite au journal d'audit.\n\n**Permission requise** : `clients.creer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    },
                    "libelle": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "supprime",
                    "libelle"
                  ]
                },
                "example": {
                  "supprime": true,
                  "libelle": "Entrepôt secondaire"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Le site sert déjà (contrat, commande, ordre, devis…).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.creer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/contacts/{id}": {
      "delete": {
        "operationId": "deleteContactsParId",
        "tags": [
          "Clients"
        ],
        "summary": "Supprimer un contact d'un client",
        "description": "Refusé pour le dernier contact du client et pour un contact désigné comme interlocuteur d'un site. Si le contact supprimé était le principal, le plus ancien contact restant le devient. La suppression est inscrite au journal d'audit.\n\n**Permission requise** : `clients.creer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "supprime"
                  ]
                },
                "example": {
                  "supprime": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Dernier contact du client, ou interlocuteur d'un site.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.creer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/reservations": {
      "post": {
        "operationId": "postReservations",
        "tags": [
          "Clients"
        ],
        "summary": "Demander la réservation d'un client existant",
        "description": "Un partenaire validé ou actif demande à prendre un client connu qui n'a pas de partenaire : la réservation naît `demandee` et le client passe `reservation_demandee`, en attente de la décision de CYBASTION. Refusé si le client est déjà dans son portefeuille, suivi par un autre partenaire (sans le nommer), ou si une demande du même partenaire est en cours. Refusé à tout appelant qui n'est pas un partenaire.\n\n**Permission requise** : `clients.reservation_demander`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "motif": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "client_id"
                ]
              },
              "example": {
                "client_id": "f241c4d4-a8c6-4cf2-8cc5-be0012dcdcb6",
                "motif": "Client voisin de nos sites."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "demandee_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "doublons_detectes": {
                      "type": "null"
                    },
                    "motif_decision": {
                      "type": "null"
                    },
                    "traitee_par": {
                      "type": "null"
                    },
                    "traitee_le": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "client_id",
                    "partenaire_id",
                    "demandee_par",
                    "statut",
                    "doublons_detectes",
                    "motif_decision",
                    "traitee_par",
                    "traitee_le",
                    "cree_le",
                    "modifie_le"
                  ]
                },
                "example": {
                  "id": "88c331c1-9b9d-4a92-a740-8f8d876d20a0",
                  "client_id": "f241c4d4-a8c6-4cf2-8cc5-be0012dcdcb6",
                  "partenaire_id": "bacf2aec-2059-465e-ae6f-c83ad2e94600",
                  "demandee_par": "0fac7ff7-a5af-4a7d-a0f3-bd4b974bdca4",
                  "statut": "demandee",
                  "doublons_detectes": null,
                  "motif_decision": null,
                  "traitee_par": null,
                  "traitee_le": null,
                  "cree_le": "2026-10-19T10:45:15.216Z",
                  "modifie_le": "2026-10-19T10:45:15.216Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Client déjà suivi, demande déjà en cours, ou partenaire non validé.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.reservation_demander",
        "x-satelica-cloisonnement": "applique"
      },
      "get": {
        "operationId": "getReservations",
        "tags": [
          "Clients"
        ],
        "summary": "Lister les réservations",
        "description": "Les réservations, de la plus récente à la plus ancienne, avec le client, le partenaire, le demandeur et l'auteur de la décision. Filtres : statut (plusieurs valeurs, répétées ou séparées par des virgules), client et partenaire. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : `clients.consulter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "partenaire_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                {
                  "type": "null"
                }
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "demandee_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "doublons_detectes": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "items": {
                              "type": "object",
                              "properties": {
                                "niveau": {
                                  "type": "string"
                                },
                                "criteres": {
                                  "type": "array",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "client_id": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "similarite": {
                                  "type": [
                                    "number",
                                    "null"
                                  ]
                                },
                                "raison_sociale": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "niveau",
                                "criteres",
                                "client_id",
                                "similarite",
                                "raison_sociale"
                              ]
                            }
                          },
                          "motif_decision": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "traitee_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "traitee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut"
                            ]
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "ville",
                              "code_confidentiel"
                            ]
                          },
                          "demandeur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "traitee_par_utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "client_id",
                          "partenaire_id",
                          "demandee_par",
                          "statut",
                          "doublons_detectes",
                          "motif_decision",
                          "traitee_par",
                          "traitee_le",
                          "cree_le",
                          "modifie_le",
                          "client",
                          "partenaire",
                          "demandeur",
                          "traitee_par_utilisateur"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "65d3481d-591e-4e89-93cb-dc9b41c8690f",
                      "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                      "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                      "demandee_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                      "statut": "validee",
                      "doublons_detectes": [
                        {
                          "niveau": "alerte",
                          "criteres": [
                            "raison_sociale_proche",
                            "telephone_identique"
                          ],
                          "client_id": "41568bd5-57d9-4de6-9d9a-5d27eaf3868a",
                          "similarite": 0.72,
                          "raison_sociale": "ZZ Recette Client 2EEAF409"
                        },
                        {
                          "niveau": "alerte",
                          "criteres": [
                            "telephone_identique"
                          ],
                          "client_id": "f474c650-a619-43f4-884f-c1a3bac3bd3b",
                          "similarite": null,
                          "raison_sociale": "ZZ Recette Client 9C7FAFC2"
                        }
                      ],
                      "motif_decision": "Fixture de recette.",
                      "traitee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "traitee_le": "2026-10-19T10:45:40.529Z",
                      "cree_le": "2026-10-19T10:45:40.372Z",
                      "modifie_le": "2026-10-19T10:45:40.528Z",
                      "client": {
                        "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                        "raison_sociale": "ZZ Recette Client 4D20EED1",
                        "statut": "reserve"
                      },
                      "partenaire": {
                        "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                        "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                        "statut": "actif",
                        "ville": "Abidjan",
                        "code_confidentiel": "C-0076"
                      },
                      "demandeur": {
                        "id": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A 856174D4",
                        "email": "zz.recette.856174d4@exemple.invalide"
                      },
                      "traitee_par_utilisateur": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction",
                        "email": "admin.cybastion@preprod.satelica.test"
                      }
                    },
                    {
                      "id": "88c331c1-9b9d-4a92-a740-8f8d876d20a0",
                      "client_id": "f241c4d4-a8c6-4cf2-8cc5-be0012dcdcb6",
                      "partenaire_id": "bacf2aec-2059-465e-ae6f-c83ad2e94600",
                      "demandee_par": "0fac7ff7-a5af-4a7d-a0f3-bd4b974bdca4",
                      "statut": "validee",
                      "doublons_detectes": null,
                      "motif_decision": "Demande de réservation fondée.",
                      "traitee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "traitee_le": "2026-10-19T10:45:15.348Z",
                      "cree_le": "2026-10-19T10:45:15.216Z",
                      "modifie_le": "2026-10-19T10:45:15.346Z",
                      "client": {
                        "id": "f241c4d4-a8c6-4cf2-8cc5-be0012dcdcb6",
                        "raison_sociale": "ZZ Recette Client 3719E805",
                        "statut": "reserve"
                      },
                      "partenaire": {
                        "id": "bacf2aec-2059-465e-ae6f-c83ad2e94600",
                        "raison_sociale": "ZZ Recette Partenaire B 3FC944FA",
                        "statut": "actif",
                        "ville": "Abidjan",
                        "code_confidentiel": "C-0074"
                      },
                      "demandeur": {
                        "id": "0fac7ff7-a5af-4a7d-a0f3-bd4b974bdca4",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire B 3FC944FA",
                        "email": "zz.recette.3fc944fa@exemple.invalide"
                      },
                      "traitee_par_utilisateur": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction",
                        "email": "admin.cybastion@preprod.satelica.test"
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.consulter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/clients/{id}/partenaire": {
      "patch": {
        "operationId": "patchClientsParIdPartenaire",
        "tags": [
          "Clients"
        ],
        "summary": "Attribuer un client à un partenaire",
        "description": "Clôt l'affectation en cours et en ouvre une au partenaire désigné, qui doit être validé ou actif. Comme une réservation validée : un prospect ou un client en attente passe `reserve`, les réservations ouvertes sont closes (celle du partenaire retenu validée, les autres refusées) et leurs demandeurs prévenus. L'accès part au contact principal seulement si le client n'avait pas de partenaire ; sinon `acces` vaut `null`.\n\n**Permission requise** : `clients.affecter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "partenaire_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "motif": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "partenaire_id"
                ]
              },
              "example": {
                "partenaire_id": "bacf2aec-2059-465e-ae6f-c83ad2e94600",
                "motif": "Demande de réservation fondée."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "forme_juridique": {
                      "type": "null"
                    },
                    "rccm": {
                      "type": "string"
                    },
                    "ncc": {
                      "type": "string"
                    },
                    "secteur_id": {
                      "type": "null"
                    },
                    "adresse_facturation": {
                      "type": "null"
                    },
                    "ville": {
                      "type": "string"
                    },
                    "zone_id": {
                      "type": "null"
                    },
                    "telephone": {
                      "type": "null"
                    },
                    "email": {
                      "type": "null"
                    },
                    "origine": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "statut_kyc": {
                      "type": "string"
                    },
                    "partenaire_actuel_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "credit_approuve": {
                      "type": "boolean"
                    },
                    "plafond_encours": {
                      "type": "null"
                    },
                    "credit_approuve_par": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "logo_fichier_id": {
                      "type": "null"
                    },
                    "mode_paiement_souhaite": {
                      "type": "null"
                    },
                    "partenaire_actuel": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville",
                        "code_confidentiel"
                      ]
                    },
                    "zone": {
                      "type": "null"
                    },
                    "secteur": {
                      "type": "null"
                    },
                    "contact_principal": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "client_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "fonction": {
                          "type": "null"
                        },
                        "email": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "null"
                        },
                        "principal": {
                          "type": "boolean"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "modifie_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "client_id",
                        "prenom",
                        "nom",
                        "fonction",
                        "email",
                        "telephone",
                        "principal",
                        "cree_le",
                        "modifie_le"
                      ]
                    },
                    "nb_sites": {
                      "type": "integer"
                    },
                    "reservation_en_attente": {
                      "type": "null"
                    },
                    "acces": {
                      "type": "object",
                      "properties": {
                        "statut": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        },
                        "utilisateur_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "statut",
                        "email",
                        "utilisateur_id",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "raison_sociale",
                    "forme_juridique",
                    "rccm",
                    "ncc",
                    "secteur_id",
                    "adresse_facturation",
                    "ville",
                    "zone_id",
                    "telephone",
                    "email",
                    "origine",
                    "statut",
                    "statut_kyc",
                    "partenaire_actuel_id",
                    "credit_approuve",
                    "plafond_encours",
                    "credit_approuve_par",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "logo_fichier_id",
                    "mode_paiement_souhaite",
                    "partenaire_actuel",
                    "zone",
                    "secteur",
                    "contact_principal",
                    "nb_sites",
                    "reservation_en_attente",
                    "acces"
                  ]
                },
                "example": {
                  "id": "f241c4d4-a8c6-4cf2-8cc5-be0012dcdcb6",
                  "organisation_id": "4b0f855a-cfd7-4f8a-be4d-d58a5e2dc8bb",
                  "raison_sociale": "ZZ Recette Client 3719E805",
                  "forme_juridique": null,
                  "rccm": "CI-ZZD-3719E805",
                  "ncc": "NCC-ZZD-3719E805",
                  "secteur_id": null,
                  "adresse_facturation": null,
                  "ville": "Abidjan",
                  "zone_id": null,
                  "telephone": null,
                  "email": null,
                  "origine": "partenaire",
                  "statut": "reserve",
                  "statut_kyc": "en_verification",
                  "partenaire_actuel_id": "bacf2aec-2059-465e-ae6f-c83ad2e94600",
                  "credit_approuve": false,
                  "plafond_encours": null,
                  "credit_approuve_par": null,
                  "cree_par": "10d90c38-c562-44ac-8908-a67fd6f725e4",
                  "cree_le": "2026-10-19T10:45:14.880Z",
                  "modifie_le": "2026-10-19T10:45:15.346Z",
                  "logo_fichier_id": null,
                  "mode_paiement_souhaite": null,
                  "partenaire_actuel": {
                    "id": "bacf2aec-2059-465e-ae6f-c83ad2e94600",
                    "raison_sociale": "ZZ Recette Partenaire B 3FC944FA",
                    "statut": "actif",
                    "ville": "Abidjan",
                    "code_confidentiel": "C-0074"
                  },
                  "zone": null,
                  "secteur": null,
                  "contact_principal": {
                    "id": "894d1ea3-16c9-4f23-99a4-66c7cf2acfe1",
                    "client_id": "f241c4d4-a8c6-4cf2-8cc5-be0012dcdcb6",
                    "prenom": "ZZ Recette",
                    "nom": "Contact 3719E805",
                    "fonction": null,
                    "email": "contact.3719e805@exemple.invalide",
                    "telephone": null,
                    "principal": true,
                    "cree_le": "2026-10-19T10:45:14.883Z",
                    "modifie_le": "2026-10-19T10:45:14.883Z"
                  },
                  "nb_sites": 1,
                  "reservation_en_attente": null,
                  "acces": {
                    "statut": "envoye",
                    "email": "contact.3719e805@exemple.invalide",
                    "utilisateur_id": "f57f71b9-072e-4ccb-8e0d-92eb2c7c3755",
                    "message": "Accès envoyé à contact.3719e805@exemple.invalide : un courriel l’invite à choisir son mot de passe."
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Partenaire non actif, ou client déjà détenu par un autre partenaire.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.affecter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/reservations/{id}/decision": {
      "post": {
        "operationId": "postReservationsParIdDecision",
        "tags": [
          "Clients"
        ],
        "summary": "Valider ou refuser une réservation",
        "description": "Tranche une réservation `demandee` ou `conflit` ; un refus exige un motif. Validée, elle rattache le client au partenaire (affectation, statut `reserve`, autres demandes refusées et leurs auteurs prévenus), puis ouvre l'accès du contact principal si l'organisation du client n'a encore aucun compte. Refusée, le client redevient `prospect` si plus rien ne l'attend. Le partenaire demandeur est notifié de la décision.\n\n**Permission requise** : `clients.reservation_valider`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "validee",
                      "refusee"
                    ]
                  },
                  "motif": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "validee",
                "motif": "Fixture de recette."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 6 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "demandee_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "doublons_detectes": {
                      "type": [
                        "array",
                        "null"
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "niveau": {
                            "type": "string"
                          },
                          "criteres": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "similarite": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "raison_sociale": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "niveau",
                          "criteres",
                          "client_id",
                          "similarite",
                          "raison_sociale"
                        ]
                      }
                    },
                    "motif_decision": {
                      "type": "string"
                    },
                    "traitee_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "traitee_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville",
                        "code_confidentiel"
                      ]
                    },
                    "acces": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "statut": {
                          "type": "string"
                        },
                        "email": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "utilisateur_id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "uuid"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "statut",
                        "email",
                        "utilisateur_id",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "client_id",
                    "partenaire_id",
                    "demandee_par",
                    "statut",
                    "doublons_detectes",
                    "motif_decision",
                    "traitee_par",
                    "traitee_le",
                    "cree_le",
                    "modifie_le",
                    "client",
                    "partenaire",
                    "acces"
                  ]
                },
                "example": {
                  "id": "95316f2f-30f5-4e98-8613-8cf8c7a9e5b5",
                  "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                  "partenaire_id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                  "demandee_par": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                  "statut": "validee",
                  "doublons_detectes": [
                    {
                      "niveau": "alerte",
                      "criteres": [
                        "raison_sociale_proche",
                        "telephone_identique"
                      ],
                      "client_id": "a0e7b70a-3e2d-4281-bfe1-b5e6b7fa501d",
                      "similarite": 0.76,
                      "raison_sociale": "ZZ Recette Client 585738DF"
                    },
                    {
                      "niveau": "alerte",
                      "criteres": [
                        "raison_sociale_proche",
                        "telephone_identique"
                      ],
                      "client_id": "4b4b7b6b-aae0-4c67-88c1-1f8f34abadc0",
                      "similarite": 0.72,
                      "raison_sociale": "ZZ Recette Client F31EF585"
                    }
                  ],
                  "motif_decision": "Fixture de recette.",
                  "traitee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "traitee_le": "2026-10-19T10:44:16.306Z",
                  "cree_le": "2026-10-19T10:44:16.139Z",
                  "modifie_le": "2026-10-19T10:44:16.306Z",
                  "client": {
                    "id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                    "raison_sociale": "ZZ Recette Client 54587534",
                    "statut": "reserve"
                  },
                  "partenaire": {
                    "id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                    "raison_sociale": "ZZ Recette Partenaire W 8E10C2F1",
                    "statut": "actif",
                    "ville": "Abidjan",
                    "code_confidentiel": "C-0070"
                  },
                  "acces": {
                    "statut": "envoye",
                    "email": "contact.54587534@exemple.invalide",
                    "utilisateur_id": "506f53bb-b691-4740-b935-947e69eff9a5",
                    "message": "Accès envoyé à contact.54587534@exemple.invalide : un courriel l’invite à choisir son mot de passe."
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Cette réservation a déjà été traitée.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.reservation_valider",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/clients/{id}/kyc": {
      "patch": {
        "operationId": "patchClientsParIdKyc",
        "tags": [
          "Clients"
        ],
        "summary": "Trancher la conformité du dossier d'un client",
        "description": "Pose le statut KYC du client ; tout autre statut que `conforme` exige un motif. Déclarer conforme est refusé tant qu'une pièce obligatoire manque ou est périmée. Le statut commercial ne bouge pas, et le client est notifié de la décision. Reposer le statut déjà en place ne change rien (`deja_pose: true`).\n\n**Permission requise** : `clients.kyc_valider`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "statut": {
                    "type": "string",
                    "enum": [
                      "a_fournir",
                      "en_verification",
                      "conforme",
                      "a_completer",
                      "rejete"
                    ]
                  },
                  "motif": {
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "statut"
                ]
              },
              "example": {
                "statut": "a_completer",
                "motif": "Le RCCM transmis est illisible."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "statut_kyc": {
                      "type": "string"
                    },
                    "kyc": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "valides": {
                          "type": "integer"
                        },
                        "a_verifier": {
                          "type": "integer"
                        },
                        "a_completer": {
                          "type": "integer"
                        },
                        "rejetes": {
                          "type": "integer"
                        },
                        "expires": {
                          "type": "integer"
                        },
                        "obligatoires_manquants": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total",
                        "valides",
                        "a_verifier",
                        "a_completer",
                        "rejetes",
                        "expires",
                        "obligatoires_manquants"
                      ]
                    },
                    "permet": {
                      "type": "array",
                      "items": {}
                    }
                  },
                  "required": [
                    "id",
                    "raison_sociale",
                    "statut",
                    "statut_kyc",
                    "kyc",
                    "permet"
                  ]
                },
                "example": {
                  "id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                  "raison_sociale": "ZZ Recette Client 54587534",
                  "statut": "reserve",
                  "statut_kyc": "a_completer",
                  "kyc": {
                    "total": 4,
                    "valides": 0,
                    "a_verifier": 4,
                    "a_completer": 0,
                    "rejetes": 0,
                    "expires": 0,
                    "obligatoires_manquants": 5
                  },
                  "permet": []
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Une pièce obligatoire manque ou est périmée : le dossier ne peut être conforme.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.kyc_valider",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/commandes": {
      "get": {
        "operationId": "getCommandes",
        "tags": [
          "Commandes et contrats"
        ],
        "summary": "Lister les commandes",
        "description": "Les commandes, de la plus récente à la plus ancienne, filtrables par statut (plusieurs valeurs, répétées ou séparées par des virgules) et par client. Chacune porte son solde, recalculé depuis les paiements, la frise des sept étapes (`etapes`, `etape_courante`), son client, son partenaire, son site, le devis signé, le contrat et le dernier ordre d'installation. Une commande ne se crée pas par l'API : elle naît de la signature d'un devis.\n\n**Permission requise** : L'une de : `contrats.gerer`, `espace_partenaire.acceder`, `devis.accepter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 5 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "devis_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "site_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "mode_paiement": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "total_ht": {
                            "type": "integer"
                          },
                          "total_ttc": {
                            "type": "integer"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "factures": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "numero": {
                                  "type": "string"
                                },
                                "statut": {
                                  "type": "string"
                                },
                                "montant_ttc": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id",
                                "numero",
                                "statut",
                                "montant_ttc"
                              ]
                            }
                          },
                          "montant_paye": {
                            "type": "integer"
                          },
                          "montant_en_attente": {
                            "type": "integer"
                          },
                          "reste_a_payer": {
                            "type": "integer"
                          },
                          "reste_a_declarer": {
                            "type": "integer"
                          },
                          "trop_percu": {
                            "type": "integer"
                          },
                          "soldee": {
                            "type": "boolean"
                          },
                          "partiellement_reglee": {
                            "type": "boolean"
                          },
                          "paiements_en_attente": {
                            "type": "integer"
                          },
                          "etapes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "code": {
                                  "type": "string"
                                },
                                "libelle": {
                                  "type": "string"
                                },
                                "etat": {
                                  "type": "string"
                                },
                                "date": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "format": "date"
                                }
                              },
                              "required": [
                                "code",
                                "libelle",
                                "etat",
                                "date"
                              ]
                            }
                          },
                          "etape_courante": {
                            "type": "integer"
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "credit_approuve": {
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "credit_approuve"
                            ]
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "ville",
                              "code_confidentiel"
                            ]
                          },
                          "site": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "adresse": {
                                "type": "null"
                              }
                            },
                            "required": [
                              "id",
                              "libelle",
                              "ville",
                              "adresse"
                            ]
                          },
                          "devis_signe": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "signe_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut",
                              "signe_le"
                            ]
                          },
                          "contrat": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "active_le": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time"
                              },
                              "date_debut": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time"
                              },
                              "date_fin": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time"
                              },
                              "offres": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "code": {
                                    "type": "string"
                                  },
                                  "libelle": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "code",
                                  "libelle"
                                ]
                              },
                              "activations": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "type": "string",
                                      "format": "uuid"
                                    },
                                    "statut": {
                                      "type": "string"
                                    },
                                    "demandee_le": {
                                      "type": [
                                        "string",
                                        "null"
                                      ],
                                      "format": "date-time"
                                    },
                                    "activee_le": {
                                      "type": "string",
                                      "format": "date-time"
                                    },
                                    "reference_vipnet": {
                                      "type": "string"
                                    },
                                    "connexions": {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "type": "string",
                                          "format": "uuid"
                                        },
                                        "identifiant_vipnet": {
                                          "type": "string"
                                        },
                                        "statut": {
                                          "type": "string"
                                        }
                                      },
                                      "required": [
                                        "id",
                                        "identifiant_vipnet",
                                        "statut"
                                      ]
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "statut",
                                    "demandee_le",
                                    "activee_le",
                                    "reference_vipnet",
                                    "connexions"
                                  ]
                                }
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut",
                              "active_le",
                              "date_debut",
                              "date_fin",
                              "offres",
                              "activations"
                            ]
                          },
                          "ordre_installation": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "envoye_le": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time"
                              },
                              "date_cible": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "date_limite": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "creneaux": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "technicien": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "reference_vipnet": {
                                "type": "null"
                              },
                              "commentaire": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "proces_verbaux": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": {
                                      "type": "string",
                                      "format": "uuid"
                                    },
                                    "type": {
                                      "type": "string"
                                    },
                                    "statut": {
                                      "type": "string"
                                    },
                                    "date_intervention": {
                                      "type": "string",
                                      "format": "date-time"
                                    },
                                    "valide_le": {
                                      "type": "string",
                                      "format": "date-time"
                                    }
                                  },
                                  "required": [
                                    "id",
                                    "type",
                                    "statut",
                                    "date_intervention",
                                    "valide_le"
                                  ]
                                }
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut",
                              "envoye_le",
                              "date_cible",
                              "date_limite",
                              "creneaux",
                              "technicien",
                              "reference_vipnet",
                              "commentaire",
                              "modifie_le",
                              "proces_verbaux"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "devis_id",
                          "client_id",
                          "partenaire_id",
                          "site_id",
                          "mode_paiement",
                          "statut",
                          "total_ht",
                          "total_ttc",
                          "cree_le",
                          "modifie_le",
                          "factures",
                          "montant_paye",
                          "montant_en_attente",
                          "reste_a_payer",
                          "reste_a_declarer",
                          "trop_percu",
                          "soldee",
                          "partiellement_reglee",
                          "paiements_en_attente",
                          "etapes",
                          "etape_courante",
                          "client",
                          "partenaire",
                          "site",
                          "devis_signe",
                          "contrat",
                          "ordre_installation"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                      "numero": "CMD-2026-000032",
                      "devis_id": "21ff2ce1-1c6c-4f56-86b2-d0a0600b829b",
                      "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                      "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                      "site_id": "e114d094-6e40-45c9-913d-522133ed600a",
                      "mode_paiement": "prepaye",
                      "statut": "attente_paiement",
                      "total_ht": 20000,
                      "total_ttc": 23600,
                      "cree_le": "2026-10-19T10:45:45.742Z",
                      "modifie_le": "2026-10-19T10:45:45.742Z",
                      "factures": [],
                      "montant_paye": 0,
                      "montant_en_attente": 0,
                      "reste_a_payer": 23600,
                      "reste_a_declarer": 23600,
                      "trop_percu": 0,
                      "soldee": false,
                      "partiellement_reglee": false,
                      "paiements_en_attente": 0,
                      "etapes": [
                        {
                          "code": "signature",
                          "libelle": "Devis signé",
                          "etat": "terminee",
                          "date": "2026-10-19"
                        },
                        {
                          "code": "attente_paiement",
                          "libelle": "Attente de paiement",
                          "etat": "en_cours",
                          "date": "2026-10-19"
                        }
                      ],
                      "etape_courante": 1,
                      "client": {
                        "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                        "raison_sociale": "ZZ Recette Client 4D20EED1",
                        "statut": "reserve",
                        "credit_approuve": false
                      },
                      "partenaire": {
                        "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                        "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                        "statut": "actif",
                        "ville": "Abidjan",
                        "code_confidentiel": "C-0076"
                      },
                      "site": {
                        "id": "e114d094-6e40-45c9-913d-522133ed600a",
                        "libelle": "Site 4D20EED1",
                        "ville": "Abidjan",
                        "adresse": null
                      },
                      "devis_signe": {
                        "id": "21ff2ce1-1c6c-4f56-86b2-d0a0600b829b",
                        "numero": "DEV-2026-000067",
                        "statut": "signe",
                        "signe_le": "2026-10-19T12:00:00.000Z"
                      },
                      "contrat": {
                        "id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                        "numero": "CTR-2026-000032",
                        "statut": "projet",
                        "active_le": null,
                        "date_debut": null,
                        "date_fin": null,
                        "offres": {
                          "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                          "code": "DATA-50GO-HEBDO",
                          "libelle": "Forfait 50 Go hebdomadaire"
                        },
                        "activations": []
                      },
                      "ordre_installation": null
                    },
                    {
                      "id": "183c1dab-cc43-488d-bac5-1df62198157d",
                      "numero": "CMD-2026-000031",
                      "devis_id": "b0f2f80b-5d66-47d9-a879-831789e9b3be",
                      "client_id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                      "partenaire_id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                      "site_id": "01e18522-0666-4175-b960-ad1a6ff901d6",
                      "mode_paiement": "prepaye",
                      "statut": "attente_paiement",
                      "total_ht": 20000,
                      "total_ttc": 23600,
                      "cree_le": "2026-10-19T10:45:10.739Z",
                      "modifie_le": "2026-10-19T10:45:11.581Z",
                      "factures": [],
                      "montant_paye": 0,
                      "montant_en_attente": 0,
                      "reste_a_payer": 23600,
                      "reste_a_declarer": 23600,
                      "trop_percu": 0,
                      "soldee": false,
                      "partiellement_reglee": false,
                      "paiements_en_attente": 0,
                      "etapes": [
                        {
                          "code": "signature",
                          "libelle": "Devis signé",
                          "etat": "terminee",
                          "date": "2026-10-19"
                        },
                        {
                          "code": "attente_paiement",
                          "libelle": "Attente de paiement",
                          "etat": "en_cours",
                          "date": "2026-10-19"
                        }
                      ],
                      "etape_courante": 1,
                      "client": {
                        "id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                        "raison_sociale": "ZZ Recette Client 62AAEFDF",
                        "statut": "reserve",
                        "credit_approuve": false
                      },
                      "partenaire": {
                        "id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                        "raison_sociale": "ZZ Recette Partenaire A 137E8405",
                        "statut": "actif",
                        "ville": "Yamoussoukro",
                        "code_confidentiel": "C-0073"
                      },
                      "site": {
                        "id": "01e18522-0666-4175-b960-ad1a6ff901d6",
                        "libelle": "Site 62AAEFDF",
                        "ville": "Abidjan",
                        "adresse": null
                      },
                      "devis_signe": {
                        "id": "b0f2f80b-5d66-47d9-a879-831789e9b3be",
                        "numero": "DEV-2026-000066",
                        "statut": "signe",
                        "signe_le": "2026-10-19T12:00:00.000Z"
                      },
                      "contrat": {
                        "id": "1b224d24-99d2-4b64-958d-1968fa1acf8f",
                        "numero": "CTR-2026-000031",
                        "statut": "projet",
                        "active_le": null,
                        "date_debut": null,
                        "date_fin": null,
                        "offres": {
                          "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                          "code": "DATA-50GO-HEBDO",
                          "libelle": "Forfait 50 Go hebdomadaire"
                        },
                        "activations": []
                      },
                      "ordre_installation": {
                        "id": "af920990-711b-4967-9613-d97acc5581af",
                        "numero": "INS-2026-000036",
                        "statut": "annule",
                        "envoye_le": null,
                        "date_cible": "2026-10-22T00:00:00.000Z",
                        "date_limite": "2026-10-26T00:00:00.000Z",
                        "creneaux": null,
                        "technicien": null,
                        "reference_vipnet": null,
                        "commentaire": null,
                        "modifie_le": "2026-10-19T10:45:11.581Z",
                        "proces_verbaux": []
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 17,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "contrats.gerer",
          "espace_partenaire.acceder",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/commandes/{id}": {
      "get": {
        "operationId": "getCommandesParId",
        "tags": [
          "Commandes et contrats"
        ],
        "summary": "Lire le détail d'une commande",
        "description": "Toute la fiche d'une commande en une lecture : lignes du devis signé, échéancier, commissions, règlements, factures avec leur reste dû, ordre d'installation et ses procès-verbaux, contrat, dernière activation et offre souscrite. `installation_debloquee` dit si l'ordre d'installation peut être émis, selon la règle que le serveur applique à l'émission. Le solde et la frise des étapes sont recalculés à chaque lecture.\n\n**Permission requise** : L'une de : `contrats.gerer`, `espace_partenaire.acceder`, `devis.accepter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 12 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "devis_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "mode_paiement": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "total_ht": {
                      "type": "integer"
                    },
                    "total_ttc": {
                      "type": "integer"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "ordres_installation": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "envoye_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "date_cible": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "date_limite": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "creneaux": {
                            "type": "null"
                          },
                          "technicien": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "reference_vipnet": {
                            "type": "null"
                          },
                          "commentaire": {
                            "type": "null"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "proces_verbaux": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "type": {
                                  "type": "string"
                                },
                                "statut": {
                                  "type": "string"
                                },
                                "date_intervention": {
                                  "type": "string",
                                  "format": "date-time"
                                },
                                "valide_le": {
                                  "type": "string",
                                  "format": "date-time"
                                }
                              },
                              "required": [
                                "id",
                                "type",
                                "statut",
                                "date_intervention",
                                "valide_le"
                              ]
                            }
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "statut",
                          "envoye_le",
                          "date_cible",
                          "date_limite",
                          "creneaux",
                          "technicien",
                          "reference_vipnet",
                          "commentaire",
                          "modifie_le",
                          "proces_verbaux"
                        ]
                      }
                    },
                    "factures": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "montant_paye": {
                            "type": "integer"
                          },
                          "date_echeance": {
                            "type": "string",
                            "format": "date"
                          },
                          "reste_du": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "statut",
                          "montant_ttc",
                          "montant_paye",
                          "date_echeance",
                          "reste_du"
                        ]
                      }
                    },
                    "commissions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type_ligne": {
                            "type": "string"
                          },
                          "taux_applique": {
                            "type": "string"
                          },
                          "montant_latent": {
                            "type": "string"
                          },
                          "montant_realise": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "type_ligne",
                          "taux_applique",
                          "montant_latent",
                          "montant_realise",
                          "statut"
                        ]
                      }
                    },
                    "installation_debloquee": {
                      "type": "boolean"
                    },
                    "offre": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code": {
                          "type": "string"
                        },
                        "libelle": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "code",
                        "libelle"
                      ]
                    },
                    "montant_paye": {
                      "type": "integer"
                    },
                    "montant_en_attente": {
                      "type": "integer"
                    },
                    "reste_a_payer": {
                      "type": "integer"
                    },
                    "reste_a_declarer": {
                      "type": "integer"
                    },
                    "trop_percu": {
                      "type": "integer"
                    },
                    "soldee": {
                      "type": "boolean"
                    },
                    "partiellement_reglee": {
                      "type": "boolean"
                    },
                    "paiements_en_attente": {
                      "type": "integer"
                    },
                    "etapes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "etat": {
                            "type": "string"
                          },
                          "date": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date"
                          }
                        },
                        "required": [
                          "code",
                          "libelle",
                          "etat",
                          "date"
                        ]
                      }
                    },
                    "etape_courante": {
                      "type": "integer"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "credit_approuve": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "credit_approuve"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville",
                        "code_confidentiel"
                      ]
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "adresse": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville",
                        "adresse"
                      ]
                    },
                    "devis_signe": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "signe_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "pdf_fichier_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "pdf_signe_fichier_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "devis_lignes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "type_ligne": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "quantite": {
                                "type": "integer"
                              },
                              "prix_unitaire_ht": {
                                "type": "string"
                              },
                              "remise_pct": {
                                "type": "string"
                              },
                              "taux_tva": {
                                "type": "string"
                              },
                              "montant_ht": {
                                "type": "string"
                              },
                              "montant_ttc": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "type_ligne",
                              "libelle",
                              "quantite",
                              "prix_unitaire_ht",
                              "remise_pct",
                              "taux_tva",
                              "montant_ht",
                              "montant_ttc"
                            ]
                          }
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "signe_le",
                        "pdf_fichier_id",
                        "pdf_signe_fichier_id",
                        "devis_lignes"
                      ]
                    },
                    "contrat": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "active_le": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "date_debut": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "date_fin": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "offres": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "code": {
                              "type": "string"
                            },
                            "libelle": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "code",
                            "libelle"
                          ]
                        },
                        "activations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "demandee_le": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time"
                              },
                              "activee_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "reference_vipnet": {
                                "type": "string"
                              },
                              "connexions": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "identifiant_vipnet": {
                                    "type": "string"
                                  },
                                  "statut": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "identifiant_vipnet",
                                  "statut"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "statut",
                              "demandee_le",
                              "activee_le",
                              "reference_vipnet",
                              "connexions"
                            ]
                          }
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "active_le",
                        "date_debut",
                        "date_fin",
                        "offres",
                        "activations"
                      ]
                    },
                    "activation": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "demandee_le": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "activee_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "reference_vipnet": {
                          "type": "string"
                        },
                        "connexions": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "identifiant_vipnet": {
                              "type": "string"
                            },
                            "statut": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "identifiant_vipnet",
                            "statut"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "statut",
                        "demandee_le",
                        "activee_le",
                        "reference_vipnet",
                        "connexions"
                      ]
                    },
                    "reglements": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "montant": {
                            "type": "integer"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "canal": {
                            "type": "string"
                          },
                          "date_paiement": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "valide_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "reference_externe": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "motif_rejet": {
                            "type": "null"
                          }
                        },
                        "required": [
                          "id",
                          "montant",
                          "statut",
                          "canal",
                          "date_paiement",
                          "valide_le",
                          "reference_externe",
                          "motif_rejet"
                        ]
                      }
                    },
                    "echeancier": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "rang": {
                            "type": "integer"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "date_echeance": {
                            "type": "string",
                            "format": "date"
                          },
                          "statut": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "type",
                          "rang",
                          "montant_ttc",
                          "date_echeance",
                          "statut"
                        ]
                      }
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "devis_id",
                    "client_id",
                    "partenaire_id",
                    "site_id",
                    "mode_paiement",
                    "statut",
                    "total_ht",
                    "total_ttc",
                    "cree_le",
                    "modifie_le",
                    "ordres_installation",
                    "factures",
                    "commissions",
                    "installation_debloquee",
                    "offre",
                    "montant_paye",
                    "montant_en_attente",
                    "reste_a_payer",
                    "reste_a_declarer",
                    "trop_percu",
                    "soldee",
                    "partiellement_reglee",
                    "paiements_en_attente",
                    "etapes",
                    "etape_courante",
                    "client",
                    "partenaire",
                    "site",
                    "devis_signe",
                    "contrat",
                    "activation",
                    "reglements",
                    "echeancier"
                  ]
                },
                "example": {
                  "id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                  "numero": "CMD-2026-000029",
                  "devis_id": "52764ad5-f498-419d-8732-f7aaf13cb517",
                  "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                  "partenaire_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                  "site_id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                  "mode_paiement": "prepaye",
                  "statut": "attente_paiement",
                  "total_ht": 20000,
                  "total_ttc": 23600,
                  "cree_le": "2026-10-19T10:44:31.927Z",
                  "modifie_le": "2026-10-19T10:44:31.927Z",
                  "ordres_installation": [],
                  "factures": [],
                  "commissions": [
                    {
                      "id": "46a7e9ab-fddf-4f64-bcd2-d5efc7be7227",
                      "type_ligne": "forfait_data",
                      "taux_applique": "20",
                      "montant_latent": "4000",
                      "montant_realise": "0",
                      "statut": "latente"
                    }
                  ],
                  "installation_debloquee": false,
                  "offre": {
                    "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                    "code": "DATA-50GO-HEBDO",
                    "libelle": "Forfait 50 Go hebdomadaire"
                  },
                  "montant_paye": 0,
                  "montant_en_attente": 0,
                  "reste_a_payer": 23600,
                  "reste_a_declarer": 23600,
                  "trop_percu": 0,
                  "soldee": false,
                  "partiellement_reglee": false,
                  "paiements_en_attente": 0,
                  "etapes": [
                    {
                      "code": "signature",
                      "libelle": "Devis signé",
                      "etat": "terminee",
                      "date": "2026-10-19"
                    },
                    {
                      "code": "attente_paiement",
                      "libelle": "Attente de paiement",
                      "etat": "en_cours",
                      "date": "2026-10-19"
                    }
                  ],
                  "etape_courante": 1,
                  "client": {
                    "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                    "raison_sociale": "ZZ Recette WNCYUQRHJW",
                    "statut": "reserve",
                    "credit_approuve": false
                  },
                  "partenaire": {
                    "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                    "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                    "statut": "actif",
                    "ville": "Abidjan",
                    "code_confidentiel": "C-0071"
                  },
                  "site": {
                    "id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                    "libelle": "Siège",
                    "ville": "Abidjan",
                    "adresse": null
                  },
                  "devis_signe": {
                    "id": "52764ad5-f498-419d-8732-f7aaf13cb517",
                    "numero": "DEV-2026-000061",
                    "statut": "signe",
                    "signe_le": "2026-10-19T12:00:00.000Z",
                    "pdf_fichier_id": "ec57136e-4d63-47bf-807f-27ef828d3dbc",
                    "pdf_signe_fichier_id": "ea1534bf-688c-4401-a962-e5dfbd2fa432",
                    "devis_lignes": [
                      {
                        "id": "f9e6b4e9-3309-4a0c-838a-4fb68548bcb2",
                        "type_ligne": "forfait_data",
                        "libelle": "Forfait 50 Go hebdomadaire",
                        "quantite": 1,
                        "prix_unitaire_ht": "20000",
                        "remise_pct": "0",
                        "taux_tva": "18",
                        "montant_ht": "20000",
                        "montant_ttc": "23600"
                      }
                    ]
                  },
                  "contrat": {
                    "id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                    "numero": "CTR-2026-000029",
                    "statut": "projet",
                    "active_le": null,
                    "date_debut": null,
                    "date_fin": null,
                    "offres": {
                      "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                      "code": "DATA-50GO-HEBDO",
                      "libelle": "Forfait 50 Go hebdomadaire"
                    },
                    "activations": []
                  },
                  "activation": null,
                  "reglements": [],
                  "echeancier": [
                    {
                      "id": "9a33ed7e-47b2-47e0-82a6-33b27fa62256",
                      "type": "forfait",
                      "rang": 3,
                      "montant_ttc": 23600,
                      "date_echeance": "2026-10-19",
                      "statut": "due"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "contrats.gerer",
          "espace_partenaire.acceder",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/contrats": {
      "get": {
        "operationId": "getContrats",
        "tags": [
          "Commandes et contrats"
        ],
        "summary": "Lister les contrats",
        "description": "Les contrats, du plus récent au plus ancien, filtrables par statut (plusieurs valeurs, répétées ou séparées par des virgules) et par client, avec leur client, partenaire, site, offre et commande. `est_projet` signale un contrat encore à l'état de projet.\n\n**Permission requise** : L'une de : `contrats.gerer`, `espace_partenaire.acceder`, `devis.accepter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 7 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "commande_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "site_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "offre_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "mode_paiement": {
                            "type": "string"
                          },
                          "modalite_equipement": {
                            "type": "string"
                          },
                          "date_debut": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date"
                          },
                          "date_fin": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "pdf_fichier_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "pdf_signe_fichier_id": {
                            "type": "null"
                          },
                          "signe_le": {
                            "type": "null"
                          },
                          "active_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "contrat_precedent_id": {
                            "type": "null"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "est_projet": {
                            "type": "boolean"
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "credit_approuve": {
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "credit_approuve"
                            ]
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "ville",
                              "code_confidentiel"
                            ]
                          },
                          "site": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "adresse": {
                                "type": "null"
                              }
                            },
                            "required": [
                              "id",
                              "libelle",
                              "ville",
                              "adresse"
                            ]
                          },
                          "offre": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "volume_go": {
                                "type": "integer"
                              },
                              "periode": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "volume_go",
                              "periode"
                            ]
                          },
                          "commande": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "commande_id",
                          "client_id",
                          "site_id",
                          "partenaire_id",
                          "offre_id",
                          "mode_paiement",
                          "modalite_equipement",
                          "date_debut",
                          "date_fin",
                          "statut",
                          "pdf_fichier_id",
                          "pdf_signe_fichier_id",
                          "signe_le",
                          "active_le",
                          "contrat_precedent_id",
                          "cree_le",
                          "modifie_le",
                          "est_projet",
                          "client",
                          "partenaire",
                          "site",
                          "offre",
                          "commande"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                      "numero": "CTR-2026-000029",
                      "commande_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                      "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                      "site_id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                      "partenaire_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                      "offre_id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                      "mode_paiement": "prepaye",
                      "modalite_equipement": "comptant",
                      "date_debut": null,
                      "date_fin": null,
                      "statut": "projet",
                      "pdf_fichier_id": null,
                      "pdf_signe_fichier_id": null,
                      "signe_le": null,
                      "active_le": null,
                      "contrat_precedent_id": null,
                      "cree_le": "2026-10-19T10:44:31.932Z",
                      "modifie_le": "2026-10-19T10:44:31.932Z",
                      "est_projet": true,
                      "client": {
                        "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                        "raison_sociale": "ZZ Recette WNCYUQRHJW",
                        "statut": "reserve",
                        "credit_approuve": false
                      },
                      "partenaire": {
                        "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                        "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                        "statut": "actif",
                        "ville": "Abidjan",
                        "code_confidentiel": "C-0071"
                      },
                      "site": {
                        "id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                        "libelle": "Siège",
                        "ville": "Abidjan",
                        "adresse": null
                      },
                      "offre": {
                        "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                        "code": "DATA-50GO-HEBDO",
                        "libelle": "Forfait 50 Go hebdomadaire",
                        "volume_go": 50,
                        "periode": "hebdomadaire"
                      },
                      "commande": {
                        "id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                        "numero": "CMD-2026-000029",
                        "statut": "attente_paiement"
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 20,
                    "total": 1,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "contrats.gerer",
          "espace_partenaire.acceder",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/contrats/{id}": {
      "get": {
        "operationId": "getContratsParId",
        "tags": [
          "Commandes et contrats"
        ],
        "summary": "Lire le détail d'un contrat",
        "description": "La fiche d'un contrat : offre, commande, activations, liaison active (`connexion`), équipements avec leur produit, contrat renouvelé (`contrat_precedent`), factures, échéances et commissions, ainsi que les fichiers PDF du contrat avant et après signature (`pdf_fichier`, `pdf_signe_fichier`).\n\n**Permission requise** : L'une de : `contrats.gerer`, `espace_partenaire.acceder`, `devis.accepter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "commande_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "offre_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "mode_paiement": {
                      "type": "string"
                    },
                    "modalite_equipement": {
                      "type": "string"
                    },
                    "date_debut": {
                      "type": "string",
                      "format": "date"
                    },
                    "date_fin": {
                      "type": "string",
                      "format": "date"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "pdf_fichier_id": {
                      "type": "null"
                    },
                    "pdf_signe_fichier_id": {
                      "type": "null"
                    },
                    "signe_le": {
                      "type": "null"
                    },
                    "active_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "contrat_precedent_id": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "activations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "demandee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "activee_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "reference_vipnet": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "statut",
                          "demandee_le",
                          "activee_le",
                          "reference_vipnet"
                        ]
                      }
                    },
                    "connexions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "identifiant_vipnet": {
                            "type": "string"
                          },
                          "active_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "statut",
                          "identifiant_vipnet",
                          "active_le"
                        ]
                      }
                    },
                    "equipements": {
                      "type": "array",
                      "items": {}
                    },
                    "factures": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "montant_paye": {
                            "type": "integer"
                          },
                          "date_emission": {
                            "type": "string",
                            "format": "date"
                          },
                          "date_echeance": {
                            "type": "string",
                            "format": "date"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "statut",
                          "montant_ttc",
                          "montant_paye",
                          "date_emission",
                          "date_echeance"
                        ]
                      }
                    },
                    "echeances": {
                      "type": "array",
                      "items": {}
                    },
                    "commissions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "type_ligne": {
                            "type": "string"
                          },
                          "montant_latent": {
                            "type": "integer"
                          },
                          "montant_realise": {
                            "type": "integer"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "statut",
                          "type_ligne",
                          "montant_latent",
                          "montant_realise",
                          "cree_le"
                        ]
                      }
                    },
                    "est_projet": {
                      "type": "boolean"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "credit_approuve": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "credit_approuve"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville",
                        "code_confidentiel"
                      ]
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "adresse": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville",
                        "adresse"
                      ]
                    },
                    "offre": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "produit_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code": {
                          "type": "string"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "volume_go": {
                          "type": "integer"
                        },
                        "periode": {
                          "type": "string"
                        },
                        "debit": {
                          "type": "string"
                        },
                        "nb_appareils": {
                          "type": "null"
                        },
                        "nb_acces": {
                          "type": "null"
                        },
                        "actif": {
                          "type": "boolean"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "modifie_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "produit_id",
                        "code",
                        "libelle",
                        "volume_go",
                        "periode",
                        "debit",
                        "nb_appareils",
                        "nb_acces",
                        "actif",
                        "cree_le",
                        "modifie_le"
                      ]
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "total_ttc": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "total_ttc"
                      ]
                    },
                    "contrat_precedent": {
                      "type": "null"
                    },
                    "connexion": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "identifiant_vipnet": {
                          "type": "string"
                        },
                        "active_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "statut",
                        "identifiant_vipnet",
                        "active_le"
                      ]
                    },
                    "pdf_fichier": {
                      "type": "null"
                    },
                    "pdf_signe_fichier": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "commande_id",
                    "client_id",
                    "site_id",
                    "partenaire_id",
                    "offre_id",
                    "mode_paiement",
                    "modalite_equipement",
                    "date_debut",
                    "date_fin",
                    "statut",
                    "pdf_fichier_id",
                    "pdf_signe_fichier_id",
                    "signe_le",
                    "active_le",
                    "contrat_precedent_id",
                    "cree_le",
                    "modifie_le",
                    "activations",
                    "connexions",
                    "equipements",
                    "factures",
                    "echeances",
                    "commissions",
                    "est_projet",
                    "client",
                    "partenaire",
                    "site",
                    "offre",
                    "commande",
                    "contrat_precedent",
                    "connexion",
                    "pdf_fichier",
                    "pdf_signe_fichier"
                  ]
                },
                "example": {
                  "id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                  "numero": "CTR-2026-000029",
                  "commande_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                  "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                  "site_id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                  "partenaire_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                  "offre_id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                  "mode_paiement": "prepaye",
                  "modalite_equipement": "comptant",
                  "date_debut": "2026-10-19",
                  "date_fin": "2026-10-25",
                  "statut": "actif",
                  "pdf_fichier_id": null,
                  "pdf_signe_fichier_id": null,
                  "signe_le": null,
                  "active_le": "2026-10-19T10:44:38.747Z",
                  "contrat_precedent_id": null,
                  "cree_le": "2026-10-19T10:44:31.932Z",
                  "modifie_le": "2026-10-19T10:44:38.743Z",
                  "activations": [
                    {
                      "id": "f0c4b68f-5411-4289-8626-973622d990d5",
                      "statut": "activee",
                      "demandee_le": null,
                      "activee_le": "2026-10-19T10:44:38.743Z",
                      "reference_vipnet": "VIP-WNCYUQRHJW"
                    }
                  ],
                  "connexions": [
                    {
                      "id": "2cbd8fbf-efb3-4fd9-a660-e676fb9c6dc0",
                      "statut": "active",
                      "identifiant_vipnet": "SL-CNX-WNCYUQRHJW",
                      "active_le": "2026-10-19T10:44:38.751Z"
                    }
                  ],
                  "equipements": [],
                  "factures": [
                    {
                      "id": "a4c1adae-118b-4c59-997c-ce7898f76a76",
                      "numero": "FAC-2026-000020",
                      "statut": "payee",
                      "montant_ttc": 23600,
                      "montant_paye": 23600,
                      "date_emission": "2026-10-19",
                      "date_echeance": "2026-10-12"
                    }
                  ],
                  "echeances": [],
                  "commissions": [
                    {
                      "id": "46a7e9ab-fddf-4f64-bcd2-d5efc7be7227",
                      "statut": "realisee",
                      "type_ligne": "forfait_data",
                      "montant_latent": 4000,
                      "montant_realise": 4000,
                      "cree_le": "2026-10-19T10:44:31.936Z"
                    }
                  ],
                  "est_projet": false,
                  "client": {
                    "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                    "raison_sociale": "ZZ Recette WNCYUQRHJW",
                    "statut": "actif",
                    "credit_approuve": false
                  },
                  "partenaire": {
                    "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                    "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                    "statut": "actif",
                    "ville": "Abidjan",
                    "code_confidentiel": "C-0071"
                  },
                  "site": {
                    "id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                    "libelle": "Siège",
                    "ville": "Abidjan",
                    "adresse": null
                  },
                  "offre": {
                    "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                    "produit_id": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                    "code": "DATA-50GO-HEBDO",
                    "libelle": "Forfait 50 Go hebdomadaire",
                    "volume_go": 50,
                    "periode": "hebdomadaire",
                    "debit": "Selon capacité",
                    "nb_appareils": null,
                    "nb_acces": null,
                    "actif": true,
                    "cree_le": "2026-10-12T13:18:08.116Z",
                    "modifie_le": "2026-10-12T13:18:08.116Z"
                  },
                  "commande": {
                    "id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                    "numero": "CMD-2026-000029",
                    "statut": "active",
                    "total_ttc": "23600"
                  },
                  "contrat_precedent": null,
                  "connexion": {
                    "id": "2cbd8fbf-efb3-4fd9-a660-e676fb9c6dc0",
                    "statut": "active",
                    "identifiant_vipnet": "SL-CNX-WNCYUQRHJW",
                    "active_le": "2026-10-19T10:44:38.751Z"
                  },
                  "pdf_fichier": null,
                  "pdf_signe_fichier": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "contrats.gerer",
          "espace_partenaire.acceder",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/contrats/{id}/document": {
      "post": {
        "operationId": "postContratsParIdDocument",
        "tags": [
          "Commandes et contrats"
        ],
        "summary": "Éditer le contrat en PDF",
        "description": "Produit le PDF du contrat et le dépose dans le stockage ; le client et le partenaire peuvent l'obtenir eux-mêmes, dans la limite de ce qu'ils peuvent lire. Déjà produit, le document existant est rendu tel quel (`deja_produit: true`) : deux pièces au même numéro ne peuvent pas exister. La réponse donne l'identifiant du fichier, sa taille et son empreinte SHA-256, pas le binaire.\n\n**Permission requise** : L'une de : `contrats.gerer`, `espace_partenaire.acceder`, `devis.accepter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "contrat_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "taille_octets": {
                      "type": "integer"
                    },
                    "empreinte_sha256": {
                      "type": "string"
                    },
                    "modele": {
                      "type": "string"
                    },
                    "deja_produit": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "contrat_id",
                    "numero",
                    "fichier_id",
                    "taille_octets",
                    "empreinte_sha256",
                    "modele",
                    "deja_produit"
                  ]
                },
                "example": {
                  "contrat_id": "8d60d27f-4fe9-4c26-b8f3-d603de945e4f",
                  "numero": "CTR-2026-000030",
                  "fichier_id": "4a9ac9a2-3913-4e6a-bd40-b48e69a83135",
                  "taille_octets": 54801,
                  "empreinte_sha256": "8a6c369222190f1ebf584a65533f56bd4871c8537ee9f2cf7c70e3706674b871",
                  "modele": "modèle livré",
                  "deja_produit": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "contrats.gerer",
          "espace_partenaire.acceder",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/parametres": {
      "get": {
        "operationId": "getParametres",
        "tags": [
          "Administration"
        ],
        "summary": "Lister les paramètres de la plateforme",
        "description": "Tous les paramètres métier (délais, seuils, modes), avec leur valeur, leur libellé et s'ils sont modifiables. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : Être connecté (aucune permission particulière).\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "cle": {
                            "type": "string"
                          },
                          "valeur": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "integer"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string"
                                    },
                                    {
                                      "type": "integer"
                                    }
                                  ]
                                }
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "card": {
                                    "type": "number"
                                  },
                                  "wave": {
                                    "type": "number"
                                  },
                                  "mobile_money": {
                                    "type": "number"
                                  },
                                  "card_international": {
                                    "type": "number"
                                  }
                                },
                                "required": [
                                  "card",
                                  "wave",
                                  "mobile_money",
                                  "card_international"
                                ]
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "modifiable": {
                            "type": "boolean"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "cle",
                          "valeur",
                          "libelle",
                          "modifiable",
                          "modifie_le"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "cle": "affectation.delai_prise_contact_heures",
                      "valeur": null,
                      "libelle": "Délai maximum de prise de contact par le partenaire (heures) — à définir",
                      "modifiable": true,
                      "modifie_le": "2026-10-12T13:18:08.116Z"
                    },
                    {
                      "cle": "affectation.nb_partenaires_proposes",
                      "valeur": null,
                      "libelle": "Nombre de partenaires proposés à un client venu en direct — à définir",
                      "modifiable": true,
                      "modifie_le": "2026-10-12T13:18:08.116Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "connecte",
        "x-satelica-cloisonnement": "sans_objet"
      }
    },
    "/api/v1/parametres/{cle}": {
      "patch": {
        "operationId": "patchParametresParCle",
        "tags": [
          "Administration"
        ],
        "summary": "Modifier la valeur d'un paramètre",
        "description": "Remplace la valeur du paramètre désigné par sa clé (`delais.prise_contact_heures`, par exemple). La valeur est libre : nombre, texte, booléen ou liste. Un paramètre non modifiable est refusé. La modification est inscrite au journal d’audit.\n\n**Permission requise** : `parametres.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "cle",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 120,
              "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "valeur": {}
                },
                "required": [
                  "valeur"
                ]
              },
              "example": {
                "valeur": "signature"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "cle": {
                      "type": "string"
                    },
                    "valeur": {
                      "type": "string"
                    },
                    "libelle": {
                      "type": "string"
                    },
                    "modifiable": {
                      "type": "boolean"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "cle",
                    "valeur",
                    "libelle",
                    "modifiable",
                    "modifie_le"
                  ]
                },
                "example": {
                  "cle": "commission.declencheur_latente",
                  "valeur": "signature",
                  "libelle": "Commission latente à",
                  "modifiable": true,
                  "modifie_le": "2026-10-19T10:45:18.856Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "parametres.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/partenaires/{id}/suppression": {
      "get": {
        "operationId": "getPartenairesParIdSuppression",
        "tags": [
          "Partenaires"
        ],
        "summary": "Vérifier si un partenaire peut être supprimé",
        "description": "Dit si le dossier du partenaire peut être supprimé et, sinon, pourquoi : signature électronique, clients portés, commissions, demandes de versement, contrats, commandes, contrat-cadre signé ou traces dans le dossier d'un client. Quand c'est possible, renvoie l'inventaire de ce que la suppression emporterait. Ne modifie rien : à appeler avant `DELETE /partenaires/{id}`.\n\n**Permission requise** : `partenaires.supprimer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut"
                      ]
                    },
                    "possible": {
                      "type": "boolean"
                    },
                    "refus": {
                      "type": "string"
                    },
                    "inventaire": {
                      "type": "object",
                      "properties": {}
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "partenaire",
                    "possible",
                    "refus",
                    "inventaire",
                    "total"
                  ]
                },
                "example": {
                  "partenaire": {
                    "id": "d9164b91-7b18-4b5a-9cc9-99de62c3ac8b",
                    "raison_sociale": "Distributeur de démonstration Odoo",
                    "statut": "actif"
                  },
                  "possible": false,
                  "refus": "Ce partenaire porte 1 client : cédez-le à un autre partenaire avant de supprimer son dossier.",
                  "inventaire": {},
                  "total": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "partenaires.supprimer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/partenaires/{id}": {
      "delete": {
        "operationId": "deletePartenairesParId",
        "tags": [
          "Partenaires"
        ],
        "summary": "Supprimer un partenaire et tout son dossier",
        "description": "Efface le partenaire et tout ce qui en dépend, en une transaction. Exige un motif et la raison sociale recopiée à l'identique (`confirmation`). Refusé tant qu'il porte un client (à céder d'abord) ou qu'il a produit un fait : signature, commission, demande de versement, contrat, commande, contrat-cadre signé, trace dans le dossier d'un client. Le nom, le motif et l'inventaire effacé sont inscrits au journal d'audit.\n\n**Permission requise** : `partenaires.supprimer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "motif": {
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 500
                  },
                  "confirmation": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 300
                  }
                },
                "required": [
                  "motif",
                  "confirmation"
                ]
              },
              "example": {
                "motif": "Référencé en double.",
                "confirmation": "ZZ Recette Partenaire F 3E38C6A4"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "emporte": {
                      "type": "object",
                      "properties": {
                        "comptes d’accès": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "comptes d’accès"
                      ]
                    }
                  },
                  "required": [
                    "supprime",
                    "raison_sociale",
                    "emporte"
                  ]
                },
                "example": {
                  "supprime": true,
                  "raison_sociale": "ZZ Recette Partenaire F 3E38C6A4",
                  "emporte": {
                    "comptes d’accès": 2
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Le partenaire porte des clients ou a produit un fait qui interdit sa suppression.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "partenaires.supprimer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "get": {
        "operationId": "getPartenairesParId",
        "tags": [
          "Partenaires"
        ],
        "summary": "Lire la fiche d'un partenaire",
        "description": "La fiche complète : organisation, zones, secteurs, conditions commerciales, contrats-cadres, pièces du dossier en vigueur et leur résumé, clients rattachés et comptes utilisateurs de son organisation.\n\n**Permission requise** : L'une de : `partenaires.consulter`, `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "forme_juridique": {
                      "type": "null"
                    },
                    "rccm": {
                      "type": "string"
                    },
                    "ncc": {
                      "type": "string"
                    },
                    "adresse": {
                      "type": "null"
                    },
                    "ville": {
                      "type": "string"
                    },
                    "zone_principale_id": {
                      "type": "null"
                    },
                    "telephone": {
                      "type": "null"
                    },
                    "email": {
                      "type": "string"
                    },
                    "capacite_commerciale": {
                      "type": "null"
                    },
                    "mode_versement": {
                      "type": "string"
                    },
                    "rib": {
                      "type": "null"
                    },
                    "numero_mobile_money": {
                      "type": "null"
                    },
                    "logo_fichier_id": {
                      "type": "null"
                    },
                    "presentation": {
                      "type": "null"
                    },
                    "profil_publie": {
                      "type": "boolean"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "valide_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "code_confidentiel": {
                      "type": "string"
                    },
                    "conditions_commerciales": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "version": {
                            "type": "integer"
                          },
                          "contenu": {
                            "type": "object",
                            "properties": {
                              "remise_max_pct": {
                                "type": "integer"
                              },
                              "taux_premiere_vente": {
                                "type": "integer"
                              },
                              "taux_renouvellement": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "remise_max_pct",
                              "taux_premiere_vente",
                              "taux_renouvellement"
                            ]
                          },
                          "statut": {
                            "type": "string"
                          },
                          "proposees_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "acceptees_par": {
                            "type": "null"
                          },
                          "acceptees_le": {
                            "type": "null"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "partenaire_id",
                          "version",
                          "contenu",
                          "statut",
                          "proposees_par",
                          "acceptees_par",
                          "acceptees_le",
                          "cree_le",
                          "modifie_le"
                        ]
                      }
                    },
                    "contrats_cadres": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "conditions_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "fichier_genere_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "fichier_signe_id": {
                            "type": "null"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "date_debut": {
                            "type": "null"
                          },
                          "date_fin": {
                            "type": "null"
                          },
                          "signe_le": {
                            "type": "null"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "partenaire_id",
                          "conditions_id",
                          "fichier_genere_id",
                          "fichier_signe_id",
                          "statut",
                          "date_debut",
                          "date_fin",
                          "signe_le",
                          "cree_le",
                          "modifie_le"
                        ]
                      }
                    },
                    "logo_adresse": {
                      "type": "null"
                    },
                    "organisation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "type": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "modifie_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "type",
                        "nom",
                        "statut",
                        "cree_le",
                        "modifie_le"
                      ]
                    },
                    "zone_principale": {
                      "type": "null"
                    },
                    "zones": {
                      "type": "array",
                      "items": {}
                    },
                    "secteurs": {
                      "type": "array",
                      "items": {}
                    },
                    "nb_clients": {
                      "type": "integer"
                    },
                    "kyc": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "valides": {
                          "type": "integer"
                        },
                        "a_verifier": {
                          "type": "integer"
                        },
                        "a_completer": {
                          "type": "integer"
                        },
                        "rejetes": {
                          "type": "integer"
                        },
                        "expires": {
                          "type": "integer"
                        },
                        "obligatoires_manquants": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total",
                        "valides",
                        "a_verifier",
                        "a_completer",
                        "rejetes",
                        "expires",
                        "obligatoires_manquants"
                      ]
                    },
                    "documents_kyc": {
                      "type": "array",
                      "items": {}
                    },
                    "clients": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "raison_sociale": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "raison_sociale",
                          "statut"
                        ]
                      }
                    },
                    "utilisateurs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "role_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "prenom": {
                            "type": "string"
                          },
                          "nom": {
                            "type": "string"
                          },
                          "email": {
                            "type": "string"
                          },
                          "telephone": {
                            "type": "null"
                          },
                          "fonction": {
                            "type": "null"
                          },
                          "actif": {
                            "type": "boolean"
                          },
                          "double_authentification": {
                            "type": "boolean"
                          },
                          "derniere_connexion": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "invite_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "roles": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "code": {
                                  "type": "string"
                                },
                                "libelle": {
                                  "type": "string"
                                },
                                "type_organisation": {
                                  "type": "string"
                                },
                                "systeme": {
                                  "type": "boolean"
                                },
                                "cree_le": {
                                  "type": "string",
                                  "format": "date-time"
                                },
                                "modifie_le": {
                                  "type": "string",
                                  "format": "date-time"
                                }
                              },
                              "required": [
                                "id",
                                "code",
                                "libelle",
                                "type_organisation",
                                "systeme",
                                "cree_le",
                                "modifie_le"
                              ]
                            }
                          },
                          "organisation": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "type": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "type",
                              "nom",
                              "statut",
                              "cree_le",
                              "modifie_le"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "organisation_id",
                          "role_id",
                          "prenom",
                          "nom",
                          "email",
                          "telephone",
                          "fonction",
                          "actif",
                          "double_authentification",
                          "derniere_connexion",
                          "invite_par",
                          "cree_le",
                          "modifie_le",
                          "roles",
                          "organisation"
                        ]
                      }
                    },
                    "historique": {
                      "type": "array",
                      "items": {}
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "raison_sociale",
                    "forme_juridique",
                    "rccm",
                    "ncc",
                    "adresse",
                    "ville",
                    "zone_principale_id",
                    "telephone",
                    "email",
                    "capacite_commerciale",
                    "mode_versement",
                    "rib",
                    "numero_mobile_money",
                    "logo_fichier_id",
                    "presentation",
                    "profil_publie",
                    "statut",
                    "valide_par",
                    "valide_le",
                    "cree_le",
                    "modifie_le",
                    "code_confidentiel",
                    "conditions_commerciales",
                    "contrats_cadres",
                    "logo_adresse",
                    "organisation",
                    "zone_principale",
                    "zones",
                    "secteurs",
                    "nb_clients",
                    "kyc",
                    "documents_kyc",
                    "clients",
                    "utilisateurs",
                    "historique"
                  ]
                },
                "example": {
                  "id": "4fd8cdd8-4db0-4f30-a7c1-58308cbeb476",
                  "organisation_id": "3b202fda-d1cb-43b4-82eb-ddb847b5bd8b",
                  "raison_sociale": "ZZ Recette Partenaire F 3E38C6A4",
                  "forme_juridique": null,
                  "rccm": "CI-ZZR-3E38C6A4",
                  "ncc": "NCC-ZZR-3E38C6A4",
                  "adresse": null,
                  "ville": "Abidjan",
                  "zone_principale_id": null,
                  "telephone": null,
                  "email": "partenaire.zzr.3e38c6a4@satelica.test",
                  "capacite_commerciale": null,
                  "mode_versement": "virement",
                  "rib": null,
                  "numero_mobile_money": null,
                  "logo_fichier_id": null,
                  "presentation": null,
                  "profil_publie": false,
                  "statut": "actif",
                  "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "valide_le": "2026-10-19T10:45:18.059Z",
                  "cree_le": "2026-10-19T10:45:17.019Z",
                  "modifie_le": "2026-10-19T10:45:18.058Z",
                  "code_confidentiel": "C-0075",
                  "conditions_commerciales": [],
                  "contrats_cadres": [],
                  "logo_adresse": null,
                  "organisation": {
                    "id": "3b202fda-d1cb-43b4-82eb-ddb847b5bd8b",
                    "type": "partenaire",
                    "nom": "ZZ Recette Partenaire F 3E38C6A4",
                    "statut": "active",
                    "cree_le": "2026-10-19T10:45:17.018Z",
                    "modifie_le": "2026-10-19T10:45:17.018Z"
                  },
                  "zone_principale": null,
                  "zones": [],
                  "secteurs": [],
                  "nb_clients": 0,
                  "kyc": {
                    "total": 0,
                    "valides": 0,
                    "a_verifier": 0,
                    "a_completer": 0,
                    "rejetes": 0,
                    "expires": 0,
                    "obligatoires_manquants": 5
                  },
                  "documents_kyc": [],
                  "clients": [],
                  "utilisateurs": [
                    {
                      "id": "711a7e90-9c9a-4983-9e04-9f2261565f1b",
                      "organisation_id": "3b202fda-d1cb-43b4-82eb-ddb847b5bd8b",
                      "role_id": "d4d9b5da-4cf4-4c3c-8932-a40a541e991f",
                      "prenom": "ZZ Recette",
                      "nom": "Partenaire F 3E38C6A4",
                      "email": "partenaire.zzr.3e38c6a4@satelica.test",
                      "telephone": null,
                      "fonction": null,
                      "actif": true,
                      "double_authentification": false,
                      "derniere_connexion": null,
                      "invite_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "cree_le": "2026-10-19T10:45:17.153Z",
                      "modifie_le": "2026-10-19T10:45:17.153Z",
                      "roles": [
                        {
                          "id": "d4d9b5da-4cf4-4c3c-8932-a40a541e991f",
                          "code": "partenaire_administrateur",
                          "libelle": "Administrateur partenaire",
                          "type_organisation": "partenaire",
                          "systeme": true,
                          "cree_le": "2026-10-12T13:18:08.116Z",
                          "modifie_le": "2026-10-12T13:18:08.116Z"
                        }
                      ],
                      "organisation": {
                        "id": "3b202fda-d1cb-43b4-82eb-ddb847b5bd8b",
                        "type": "partenaire",
                        "nom": "ZZ Recette Partenaire F 3E38C6A4",
                        "statut": "active",
                        "cree_le": "2026-10-19T10:45:17.018Z",
                        "modifie_le": "2026-10-19T10:45:17.018Z"
                      }
                    },
                    {
                      "id": "84496735-0d52-49d1-b24f-234971fa8737",
                      "organisation_id": "3b202fda-d1cb-43b4-82eb-ddb847b5bd8b",
                      "role_id": "d4d9b5da-4cf4-4c3c-8932-a40a541e991f",
                      "prenom": "ZZ Recette",
                      "nom": "Partenaire F 3E38C6A4",
                      "email": "zz.recette.3e38c6a4@exemple.invalide",
                      "telephone": null,
                      "fonction": null,
                      "actif": true,
                      "double_authentification": false,
                      "derniere_connexion": null,
                      "invite_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "cree_le": "2026-10-19T10:45:17.793Z",
                      "modifie_le": "2026-10-19T10:45:17.793Z",
                      "roles": [
                        {
                          "id": "d4d9b5da-4cf4-4c3c-8932-a40a541e991f",
                          "code": "partenaire_administrateur",
                          "libelle": "Administrateur partenaire",
                          "type_organisation": "partenaire",
                          "systeme": true,
                          "cree_le": "2026-10-12T13:18:08.116Z",
                          "modifie_le": "2026-10-12T13:18:08.116Z"
                        }
                      ],
                      "organisation": {
                        "id": "3b202fda-d1cb-43b4-82eb-ddb847b5bd8b",
                        "type": "partenaire",
                        "nom": "ZZ Recette Partenaire F 3E38C6A4",
                        "statut": "active",
                        "cree_le": "2026-10-19T10:45:17.018Z",
                        "modifie_le": "2026-10-19T10:45:17.018Z"
                      }
                    }
                  ],
                  "historique": []
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "partenaires.consulter",
          "espace_partenaire.acceder"
        ],
        "x-satelica-cloisonnement": "applique"
      },
      "patch": {
        "operationId": "patchPartenairesParId",
        "tags": [
          "Partenaires"
        ],
        "summary": "Corriger la fiche d'un partenaire",
        "description": "Modifie l'identité, les coordonnées et les modalités de versement : seuls les champs envoyés changent, `null` vide un champ facultatif, et l'adresse e-mail se corrige sans pouvoir s'effacer. Le statut ne se modifie pas ici. Refusé si le RCCM ou le NCC est déjà celui d'un autre partenaire ; une nouvelle raison sociale renomme aussi l'organisation.\n\n**Permission requise** : L'une de : `partenaires.qualifier`, `partenaires.activer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "raison_sociale": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 200
                  },
                  "forme_juridique": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 80
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "rccm": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 60
                  },
                  "ncc": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 60
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "adresse": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 300
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "ville": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 120
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "zone_principale_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "logo_fichier_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "telephone": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "email": {
                    "type": "string",
                    "maxLength": 200,
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "capacite_commerciale": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 100000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "mode_versement": {
                    "type": "string",
                    "enum": [
                      "virement",
                      "mobile_money",
                      "wave"
                    ]
                  },
                  "rib": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 60
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "numero_mobile_money": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 40
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                }
              },
              "example": {
                "ville": "Yamoussoukro",
                "adresse": "Quartier Habitat, Yamoussoukro"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "forme_juridique": {
                      "type": "null"
                    },
                    "rccm": {
                      "type": "string"
                    },
                    "ncc": {
                      "type": "string"
                    },
                    "adresse": {
                      "type": "string"
                    },
                    "ville": {
                      "type": "string"
                    },
                    "zone_principale_id": {
                      "type": "null"
                    },
                    "telephone": {
                      "type": "null"
                    },
                    "email": {
                      "type": "string"
                    },
                    "capacite_commerciale": {
                      "type": "null"
                    },
                    "mode_versement": {
                      "type": "string"
                    },
                    "rib": {
                      "type": "null"
                    },
                    "numero_mobile_money": {
                      "type": "null"
                    },
                    "logo_fichier_id": {
                      "type": "null"
                    },
                    "presentation": {
                      "type": "null"
                    },
                    "profil_publie": {
                      "type": "boolean"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "valide_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "code_confidentiel": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "raison_sociale",
                    "forme_juridique",
                    "rccm",
                    "ncc",
                    "adresse",
                    "ville",
                    "zone_principale_id",
                    "telephone",
                    "email",
                    "capacite_commerciale",
                    "mode_versement",
                    "rib",
                    "numero_mobile_money",
                    "logo_fichier_id",
                    "presentation",
                    "profil_publie",
                    "statut",
                    "valide_par",
                    "valide_le",
                    "cree_le",
                    "modifie_le",
                    "code_confidentiel"
                  ]
                },
                "example": {
                  "id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                  "organisation_id": "e7b69fac-9d3d-47b1-8598-3d1446631729",
                  "raison_sociale": "ZZ Recette Partenaire A 137E8405",
                  "forme_juridique": null,
                  "rccm": "CI-ZZR-137E8405",
                  "ncc": "NCC-ZZR-137E8405",
                  "adresse": "Quartier Habitat, Yamoussoukro",
                  "ville": "Yamoussoukro",
                  "zone_principale_id": null,
                  "telephone": null,
                  "email": "partenaire.zzr.137e8405@satelica.test",
                  "capacite_commerciale": null,
                  "mode_versement": "virement",
                  "rib": null,
                  "numero_mobile_money": null,
                  "logo_fichier_id": null,
                  "presentation": null,
                  "profil_publie": false,
                  "statut": "actif",
                  "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "valide_le": "2026-10-19T10:44:52.958Z",
                  "cree_le": "2026-10-19T10:44:52.134Z",
                  "modifie_le": "2026-10-19T10:44:57.318Z",
                  "code_confidentiel": "C-0073"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Ce RCCM ou ce NCC est déjà celui d'un autre partenaire.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "partenaires.qualifier",
          "partenaires.activer"
        ],
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/conditions-commerciales/{id}/decision": {
      "post": {
        "operationId": "postConditionsCommercialesParIdDecision",
        "tags": [
          "Partenaires"
        ],
        "summary": "Accepter ou refuser des conditions commerciales",
        "description": "Le partenaire accepte ou refuse des conditions commerciales au statut `proposees` ; un refus exige un motif. La décision est tracée sur la fiche du partenaire et inscrite au journal d'audit.\n\n**Permission requise** : `partenaire.conditions_accepter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "acceptees",
                      "refusees"
                    ]
                  },
                  "motif": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "acceptees"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "version": {
                      "type": "integer"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "acceptees_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "version",
                    "statut",
                    "acceptees_le"
                  ]
                },
                "example": {
                  "id": "477ee2e6-6f3b-47b2-81c8-a3f44cdb6ece",
                  "version": 1,
                  "statut": "acceptees",
                  "acceptees_le": "2026-10-19T10:44:59.987Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Ces conditions ne sont plus à décider.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "partenaire.conditions_accepter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/contrats-cadres/{id}/signature": {
      "post": {
        "operationId": "postContratsCadresParIdSignature",
        "tags": [
          "Partenaires"
        ],
        "summary": "Déposer le contrat-cadre signé",
        "description": "Rattache au contrat-cadre le fichier signé, déjà envoyé par l'appelant (`POST /fichiers`) et déclaré sain par l'antivirus. Le contrat, `genere` ou `envoye`, passe `signe` à la date donnée (le jour même par défaut). Le dépôt est tracé sur la fiche du partenaire et inscrit au journal d'audit.\n\n**Permission requise** : `partenaire.dossier_gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fichier_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "signe_le": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  }
                },
                "required": [
                  "fichier_id"
                ]
              },
              "example": {
                "fichier_id": "f7e98aff-138f-4207-9caa-45c61fc67e67",
                "signe_le": "2026-10-19"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "signe_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "statut",
                    "signe_le"
                  ]
                },
                "example": {
                  "id": "bcdc9a49-ab9d-403c-949b-49a9361748ba",
                  "numero": "CC-ZZR-9F00E83E",
                  "statut": "signe",
                  "signe_le": "2026-10-19T12:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Contrat déjà signé ou non signable, ou fichier non déclaré sain.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "partenaire.dossier_gerer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/partenaires/{id}/profil-public": {
      "patch": {
        "operationId": "patchPartenairesParIdProfilPublic",
        "tags": [
          "Partenaires"
        ],
        "summary": "Modifier le profil public d'un partenaire",
        "description": "Met à jour la présentation, le logo, le téléphone, l'e-mail et la ville du profil affiché sur la vitrine. Toute modification retire le profil de la vitrine (`profil_publie` faux) ; `soumettre: true` en demande la publication, que CYBASTION décide. Le logo doit être une image déposée par l'appelant et déclarée saine.\n\n**Permission requise** : `partenaire.dossier_gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "presentation": {
                    "type": "string",
                    "maxLength": 4000
                  },
                  "logo_fichier_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "telephone": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "email": {
                    "type": "string",
                    "maxLength": 200,
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "ville": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "soumettre": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "presentation": "Distributeur Starlink pour les entreprises du centre du pays.",
                "ville": "Yamoussoukro",
                "soumettre": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "presentation": {
                      "type": "string"
                    },
                    "logo_fichier_id": {
                      "type": "null"
                    },
                    "telephone": {
                      "type": "null"
                    },
                    "email": {
                      "type": "string"
                    },
                    "ville": {
                      "type": "string"
                    },
                    "profil_publie": {
                      "type": "boolean"
                    },
                    "soumis_a_publication": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "raison_sociale",
                    "presentation",
                    "logo_fichier_id",
                    "telephone",
                    "email",
                    "ville",
                    "profil_publie",
                    "soumis_a_publication"
                  ]
                },
                "example": {
                  "id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                  "raison_sociale": "ZZ Recette Partenaire A 137E8405",
                  "presentation": "Distributeur Starlink pour les entreprises du centre du pays.",
                  "logo_fichier_id": null,
                  "telephone": null,
                  "email": "partenaire.zzr.137e8405@satelica.test",
                  "ville": "Yamoussoukro",
                  "profil_publie": false,
                  "soumis_a_publication": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Le logo n'a pas passé le contrôle antivirus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "partenaire.dossier_gerer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/documents-kyc": {
      "post": {
        "operationId": "postDocumentsKyc",
        "tags": [
          "Partenaires"
        ],
        "summary": "Déposer une pièce au dossier",
        "description": "Rattache un fichier déjà envoyé par l'appelant (`POST /fichiers`) et déclaré sain au dossier d'une organisation : la sienne par défaut, ou celle d'un client de son portefeuille ou dont il a une réservation en cours (`organisation_id`). Le type doit être actif et viser ce genre d'organisation. La pièce naît `depose`, les versions précédentes non validées du même type passent `remplace` et le dossier d'un client passe en vérification ; sans date d'expiration, elle se déduit du type.\n\n**Permission requise** : L'une de : `partenaire.dossier_gerer`, `client.dossier_gerer`, `clients.creer`, `partenaires.documents_verifier`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type_document_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "fichier_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "organisation_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "date_emission": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  },
                  "date_expiration": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  }
                },
                "required": [
                  "type_document_id",
                  "fichier_id"
                ]
              },
              "example": {
                "type_document_id": "667a07d3-90d6-4b45-9430-ef1f215e331c",
                "fichier_id": "c34f6bb8-9e68-4d97-82bd-3f19f368766b",
                "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc",
                "date_expiration": "2026-10-29"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "type_document": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code": {
                          "type": "string"
                        },
                        "libelle": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "code",
                        "libelle"
                      ]
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    }
                  },
                  "required": [
                    "id",
                    "statut",
                    "type_document",
                    "organisation_id"
                  ]
                },
                "example": {
                  "id": "b3e321b1-fe84-46f9-888d-0ed736c744e7",
                  "statut": "depose",
                  "type_document": {
                    "id": "667a07d3-90d6-4b45-9430-ef1f215e331c",
                    "code": "client_document_complementaire",
                    "libelle": "Document KYC complémentaire"
                  },
                  "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Fichier déjà au dossier pour ce type, ou non déclaré sain.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "partenaire.dossier_gerer",
          "client.dossier_gerer",
          "clients.creer",
          "partenaires.documents_verifier"
        ],
        "x-satelica-cloisonnement": "applique"
      },
      "get": {
        "operationId": "getDocumentsKyc",
        "tags": [
          "Partenaires"
        ],
        "summary": "Lister les pièces des dossiers",
        "description": "Les pièces KYC, des plus récentes aux plus anciennes, avec leur type, leur fichier, leur vérificateur et leur titulaire (la fiche partenaire ou client à ouvrir). Sans filtre de statut, seul le dossier en vigueur est servi : une pièce `remplace` ne revient que demandée. Filtres : cible, statut (plusieurs valeurs) et organisation. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : L'une de : `partenaires.documents_verifier`, `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "cible",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "partenaire",
                "client"
              ]
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "organisation_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 5 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type_document_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "fichier_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "date_emission": {
                            "type": "null"
                          },
                          "date_expiration": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "motif": {
                            "type": "null"
                          },
                          "verifie_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "verifie_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "type_document": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "cible": {
                                "type": "string"
                              },
                              "obligatoire": {
                                "type": "boolean"
                              },
                              "validite_mois": {
                                "type": "null"
                              },
                              "actif": {
                                "type": "boolean"
                              },
                              "exigee_creation": {
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "cible",
                              "obligatoire",
                              "validite_mois",
                              "actif",
                              "exigee_creation"
                            ]
                          },
                          "fichier": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "bucket": {
                                "type": "string"
                              },
                              "chemin": {
                                "type": "string"
                              },
                              "nom_original": {
                                "type": "string"
                              },
                              "type_mime": {
                                "type": "string"
                              },
                              "taille_octets": {
                                "type": "integer"
                              },
                              "empreinte_sha256": {
                                "type": "string"
                              },
                              "statut_scan": {
                                "type": "string"
                              },
                              "depose_par": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "bucket",
                              "chemin",
                              "nom_original",
                              "type_mime",
                              "taille_octets",
                              "empreinte_sha256",
                              "statut_scan",
                              "depose_par",
                              "cree_le"
                            ]
                          },
                          "verifie_par_utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "titulaire": {
                            "type": "object",
                            "properties": {
                              "cible": {
                                "type": "string"
                              },
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "nom": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "cible",
                              "id",
                              "nom"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "organisation_id",
                          "type_document_id",
                          "fichier_id",
                          "date_emission",
                          "date_expiration",
                          "statut",
                          "motif",
                          "verifie_par",
                          "verifie_le",
                          "cree_le",
                          "modifie_le",
                          "type_document",
                          "fichier",
                          "verifie_par_utilisateur",
                          "titulaire"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "b3e321b1-fe84-46f9-888d-0ed736c744e7",
                      "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc",
                      "type_document_id": "667a07d3-90d6-4b45-9430-ef1f215e331c",
                      "fichier_id": "c34f6bb8-9e68-4d97-82bd-3f19f368766b",
                      "date_emission": null,
                      "date_expiration": "2026-10-29",
                      "statut": "depose",
                      "motif": null,
                      "verifie_par": null,
                      "verifie_le": null,
                      "cree_le": "2026-10-19T10:44:29.270Z",
                      "modifie_le": "2026-10-19T10:44:29.270Z",
                      "type_document": {
                        "id": "667a07d3-90d6-4b45-9430-ef1f215e331c",
                        "code": "client_document_complementaire",
                        "libelle": "Document KYC complémentaire",
                        "cible": "client",
                        "obligatoire": false,
                        "validite_mois": null,
                        "actif": true,
                        "exigee_creation": false
                      },
                      "fichier": {
                        "id": "c34f6bb8-9e68-4d97-82bd-3f19f368766b",
                        "bucket": "kyc",
                        "chemin": "kyc/2026/10/45498750-88ae-4f39-8b46-01900785999d.pdf",
                        "nom_original": "rccm.pdf",
                        "type_mime": "application/pdf",
                        "taille_octets": 191,
                        "empreinte_sha256": "cf9f8c74b748cd6f0a1cecf17dbc38d2089427ac482ab3ec1001d4e80ccb3a8e",
                        "statut_scan": "sain",
                        "depose_par": "d60b33fd-8d32-4475-a107-5d4bd82d6f3f",
                        "cree_le": "2026-10-19T10:44:28.491Z"
                      },
                      "verifie_par_utilisateur": null,
                      "titulaire": {
                        "cible": "client",
                        "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                        "nom": "ZZ Recette WNCYUQRHJW"
                      }
                    },
                    {
                      "id": "6a3c23f6-79ef-4ed4-be64-2bb0cbcb6fc6",
                      "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc",
                      "type_document_id": "5aeb6ee0-19e8-4ba1-977a-c2c9e532979c",
                      "fichier_id": "2f0f517a-68f2-4de5-8f64-c12b0fac3b28",
                      "date_emission": null,
                      "date_expiration": null,
                      "statut": "depose",
                      "motif": null,
                      "verifie_par": null,
                      "verifie_le": null,
                      "cree_le": "2026-10-19T10:44:26.210Z",
                      "modifie_le": "2026-10-19T10:44:26.210Z",
                      "type_document": {
                        "id": "5aeb6ee0-19e8-4ba1-977a-c2c9e532979c",
                        "code": "client_rccm",
                        "libelle": "Registre du commerce (RCCM)",
                        "cible": "client",
                        "obligatoire": true,
                        "validite_mois": null,
                        "actif": true,
                        "exigee_creation": true
                      },
                      "fichier": {
                        "id": "2f0f517a-68f2-4de5-8f64-c12b0fac3b28",
                        "bucket": "kyc",
                        "chemin": "kyc/2026/10/9c5b52a9-57ce-4043-ace5-88bbcd5011ce.pdf",
                        "nom_original": "client_rccm-WNCYUQRHJW.pdf",
                        "type_mime": "application/pdf",
                        "taille_octets": 216,
                        "empreinte_sha256": "a227d50a44f2c3bccc332fdd4ae80040e8ae3a8ef32a0c585ad3b0f90d9d0427",
                        "statut_scan": "sain",
                        "depose_par": "d60b33fd-8d32-4475-a107-5d4bd82d6f3f",
                        "cree_le": "2026-10-19T10:44:26.049Z"
                      },
                      "verifie_par_utilisateur": null,
                      "titulaire": {
                        "cible": "client",
                        "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                        "nom": "ZZ Recette WNCYUQRHJW"
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "partenaires.documents_verifier",
          "espace_partenaire.acceder"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/partenaires": {
      "post": {
        "operationId": "postPartenaires",
        "tags": [
          "Partenaires"
        ],
        "summary": "Référencer un partenaire",
        "description": "Crée l'organisation et la fiche du partenaire, au statut `candidat` : référencé, pas encore autorisé à vendre. Le RCCM, l'adresse e-mail et le responsable sont obligatoires ; un RCCM ou un NCC déjà connu est refusé. L'accès `partenaire_administrateur` part aussitôt au responsable, à l'adresse du partenaire ; la réponse en donne l'issue (`acces`) et les étapes restantes (`prochaines_etapes`).\n\n**Permission requise** : L'une de : `partenaires.qualifier`, `partenaires.activer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "raison_sociale": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 200
                  },
                  "forme_juridique": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "rccm": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 60
                  },
                  "ncc": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 60
                  },
                  "adresse": {
                    "type": "string",
                    "maxLength": 300
                  },
                  "ville": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "zone_principale_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "logo_fichier_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "telephone": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "email": {
                    "type": "string",
                    "maxLength": 200,
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "responsable": {
                    "type": "object",
                    "properties": {
                      "prenom": {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 100
                      },
                      "nom": {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 100
                      },
                      "fonction": {
                        "type": "string",
                        "maxLength": 120
                      },
                      "telephone": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "prenom",
                      "nom"
                    ]
                  },
                  "capacite_commerciale": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 100000
                  },
                  "mode_versement": {
                    "type": "string",
                    "enum": [
                      "virement",
                      "mobile_money",
                      "wave"
                    ]
                  },
                  "rib": {
                    "type": "string",
                    "maxLength": 60
                  },
                  "numero_mobile_money": {
                    "type": "string",
                    "maxLength": 40
                  }
                },
                "required": [
                  "raison_sociale",
                  "rccm",
                  "email",
                  "responsable"
                ]
              },
              "example": {
                "raison_sociale": "ZZ Recette Partenaire W 8E10C2F1",
                "ville": "Abidjan",
                "rccm": "CI-ZZR-8E10C2F1",
                "ncc": "NCC-ZZR-8E10C2F1",
                "email": "partenaire.zzr.8E10C2F1@satelica.test",
                "responsable": {
                  "prenom": "ZZ Recette",
                  "nom": "Partenaire W 8E10C2F1"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 10 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "forme_juridique": {
                      "type": "null"
                    },
                    "rccm": {
                      "type": "string"
                    },
                    "ncc": {
                      "type": "string"
                    },
                    "adresse": {
                      "type": "null"
                    },
                    "ville": {
                      "type": "string"
                    },
                    "zone_principale_id": {
                      "type": "null"
                    },
                    "telephone": {
                      "type": "null"
                    },
                    "email": {
                      "type": "string"
                    },
                    "capacite_commerciale": {
                      "type": "null"
                    },
                    "mode_versement": {
                      "type": "string"
                    },
                    "rib": {
                      "type": "null"
                    },
                    "numero_mobile_money": {
                      "type": "null"
                    },
                    "logo_fichier_id": {
                      "type": "null"
                    },
                    "presentation": {
                      "type": "null"
                    },
                    "profil_publie": {
                      "type": "boolean"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "valide_par": {
                      "type": "null"
                    },
                    "valide_le": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "code_confidentiel": {
                      "type": "string"
                    },
                    "organisation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom",
                        "type",
                        "statut"
                      ]
                    },
                    "zone_principale": {
                      "type": "null"
                    },
                    "acces": {
                      "type": "object",
                      "properties": {
                        "statut": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        },
                        "utilisateur_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "statut",
                        "email",
                        "utilisateur_id",
                        "message"
                      ]
                    },
                    "prochaines_etapes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "raison_sociale",
                    "forme_juridique",
                    "rccm",
                    "ncc",
                    "adresse",
                    "ville",
                    "zone_principale_id",
                    "telephone",
                    "email",
                    "capacite_commerciale",
                    "mode_versement",
                    "rib",
                    "numero_mobile_money",
                    "logo_fichier_id",
                    "presentation",
                    "profil_publie",
                    "statut",
                    "valide_par",
                    "valide_le",
                    "cree_le",
                    "modifie_le",
                    "code_confidentiel",
                    "organisation",
                    "zone_principale",
                    "acces",
                    "prochaines_etapes"
                  ]
                },
                "example": {
                  "id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                  "organisation_id": "7d86069a-804c-433e-ba25-cabf6ca7bb63",
                  "raison_sociale": "ZZ Recette Partenaire W 8E10C2F1",
                  "forme_juridique": null,
                  "rccm": "CI-ZZR-8E10C2F1",
                  "ncc": "NCC-ZZR-8E10C2F1",
                  "adresse": null,
                  "ville": "Abidjan",
                  "zone_principale_id": null,
                  "telephone": null,
                  "email": "partenaire.zzr.8e10c2f1@satelica.test",
                  "capacite_commerciale": null,
                  "mode_versement": "virement",
                  "rib": null,
                  "numero_mobile_money": null,
                  "logo_fichier_id": null,
                  "presentation": null,
                  "profil_publie": false,
                  "statut": "candidat",
                  "valide_par": null,
                  "valide_le": null,
                  "cree_le": "2026-10-19T10:44:13.865Z",
                  "modifie_le": "2026-10-19T10:44:13.865Z",
                  "code_confidentiel": "C-0070",
                  "organisation": {
                    "id": "7d86069a-804c-433e-ba25-cabf6ca7bb63",
                    "nom": "ZZ Recette Partenaire W 8E10C2F1",
                    "type": "partenaire",
                    "statut": "active"
                  },
                  "zone_principale": null,
                  "acces": {
                    "statut": "envoye",
                    "email": "partenaire.zzr.8e10c2f1@satelica.test",
                    "utilisateur_id": "83ac1e48-3170-445e-9643-07f36ec4ce1f",
                    "message": "Accès envoyé à partenaire.zzr.8e10c2f1@satelica.test : un courriel l’invite à choisir son mot de passe."
                  },
                  "prochaines_etapes": [
                    "Déposer ou faire déposer les pièces du dossier",
                    "Vérifier les pièces, puis activer le partenaire"
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Ce RCCM ou ce NCC est déjà celui d'un autre partenaire.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "partenaires.qualifier",
          "partenaires.activer"
        ],
        "x-satelica-cloisonnement": "cybastion"
      },
      "get": {
        "operationId": "getPartenaires",
        "tags": [
          "Partenaires"
        ],
        "summary": "Lister les partenaires",
        "description": "Les partenaires, par raison sociale, avec organisation, zones, secteurs, adresse du logo, nombre de clients et résumé du dossier KYC (pièces valides, à vérifier, expirées, obligatoires manquantes). Filtres : statut, zone principale et recherche sur la raison sociale, le RCCM, le NCC ou la référence confidentielle (`C-xxxx`).\n\n**Permission requise** : L'une de : `partenaires.consulter`, `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "candidat",
                "en_verification",
                "a_completer",
                "rejete",
                "valide",
                "actif",
                "suspendu"
              ]
            }
          },
          {
            "name": "zone_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "recherche",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 120
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 6 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "raison_sociale": {
                            "type": "string"
                          },
                          "forme_juridique": {
                            "type": "null"
                          },
                          "rccm": {
                            "type": "string"
                          },
                          "ncc": {
                            "type": "string"
                          },
                          "adresse": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "ville": {
                            "type": "string"
                          },
                          "zone_principale_id": {
                            "type": "null"
                          },
                          "telephone": {
                            "type": "null"
                          },
                          "email": {
                            "type": "string"
                          },
                          "capacite_commerciale": {
                            "type": "null"
                          },
                          "mode_versement": {
                            "type": "string"
                          },
                          "rib": {
                            "type": "null"
                          },
                          "numero_mobile_money": {
                            "type": "null"
                          },
                          "logo_fichier_id": {
                            "type": "null"
                          },
                          "presentation": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "profil_publie": {
                            "type": "boolean"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "valide_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "valide_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "code_confidentiel": {
                            "type": "string"
                          },
                          "logo_adresse": {
                            "type": "null"
                          },
                          "organisation": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "type": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "type",
                              "nom",
                              "statut",
                              "cree_le",
                              "modifie_le"
                            ]
                          },
                          "zone_principale": {
                            "type": "null"
                          },
                          "zones": {
                            "type": "array",
                            "items": {}
                          },
                          "secteurs": {
                            "type": "array",
                            "items": {}
                          },
                          "nb_clients": {
                            "type": "integer"
                          },
                          "kyc": {
                            "type": "object",
                            "properties": {
                              "total": {
                                "type": "integer"
                              },
                              "valides": {
                                "type": "integer"
                              },
                              "a_verifier": {
                                "type": "integer"
                              },
                              "a_completer": {
                                "type": "integer"
                              },
                              "rejetes": {
                                "type": "integer"
                              },
                              "expires": {
                                "type": "integer"
                              },
                              "obligatoires_manquants": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "total",
                              "valides",
                              "a_verifier",
                              "a_completer",
                              "rejetes",
                              "expires",
                              "obligatoires_manquants"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "organisation_id",
                          "raison_sociale",
                          "forme_juridique",
                          "rccm",
                          "ncc",
                          "adresse",
                          "ville",
                          "zone_principale_id",
                          "telephone",
                          "email",
                          "capacite_commerciale",
                          "mode_versement",
                          "rib",
                          "numero_mobile_money",
                          "logo_fichier_id",
                          "presentation",
                          "profil_publie",
                          "statut",
                          "valide_par",
                          "valide_le",
                          "cree_le",
                          "modifie_le",
                          "code_confidentiel",
                          "logo_adresse",
                          "organisation",
                          "zone_principale",
                          "zones",
                          "secteurs",
                          "nb_clients",
                          "kyc"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "d9164b91-7b18-4b5a-9cc9-99de62c3ac8b",
                      "organisation_id": "935bd040-8eae-4dc8-87e4-7ed05a41d615",
                      "raison_sociale": "Distributeur de démonstration Odoo",
                      "forme_juridique": null,
                      "rccm": "CI-ABJ-2026-B-ODOO1",
                      "ncc": "NCC-ODOO-0001",
                      "adresse": null,
                      "ville": "Abidjan",
                      "zone_principale_id": null,
                      "telephone": null,
                      "email": "contact.distributeur@preprod.satelica.test",
                      "capacite_commerciale": null,
                      "mode_versement": "virement",
                      "rib": null,
                      "numero_mobile_money": null,
                      "logo_fichier_id": null,
                      "presentation": null,
                      "profil_publie": false,
                      "statut": "actif",
                      "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "valide_le": "2026-10-12T19:06:50.716Z",
                      "cree_le": "2026-10-12T19:06:50.200Z",
                      "modifie_le": "2026-10-12T19:06:50.715Z",
                      "code_confidentiel": "C-0026",
                      "logo_adresse": null,
                      "organisation": {
                        "id": "935bd040-8eae-4dc8-87e4-7ed05a41d615",
                        "type": "partenaire",
                        "nom": "Distributeur de démonstration Odoo",
                        "statut": "active",
                        "cree_le": "2026-10-12T19:06:50.197Z",
                        "modifie_le": "2026-10-12T19:06:50.197Z"
                      },
                      "zone_principale": null,
                      "zones": [],
                      "secteurs": [],
                      "nb_clients": 1,
                      "kyc": {
                        "total": 0,
                        "valides": 0,
                        "a_verifier": 0,
                        "a_completer": 0,
                        "rejetes": 0,
                        "expires": 0,
                        "obligatoires_manquants": 5
                      }
                    },
                    {
                      "id": "51fb2993-5cda-47ef-9a6c-bd4e91da812b",
                      "organisation_id": "2031ad71-f339-42a3-86ba-266eab033131",
                      "raison_sociale": "ZZ Recette Partenaire A 02E1D80F",
                      "forme_juridique": null,
                      "rccm": "CI-ZZR-02E1D80F",
                      "ncc": "NCC-ZZR-02E1D80F",
                      "adresse": "Quartier Habitat, Yamoussoukro",
                      "ville": "Yamoussoukro",
                      "zone_principale_id": null,
                      "telephone": null,
                      "email": "partenaire.zzr.02e1d80f@satelica.test",
                      "capacite_commerciale": null,
                      "mode_versement": "virement",
                      "rib": null,
                      "numero_mobile_money": null,
                      "logo_fichier_id": null,
                      "presentation": "Distributeur Starlink pour les entreprises du centre du pays.",
                      "profil_publie": false,
                      "statut": "actif",
                      "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "valide_le": "2026-10-19T10:39:41.933Z",
                      "cree_le": "2026-10-19T10:39:41.164Z",
                      "modifie_le": "2026-10-19T10:39:46.370Z",
                      "code_confidentiel": "C-0058",
                      "logo_adresse": null,
                      "organisation": {
                        "id": "2031ad71-f339-42a3-86ba-266eab033131",
                        "type": "partenaire",
                        "nom": "ZZ Recette Partenaire A 02E1D80F",
                        "statut": "active",
                        "cree_le": "2026-10-19T10:39:41.161Z",
                        "modifie_le": "2026-10-19T10:39:41.161Z"
                      },
                      "zone_principale": null,
                      "zones": [],
                      "secteurs": [],
                      "nb_clients": 1,
                      "kyc": {
                        "total": 0,
                        "valides": 0,
                        "a_verifier": 0,
                        "a_completer": 0,
                        "rejetes": 0,
                        "expires": 0,
                        "obligatoires_manquants": 5
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 20,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "partenaires.consulter",
          "espace_partenaire.acceder"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/partenaires/{id}/statut": {
      "patch": {
        "operationId": "patchPartenairesParIdStatut",
        "tags": [
          "Partenaires"
        ],
        "summary": "Changer le statut d'un partenaire",
        "description": "Pose le statut demandé : valider, activer, rejeter, suspendre ou réactiver le partenaire ; rejeter ou suspendre exige un motif. Enregistrer ou réserver un client n'est permis qu'à un partenaire `valide` ou `actif`. Le changement et son motif sont tracés sur sa fiche et inscrits au journal d'audit.\n\n**Permission requise** : `partenaires.activer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "statut": {
                    "type": "string",
                    "enum": [
                      "candidat",
                      "en_verification",
                      "a_completer",
                      "rejete",
                      "valide",
                      "actif",
                      "suspendu"
                    ]
                  },
                  "motif": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "statut"
                ]
              },
              "example": {
                "statut": "valide",
                "motif": "Fixture de recette."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 21 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "forme_juridique": {
                      "type": "null"
                    },
                    "rccm": {
                      "type": "string"
                    },
                    "ncc": {
                      "type": "string"
                    },
                    "adresse": {
                      "type": "null"
                    },
                    "ville": {
                      "type": "string"
                    },
                    "zone_principale_id": {
                      "type": "null"
                    },
                    "telephone": {
                      "type": "null"
                    },
                    "email": {
                      "type": "string"
                    },
                    "capacite_commerciale": {
                      "type": "null"
                    },
                    "mode_versement": {
                      "type": "string"
                    },
                    "rib": {
                      "type": "null"
                    },
                    "numero_mobile_money": {
                      "type": "null"
                    },
                    "logo_fichier_id": {
                      "type": "null"
                    },
                    "presentation": {
                      "type": "null"
                    },
                    "profil_publie": {
                      "type": "boolean"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "valide_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "code_confidentiel": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "raison_sociale",
                    "forme_juridique",
                    "rccm",
                    "ncc",
                    "adresse",
                    "ville",
                    "zone_principale_id",
                    "telephone",
                    "email",
                    "capacite_commerciale",
                    "mode_versement",
                    "rib",
                    "numero_mobile_money",
                    "logo_fichier_id",
                    "presentation",
                    "profil_publie",
                    "statut",
                    "valide_par",
                    "valide_le",
                    "cree_le",
                    "modifie_le",
                    "code_confidentiel"
                  ]
                },
                "example": {
                  "id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                  "organisation_id": "7d86069a-804c-433e-ba25-cabf6ca7bb63",
                  "raison_sociale": "ZZ Recette Partenaire W 8E10C2F1",
                  "forme_juridique": null,
                  "rccm": "CI-ZZR-8E10C2F1",
                  "ncc": "NCC-ZZR-8E10C2F1",
                  "adresse": null,
                  "ville": "Abidjan",
                  "zone_principale_id": null,
                  "telephone": null,
                  "email": "partenaire.zzr.8e10c2f1@satelica.test",
                  "capacite_commerciale": null,
                  "mode_versement": "virement",
                  "rib": null,
                  "numero_mobile_money": null,
                  "logo_fichier_id": null,
                  "presentation": null,
                  "profil_publie": false,
                  "statut": "valide",
                  "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "valide_le": "2026-10-19T10:44:14.556Z",
                  "cree_le": "2026-10-19T10:44:13.865Z",
                  "modifie_le": "2026-10-19T10:44:14.556Z",
                  "code_confidentiel": "C-0070"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "partenaires.activer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/documents-kyc/{id}": {
      "delete": {
        "operationId": "deleteDocumentsKycParId",
        "tags": [
          "Partenaires"
        ],
        "summary": "Retirer une pièce déposée par erreur",
        "description": "Supprime une pièce du dossier que personne n'a encore examinée, avec le même contrôle de périmètre qu'au dépôt. Une pièce validée, rejetée, à compléter ou remplacée ne se supprime pas : on en dépose une nouvelle version. Le fichier reste au stockage et la suppression est inscrite au journal d'audit.\n\n**Permission requise** : L'une de : `partenaire.dossier_gerer`, `client.dossier_gerer`, `clients.creer`, `partenaires.documents_verifier`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "supprime"
                  ]
                },
                "example": {
                  "supprime": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Pièce déjà examinée ou remplacée : elle ne se supprime plus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "partenaire.dossier_gerer",
          "client.dossier_gerer",
          "clients.creer",
          "partenaires.documents_verifier"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/documents-kyc/{id}/decision": {
      "post": {
        "operationId": "postDocumentsKycParIdDecision",
        "tags": [
          "Partenaires"
        ],
        "summary": "Valider, refuser ou faire compléter une pièce",
        "description": "Décide d'une pièce du dossier ; refuser ou faire compléter exige un motif. Valider une pièce fait passer `remplace` les autres versions validées du même type. L'organisation titulaire est notifiée, et la décision inscrite au journal d'audit.\n\n**Permission requise** : `partenaires.documents_verifier`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "valide",
                      "rejete",
                      "a_completer"
                    ]
                  },
                  "motif": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "valide"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type_document_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "date_emission": {
                      "type": "null"
                    },
                    "date_expiration": {
                      "type": "string",
                      "format": "date"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "motif": {
                      "type": "null"
                    },
                    "verifie_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "verifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "type_document": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code": {
                          "type": "string"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "cible": {
                          "type": "string"
                        },
                        "obligatoire": {
                          "type": "boolean"
                        },
                        "validite_mois": {
                          "type": "null"
                        },
                        "actif": {
                          "type": "boolean"
                        },
                        "exigee_creation": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "code",
                        "libelle",
                        "cible",
                        "obligatoire",
                        "validite_mois",
                        "actif",
                        "exigee_creation"
                      ]
                    },
                    "fichier": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "bucket": {
                          "type": "string"
                        },
                        "chemin": {
                          "type": "string"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        },
                        "taille_octets": {
                          "type": "integer"
                        },
                        "empreinte_sha256": {
                          "type": "string"
                        },
                        "statut_scan": {
                          "type": "string"
                        },
                        "depose_par": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "bucket",
                        "chemin",
                        "nom_original",
                        "type_mime",
                        "taille_octets",
                        "empreinte_sha256",
                        "statut_scan",
                        "depose_par",
                        "cree_le"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "type_document_id",
                    "fichier_id",
                    "date_emission",
                    "date_expiration",
                    "statut",
                    "motif",
                    "verifie_par",
                    "verifie_le",
                    "cree_le",
                    "modifie_le",
                    "type_document",
                    "fichier"
                  ]
                },
                "example": {
                  "id": "b3e321b1-fe84-46f9-888d-0ed736c744e7",
                  "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc",
                  "type_document_id": "667a07d3-90d6-4b45-9430-ef1f215e331c",
                  "fichier_id": "c34f6bb8-9e68-4d97-82bd-3f19f368766b",
                  "date_emission": null,
                  "date_expiration": "2026-10-29",
                  "statut": "valide",
                  "motif": null,
                  "verifie_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "verifie_le": "2026-10-19T10:44:47.288Z",
                  "cree_le": "2026-10-19T10:44:29.270Z",
                  "modifie_le": "2026-10-19T10:44:47.287Z",
                  "type_document": {
                    "id": "667a07d3-90d6-4b45-9430-ef1f215e331c",
                    "code": "client_document_complementaire",
                    "libelle": "Document KYC complémentaire",
                    "cible": "client",
                    "obligatoire": false,
                    "validite_mois": null,
                    "actif": true,
                    "exigee_creation": false
                  },
                  "fichier": {
                    "id": "c34f6bb8-9e68-4d97-82bd-3f19f368766b",
                    "bucket": "kyc",
                    "chemin": "kyc/2026/10/45498750-88ae-4f39-8b46-01900785999d.pdf",
                    "nom_original": "rccm.pdf",
                    "type_mime": "application/pdf",
                    "taille_octets": 191,
                    "empreinte_sha256": "cf9f8c74b748cd6f0a1cecf17dbc38d2089427ac482ab3ec1001d4e80ccb3a8e",
                    "statut_scan": "sain",
                    "depose_par": "d60b33fd-8d32-4475-a107-5d4bd82d6f3f",
                    "cree_le": "2026-10-19T10:44:28.491Z"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Pièce remplacée : la décision se prend sur la version qui lui a succédé.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "partenaires.documents_verifier",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/documents-kyc/expirations": {
      "get": {
        "operationId": "getDocumentsKycExpirations",
        "tags": [
          "Partenaires"
        ],
        "summary": "Lister les pièces qui expirent bientôt",
        "description": "Les pièces datées déjà périmées ou qui expirent dans la fenêtre de prévenance (`jours`, sinon le paramètre `kyc.alerte_expiration_jours`, 30 par défaut), hors pièces rejetées ou remplacées, de l'échéance la plus proche à la plus lointaine (500 au plus). Chaque pièce porte ses jours restants et son état d'expiration ; la réponse compte les périmées, les bientôt périmées et les obligatoires périmées. N'envoie aucune notification.\n\n**Permission requise** : L'une de : `partenaires.documents_verifier`, `partenaire.dossier_gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "jours",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 365
            }
          },
          {
            "name": "organisation_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jour": {
                      "type": "string",
                      "format": "date"
                    },
                    "prevenance_jours": {
                      "type": "integer"
                    },
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "date_emission": {
                            "type": "null"
                          },
                          "date_expiration": {
                            "type": "string",
                            "format": "date"
                          },
                          "jours_avant_expiration": {
                            "type": "integer"
                          },
                          "etat_expiration": {
                            "type": "string"
                          },
                          "organisation": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "nom",
                              "type"
                            ]
                          },
                          "type_document": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "obligatoire": {
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "obligatoire"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "statut",
                          "date_emission",
                          "date_expiration",
                          "jours_avant_expiration",
                          "etat_expiration",
                          "organisation",
                          "type_document"
                        ]
                      }
                    },
                    "perimees": {
                      "type": "integer"
                    },
                    "bientot_perimees": {
                      "type": "integer"
                    },
                    "obligatoires_perimees": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "jour",
                    "prevenance_jours",
                    "donnees",
                    "perimees",
                    "bientot_perimees",
                    "obligatoires_perimees"
                  ]
                },
                "example": {
                  "jour": "2026-10-19",
                  "prevenance_jours": 30,
                  "donnees": [
                    {
                      "id": "de160087-4ca3-4d2b-af65-311778e7b100",
                      "statut": "valide",
                      "date_emission": null,
                      "date_expiration": "2026-10-29",
                      "jours_avant_expiration": 10,
                      "etat_expiration": "bientot_perimee",
                      "organisation": {
                        "id": "a97aac5d-459c-4c08-a60a-2f6b09d51af1",
                        "nom": "ZZ Recette VTUKFKBFPT",
                        "type": "client"
                      },
                      "type_document": {
                        "id": "667a07d3-90d6-4b45-9430-ef1f215e331c",
                        "code": "client_document_complementaire",
                        "libelle": "Document KYC complémentaire",
                        "obligatoire": false
                      }
                    },
                    {
                      "id": "b941a1f0-db98-430a-ac43-3dce3dfe004e",
                      "statut": "valide",
                      "date_emission": null,
                      "date_expiration": "2026-10-29",
                      "jours_avant_expiration": 10,
                      "etat_expiration": "bientot_perimee",
                      "organisation": {
                        "id": "940332f6-b108-47ff-b65d-d60e63a87a20",
                        "nom": "ZZ Recette NDDKNBHRYB",
                        "type": "client"
                      },
                      "type_document": {
                        "id": "667a07d3-90d6-4b45-9430-ef1f215e331c",
                        "code": "client_document_complementaire",
                        "libelle": "Document KYC complémentaire",
                        "obligatoire": false
                      }
                    }
                  ],
                  "perimees": 0,
                  "bientot_perimees": 3,
                  "obligatoires_perimees": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "partenaires.documents_verifier",
          "partenaire.dossier_gerer"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/documents-kyc/alertes": {
      "post": {
        "operationId": "postDocumentsKycAlertes",
        "tags": [
          "Partenaires"
        ],
        "summary": "Prévenir des pièces qui arrivent à terme",
        "description": "Notifie le titulaire de chaque pièce validée qui expire dans la fenêtre de prévenance (`kyc.alerte_expiration_jours`) et, pour un client, le partenaire qui le détient. Idempotent : une pièce déjà signalée dans la fenêtre ne l'est pas de nouveau, ce que le journal des passages précédents permet de savoir. Le bilan distingue les pièces alertées, déjà signalées et sans destinataire actif.\n\n**Permission requise** : `partenaires.documents_verifier`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "alertees": {
                      "type": "integer"
                    },
                    "sans_destinataire": {
                      "type": "integer"
                    },
                    "deja_signalees": {
                      "type": "integer"
                    },
                    "examinees": {
                      "type": "integer"
                    },
                    "prevenance_jours": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "alertees",
                    "deja_signalees",
                    "examinees",
                    "prevenance_jours"
                  ]
                },
                "example": {
                  "alertees": 1,
                  "sans_destinataire": 0,
                  "deja_signalees": 2,
                  "examinees": 3,
                  "prevenance_jours": 30
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "partenaires.documents_verifier",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/mon-espace/relances": {
      "get": {
        "operationId": "getMonEspaceRelances",
        "tags": [
          "Espace partenaire"
        ],
        "summary": "Lister ce que le partenaire doit relancer",
        "description": "Trois files du portefeuille de l'appelant : devis envoyés sans réponse depuis `relance.devis_delai_jours` (7 par défaut), commandes en attente de paiement depuis `relance.commande_delai_jours` (3 par défaut), factures échues avec un reste à payer. Ce qui a déjà été relancé le jour même en sort. Chaque ligne porte le client, son contact principal, le montant (le reste dû pour une facture), l’ancienneté et le nombre de relances. Refusée à un compte qui n'est pas un partenaire.\n\n**Permission requise** : `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "devis": {
                      "type": "array",
                      "items": {}
                    },
                    "commandes": {
                      "type": "array",
                      "items": {}
                    },
                    "factures": {
                      "type": "array",
                      "items": {}
                    }
                  },
                  "required": [
                    "devis",
                    "commandes",
                    "factures"
                  ]
                },
                "example": {
                  "devis": [],
                  "commandes": [],
                  "factures": []
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "espace_partenaire.acceder",
        "x-satelica-cloisonnement": "applique"
      },
      "post": {
        "operationId": "postMonEspaceRelances",
        "tags": [
          "Espace partenaire"
        ],
        "summary": "Consigner la relance d'un client",
        "description": "Le partenaire consigne le rappel qu'il vient de faire sur un devis, une commande ou une facture de son portefeuille : rien n’est envoyé au client. La trace va dans l'historique (devis, commande) ou dans les relances de la facture, alors inscrite au journal d'audit. Renvoie la ligne de relance à jour. Refusée hors compte partenaire.\n\n**Permission requise** : `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "objet": {
                    "type": "string",
                    "enum": [
                      "devis",
                      "commande",
                      "facture"
                    ]
                  },
                  "objet_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "canal": {
                    "type": "string",
                    "enum": [
                      "appel",
                      "email",
                      "whatsapp",
                      "sms"
                    ]
                  },
                  "commentaire": {
                    "type": "string",
                    "maxLength": 2000
                  }
                },
                "required": [
                  "objet",
                  "objet_id",
                  "canal"
                ]
              },
              "example": {
                "objet": "devis",
                "objet_id": "21ff2ce1-1c6c-4f56-86b2-d0a0600b829b",
                "canal": "appel",
                "commentaire": "Épreuve."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "objet": {
                      "type": "string"
                    },
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale"
                      ]
                    },
                    "contact": {
                      "type": "object",
                      "properties": {
                        "nom": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "nom",
                        "telephone",
                        "email"
                      ]
                    },
                    "montant": {
                      "type": "integer"
                    },
                    "depuis_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date"
                    },
                    "jours": {
                      "type": "integer"
                    },
                    "lien": {
                      "type": "string"
                    },
                    "nb_relances": {
                      "type": "integer"
                    },
                    "derniere_relance_le": {
                      "type": "string",
                      "format": "date"
                    }
                  },
                  "required": [
                    "objet",
                    "id",
                    "numero",
                    "client",
                    "contact",
                    "montant",
                    "depuis_le",
                    "jours",
                    "lien",
                    "nb_relances",
                    "derniere_relance_le"
                  ]
                },
                "example": {
                  "objet": "devis",
                  "id": "21ff2ce1-1c6c-4f56-86b2-d0a0600b829b",
                  "numero": "DEV-2026-000067",
                  "client": {
                    "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                    "raison_sociale": "ZZ Recette Client 4D20EED1"
                  },
                  "contact": {
                    "nom": "ZZ Recette Contact 4D20EED1",
                    "telephone": "+225 07 00 00 00 00",
                    "email": "contact.4d20eed1@exemple.invalide"
                  },
                  "montant": 23600,
                  "depuis_le": "2026-10-19",
                  "jours": 0,
                  "lien": "/espace-partenaire/devis/21ff2ce1-1c6c-4f56-86b2-d0a0600b829b",
                  "nb_relances": 1,
                  "derniere_relance_le": "2026-10-19"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "espace_partenaire.acceder",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/mon-espace/taux": {
      "get": {
        "operationId": "getMonEspaceTaux",
        "tags": [
          "Espace partenaire"
        ],
        "summary": "Lire ses taux de commission et son seuil de surperformance",
        "description": "Pour chaque type de ligne, la règle de commission d'une première vente du partenaire (taux de base, taux majoré, seuil, plafond de remise) et le taux applicable selon son cumul. Avec la progression vers le seuil : montant, cumul sur la base et la période de la règle qui le porte (CA HT encaissé sur l’année civile à défaut), pourcentage et reste. Refusée à un compte qui n'est pas un partenaire.\n\n**Permission requise** : `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "taux": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type_ligne": {
                            "type": "string"
                          },
                          "regle_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "taux_base": {
                            "type": "integer"
                          },
                          "taux_majore": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "seuil_montant": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "remise_max_pct": {
                            "type": "number"
                          },
                          "taux_applicable": {
                            "type": "integer"
                          },
                          "majoree": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "type_ligne",
                          "regle_id",
                          "taux_base",
                          "taux_majore",
                          "seuil_montant",
                          "remise_max_pct",
                          "taux_applicable",
                          "majoree"
                        ]
                      }
                    },
                    "seuil": {
                      "type": "object",
                      "properties": {
                        "montant": {
                          "type": "integer"
                        },
                        "cumul": {
                          "type": "integer"
                        },
                        "base": {
                          "type": "string"
                        },
                        "periode": {
                          "type": "string"
                        },
                        "du": {
                          "type": "string",
                          "format": "date"
                        },
                        "au": {
                          "type": "string",
                          "format": "date"
                        },
                        "progression_pct": {
                          "type": "number"
                        },
                        "atteint": {
                          "type": "boolean"
                        },
                        "reste": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "montant",
                        "cumul",
                        "base",
                        "periode",
                        "du",
                        "au",
                        "progression_pct",
                        "atteint",
                        "reste"
                      ]
                    }
                  },
                  "required": [
                    "taux",
                    "seuil"
                  ]
                },
                "example": {
                  "taux": [
                    {
                      "type_ligne": "equipement",
                      "regle_id": "00376ce9-b379-44ae-bd01-99d9b600c746",
                      "taux_base": 5,
                      "taux_majore": 7,
                      "seuil_montant": 75000000,
                      "remise_max_pct": 2.5,
                      "taux_applicable": 5,
                      "majoree": false
                    },
                    {
                      "type_ligne": "installation",
                      "regle_id": "6879ad1e-85f9-48ae-b676-16b0a85cdfcf",
                      "taux_base": 0,
                      "taux_majore": null,
                      "seuil_montant": null,
                      "remise_max_pct": 0,
                      "taux_applicable": 0,
                      "majoree": false
                    }
                  ],
                  "seuil": {
                    "montant": 25000000,
                    "cumul": 0,
                    "base": "ca_ht_encaisse",
                    "periode": "annee_civile",
                    "du": "2026-01-01",
                    "au": "2026-12-31",
                    "progression_pct": 0,
                    "atteint": false,
                    "reste": 25000000
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "espace_partenaire.acceder",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/mon-espace/portefeuille/{clientId}": {
      "get": {
        "operationId": "getMonEspacePortefeuilleParClientId",
        "tags": [
          "Espace partenaire"
        ],
        "summary": "Lire le suivi commercial d'un client du portefeuille",
        "description": "La fiche d'un client du portefeuille de l'appelant, avec son suivi : étape commerciale la plus avancée, offre de la commande la plus récente, nombre de devis, de commandes et de sites, contact principal, dernière activité. Un client qui n'est pas dans son portefeuille est introuvable. Refusée à un compte qui n'est pas un partenaire.\n\n**Permission requise** : `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "clientId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "forme_juridique": {
                      "type": "null"
                    },
                    "rccm": {
                      "type": "string"
                    },
                    "ncc": {
                      "type": "string"
                    },
                    "secteur_id": {
                      "type": "null"
                    },
                    "adresse_facturation": {
                      "type": "null"
                    },
                    "ville": {
                      "type": "string"
                    },
                    "zone_id": {
                      "type": "null"
                    },
                    "telephone": {
                      "type": "null"
                    },
                    "email": {
                      "type": "string"
                    },
                    "origine": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "statut_kyc": {
                      "type": "string"
                    },
                    "partenaire_actuel_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "credit_approuve": {
                      "type": "boolean"
                    },
                    "plafond_encours": {
                      "type": "null"
                    },
                    "credit_approuve_par": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "devis": {
                      "type": "array",
                      "items": {}
                    },
                    "commandes": {
                      "type": "array",
                      "items": {}
                    },
                    "segment": {
                      "type": "string"
                    },
                    "etape": {
                      "type": "string"
                    },
                    "nb_devis": {
                      "type": "integer"
                    },
                    "nb_commandes": {
                      "type": "integer"
                    },
                    "nb_sites": {
                      "type": "integer"
                    },
                    "contact_principal": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "client_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "fonction": {
                          "type": "null"
                        },
                        "email": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "string"
                        },
                        "principal": {
                          "type": "boolean"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "modifie_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "client_id",
                        "prenom",
                        "nom",
                        "fonction",
                        "email",
                        "telephone",
                        "principal",
                        "cree_le",
                        "modifie_le"
                      ]
                    },
                    "secteur": {
                      "type": "null"
                    },
                    "zone": {
                      "type": "null"
                    },
                    "partenaire_actuel": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville"
                      ]
                    },
                    "offre": {
                      "type": "null"
                    },
                    "reservation": {
                      "type": "null"
                    },
                    "derniere_activite_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "raison_sociale",
                    "forme_juridique",
                    "rccm",
                    "ncc",
                    "secteur_id",
                    "adresse_facturation",
                    "ville",
                    "zone_id",
                    "telephone",
                    "email",
                    "origine",
                    "statut",
                    "statut_kyc",
                    "partenaire_actuel_id",
                    "credit_approuve",
                    "plafond_encours",
                    "credit_approuve_par",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "devis",
                    "commandes",
                    "segment",
                    "etape",
                    "nb_devis",
                    "nb_commandes",
                    "nb_sites",
                    "contact_principal",
                    "secteur",
                    "zone",
                    "partenaire_actuel",
                    "offre",
                    "reservation",
                    "derniere_activite_le"
                  ]
                },
                "example": {
                  "id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                  "organisation_id": "43237729-97df-4670-a6c5-45b1d6b404e2",
                  "raison_sociale": "ZZ Recette Client 62AAEFDF",
                  "forme_juridique": null,
                  "rccm": "CI-ZZC-62AAEFDF",
                  "ncc": "NCC-ZZC-62AAEFDF",
                  "secteur_id": null,
                  "adresse_facturation": null,
                  "ville": "Abidjan",
                  "zone_id": null,
                  "telephone": null,
                  "email": "contact.62aaefdf@exemple.invalide",
                  "origine": "partenaire",
                  "statut": "reserve",
                  "statut_kyc": "en_verification",
                  "partenaire_actuel_id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                  "credit_approuve": false,
                  "plafond_encours": null,
                  "credit_approuve_par": null,
                  "cree_par": "10d90c38-c562-44ac-8908-a67fd6f725e4",
                  "cree_le": "2026-10-19T10:44:55.660Z",
                  "modifie_le": "2026-10-19T10:44:55.822Z",
                  "devis": [],
                  "commandes": [],
                  "segment": "gere",
                  "etape": "Client enregistré",
                  "nb_devis": 0,
                  "nb_commandes": 0,
                  "nb_sites": 1,
                  "contact_principal": {
                    "id": "83f736dc-941e-44e7-9ad7-56b9ee1061a7",
                    "client_id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                    "prenom": "ZZ Recette",
                    "nom": "Contact 62AAEFDF",
                    "fonction": null,
                    "email": "contact.62aaefdf@exemple.invalide",
                    "telephone": "+225 07 00 00 00 00",
                    "principal": true,
                    "cree_le": "2026-10-19T10:44:55.663Z",
                    "modifie_le": "2026-10-19T10:44:55.663Z"
                  },
                  "secteur": null,
                  "zone": null,
                  "partenaire_actuel": {
                    "id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                    "raison_sociale": "ZZ Recette Partenaire A 137E8405",
                    "statut": "actif",
                    "ville": "Abidjan"
                  },
                  "offre": null,
                  "reservation": null,
                  "derniere_activite_le": "2026-10-19T10:44:55.822Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "espace_partenaire.acceder",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/mon-espace/portefeuille": {
      "get": {
        "operationId": "getMonEspacePortefeuille",
        "tags": [
          "Espace partenaire"
        ],
        "summary": "Lister le portefeuille du partenaire",
        "description": "Les clients gérés par l'appelant (étape commerciale, offre suivie, compteurs), suivis des clients qu'il a demandés en réservation sans les avoir encore obtenus (`segment: en_reservation`). Un doublon détecté n’y est résumé que par son nombre et ses critères, sans nommer l'autre partenaire. Réponse `{ clients, compteurs }`, non paginée. Refusée à un compte qui n'est pas un partenaire.\n\n**Permission requise** : `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 9 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "clients": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "raison_sociale": {
                            "type": "string"
                          },
                          "forme_juridique": {
                            "type": "null"
                          },
                          "rccm": {
                            "type": "string"
                          },
                          "ncc": {
                            "type": "string"
                          },
                          "secteur_id": {
                            "type": "null"
                          },
                          "adresse_facturation": {
                            "type": "null"
                          },
                          "ville": {
                            "type": "string"
                          },
                          "zone_id": {
                            "type": "null"
                          },
                          "telephone": {
                            "type": "null"
                          },
                          "email": {
                            "type": "string"
                          },
                          "origine": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "statut_kyc": {
                            "type": "string"
                          },
                          "partenaire_actuel_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "credit_approuve": {
                            "type": "boolean"
                          },
                          "plafond_encours": {
                            "type": "null"
                          },
                          "credit_approuve_par": {
                            "type": "null"
                          },
                          "cree_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "devis": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "statut": {
                                  "type": "string"
                                },
                                "modifie_le": {
                                  "type": "string",
                                  "format": "date-time"
                                }
                              },
                              "required": [
                                "statut",
                                "modifie_le"
                              ]
                            }
                          },
                          "commandes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "statut": {
                                  "type": "string"
                                },
                                "modifie_le": {
                                  "type": "string",
                                  "format": "date-time"
                                },
                                "devis": {
                                  "type": "object",
                                  "properties": {
                                    "devis_lignes": {
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "offres": {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "type": "string",
                                                "format": "uuid"
                                              },
                                              "code": {
                                                "type": "string"
                                              },
                                              "libelle": {
                                                "type": "string"
                                              },
                                              "volume_go": {
                                                "type": "integer"
                                              },
                                              "periode": {
                                                "type": "string"
                                              },
                                              "debit": {
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "code",
                                              "libelle",
                                              "volume_go",
                                              "periode",
                                              "debit"
                                            ]
                                          }
                                        },
                                        "required": [
                                          "offres"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "devis_lignes"
                                  ]
                                }
                              },
                              "required": [
                                "statut",
                                "modifie_le",
                                "devis"
                              ]
                            }
                          },
                          "segment": {
                            "type": "string"
                          },
                          "etape": {
                            "type": "string"
                          },
                          "nb_devis": {
                            "type": "integer"
                          },
                          "nb_commandes": {
                            "type": "integer"
                          },
                          "nb_sites": {
                            "type": "integer"
                          },
                          "contact_principal": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "client_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "fonction": {
                                "type": "null"
                              },
                              "email": {
                                "type": "string"
                              },
                              "telephone": {
                                "type": "string"
                              },
                              "principal": {
                                "type": "boolean"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "client_id",
                              "prenom",
                              "nom",
                              "fonction",
                              "email",
                              "telephone",
                              "principal",
                              "cree_le",
                              "modifie_le"
                            ]
                          },
                          "secteur": {
                            "type": "null"
                          },
                          "zone": {
                            "type": "null"
                          },
                          "partenaire_actuel": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "ville"
                            ]
                          },
                          "offre": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "volume_go": {
                                "type": "integer"
                              },
                              "periode": {
                                "type": "string"
                              },
                              "debit": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "volume_go",
                              "periode",
                              "debit"
                            ]
                          },
                          "reservation": {
                            "type": "null"
                          },
                          "derniere_activite_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "organisation_id",
                          "raison_sociale",
                          "forme_juridique",
                          "rccm",
                          "ncc",
                          "secteur_id",
                          "adresse_facturation",
                          "ville",
                          "zone_id",
                          "telephone",
                          "email",
                          "origine",
                          "statut",
                          "statut_kyc",
                          "partenaire_actuel_id",
                          "credit_approuve",
                          "plafond_encours",
                          "credit_approuve_par",
                          "cree_par",
                          "cree_le",
                          "modifie_le",
                          "devis",
                          "commandes",
                          "segment",
                          "etape",
                          "nb_devis",
                          "nb_commandes",
                          "nb_sites",
                          "contact_principal",
                          "secteur",
                          "zone",
                          "partenaire_actuel",
                          "offre",
                          "reservation",
                          "derniere_activite_le"
                        ]
                      }
                    },
                    "compteurs": {
                      "type": "object",
                      "properties": {
                        "gere": {
                          "type": "integer"
                        },
                        "en_reservation": {
                          "type": "integer"
                        },
                        "sans_partenaire": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "gere",
                        "en_reservation",
                        "sans_partenaire"
                      ]
                    }
                  },
                  "required": [
                    "clients",
                    "compteurs"
                  ]
                },
                "example": {
                  "clients": [],
                  "compteurs": {
                    "gere": 0,
                    "en_reservation": 0,
                    "sans_partenaire": 0
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "espace_partenaire.acceder",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/mon-espace/dossier": {
      "get": {
        "operationId": "getMonEspaceDossier",
        "tags": [
          "Espace partenaire"
        ],
        "summary": "Lire son dossier partenaire",
        "description": "La fiche du partenaire (coordonnées de versement masquées, adresse du logo, zones, secteurs), ses pièces exigées croisées avec celles déposées, la complétude des pièces obligatoires, les pièces qui expirent sous 30 jours, ses conditions commerciales (toutes versions), son contrat-cadre et l’état de son profil public, avec le motif d'un refus. Refusée à un compte qui n'est pas un partenaire.\n\n**Permission requise** : `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 7 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "forme_juridique": {
                          "type": "null"
                        },
                        "rccm": {
                          "type": "string"
                        },
                        "ncc": {
                          "type": "string"
                        },
                        "adresse": {
                          "type": "null"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "zone_principale_id": {
                          "type": "null"
                        },
                        "telephone": {
                          "type": "null"
                        },
                        "email": {
                          "type": "string"
                        },
                        "capacite_commerciale": {
                          "type": "null"
                        },
                        "mode_versement": {
                          "type": "string"
                        },
                        "logo_fichier_id": {
                          "type": "null"
                        },
                        "presentation": {
                          "type": "null"
                        },
                        "profil_publie": {
                          "type": "boolean"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "valide_par": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "valide_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "modifie_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        },
                        "logo_adresse": {
                          "type": "null"
                        },
                        "rib_masque": {
                          "type": "null"
                        },
                        "mobile_money_masque": {
                          "type": "null"
                        },
                        "organisation": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "nom": {
                              "type": "string"
                            },
                            "type": {
                              "type": "string"
                            },
                            "statut": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "nom",
                            "type",
                            "statut"
                          ]
                        },
                        "zone_principale": {
                          "type": "null"
                        },
                        "zones": {
                          "type": "array",
                          "items": {}
                        },
                        "secteurs": {
                          "type": "array",
                          "items": {}
                        },
                        "nb_clients": {
                          "type": "integer"
                        },
                        "kyc": {
                          "type": "object",
                          "properties": {
                            "total": {
                              "type": "integer"
                            },
                            "valides": {
                              "type": "integer"
                            },
                            "a_verifier": {
                              "type": "integer"
                            },
                            "a_completer": {
                              "type": "integer"
                            },
                            "rejetes": {
                              "type": "integer"
                            },
                            "expires": {
                              "type": "integer"
                            },
                            "manquants": {
                              "type": "integer"
                            },
                            "complet": {
                              "type": "boolean"
                            }
                          },
                          "required": [
                            "total",
                            "valides",
                            "a_verifier",
                            "a_completer",
                            "rejetes",
                            "expires",
                            "manquants",
                            "complet"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "organisation_id",
                        "raison_sociale",
                        "forme_juridique",
                        "rccm",
                        "ncc",
                        "adresse",
                        "ville",
                        "zone_principale_id",
                        "telephone",
                        "email",
                        "capacite_commerciale",
                        "mode_versement",
                        "logo_fichier_id",
                        "presentation",
                        "profil_publie",
                        "statut",
                        "valide_par",
                        "valide_le",
                        "cree_le",
                        "modifie_le",
                        "code_confidentiel",
                        "logo_adresse",
                        "rib_masque",
                        "mobile_money_masque",
                        "organisation",
                        "zone_principale",
                        "zones",
                        "secteurs",
                        "nb_clients",
                        "kyc"
                      ]
                    },
                    "pieces": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type_document": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "obligatoire": {
                                "type": "boolean"
                              },
                              "validite_mois": {
                                "type": "null"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "obligatoire",
                              "validite_mois"
                            ]
                          },
                          "document": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "type_document_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "motif": {
                                "type": "null"
                              },
                              "date_emission": {
                                "type": "null"
                              },
                              "date_expiration": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "fichier_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "verifie_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "fichier": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "nom_original": {
                                    "type": "string"
                                  },
                                  "type_mime": {
                                    "type": "string"
                                  },
                                  "taille_octets": {
                                    "type": "integer"
                                  },
                                  "statut_scan": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "nom_original",
                                  "type_mime",
                                  "taille_octets",
                                  "statut_scan"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "type_document_id",
                              "statut",
                              "motif",
                              "date_emission",
                              "date_expiration",
                              "fichier_id",
                              "verifie_le",
                              "cree_le",
                              "fichier"
                            ]
                          },
                          "statut": {
                            "type": "string"
                          },
                          "jours_avant_expiration": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "type_document",
                          "document",
                          "statut",
                          "jours_avant_expiration"
                        ]
                      }
                    },
                    "completude_pct": {
                      "type": "integer"
                    },
                    "obligatoires": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "valides": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total",
                        "valides"
                      ]
                    },
                    "alertes_expiration": {
                      "type": "array",
                      "items": {}
                    },
                    "conditions": {
                      "type": "null"
                    },
                    "versions_conditions": {
                      "type": "array",
                      "items": {}
                    },
                    "contrat_cadre": {
                      "type": "null"
                    },
                    "profil": {
                      "type": "object",
                      "properties": {
                        "presentation": {
                          "type": "null"
                        },
                        "logo": {
                          "type": "null"
                        },
                        "profil_publie": {
                          "type": "boolean"
                        },
                        "etat": {
                          "type": "string"
                        },
                        "motif_refus": {
                          "type": "null"
                        },
                        "soumis_le": {
                          "type": "null"
                        },
                        "modifie_le": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "presentation",
                        "logo",
                        "profil_publie",
                        "etat",
                        "motif_refus",
                        "soumis_le",
                        "modifie_le"
                      ]
                    }
                  },
                  "required": [
                    "partenaire",
                    "pieces",
                    "completude_pct",
                    "obligatoires",
                    "alertes_expiration",
                    "conditions",
                    "versions_conditions",
                    "contrat_cadre",
                    "profil"
                  ]
                },
                "example": {
                  "partenaire": {
                    "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                    "organisation_id": "934a4f65-f131-43c7-8f16-93262ee7472f",
                    "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                    "forme_juridique": null,
                    "rccm": "CI-ZZR-DFA45D10",
                    "ncc": "NCC-ZZR-DFA45D10",
                    "adresse": null,
                    "ville": "Abidjan",
                    "zone_principale_id": null,
                    "telephone": null,
                    "email": "partenaire.zzr.dfa45d10@satelica.test",
                    "capacite_commerciale": null,
                    "mode_versement": "virement",
                    "logo_fichier_id": null,
                    "presentation": null,
                    "profil_publie": false,
                    "statut": "actif",
                    "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                    "valide_le": "2026-10-19T10:44:23.274Z",
                    "cree_le": "2026-10-19T10:44:22.478Z",
                    "modifie_le": "2026-10-19T10:44:23.274Z",
                    "code_confidentiel": "C-0071",
                    "logo_adresse": null,
                    "rib_masque": null,
                    "mobile_money_masque": null,
                    "organisation": {
                      "id": "934a4f65-f131-43c7-8f16-93262ee7472f",
                      "nom": "ZZ Recette Partenaire A DFA45D10",
                      "type": "partenaire",
                      "statut": "active"
                    },
                    "zone_principale": null,
                    "zones": [],
                    "secteurs": [],
                    "nb_clients": 1,
                    "kyc": {
                      "total": 5,
                      "valides": 0,
                      "a_verifier": 0,
                      "a_completer": 0,
                      "rejetes": 0,
                      "expires": 0,
                      "manquants": 6,
                      "complet": false
                    }
                  },
                  "pieces": [
                    {
                      "type_document": {
                        "id": "38e14c1d-ae9a-45b6-b623-d3868e3545e0",
                        "code": "partenaire_attestation_fiscale",
                        "libelle": "Attestation de régularité fiscale",
                        "obligatoire": true,
                        "validite_mois": null
                      },
                      "document": null,
                      "statut": "manquant",
                      "jours_avant_expiration": null
                    },
                    {
                      "type_document": {
                        "id": "3c4e3cd4-555f-4ed4-b837-2e754a4af548",
                        "code": "partenaire_piece_identite",
                        "libelle": "Pièce d'identité du représentant légal",
                        "obligatoire": true,
                        "validite_mois": null
                      },
                      "document": null,
                      "statut": "manquant",
                      "jours_avant_expiration": null
                    }
                  ],
                  "completude_pct": 0,
                  "obligatoires": {
                    "total": 5,
                    "valides": 0
                  },
                  "alertes_expiration": [],
                  "conditions": null,
                  "versions_conditions": [],
                  "contrat_cadre": null,
                  "profil": {
                    "presentation": null,
                    "logo": null,
                    "profil_publie": false,
                    "etat": "brouillon",
                    "motif_refus": null,
                    "soumis_le": null,
                    "modifie_le": null
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "espace_partenaire.acceder",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/mon-espace/accueil": {
      "get": {
        "operationId": "getMonEspaceAccueil",
        "tags": [
          "Espace partenaire"
        ],
        "summary": "Lire l'accueil de l'espace partenaire",
        "description": "La synthèse de l’accueil : ventes signées du mois et variation sur le mois précédent, commissions du mois (latentes et réalisées, disjointes), clients gérés et actifs, réservations en attente, devis et commandes en cours, progression vers le seuil, file de tâches (la plus urgente, puis la plus ancienne d’abord), clients récents, fil d'activité et ventes des 12 derniers mois. Refusée hors compte partenaire.\n\n**Permission requise** : `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 6 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville"
                      ]
                    },
                    "periode": {
                      "type": "object",
                      "properties": {
                        "mois": {
                          "type": "string"
                        },
                        "libelle": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "mois",
                        "libelle"
                      ]
                    },
                    "ventes_mois": {
                      "type": "object",
                      "properties": {
                        "montant_ht": {
                          "type": "integer"
                        },
                        "nb": {
                          "type": "integer"
                        },
                        "variation_pct": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "montant_ht",
                        "nb",
                        "variation_pct"
                      ]
                    },
                    "commissions_mois": {
                      "type": "object",
                      "properties": {
                        "latente": {
                          "type": "integer"
                        },
                        "realisee": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "latente",
                        "realisee",
                        "total"
                      ]
                    },
                    "clients": {
                      "type": "object",
                      "properties": {
                        "gere": {
                          "type": "integer"
                        },
                        "actifs": {
                          "type": "integer"
                        },
                        "en_reservation": {
                          "type": "integer"
                        },
                        "sans_partenaire": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "gere",
                        "actifs",
                        "en_reservation",
                        "sans_partenaire"
                      ]
                    },
                    "reservations_en_attente": {
                      "type": "integer"
                    },
                    "devis_en_cours": {
                      "type": "integer"
                    },
                    "commandes_en_cours": {
                      "type": "integer"
                    },
                    "seuil": {
                      "type": "object",
                      "properties": {
                        "montant": {
                          "type": "integer"
                        },
                        "cumul": {
                          "type": "integer"
                        },
                        "base": {
                          "type": "string"
                        },
                        "periode": {
                          "type": "string"
                        },
                        "du": {
                          "type": "string",
                          "format": "date"
                        },
                        "au": {
                          "type": "string",
                          "format": "date"
                        },
                        "progression_pct": {
                          "type": "number"
                        },
                        "atteint": {
                          "type": "boolean"
                        },
                        "reste": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "montant",
                        "cumul",
                        "base",
                        "periode",
                        "du",
                        "au",
                        "progression_pct",
                        "atteint",
                        "reste"
                      ]
                    },
                    "a_faire": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "cle": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          },
                          "titre": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "lien": {
                            "type": "string"
                          },
                          "priorite": {
                            "type": "string"
                          },
                          "date": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date"
                          }
                        },
                        "required": [
                          "cle",
                          "type",
                          "titre",
                          "description",
                          "lien",
                          "priorite",
                          "date"
                        ]
                      }
                    },
                    "clients_recents": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "raison_sociale": {
                            "type": "string"
                          },
                          "forme_juridique": {
                            "type": "null"
                          },
                          "rccm": {
                            "type": "string"
                          },
                          "ncc": {
                            "type": "string"
                          },
                          "secteur_id": {
                            "type": "null"
                          },
                          "adresse_facturation": {
                            "type": "null"
                          },
                          "ville": {
                            "type": "string"
                          },
                          "zone_id": {
                            "type": "null"
                          },
                          "telephone": {
                            "type": "null"
                          },
                          "email": {
                            "type": "string"
                          },
                          "origine": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "statut_kyc": {
                            "type": "string"
                          },
                          "partenaire_actuel_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "credit_approuve": {
                            "type": "boolean"
                          },
                          "plafond_encours": {
                            "type": "null"
                          },
                          "credit_approuve_par": {
                            "type": "null"
                          },
                          "cree_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "devis": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "statut": {
                                  "type": "string"
                                },
                                "modifie_le": {
                                  "type": "string",
                                  "format": "date-time"
                                }
                              },
                              "required": [
                                "statut",
                                "modifie_le"
                              ]
                            }
                          },
                          "commandes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "statut": {
                                  "type": "string"
                                },
                                "modifie_le": {
                                  "type": "string",
                                  "format": "date-time"
                                },
                                "devis": {
                                  "type": "object",
                                  "properties": {
                                    "devis_lignes": {
                                      "type": "array",
                                      "items": {
                                        "type": "object",
                                        "properties": {
                                          "offres": {
                                            "type": "object",
                                            "properties": {
                                              "id": {
                                                "type": "string",
                                                "format": "uuid"
                                              },
                                              "code": {
                                                "type": "string"
                                              },
                                              "libelle": {
                                                "type": "string"
                                              },
                                              "volume_go": {
                                                "type": "integer"
                                              },
                                              "periode": {
                                                "type": "string"
                                              },
                                              "debit": {
                                                "type": "string"
                                              }
                                            },
                                            "required": [
                                              "id",
                                              "code",
                                              "libelle",
                                              "volume_go",
                                              "periode",
                                              "debit"
                                            ]
                                          }
                                        },
                                        "required": [
                                          "offres"
                                        ]
                                      }
                                    }
                                  },
                                  "required": [
                                    "devis_lignes"
                                  ]
                                }
                              },
                              "required": [
                                "statut",
                                "modifie_le",
                                "devis"
                              ]
                            }
                          },
                          "segment": {
                            "type": "string"
                          },
                          "etape": {
                            "type": "string"
                          },
                          "nb_devis": {
                            "type": "integer"
                          },
                          "nb_commandes": {
                            "type": "integer"
                          },
                          "nb_sites": {
                            "type": "integer"
                          },
                          "contact_principal": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "client_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "fonction": {
                                "type": "null"
                              },
                              "email": {
                                "type": "string"
                              },
                              "telephone": {
                                "type": "string"
                              },
                              "principal": {
                                "type": "boolean"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "client_id",
                              "prenom",
                              "nom",
                              "fonction",
                              "email",
                              "telephone",
                              "principal",
                              "cree_le",
                              "modifie_le"
                            ]
                          },
                          "secteur": {
                            "type": "null"
                          },
                          "zone": {
                            "type": "null"
                          },
                          "partenaire_actuel": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "ville"
                            ]
                          },
                          "offre": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "volume_go": {
                                "type": "integer"
                              },
                              "periode": {
                                "type": "string"
                              },
                              "debit": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "volume_go",
                              "periode",
                              "debit"
                            ]
                          },
                          "reservation": {
                            "type": "null"
                          },
                          "derniere_activite_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "organisation_id",
                          "raison_sociale",
                          "forme_juridique",
                          "rccm",
                          "ncc",
                          "secteur_id",
                          "adresse_facturation",
                          "ville",
                          "zone_id",
                          "telephone",
                          "email",
                          "origine",
                          "statut",
                          "statut_kyc",
                          "partenaire_actuel_id",
                          "credit_approuve",
                          "plafond_encours",
                          "credit_approuve_par",
                          "cree_par",
                          "cree_le",
                          "modifie_le",
                          "devis",
                          "commandes",
                          "segment",
                          "etape",
                          "nb_devis",
                          "nb_commandes",
                          "nb_sites",
                          "contact_principal",
                          "secteur",
                          "zone",
                          "partenaire_actuel",
                          "offre",
                          "reservation",
                          "derniere_activite_le"
                        ]
                      }
                    },
                    "activite": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "objet_type": {
                            "type": "string"
                          },
                          "objet_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "statut_avant": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "statut_apres": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "auteur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "objet_type",
                          "objet_id",
                          "type",
                          "message",
                          "statut_avant",
                          "statut_apres",
                          "cree_le",
                          "auteur"
                        ]
                      }
                    },
                    "ventes_par_mois": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "mois": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "montant_ht": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "mois",
                          "libelle",
                          "montant_ht"
                        ]
                      }
                    }
                  },
                  "required": [
                    "partenaire",
                    "periode",
                    "ventes_mois",
                    "commissions_mois",
                    "clients",
                    "reservations_en_attente",
                    "devis_en_cours",
                    "commandes_en_cours",
                    "seuil",
                    "a_faire",
                    "clients_recents",
                    "activite",
                    "ventes_par_mois"
                  ]
                },
                "example": {
                  "partenaire": {
                    "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                    "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                    "statut": "actif",
                    "ville": "Abidjan"
                  },
                  "periode": {
                    "mois": "2026-10",
                    "libelle": "octobre 2026"
                  },
                  "ventes_mois": {
                    "montant_ht": 0,
                    "nb": 0,
                    "variation_pct": null
                  },
                  "commissions_mois": {
                    "latente": 0,
                    "realisee": 0,
                    "total": 0
                  },
                  "clients": {
                    "gere": 0,
                    "actifs": 0,
                    "en_reservation": 0,
                    "sans_partenaire": 0
                  },
                  "reservations_en_attente": 0,
                  "devis_en_cours": 0,
                  "commandes_en_cours": 0,
                  "seuil": {
                    "montant": 25000000,
                    "cumul": 0,
                    "base": "ca_ht_encaisse",
                    "periode": "annee_civile",
                    "du": "2026-01-01",
                    "au": "2026-12-31",
                    "progression_pct": 0,
                    "atteint": false,
                    "reste": 25000000
                  },
                  "a_faire": [],
                  "clients_recents": [],
                  "activite": [],
                  "ventes_par_mois": [
                    {
                      "mois": "2025-11",
                      "libelle": "novembre 2025",
                      "montant_ht": 0
                    },
                    {
                      "mois": "2025-12",
                      "libelle": "décembre 2025",
                      "montant_ht": 0
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "espace_partenaire.acceder",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/signatures": {
      "post": {
        "operationId": "postSignatures",
        "tags": [
          "Ventes"
        ],
        "summary": "Demander un code de signature électronique",
        "description": "Première étape de la signature d'un devis ou d'un contrat déjà édité : tire un code à six chiffres et l'envoie par courriel à l'adresse du compte appelant, sans le conserver en clair. Sa validité vient du paramètre `signature.code_validite_minutes`, et une demande encore en cours sur le même document est annulée. Un devis doit être `envoye` et non expiré, un contrat pas encore signé. La réponse donne l’adresse masquée et dit si le courriel est parti (`envoye`).\n\n**Permission requise** : `documents.signer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "objet": {
                    "type": "string",
                    "enum": [
                      "devis",
                      "contrat"
                    ]
                  },
                  "objet_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "objet",
                  "objet_id"
                ]
              },
              "example": {
                "objet": "devis",
                "objet_id": "fb6983ab-de33-431b-be33-52f26f9681f3"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signature_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "objet": {
                      "type": "string"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "envoye_a": {
                      "type": "string"
                    },
                    "envoye": {
                      "type": "boolean"
                    },
                    "expire_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "validite_minutes": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "signature_id",
                    "objet",
                    "numero",
                    "envoye_a",
                    "envoye",
                    "expire_le",
                    "validite_minutes"
                  ]
                },
                "example": {
                  "signature_id": "fcd14bd4-1d8b-43d0-a290-d27a9c7bb496",
                  "objet": "devis",
                  "numero": "DEV-2026-000065",
                  "envoye_a": "z••••••••••••••••f@exemple.invalide",
                  "envoye": true,
                  "expire_le": "2026-10-19T10:55:06.352Z",
                  "validite_minutes": 10
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Signature refusée : raison dans `details.raison` (`non_configuree`, `document_absent`, `deja_signe`, `statut`, `expire`), ou compte sans courriel.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "documents.signer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/signatures/{id}/confirmer": {
      "post": {
        "operationId": "postSignaturesParIdConfirmer",
        "tags": [
          "Ventes"
        ],
        "summary": "Confirmer une signature électronique",
        "description": "Seconde étape : la personne qui a demandé le code le recopie avec son tracé (image PNG ou JPEG en data URI, 512 Ko au plus). Un code faux, expiré ou trop essayé est refusé en 400 et compté ; au-delà de `signature.tentatives_max` essais, la demande expire. Accepté, le document est recomposé avec le cartouche, scellé en PDF, et la preuve enregistrée (adresse IP, appareil, empreintes). Un devis signé ainsi conclut la vente comme un dépôt papier (commande, échéancier, contrat en projet, commission latente, notification du client et du partenaire) ; un contrat reçoit son PDF signé.\n\n**Permission requise** : `documents.signer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "pattern": "^\\d{6}$"
                  },
                  "trace": {
                    "type": "string",
                    "maxLength": 524288,
                    "pattern": "^data:image\\/(png|jpeg);base64,[A-Za-z0-9+/=]+$"
                  }
                },
                "required": [
                  "code",
                  "trace"
                ]
              },
              "example": {
                "code": "123456",
                "trace": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signature_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "reference": {
                      "type": "string"
                    },
                    "objet": {
                      "type": "string"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "signe_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "fichier_signe_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "empreinte_sha256": {
                      "type": "string"
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "total_ttc": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "total_ttc"
                      ]
                    },
                    "contrat": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero"
                      ]
                    }
                  },
                  "required": [
                    "signature_id",
                    "reference",
                    "objet",
                    "numero",
                    "signe_le",
                    "fichier_signe_id",
                    "empreinte_sha256",
                    "commande",
                    "contrat"
                  ]
                },
                "example": {
                  "signature_id": "fcd14bd4-1d8b-43d0-a290-d27a9c7bb496",
                  "reference": "SIG-FCD14BD4",
                  "objet": "devis",
                  "numero": "DEV-2026-000065",
                  "signe_le": "2026-10-19T10:45:07.059Z",
                  "fichier_signe_id": "27d32b60-6c41-4177-a02f-79bd0da233cf",
                  "empreinte_sha256": "f2f673604934473822417e25cfbc3d993ac75680dc33302bd3b2c5c39f748fe0",
                  "commande": {
                    "id": "9baafcab-4a8c-42b2-ba6c-3a5916d308cb",
                    "numero": "CMD-2026-000030",
                    "statut": "attente_paiement",
                    "total_ttc": "23600"
                  },
                  "contrat": {
                    "id": "8d60d27f-4fe9-4c26-b8f3-d603de945e4f",
                    "numero": "CTR-2026-000030"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Signature non configurée, ou demandée par une autre personne.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "documents.signer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/besoins": {
      "post": {
        "operationId": "postBesoins",
        "tags": [
          "Ventes"
        ],
        "summary": "Exprimer un besoin",
        "description": "Une entreprise cliente (seule à pouvoir l’appeler) transmet un besoin au partenaire qui suit son dossier, lu sur le client et jamais transmis : une opportunité `ouverte`, d'éligibilité `a_verifier`, est créée et le partenaire est notifié. Le site est soit un site du client (`site_id`), soit un nouveau site déclaré (`nouveau_site_libelle`), créé « à qualifier » — l’un ou l’autre, pas les deux. Rejouer la même `cle_idempotence` rend la demande déjà ouverte (`deja_transmis: true`) sans en créer une autre.\n\n**Permission requise** : `besoins.exprimer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "default": "nouveau_besoin",
                    "type": "string",
                    "enum": [
                      "nouveau_besoin",
                      "augmentation_besoin",
                      "renouvellement"
                    ]
                  },
                  "site_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "nouveau_site_libelle": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 160
                  },
                  "nouveau_site_ville": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 120
                  },
                  "sites": {
                    "default": 1,
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 999
                  },
                  "connexions": {
                    "default": 1,
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9999
                  },
                  "usage": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 2000
                  },
                  "duree": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "cle_idempotence": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 120
                  }
                },
                "required": [
                  "usage",
                  "duree"
                ]
              },
              "example": {
                "type": "nouveau_besoin",
                "nouveau_site_libelle": "ZZ Recette Besoin 2BQ96R26",
                "nouveau_site_ville": "Abidjan",
                "sites": 2,
                "connexions": 6,
                "usage": "Liaison de secours pour la recette du cloisonnement",
                "duree": "12 mois",
                "cle_idempotence": "besoin-recette-1792406782857"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        },
                        "raison_sociale": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "code_confidentiel",
                        "raison_sociale"
                      ]
                    },
                    "deja_transmis": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "statut",
                    "site_id",
                    "partenaire",
                    "deja_transmis"
                  ]
                },
                "example": {
                  "id": "e7375b41-9ae4-4cea-8f3d-49e30857e8da",
                  "statut": "ouverte",
                  "site_id": "0ec47790-5761-48a2-b312-3f0f5f8bc869",
                  "partenaire": {
                    "id": "2bf838df-d511-4a0c-a1e2-7f76064e3e3d",
                    "code_confidentiel": "C-0078",
                    "raison_sociale": "Réf. C-0078"
                  },
                  "deja_transmis": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Dossier client suivi par aucun partenaire.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "besoins.exprimer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/opportunites": {
      "post": {
        "operationId": "postOpportunites",
        "tags": [
          "Ventes"
        ],
        "summary": "Créer une opportunité",
        "description": "Un partenaire (seul à pouvoir l’appeler) ouvre une opportunité pour un client de son portefeuille : statut `ouverte`, éligibilité `a_verifier`, que CYBASTION tranchera. Le site, s’il est donné, doit appartenir au client (400 sinon).\n\n**Permission requise** : `opportunites.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "site_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "type_transaction": {
                    "default": "nouveau_besoin",
                    "type": "string",
                    "enum": [
                      "nouveau_besoin",
                      "renouvellement",
                      "augmentation_besoin",
                      "transfert"
                    ]
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "besoin": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {}
                  }
                },
                "required": [
                  "client_id"
                ]
              },
              "example": {
                "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                "site_id": "83b0497e-9931-4957-a633-225afa68ab61",
                "type_transaction": "nouveau_besoin",
                "description": "Fixture de recette : besoin de connectivité."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 6 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type_transaction": {
                      "type": "string"
                    },
                    "besoin": {
                      "type": "null"
                    },
                    "description": {
                      "type": "string"
                    },
                    "eligibilite": {
                      "type": "string"
                    },
                    "eligibilite_verifiee_par": {
                      "type": "null"
                    },
                    "eligibilite_verifiee_le": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "motif_perte": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "client_id",
                    "partenaire_id",
                    "site_id",
                    "type_transaction",
                    "besoin",
                    "description",
                    "eligibilite",
                    "eligibilite_verifiee_par",
                    "eligibilite_verifiee_le",
                    "statut",
                    "motif_perte",
                    "cree_par",
                    "cree_le",
                    "modifie_le"
                  ]
                },
                "example": {
                  "id": "aade7a70-c991-48e5-beeb-a59538d49c08",
                  "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                  "partenaire_id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                  "site_id": "83b0497e-9931-4957-a633-225afa68ab61",
                  "type_transaction": "nouveau_besoin",
                  "besoin": null,
                  "description": "Fixture de recette : besoin de connectivité.",
                  "eligibilite": "a_verifier",
                  "eligibilite_verifiee_par": null,
                  "eligibilite_verifiee_le": null,
                  "statut": "ouverte",
                  "motif_perte": null,
                  "cree_par": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                  "cree_le": "2026-10-19T10:44:17.612Z",
                  "modifie_le": "2026-10-19T10:44:17.612Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "description": "Client introuvable ou hors du portefeuille.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "opportunites.gerer",
        "x-satelica-cloisonnement": "applique"
      },
      "get": {
        "operationId": "getOpportunites",
        "tags": [
          "Ventes"
        ],
        "summary": "Lister les opportunités",
        "description": "Les opportunités (besoins), de la plus récente à la plus ancienne, filtrables par statut et éligibilité (plusieurs valeurs, répétées ou séparées par des virgules), par partenaire et par client. Chacune porte son client, son partenaire, son site, son auteur, le vérificateur de l'éligibilité, son nombre de devis et son ancienneté en heures (`anciennete_heures`). Un client y suit les besoins qu’il a exprimés.\n\n**Permission requise** : L'une de : `opportunites.gerer`, `besoins.exprimer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "eligibilite",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "partenaire_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 5 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "site_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type_transaction": {
                            "type": "string"
                          },
                          "besoin": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "exprime_par_le_client": {
                                "type": "boolean"
                              },
                              "qualifie_avec_le_devis": {
                                "type": "string"
                              },
                              "duree": {
                                "type": "string"
                              },
                              "sites": {
                                "type": "integer"
                              },
                              "usage": {
                                "type": "string"
                              },
                              "connexions": {
                                "type": "integer"
                              },
                              "cle_idempotence": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "exprime_par_le_client"
                            ]
                          },
                          "description": {
                            "type": "string"
                          },
                          "eligibilite": {
                            "type": "string"
                          },
                          "eligibilite_verifiee_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "eligibilite_verifiee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "motif_perte": {
                            "type": "null"
                          },
                          "cree_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut"
                            ]
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "code_confidentiel"
                            ]
                          },
                          "site": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "libelle",
                              "ville"
                            ]
                          },
                          "cree_par_utilisateur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom"
                            ]
                          },
                          "eligibilite_verifiee_par_utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "commentaire_eligibilite": {
                            "type": "null"
                          },
                          "nb_devis": {
                            "type": "integer"
                          },
                          "anciennete_heures": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "client_id",
                          "partenaire_id",
                          "site_id",
                          "type_transaction",
                          "besoin",
                          "description",
                          "eligibilite",
                          "eligibilite_verifiee_par",
                          "eligibilite_verifiee_le",
                          "statut",
                          "motif_perte",
                          "cree_par",
                          "cree_le",
                          "modifie_le",
                          "client",
                          "partenaire",
                          "site",
                          "cree_par_utilisateur",
                          "eligibilite_verifiee_par_utilisateur",
                          "commentaire_eligibilite",
                          "nb_devis",
                          "anciennete_heures"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "279a6cfc-90ef-4688-ac1d-36fedaac94a3",
                      "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                      "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                      "site_id": "e114d094-6e40-45c9-913d-522133ed600a",
                      "type_transaction": "nouveau_besoin",
                      "besoin": null,
                      "description": "Épreuve des sections : besoin de connectivité.",
                      "eligibilite": "a_verifier",
                      "eligibilite_verifiee_par": null,
                      "eligibilite_verifiee_le": null,
                      "statut": "ouverte",
                      "motif_perte": null,
                      "cree_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                      "cree_le": "2026-10-19T10:45:43.845Z",
                      "modifie_le": "2026-10-19T10:45:43.845Z",
                      "client": {
                        "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                        "raison_sociale": "ZZ Recette Client 4D20EED1",
                        "statut": "reserve"
                      },
                      "partenaire": {
                        "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                        "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                        "statut": "actif",
                        "ville": "Abidjan",
                        "code_confidentiel": "C-0076"
                      },
                      "site": {
                        "id": "e114d094-6e40-45c9-913d-522133ed600a",
                        "libelle": "Site 4D20EED1",
                        "ville": "Abidjan"
                      },
                      "cree_par_utilisateur": {
                        "id": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A 856174D4",
                        "email": "zz.recette.856174d4@exemple.invalide"
                      },
                      "eligibilite_verifiee_par_utilisateur": null,
                      "commentaire_eligibilite": null,
                      "nb_devis": 0,
                      "anciennete_heures": 0
                    },
                    {
                      "id": "58239ab8-1f8c-4bb1-b1de-8c1927b86e74",
                      "client_id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                      "partenaire_id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                      "site_id": "01e18522-0666-4175-b960-ad1a6ff901d6",
                      "type_transaction": "nouveau_besoin",
                      "besoin": {
                        "exprime_par_le_client": false,
                        "qualifie_avec_le_devis": "DEV-2026-000066"
                      },
                      "description": "Besoin qualifié avec le devis DEV-2026-000066",
                      "eligibilite": "a_verifier",
                      "eligibilite_verifiee_par": null,
                      "eligibilite_verifiee_le": null,
                      "statut": "gagnee",
                      "motif_perte": null,
                      "cree_par": "10d90c38-c562-44ac-8908-a67fd6f725e4",
                      "cree_le": "2026-10-19T10:45:09.974Z",
                      "modifie_le": "2026-10-19T10:45:10.736Z",
                      "client": {
                        "id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                        "raison_sociale": "ZZ Recette Client 62AAEFDF",
                        "statut": "reserve"
                      },
                      "partenaire": {
                        "id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                        "raison_sociale": "ZZ Recette Partenaire A 137E8405",
                        "statut": "actif",
                        "ville": "Yamoussoukro",
                        "code_confidentiel": "C-0073"
                      },
                      "site": {
                        "id": "01e18522-0666-4175-b960-ad1a6ff901d6",
                        "libelle": "Site 62AAEFDF",
                        "ville": "Abidjan"
                      },
                      "cree_par_utilisateur": {
                        "id": "10d90c38-c562-44ac-8908-a67fd6f725e4",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A 137E8405",
                        "email": "zz.recette.137e8405@exemple.invalide"
                      },
                      "eligibilite_verifiee_par_utilisateur": null,
                      "commentaire_eligibilite": null,
                      "nb_devis": 1,
                      "anciennete_heures": 0
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 35,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "opportunites.gerer",
          "besoins.exprimer"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/devis/simulation": {
      "post": {
        "operationId": "postDevisSimulation",
        "tags": [
          "Ventes"
        ],
        "summary": "Chiffrer un devis sans l'enregistrer",
        "description": "Calcule un devis par le même chemin que sa création, sans rien écrire : lignes au tarif en vigueur avec remise, TVA et commission, totaux, date de validité, dépassements du plafond de remise et anomalies ligne par ligne (`valide`, `erreurs`). Il faut une opportunité ou un client du portefeuille, et un site (celui de l'opportunité par défaut) ; une opportunité non éligible rend la simulation invalide. Réservée à un compte partenaire.\n\n**Permission requise** : `devis.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "opportunite_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "client_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "site_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "mode_paiement": {
                    "default": "prepaye",
                    "type": "string",
                    "enum": [
                      "prepaye",
                      "postpaye"
                    ]
                  },
                  "lignes": {
                    "maxItems": 10,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "produitId": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        "offreId": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "uuid",
                              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "quantite": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 999
                        },
                        "remisePct": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 100
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "prixUnitaireHt": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "produitId",
                        "quantite"
                      ]
                    }
                  }
                },
                "required": [
                  "lignes"
                ]
              },
              "example": {
                "opportunite_id": "d2bc3060-098c-45c8-a755-ab605579e2e8",
                "site_id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                "mode_paiement": "prepaye",
                "lignes": [
                  {
                    "produitId": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                    "offreId": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                    "quantite": 1
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "lignes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "index": {
                            "type": "integer"
                          },
                          "type_ligne": {
                            "type": "string"
                          },
                          "produit_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "offre_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "tarif_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "quantite": {
                            "type": "integer"
                          },
                          "prix_unitaire_ht": {
                            "type": "integer"
                          },
                          "remise_pct": {
                            "type": "integer"
                          },
                          "remise_max_pct": {
                            "type": "integer"
                          },
                          "taux_tva": {
                            "type": "integer"
                          },
                          "montant_brut_ht": {
                            "type": "integer"
                          },
                          "montant_remise": {
                            "type": "integer"
                          },
                          "montant_ht": {
                            "type": "integer"
                          },
                          "montant_tva": {
                            "type": "integer"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "regle_commission_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "taux_commission": {
                            "type": "integer"
                          },
                          "majoree": {
                            "type": "boolean"
                          },
                          "commission_prevue": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "index",
                          "type_ligne",
                          "produit_id",
                          "offre_id",
                          "tarif_id",
                          "libelle",
                          "quantite",
                          "prix_unitaire_ht",
                          "remise_pct",
                          "remise_max_pct",
                          "taux_tva",
                          "montant_brut_ht",
                          "montant_remise",
                          "montant_ht",
                          "montant_tva",
                          "montant_ttc",
                          "regle_commission_id",
                          "taux_commission",
                          "majoree",
                          "commission_prevue"
                        ]
                      }
                    },
                    "totaux": {
                      "type": "object",
                      "properties": {
                        "total_brut_ht": {
                          "type": "integer"
                        },
                        "total_remise": {
                          "type": "integer"
                        },
                        "total_ht": {
                          "type": "integer"
                        },
                        "total_tva": {
                          "type": "integer"
                        },
                        "total_ttc": {
                          "type": "integer"
                        },
                        "commission_prevue": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total_brut_ht",
                        "total_remise",
                        "total_ht",
                        "total_tva",
                        "total_ttc",
                        "commission_prevue"
                      ]
                    },
                    "valide_jusquau": {
                      "type": "string",
                      "format": "date"
                    },
                    "erreurs": {
                      "type": "array",
                      "items": {}
                    },
                    "valide": {
                      "type": "boolean"
                    },
                    "depassements_remise": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "ligne": {
                            "type": "integer"
                          },
                          "type_ligne": {
                            "type": "string"
                          },
                          "remise_pct": {
                            "type": "integer"
                          },
                          "plafond_pct": {
                            "type": "integer"
                          },
                          "message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "ligne",
                          "type_ligne",
                          "remise_pct",
                          "plafond_pct",
                          "message"
                        ]
                      }
                    },
                    "postpaye_autorise": {
                      "type": "boolean"
                    },
                    "motif_postpaye": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "lignes",
                    "totaux",
                    "valide_jusquau",
                    "erreurs",
                    "valide",
                    "depassements_remise",
                    "postpaye_autorise",
                    "motif_postpaye"
                  ]
                },
                "example": {
                  "lignes": [
                    {
                      "index": 0,
                      "type_ligne": "forfait_data",
                      "produit_id": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                      "offre_id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                      "tarif_id": "9aec4d3d-dd38-4020-860e-a7e651318491",
                      "libelle": "Forfait 50 Go hebdomadaire",
                      "quantite": 1,
                      "prix_unitaire_ht": 20000,
                      "remise_pct": 0,
                      "remise_max_pct": 10,
                      "taux_tva": 18,
                      "montant_brut_ht": 20000,
                      "montant_remise": 0,
                      "montant_ht": 20000,
                      "montant_tva": 3600,
                      "montant_ttc": 23600,
                      "regle_commission_id": "ff96d34b-b693-4e56-8fda-4c49ac0ed07e",
                      "taux_commission": 20,
                      "majoree": false,
                      "commission_prevue": 4000
                    }
                  ],
                  "totaux": {
                    "total_brut_ht": 20000,
                    "total_remise": 0,
                    "total_ht": 20000,
                    "total_tva": 3600,
                    "total_ttc": 23600,
                    "commission_prevue": 4000
                  },
                  "valide_jusquau": "2026-11-03",
                  "erreurs": [],
                  "valide": true,
                  "depassements_remise": [],
                  "postpaye_autorise": false,
                  "motif_postpaye": "Le postpayé n’est possible qu’après l’approbation du crédit du client par CYBASTION."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "description": "Opportunité ou client introuvable, ou hors du portefeuille.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "devis.gerer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/devis": {
      "post": {
        "operationId": "postDevis",
        "tags": [
          "Ventes"
        ],
        "summary": "Créer un devis",
        "description": "Un partenaire établit un devis `brouillon` (numéro DEV) aux montants de la simulation, recopiés dans chaque ligne : il ne sera jamais recalculé. Sans `opportunite_id`, l'opportunité naît avec lui ; une opportunité ouverte ou qualifiée passe `devis_emis`. Un devis comportant des anomalies est refusé en 400 (`details.erreurs`) ; une remise au-dessus du plafond exige `motif_remise` et retient le devis jusqu’à l’accord de CYBASTION (remise exceptionnelle `demandee`).\n\n**Permission requise** : `devis.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "opportunite_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "client_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "site_id": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "mode_paiement": {
                    "default": "prepaye",
                    "type": "string",
                    "enum": [
                      "prepaye",
                      "postpaye"
                    ]
                  },
                  "lignes": {
                    "maxItems": 10,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "produitId": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        "offreId": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "uuid",
                              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "quantite": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 999
                        },
                        "remisePct": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0,
                              "maximum": 100
                            },
                            {
                              "type": "null"
                            }
                          ]
                        },
                        "prixUnitaireHt": {
                          "anyOf": [
                            {
                              "type": "number",
                              "minimum": 0
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "produitId",
                        "quantite"
                      ]
                    }
                  },
                  "motif_remise": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 10,
                        "maxLength": 1000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "lignes"
                ]
              },
              "example": {
                "client_id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                "site_id": "01e18522-0666-4175-b960-ad1a6ff901d6",
                "mode_paiement": "prepaye",
                "lignes": [
                  {
                    "produitId": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                    "offreId": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                    "quantite": 1,
                    "remisePct": 40
                  }
                ],
                "motif_remise": "Engagement de trois sites dans l’année."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 10 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "totaux": {
                      "type": "object",
                      "properties": {
                        "total_brut_ht": {
                          "type": "integer"
                        },
                        "total_remise": {
                          "type": "integer"
                        },
                        "total_ht": {
                          "type": "integer"
                        },
                        "total_tva": {
                          "type": "integer"
                        },
                        "total_ttc": {
                          "type": "integer"
                        },
                        "commission_prevue": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total_brut_ht",
                        "total_remise",
                        "total_ht",
                        "total_tva",
                        "total_ttc",
                        "commission_prevue"
                      ]
                    },
                    "valide_jusquau": {
                      "type": "string",
                      "format": "date"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "statut",
                    "totaux",
                    "valide_jusquau"
                  ]
                },
                "example": {
                  "id": "d4824711-8407-44a1-8a56-2ea135ddfd66",
                  "numero": "DEV-2026-000059",
                  "statut": "brouillon",
                  "totaux": {
                    "total_brut_ht": 20000,
                    "total_remise": 0,
                    "total_ht": 20000,
                    "total_tva": 3600,
                    "total_ttc": 23600,
                    "commission_prevue": 4000
                  },
                  "valide_jusquau": "2026-11-03"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "description": "Opportunité ou client introuvable, ou hors du portefeuille.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "devis.gerer",
        "x-satelica-cloisonnement": "applique"
      },
      "get": {
        "operationId": "getDevis",
        "tags": [
          "Ventes"
        ],
        "summary": "Lister les devis",
        "description": "Les devis, du plus récent au plus ancien, filtrables par statut (plusieurs valeurs, répétées ou séparées par des virgules), par partenaire et par client. Chacun porte ses totaux, son offre data, sa commande, sa commission prévue — aux taux recopiés dans ses lignes, jamais recalculée — et ses jours de validité restants tant qu’il attend une réponse. Un client y lit les devis qui lui sont adressés.\n\n**Permission requise** : L'une de : `devis.gerer`, `devis.accepter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "partenaire_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 6 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "opportunite_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "site_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "mode_paiement": {
                            "type": "string"
                          },
                          "valide_jusquau": {
                            "type": "string",
                            "format": "date"
                          },
                          "total_ht": {
                            "type": "integer"
                          },
                          "total_remise": {
                            "type": "integer"
                          },
                          "total_tva": {
                            "type": "integer"
                          },
                          "total_ttc": {
                            "type": "integer"
                          },
                          "pdf_fichier_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "pdf_signe_fichier_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "envoye_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "signe_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "remise_exceptionnelle_statut": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "remise_exceptionnelle_motif": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "remise_exceptionnelle_demandee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "remise_exceptionnelle_decidee_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "remise_exceptionnelle_decidee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "remise_exceptionnelle_motif_decision": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "accepte_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "accepte_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut"
                            ]
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "code_confidentiel"
                            ]
                          },
                          "site": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "libelle",
                              "ville"
                            ]
                          },
                          "cree_par_utilisateur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom"
                            ]
                          },
                          "commande": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          },
                          "offre": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "periode": {
                                "type": "string"
                              },
                              "volume_go": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "periode",
                              "volume_go"
                            ]
                          },
                          "jours_validite_restants": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "commission_prevue": {
                            "type": "integer"
                          },
                          "nb_lignes": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "opportunite_id",
                          "client_id",
                          "partenaire_id",
                          "site_id",
                          "statut",
                          "mode_paiement",
                          "valide_jusquau",
                          "total_ht",
                          "total_remise",
                          "total_tva",
                          "total_ttc",
                          "pdf_fichier_id",
                          "pdf_signe_fichier_id",
                          "envoye_le",
                          "signe_le",
                          "cree_par",
                          "cree_le",
                          "modifie_le",
                          "remise_exceptionnelle_statut",
                          "remise_exceptionnelle_motif",
                          "remise_exceptionnelle_demandee_le",
                          "remise_exceptionnelle_decidee_par",
                          "remise_exceptionnelle_decidee_le",
                          "remise_exceptionnelle_motif_decision",
                          "accepte_le",
                          "accepte_par",
                          "client",
                          "partenaire",
                          "site",
                          "cree_par_utilisateur",
                          "commande",
                          "offre",
                          "jours_validite_restants",
                          "nb_lignes"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "21ff2ce1-1c6c-4f56-86b2-d0a0600b829b",
                      "numero": "DEV-2026-000067",
                      "opportunite_id": "279a6cfc-90ef-4688-ac1d-36fedaac94a3",
                      "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                      "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                      "site_id": "e114d094-6e40-45c9-913d-522133ed600a",
                      "statut": "envoye",
                      "mode_paiement": "prepaye",
                      "valide_jusquau": "2026-11-03",
                      "total_ht": 20000,
                      "total_remise": 0,
                      "total_tva": 3600,
                      "total_ttc": 23600,
                      "pdf_fichier_id": "d2897783-1309-4e30-8969-83bdc403f821",
                      "pdf_signe_fichier_id": null,
                      "envoye_le": "2026-10-19T10:45:45.318Z",
                      "signe_le": null,
                      "cree_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                      "cree_le": "2026-10-19T10:45:44.546Z",
                      "modifie_le": "2026-10-19T10:45:45.318Z",
                      "remise_exceptionnelle_statut": null,
                      "remise_exceptionnelle_motif": null,
                      "remise_exceptionnelle_demandee_le": null,
                      "remise_exceptionnelle_decidee_par": null,
                      "remise_exceptionnelle_decidee_le": null,
                      "remise_exceptionnelle_motif_decision": null,
                      "accepte_le": null,
                      "accepte_par": null,
                      "client": {
                        "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                        "raison_sociale": "ZZ Recette Client 4D20EED1",
                        "statut": "reserve"
                      },
                      "partenaire": {
                        "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                        "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                        "statut": "actif",
                        "ville": "Abidjan",
                        "code_confidentiel": "C-0076"
                      },
                      "site": {
                        "id": "e114d094-6e40-45c9-913d-522133ed600a",
                        "libelle": "Site 4D20EED1",
                        "ville": "Abidjan"
                      },
                      "cree_par_utilisateur": {
                        "id": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A 856174D4",
                        "email": "zz.recette.856174d4@exemple.invalide"
                      },
                      "commande": null,
                      "offre": {
                        "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                        "code": "DATA-50GO-HEBDO",
                        "libelle": "Forfait 50 Go hebdomadaire",
                        "periode": "hebdomadaire",
                        "volume_go": 50
                      },
                      "jours_validite_restants": 15,
                      "commission_prevue": 4000,
                      "nb_lignes": 1
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 1,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "devis.gerer",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/devis/{id}/document": {
      "post": {
        "operationId": "postDevisParIdDocument",
        "tags": [
          "Ventes"
        ],
        "summary": "Produire le PDF du devis",
        "description": "Compose le devis en PDF, le dépose dans le stockage et le rattache au devis. Un brouillon peut être reproduit ; au-delà, un document déjà produit ne se refait pas. La réponse donne l'identifiant du fichier, son empreinte SHA-256 et sa taille, pas le binaire.\n\n**Permission requise** : `devis.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "devis_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "empreinte_sha256": {
                      "type": "string"
                    },
                    "octets": {
                      "type": "integer"
                    },
                    "modele": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "devis_id",
                    "numero",
                    "fichier_id",
                    "empreinte_sha256",
                    "octets",
                    "modele"
                  ]
                },
                "example": {
                  "devis_id": "52764ad5-f498-419d-8732-f7aaf13cb517",
                  "numero": "DEV-2026-000061",
                  "fichier_id": "ec57136e-4d63-47bf-807f-27ef828d3dbc",
                  "empreinte_sha256": "4c413081602b32069047fbca88a2fe97c359b68ea6d3ec38c5ebb4ad4e1f01c8",
                  "octets": 49381,
                  "modele": "base (version 1)"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Document déjà produit pour un devis qui n'est plus brouillon : refaire un devis.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "devis.gerer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/devis/{id}/envoi": {
      "post": {
        "operationId": "postDevisParIdEnvoi",
        "tags": [
          "Ventes"
        ],
        "summary": "Envoyer un devis au client",
        "description": "Fait passer un devis `brouillon` à `envoye`, en produisant d'abord son PDF s'il n'existe pas encore ; le `message` facultatif est inscrit à l'historique du devis (corps facultatif). Un devis dont la remise exceptionnelle attend l’accord de CYBASTION, ou a été refusée, ne part pas.\n\n**Permission requise** : `devis.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": {
                    "type": "string",
                    "maxLength": 1000
                  }
                }
              },
              "example": {
                "message": "Recette automatisée."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 7 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "envoye_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "valide_jusquau": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "statut",
                    "envoye_le",
                    "valide_jusquau"
                  ]
                },
                "example": {
                  "id": "d4824711-8407-44a1-8a56-2ea135ddfd66",
                  "numero": "DEV-2026-000059",
                  "statut": "envoye",
                  "envoye_le": "2026-10-19T10:44:18.289Z",
                  "valide_jusquau": "2026-11-03T00:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Devis qui n'est plus brouillon, ou remise exceptionnelle en attente ou refusée.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "devis.gerer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/devis/{id}/signature": {
      "post": {
        "operationId": "postDevisParIdSignature",
        "tags": [
          "Ventes"
        ],
        "summary": "Déposer le devis signé",
        "description": "Le partenaire, ou CYBASTION, dépose le scan du devis signé par le client (`fichier_id`, déposé au préalable par le même compte ; 400 sinon), à la date portée par le document ou aujourd'hui. Le devis passe `signe` et la vente est conclue : commande `attente_paiement`, échéancier, contrat en projet, commissions latentes, opportunité gagnée, et ordre d'installation pour une vente postpayée à crédit accordé. Le client et le partenaire sont notifiés, sauf l’auteur du dépôt.\n\n**Permission requise** : L'une de : `devis.signature_deposer`, `devis.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fichier_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "signe_le": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "date",
                        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                      },
                      {
                        "type": "string",
                        "format": "date-time",
                        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
                      }
                    ]
                  }
                },
                "required": [
                  "fichier_id"
                ]
              },
              "example": {
                "fichier_id": "d03679b3-c1f3-4b0c-a8c6-491af4f66c7d"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "devis": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "signe_le": {
                          "type": "string",
                          "format": "date"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "signe_le"
                      ]
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "total_ttc": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "total_ttc"
                      ]
                    },
                    "contrat": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero"
                      ]
                    },
                    "commission_latente": {
                      "type": "integer"
                    },
                    "ordre_installation": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "devis",
                    "commande",
                    "contrat",
                    "commission_latente",
                    "ordre_installation"
                  ]
                },
                "example": {
                  "devis": {
                    "id": "934c2fbf-bef5-4c71-a4ea-5deb8fff0b6e",
                    "numero": "DEV-2026-000060",
                    "statut": "signe",
                    "signe_le": "2026-10-19"
                  },
                  "commande": {
                    "id": "517790aa-ada4-451d-8a22-1a9b3bd2136e",
                    "numero": "CMD-2026-000028",
                    "statut": "attente_paiement",
                    "total_ttc": "23600"
                  },
                  "contrat": {
                    "id": "72b5aeed-3e6e-4677-9aab-379d24ab07ac",
                    "numero": "CTR-2026-000028"
                  },
                  "commission_latente": 4000,
                  "ordre_installation": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Devis déjà signé, pas encore envoyé, expiré à la date de signature, ou fichier qui n'a pas passé l'antivirus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "devis.signature_deposer",
          "devis.gerer"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/devis/{id}/remise-exceptionnelle": {
      "post": {
        "operationId": "postDevisParIdRemiseExceptionnelle",
        "tags": [
          "Ventes"
        ],
        "summary": "Trancher une remise exceptionnelle",
        "description": "CYBASTION accorde ou refuse, avec un motif, la remise au-dessus du plafond demandée sur un devis. La décision ne recalcule rien : accordée, elle autorise l'envoi ; refusée, elle le retient, et le devis doit être annulé puis refait au plafond. Le partenaire est notifié.\n\n**Permission requise** : `devis.remise_approuver`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "accordee",
                      "refusee"
                    ]
                  },
                  "motif": {
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "decision",
                  "motif"
                ]
              },
              "example": {
                "decision": "accordee",
                "motif": "Volume annoncé crédible, accord de la direction commerciale."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "remise_exceptionnelle_statut": {
                      "type": "string"
                    },
                    "remise_exceptionnelle_motif_decision": {
                      "type": "string"
                    },
                    "remise_exceptionnelle_decidee_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "statut",
                    "remise_exceptionnelle_statut",
                    "remise_exceptionnelle_motif_decision",
                    "remise_exceptionnelle_decidee_le"
                  ]
                },
                "example": {
                  "id": "4346d4ed-84e0-41c2-a5a9-5bd0a0b95603",
                  "numero": "DEV-2026-000064",
                  "statut": "brouillon",
                  "remise_exceptionnelle_statut": "accordee",
                  "remise_exceptionnelle_motif_decision": "Volume annoncé crédible, accord de la direction commerciale.",
                  "remise_exceptionnelle_decidee_le": "2026-10-19T10:45:05.071Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Aucune remise exceptionnelle sur ce devis, ou remise déjà tranchée.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "devis.remise_approuver",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/devis/{id}/annulation": {
      "post": {
        "operationId": "postDevisParIdAnnulation",
        "tags": [
          "Ventes"
        ],
        "summary": "Annuler un devis",
        "description": "Fait passer le devis à `annule`, avec un motif inscrit à l'historique et au journal d'audit. Un devis signé ne s'annule pas par cette route : son annulation passe par CYBASTION.\n\n**Permission requise** : `devis.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "motif": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  }
                },
                "required": [
                  "motif"
                ]
              },
              "example": {
                "motif": "Le client a changé de site."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "statut"
                  ]
                },
                "example": {
                  "id": "1f2845fe-0967-4537-a593-27f7876fc722",
                  "numero": "DEV-2026-000063",
                  "statut": "annule"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Devis signé ou déjà annulé.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "devis.gerer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/devis/{id}": {
      "delete": {
        "operationId": "deleteDevisParId",
        "tags": [
          "Ventes"
        ],
        "summary": "Supprimer un devis brouillon",
        "description": "Supprime un devis resté `brouillon`, avec ses lignes ; le journal d’audit garde son numéro, son statut, son total et son nombre de lignes. Un devis envoyé s’annule au lieu d’être supprimé ; un devis signé, refusé, expiré ou annulé ne se supprime pas.\n\n**Permission requise** : `devis.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    },
                    "numero": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "supprime",
                    "numero"
                  ]
                },
                "example": {
                  "supprime": true,
                  "numero": "DEV-2026-000062"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Seul un devis brouillon se supprime.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "devis.gerer",
        "x-satelica-cloisonnement": "applique"
      },
      "get": {
        "operationId": "getDevisParId",
        "tags": [
          "Ventes"
        ],
        "summary": "Lire le détail d'un devis",
        "description": "Le devis avec ses lignes telles qu’elles ont été figées à sa création (prix, remise, TVA, commission), son opportunité, sa commande, sa commission prévue, ses jours de validité restants et ses fichiers PDF avant et après signature (`pdf_fichier`, `pdf_signe_fichier`).\n\n**Permission requise** : L'une de : `devis.gerer`, `devis.accepter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "opportunite_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "mode_paiement": {
                      "type": "string"
                    },
                    "valide_jusquau": {
                      "type": "string",
                      "format": "date"
                    },
                    "total_ht": {
                      "type": "integer"
                    },
                    "total_remise": {
                      "type": "integer"
                    },
                    "total_tva": {
                      "type": "integer"
                    },
                    "total_ttc": {
                      "type": "integer"
                    },
                    "pdf_fichier_id": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "pdf_signe_fichier_id": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "envoye_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "signe_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "remise_exceptionnelle_statut": {
                      "type": "null"
                    },
                    "remise_exceptionnelle_motif": {
                      "type": "null"
                    },
                    "remise_exceptionnelle_demandee_le": {
                      "type": "null"
                    },
                    "remise_exceptionnelle_decidee_par": {
                      "type": "null"
                    },
                    "remise_exceptionnelle_decidee_le": {
                      "type": "null"
                    },
                    "remise_exceptionnelle_motif_decision": {
                      "type": "null"
                    },
                    "accepte_le": {
                      "type": "null"
                    },
                    "accepte_par": {
                      "type": "null"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville",
                        "code_confidentiel"
                      ]
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville"
                      ]
                    },
                    "cree_par_utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "commande": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "offre": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code": {
                          "type": "string"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "periode": {
                          "type": "string"
                        },
                        "volume_go": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "id",
                        "code",
                        "libelle",
                        "periode",
                        "volume_go"
                      ]
                    },
                    "jours_validite_restants": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "commission_prevue": {
                      "type": "integer"
                    },
                    "nb_lignes": {
                      "type": "integer"
                    },
                    "lignes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "devis_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type_ligne": {
                            "type": "string"
                          },
                          "produit_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "offre_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "quantite": {
                            "type": "integer"
                          },
                          "prix_unitaire_ht": {
                            "type": "integer"
                          },
                          "remise_pct": {
                            "type": "integer"
                          },
                          "taux_tva": {
                            "type": "integer"
                          },
                          "montant_ht": {
                            "type": "integer"
                          },
                          "montant_tva": {
                            "type": "integer"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "regle_commission_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "taux_commission": {
                            "type": "integer"
                          },
                          "remise_max_pct": {
                            "type": "string"
                          },
                          "produit": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "type_ligne": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "type_ligne"
                            ]
                          },
                          "offre": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "periode": {
                                "type": "string"
                              },
                              "volume_go": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "id",
                              "code",
                              "libelle",
                              "periode",
                              "volume_go"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "devis_id",
                          "type_ligne",
                          "produit_id",
                          "offre_id",
                          "libelle",
                          "quantite",
                          "prix_unitaire_ht",
                          "remise_pct",
                          "taux_tva",
                          "montant_ht",
                          "montant_tva",
                          "montant_ttc",
                          "regle_commission_id",
                          "taux_commission",
                          "remise_max_pct",
                          "produit",
                          "offre"
                        ]
                      }
                    },
                    "opportunite": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "client_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "partenaire_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "site_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "type_transaction": {
                          "type": "string"
                        },
                        "besoin": {
                          "type": "null"
                        },
                        "description": {
                          "type": "string"
                        },
                        "eligibilite": {
                          "type": "string"
                        },
                        "eligibilite_verifiee_par": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "uuid"
                        },
                        "eligibilite_verifiee_le": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "motif_perte": {
                          "type": "null"
                        },
                        "cree_par": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "modifie_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "client": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "raison_sociale": {
                              "type": "string"
                            },
                            "statut": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "raison_sociale",
                            "statut"
                          ]
                        },
                        "partenaire": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "raison_sociale": {
                              "type": "string"
                            },
                            "statut": {
                              "type": "string"
                            },
                            "ville": {
                              "type": "string"
                            },
                            "code_confidentiel": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "raison_sociale",
                            "statut",
                            "ville",
                            "code_confidentiel"
                          ]
                        },
                        "site": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "libelle": {
                              "type": "string"
                            },
                            "ville": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "libelle",
                            "ville"
                          ]
                        },
                        "commentaire_eligibilite": {
                          "type": "null"
                        },
                        "nb_devis": {
                          "type": "integer"
                        },
                        "anciennete_heures": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "id",
                        "client_id",
                        "partenaire_id",
                        "site_id",
                        "type_transaction",
                        "besoin",
                        "description",
                        "eligibilite",
                        "eligibilite_verifiee_par",
                        "eligibilite_verifiee_le",
                        "statut",
                        "motif_perte",
                        "cree_par",
                        "cree_le",
                        "modifie_le",
                        "client",
                        "partenaire",
                        "site",
                        "commentaire_eligibilite",
                        "nb_devis",
                        "anciennete_heures"
                      ]
                    },
                    "pdf_fichier": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "bucket": {
                          "type": "string"
                        },
                        "chemin": {
                          "type": "string"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        },
                        "taille_octets": {
                          "type": "integer"
                        },
                        "empreinte_sha256": {
                          "type": "string"
                        },
                        "statut_scan": {
                          "type": "string"
                        },
                        "depose_par": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "bucket",
                        "chemin",
                        "nom_original",
                        "type_mime",
                        "taille_octets",
                        "empreinte_sha256",
                        "statut_scan",
                        "depose_par",
                        "cree_le"
                      ]
                    },
                    "pdf_signe_fichier": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "bucket": {
                          "type": "string"
                        },
                        "chemin": {
                          "type": "string"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        },
                        "taille_octets": {
                          "type": "integer"
                        },
                        "empreinte_sha256": {
                          "type": "string"
                        },
                        "statut_scan": {
                          "type": "string"
                        },
                        "depose_par": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "bucket",
                        "chemin",
                        "nom_original",
                        "type_mime",
                        "taille_octets",
                        "empreinte_sha256",
                        "statut_scan",
                        "depose_par",
                        "cree_le"
                      ]
                    },
                    "historique": {
                      "type": "array",
                      "items": {}
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "opportunite_id",
                    "client_id",
                    "partenaire_id",
                    "site_id",
                    "statut",
                    "mode_paiement",
                    "valide_jusquau",
                    "total_ht",
                    "total_remise",
                    "total_tva",
                    "total_ttc",
                    "pdf_fichier_id",
                    "pdf_signe_fichier_id",
                    "envoye_le",
                    "signe_le",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "remise_exceptionnelle_statut",
                    "remise_exceptionnelle_motif",
                    "remise_exceptionnelle_demandee_le",
                    "remise_exceptionnelle_decidee_par",
                    "remise_exceptionnelle_decidee_le",
                    "remise_exceptionnelle_motif_decision",
                    "accepte_le",
                    "accepte_par",
                    "client",
                    "partenaire",
                    "site",
                    "cree_par_utilisateur",
                    "commande",
                    "offre",
                    "jours_validite_restants",
                    "commission_prevue",
                    "nb_lignes",
                    "lignes",
                    "opportunite",
                    "pdf_fichier",
                    "pdf_signe_fichier",
                    "historique"
                  ]
                },
                "example": {
                  "id": "21ff2ce1-1c6c-4f56-86b2-d0a0600b829b",
                  "numero": "DEV-2026-000067",
                  "opportunite_id": "279a6cfc-90ef-4688-ac1d-36fedaac94a3",
                  "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                  "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                  "site_id": "e114d094-6e40-45c9-913d-522133ed600a",
                  "statut": "brouillon",
                  "mode_paiement": "prepaye",
                  "valide_jusquau": "2026-11-03",
                  "total_ht": 20000,
                  "total_remise": 0,
                  "total_tva": 3600,
                  "total_ttc": 23600,
                  "pdf_fichier_id": null,
                  "pdf_signe_fichier_id": null,
                  "envoye_le": null,
                  "signe_le": null,
                  "cree_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                  "cree_le": "2026-10-19T10:45:44.546Z",
                  "modifie_le": "2026-10-19T10:45:44.546Z",
                  "remise_exceptionnelle_statut": null,
                  "remise_exceptionnelle_motif": null,
                  "remise_exceptionnelle_demandee_le": null,
                  "remise_exceptionnelle_decidee_par": null,
                  "remise_exceptionnelle_decidee_le": null,
                  "remise_exceptionnelle_motif_decision": null,
                  "accepte_le": null,
                  "accepte_par": null,
                  "client": {
                    "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                    "raison_sociale": "ZZ Recette Client 4D20EED1",
                    "statut": "reserve"
                  },
                  "partenaire": {
                    "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                    "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                    "statut": "actif",
                    "ville": "Abidjan",
                    "code_confidentiel": "C-0076"
                  },
                  "site": {
                    "id": "e114d094-6e40-45c9-913d-522133ed600a",
                    "libelle": "Site 4D20EED1",
                    "ville": "Abidjan"
                  },
                  "cree_par_utilisateur": {
                    "id": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                    "prenom": "ZZ Recette",
                    "nom": "Partenaire A 856174D4",
                    "email": "zz.recette.856174d4@exemple.invalide"
                  },
                  "commande": null,
                  "offre": {
                    "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                    "code": "DATA-50GO-HEBDO",
                    "libelle": "Forfait 50 Go hebdomadaire",
                    "periode": "hebdomadaire",
                    "volume_go": 50
                  },
                  "jours_validite_restants": 15,
                  "commission_prevue": 4000,
                  "nb_lignes": 1,
                  "lignes": [
                    {
                      "id": "437c2d7e-ccfb-4f0d-b15a-7c8ebfba82c1",
                      "devis_id": "21ff2ce1-1c6c-4f56-86b2-d0a0600b829b",
                      "type_ligne": "forfait_data",
                      "produit_id": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                      "offre_id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                      "libelle": "Forfait 50 Go hebdomadaire",
                      "quantite": 1,
                      "prix_unitaire_ht": 20000,
                      "remise_pct": 0,
                      "taux_tva": 18,
                      "montant_ht": 20000,
                      "montant_tva": 3600,
                      "montant_ttc": 23600,
                      "regle_commission_id": "ff96d34b-b693-4e56-8fda-4c49ac0ed07e",
                      "taux_commission": 20,
                      "remise_max_pct": "10",
                      "produit": {
                        "id": "deeeb2ee-b2ec-48b3-b913-8673d386e990",
                        "code": "FORFAIT-DATA",
                        "libelle": "Forfait data",
                        "type_ligne": "forfait_data"
                      },
                      "offre": {
                        "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                        "code": "DATA-50GO-HEBDO",
                        "libelle": "Forfait 50 Go hebdomadaire",
                        "periode": "hebdomadaire",
                        "volume_go": 50
                      }
                    }
                  ],
                  "opportunite": {
                    "id": "279a6cfc-90ef-4688-ac1d-36fedaac94a3",
                    "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                    "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                    "site_id": "e114d094-6e40-45c9-913d-522133ed600a",
                    "type_transaction": "nouveau_besoin",
                    "besoin": null,
                    "description": "Épreuve des sections : besoin de connectivité.",
                    "eligibilite": "eligible",
                    "eligibilite_verifiee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                    "eligibilite_verifiee_le": "2026-10-19T10:45:44.195Z",
                    "statut": "devis_emis",
                    "motif_perte": null,
                    "cree_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                    "cree_le": "2026-10-19T10:45:43.845Z",
                    "modifie_le": "2026-10-19T10:45:44.544Z",
                    "client": {
                      "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                      "raison_sociale": "ZZ Recette Client 4D20EED1",
                      "statut": "reserve"
                    },
                    "partenaire": {
                      "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                      "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                      "statut": "actif",
                      "ville": "Abidjan",
                      "code_confidentiel": "C-0076"
                    },
                    "site": {
                      "id": "e114d094-6e40-45c9-913d-522133ed600a",
                      "libelle": "Site 4D20EED1",
                      "ville": "Abidjan"
                    },
                    "commentaire_eligibilite": null,
                    "nb_devis": 0,
                    "anciennete_heures": 0
                  },
                  "pdf_fichier": null,
                  "pdf_signe_fichier": null,
                  "historique": []
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "devis.gerer",
          "devis.accepter"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/opportunites/{id}": {
      "get": {
        "operationId": "getOpportunitesParId",
        "tags": [
          "Ventes"
        ],
        "summary": "Lire le détail d'une opportunité",
        "description": "La fiche d'une opportunité, avec l'historique de ses devis (numéro, statut, totaux, validité, date de signature), du plus récent au plus ancien.\n\n**Permission requise** : `opportunites.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type_transaction": {
                      "type": "string"
                    },
                    "besoin": {
                      "type": "object",
                      "properties": {
                        "duree": {
                          "type": "string"
                        },
                        "sites": {
                          "type": "integer"
                        },
                        "usage": {
                          "type": "string"
                        },
                        "connexions": {
                          "type": "integer"
                        },
                        "cle_idempotence": {
                          "type": "string"
                        },
                        "exprime_par_le_client": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "duree",
                        "sites",
                        "usage",
                        "connexions",
                        "cle_idempotence",
                        "exprime_par_le_client"
                      ]
                    },
                    "description": {
                      "type": "string"
                    },
                    "eligibilite": {
                      "type": "string"
                    },
                    "eligibilite_verifiee_par": {
                      "type": "null"
                    },
                    "eligibilite_verifiee_le": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "motif_perte": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "devis": {
                      "type": "array",
                      "items": {}
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville",
                        "code_confidentiel"
                      ]
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville"
                      ]
                    },
                    "cree_par_utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "eligibilite_verifiee_par_utilisateur": {
                      "type": "null"
                    },
                    "commentaire_eligibilite": {
                      "type": "null"
                    },
                    "nb_devis": {
                      "type": "integer"
                    },
                    "anciennete_heures": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "client_id",
                    "partenaire_id",
                    "site_id",
                    "type_transaction",
                    "besoin",
                    "description",
                    "eligibilite",
                    "eligibilite_verifiee_par",
                    "eligibilite_verifiee_le",
                    "statut",
                    "motif_perte",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "devis",
                    "client",
                    "partenaire",
                    "site",
                    "cree_par_utilisateur",
                    "eligibilite_verifiee_par_utilisateur",
                    "commentaire_eligibilite",
                    "nb_devis",
                    "anciennete_heures"
                  ]
                },
                "example": {
                  "id": "e7375b41-9ae4-4cea-8f3d-49e30857e8da",
                  "client_id": "d0340284-d849-479a-8b15-89c1d0da08cc",
                  "partenaire_id": "2bf838df-d511-4a0c-a1e2-7f76064e3e3d",
                  "site_id": "0ec47790-5761-48a2-b312-3f0f5f8bc869",
                  "type_transaction": "nouveau_besoin",
                  "besoin": {
                    "duree": "12 mois",
                    "sites": 2,
                    "usage": "Liaison de secours pour la recette du cloisonnement",
                    "connexions": 6,
                    "cle_idempotence": "besoin-recette-1792406782857",
                    "exprime_par_le_client": true
                  },
                  "description": "Liaison de secours pour la recette du cloisonnement",
                  "eligibilite": "a_verifier",
                  "eligibilite_verifiee_par": null,
                  "eligibilite_verifiee_le": null,
                  "statut": "ouverte",
                  "motif_perte": null,
                  "cree_par": "596208bc-80f2-4f32-951d-e40ff9b23af5",
                  "cree_le": "2026-10-19T10:46:23.534Z",
                  "modifie_le": "2026-10-19T10:46:23.534Z",
                  "devis": [],
                  "client": {
                    "id": "d0340284-d849-479a-8b15-89c1d0da08cc",
                    "raison_sociale": "ZZ Recette Client 87E9A884",
                    "statut": "reserve"
                  },
                  "partenaire": {
                    "id": "2bf838df-d511-4a0c-a1e2-7f76064e3e3d",
                    "raison_sociale": "ZZ Recette Partenaire A 60446FF3",
                    "statut": "actif",
                    "ville": "Abidjan",
                    "code_confidentiel": "C-0078"
                  },
                  "site": {
                    "id": "0ec47790-5761-48a2-b312-3f0f5f8bc869",
                    "libelle": "ZZ Recette Besoin 2BQ96R26",
                    "ville": "Abidjan"
                  },
                  "cree_par_utilisateur": {
                    "id": "596208bc-80f2-4f32-951d-e40ff9b23af5",
                    "prenom": "ZZ Recette",
                    "nom": "Client 87E9A884",
                    "email": "zz.client.87e9a884@exemple.invalide"
                  },
                  "eligibilite_verifiee_par_utilisateur": null,
                  "commentaire_eligibilite": null,
                  "nb_devis": 0,
                  "anciennete_heures": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "opportunites.gerer",
        "x-satelica-cloisonnement": "applique"
      },
      "delete": {
        "operationId": "deleteOpportunitesParId",
        "tags": [
          "Ventes"
        ],
        "summary": "Supprimer une opportunité sans devis",
        "description": "Supprime un besoin qui n'a produit aucun devis ; le journal d'audit en garde le statut, la description et le client. Dès qu'un devis en est sorti, la suppression est refusée.\n\n**Permission requise** : `opportunites.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "supprime"
                  ]
                },
                "example": {
                  "supprime": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "L'opportunité a déjà donné lieu à un devis.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "opportunites.gerer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/opportunites/{id}/eligibilite": {
      "post": {
        "operationId": "postOpportunitesParIdEligibilite",
        "tags": [
          "Ventes"
        ],
        "summary": "Trancher l'éligibilité d'une opportunité",
        "description": "CYBASTION déclare le site de l’opportunité éligible ou non éligible ; une décision `non_eligible` exige un commentaire (400 sinon). Une opportunité `ouverte` déclarée éligible passe `qualifiee` et peut être chiffrée ; non éligible, aucun devis ne peut en être établi.\n\n**Permission requise** : `eligibilite.verifier`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "eligible",
                      "non_eligible"
                    ]
                  },
                  "commentaire": {
                    "type": "string",
                    "maxLength": 1000
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "eligible"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type_transaction": {
                      "type": "string"
                    },
                    "besoin": {
                      "type": "null"
                    },
                    "description": {
                      "type": "string"
                    },
                    "eligibilite": {
                      "type": "string"
                    },
                    "eligibilite_verifiee_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "eligibilite_verifiee_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "motif_perte": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville",
                        "code_confidentiel"
                      ]
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville"
                      ]
                    },
                    "commentaire_eligibilite": {
                      "type": "null"
                    },
                    "nb_devis": {
                      "type": "integer"
                    },
                    "anciennete_heures": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "client_id",
                    "partenaire_id",
                    "site_id",
                    "type_transaction",
                    "besoin",
                    "description",
                    "eligibilite",
                    "eligibilite_verifiee_par",
                    "eligibilite_verifiee_le",
                    "statut",
                    "motif_perte",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "client",
                    "partenaire",
                    "site",
                    "commentaire_eligibilite",
                    "nb_devis",
                    "anciennete_heures"
                  ]
                },
                "example": {
                  "id": "279a6cfc-90ef-4688-ac1d-36fedaac94a3",
                  "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                  "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                  "site_id": "e114d094-6e40-45c9-913d-522133ed600a",
                  "type_transaction": "nouveau_besoin",
                  "besoin": null,
                  "description": "Épreuve des sections : besoin de connectivité.",
                  "eligibilite": "eligible",
                  "eligibilite_verifiee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "eligibilite_verifiee_le": "2026-10-19T10:45:44.195Z",
                  "statut": "qualifiee",
                  "motif_perte": null,
                  "cree_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                  "cree_le": "2026-10-19T10:45:43.845Z",
                  "modifie_le": "2026-10-19T10:45:44.197Z",
                  "client": {
                    "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                    "raison_sociale": "ZZ Recette Client 4D20EED1",
                    "statut": "reserve"
                  },
                  "partenaire": {
                    "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                    "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                    "statut": "actif",
                    "ville": "Abidjan",
                    "code_confidentiel": "C-0076"
                  },
                  "site": {
                    "id": "e114d094-6e40-45c9-913d-522133ed600a",
                    "libelle": "Site 4D20EED1",
                    "ville": "Abidjan"
                  },
                  "commentaire_eligibilite": null,
                  "nb_devis": 0,
                  "anciennete_heures": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Opportunité clôturée : gagnée, perdue ou abandonnée.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "eligibilite.verifier",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/devis/{id}/reponse": {
      "post": {
        "operationId": "postDevisParIdReponse",
        "tags": [
          "Ventes"
        ],
        "summary": "Répondre à un devis reçu",
        "description": "Le client accepte ou refuse un devis `envoye` et non expiré. Accepter ne signe pas : le devis reste `envoye`, l’acceptation est datée (`accepte_le`) et la signature vient ensuite ; refuser exige un motif (400 sinon) et fait passer le devis `refuse`. La réponse ne se donne qu’une fois, et le partenaire en est notifié.\n\n**Permission requise** : `devis.accepter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "accepte",
                      "refuse"
                    ]
                  },
                  "motif": {
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "refuse",
                "motif": "Budget reporté au prochain exercice."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "decision": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "accepte_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "prochaine_etape": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "decision",
                    "statut",
                    "accepte_le",
                    "prochaine_etape"
                  ]
                },
                "example": {
                  "id": "d4824711-8407-44a1-8a56-2ea135ddfd66",
                  "numero": "DEV-2026-000059",
                  "decision": "refuse",
                  "statut": "refuse",
                  "accepte_le": null,
                  "prochaine_etape": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Le devis n'attend plus de réponse : raison dans `details.raison` (`statut`, `deja_accepte`, `expire`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "devis.accepter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/paiements": {
      "post": {
        "operationId": "postPaiements",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Déclarer un règlement reçu hors ligne",
        "description": "Un partenaire, un client ou CYBASTION déclare un règlement en espèces, par chèque ou par virement sur une commande ou une facture : il naît « en_attente_validation » et ne produit aucun effet avant la décision de la Finance. Un client ne peut pas déclarer d'espèces et doit joindre un justificatif ; tout justificatif doit avoir été déposé par l'appelant (`POST /fichiers`) et avoir passé l'antivirus. Le montant ne peut dépasser le reste dû diminué de ce qui attend déjà la validation. Rejouer la même `cle_idempotence` renvoie le règlement déjà déclaré (`deja_declare: true`) ; une déclaration faite par le client est notifiée à son partenaire.\n\n**Permission requise** : L'une de : `paiements.declarer`, `paiements.valider`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "commande_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "facture_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "canal": {
                    "type": "string",
                    "enum": [
                      "especes",
                      "cheque",
                      "virement"
                    ]
                  },
                  "montant": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 1000000000
                  },
                  "date_paiement": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  },
                  "reference_externe": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "justificatif_fichier_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "cle_idempotence": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 120
                  }
                },
                "required": [
                  "canal",
                  "montant",
                  "date_paiement",
                  "cle_idempotence"
                ]
              },
              "example": {
                "commande_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                "canal": "virement",
                "montant": 11800,
                "date_paiement": "2026-10-19",
                "reference_externe": "VIR-WNCYUQRHJW",
                "justificatif_fichier_id": "be3ed415-f6d4-463b-981a-8c1e18fbbbc6",
                "cle_idempotence": "recette-WNCYUQRHJW"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 7 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "montant": {
                      "type": "integer"
                    },
                    "canal": {
                      "type": "string"
                    },
                    "date_paiement": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "deja_declare": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "statut",
                    "montant",
                    "canal",
                    "date_paiement",
                    "client_id",
                    "deja_declare"
                  ]
                },
                "example": {
                  "id": "e178b154-320b-4d2c-87fc-c15ad71ac741",
                  "statut": "en_attente_validation",
                  "montant": 23600,
                  "canal": "virement",
                  "date_paiement": "2026-10-19T12:00:00.000Z",
                  "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                  "deja_declare": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "paiements.declarer",
          "paiements.valider"
        ],
        "x-satelica-cloisonnement": "applique"
      },
      "get": {
        "operationId": "getPaiements",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Lister les règlements",
        "description": "Règlements en ligne et hors ligne, du plus récent au plus ancien, filtrables par statut et par canal (plusieurs valeurs séparées par des virgules), par client, commande ou facture. Chaque ligne porte le client et son partenaire, la commande, la facture, le déclarant, le valideur, son ancienneté en heures et `en_ligne` (vrai pour Paystack).\n\n**Permission requise** : L'une de : `paiements.declarer`, `paiements.valider`, `paiements.payer_en_ligne`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "canal",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "commande_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "facture_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 6 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "commande_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "facture_id": {
                            "type": "null"
                          },
                          "echeance_id": {
                            "type": "null"
                          },
                          "montant": {
                            "type": "integer"
                          },
                          "canal": {
                            "type": "string"
                          },
                          "moyen": {
                            "type": "null"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "reference_paystack": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "reference_externe": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "date_paiement": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "justificatif_fichier_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "declare_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "valide_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "valide_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "motif_rejet": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "cle_idempotence": {
                            "type": "string"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "frais_prestataire": {
                            "type": "null"
                          },
                          "montant_net": {
                            "type": "null"
                          },
                          "expire_le": {
                            "type": "null"
                          },
                          "adresse_paiement": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut"
                            ]
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "ville",
                              "code_confidentiel"
                            ]
                          },
                          "anciennete_heures": {
                            "type": "integer"
                          },
                          "en_ligne": {
                            "type": "boolean"
                          },
                          "commande": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          },
                          "facture": {
                            "type": "null"
                          },
                          "declare_par_utilisateur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "valide_par_utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "client_id",
                          "commande_id",
                          "facture_id",
                          "echeance_id",
                          "montant",
                          "canal",
                          "moyen",
                          "statut",
                          "reference_paystack",
                          "reference_externe",
                          "date_paiement",
                          "justificatif_fichier_id",
                          "declare_par",
                          "valide_par",
                          "valide_le",
                          "motif_rejet",
                          "cle_idempotence",
                          "cree_le",
                          "modifie_le",
                          "frais_prestataire",
                          "montant_net",
                          "expire_le",
                          "adresse_paiement",
                          "client",
                          "partenaire",
                          "anciennete_heures",
                          "en_ligne",
                          "commande",
                          "facture",
                          "declare_par_utilisateur",
                          "valide_par_utilisateur"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 0,
                    "pages": 0
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "paiements.declarer",
          "paiements.valider",
          "paiements.payer_en_ligne"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/paiements/{id}": {
      "get": {
        "operationId": "getPaiementsParId",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Lire la fiche d'un règlement",
        "description": "Le règlement avec son client et le partenaire de celui-ci, sa commande, sa facture, son échéance, son justificatif et la trace de la décision (valideur, motif de rejet). `rapprochement` compare le montant déclaré au reste attendu sur la pièce hors ce règlement ; `controle_validation` annonce, pour un règlement encore à trancher, le dépassement du dû que sa validation produirait et le doublon probable (`null` sinon).\n\n**Permission requise** : L'une de : `paiements.declarer`, `paiements.valider`, `paiements.payer_en_ligne`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "commande_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "facture_id": {
                      "type": "null"
                    },
                    "echeance_id": {
                      "type": "null"
                    },
                    "montant": {
                      "type": "integer"
                    },
                    "canal": {
                      "type": "string"
                    },
                    "moyen": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "reference_paystack": {
                      "type": "null"
                    },
                    "reference_externe": {
                      "type": "null"
                    },
                    "date_paiement": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "justificatif_fichier_id": {
                      "type": "null"
                    },
                    "declare_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "motif_rejet": {
                      "type": "null"
                    },
                    "cle_idempotence": {
                      "type": "string"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "frais_prestataire": {
                      "type": "null"
                    },
                    "montant_net": {
                      "type": "null"
                    },
                    "expire_le": {
                      "type": "null"
                    },
                    "adresse_paiement": {
                      "type": "null"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "ville",
                        "code_confidentiel"
                      ]
                    },
                    "anciennete_heures": {
                      "type": "integer"
                    },
                    "en_ligne": {
                      "type": "boolean"
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "total_ttc": {
                          "type": "integer"
                        },
                        "mode_paiement": {
                          "type": "string"
                        },
                        "montant_paye": {
                          "type": "integer"
                        },
                        "montant_en_attente": {
                          "type": "integer"
                        },
                        "reste_a_payer": {
                          "type": "integer"
                        },
                        "trop_percu": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "total_ttc",
                        "mode_paiement",
                        "montant_paye",
                        "montant_en_attente",
                        "reste_a_payer",
                        "trop_percu"
                      ]
                    },
                    "facture": {
                      "type": "null"
                    },
                    "rapprochement": {
                      "type": "object",
                      "properties": {
                        "objet": {
                          "type": "string"
                        },
                        "reference": {
                          "type": "string"
                        },
                        "montant_attendu": {
                          "type": "integer"
                        },
                        "montant_declare": {
                          "type": "integer"
                        },
                        "ecart": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "objet",
                        "reference",
                        "montant_attendu",
                        "montant_declare",
                        "ecart"
                      ]
                    },
                    "controle_validation": {
                      "type": "null"
                    },
                    "echeance": {
                      "type": "null"
                    },
                    "justificatif": {
                      "type": "null"
                    },
                    "declare_par_utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "valide_par_utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "client_id",
                    "commande_id",
                    "facture_id",
                    "echeance_id",
                    "montant",
                    "canal",
                    "moyen",
                    "statut",
                    "reference_paystack",
                    "reference_externe",
                    "date_paiement",
                    "justificatif_fichier_id",
                    "declare_par",
                    "valide_par",
                    "valide_le",
                    "motif_rejet",
                    "cle_idempotence",
                    "cree_le",
                    "modifie_le",
                    "frais_prestataire",
                    "montant_net",
                    "expire_le",
                    "adresse_paiement",
                    "client",
                    "partenaire",
                    "anciennete_heures",
                    "en_ligne",
                    "commande",
                    "facture",
                    "rapprochement",
                    "controle_validation",
                    "echeance",
                    "justificatif",
                    "declare_par_utilisateur",
                    "valide_par_utilisateur"
                  ]
                },
                "example": {
                  "id": "feffd5ef-1fde-4d9c-965b-f4f309def2af",
                  "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                  "commande_id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                  "facture_id": null,
                  "echeance_id": null,
                  "montant": 23600,
                  "canal": "virement",
                  "moyen": null,
                  "statut": "valide",
                  "reference_paystack": null,
                  "reference_externe": null,
                  "date_paiement": "2026-10-19T10:45:49.147Z",
                  "justificatif_fichier_id": null,
                  "declare_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                  "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "valide_le": "2026-10-19T10:45:49.147Z",
                  "motif_rejet": null,
                  "cle_idempotence": "sections-1792406747933",
                  "cree_le": "2026-10-19T10:45:48.612Z",
                  "modifie_le": "2026-10-19T10:45:49.147Z",
                  "frais_prestataire": null,
                  "montant_net": null,
                  "expire_le": null,
                  "adresse_paiement": null,
                  "client": {
                    "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                    "raison_sociale": "ZZ Recette Client 4D20EED1",
                    "statut": "actif"
                  },
                  "partenaire": {
                    "id": "73ead9a5-5d14-407b-b5b6-2d67785df304",
                    "raison_sociale": "ZZ Recette Partenaire B 3B47802A",
                    "ville": "Abidjan",
                    "code_confidentiel": "C-0077"
                  },
                  "anciennete_heures": 0,
                  "en_ligne": false,
                  "commande": {
                    "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                    "numero": "CMD-2026-000032",
                    "statut": "active",
                    "total_ttc": 23600,
                    "mode_paiement": "prepaye",
                    "montant_paye": 23600,
                    "montant_en_attente": 0,
                    "reste_a_payer": 0,
                    "trop_percu": 0
                  },
                  "facture": null,
                  "rapprochement": {
                    "objet": "commande",
                    "reference": "CMD-2026-000032",
                    "montant_attendu": 23600,
                    "montant_declare": 23600,
                    "ecart": 0
                  },
                  "controle_validation": null,
                  "echeance": null,
                  "justificatif": null,
                  "declare_par_utilisateur": {
                    "id": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                    "prenom": "ZZ Recette",
                    "nom": "Partenaire A 856174D4",
                    "email": "zz.recette.856174d4@exemple.invalide"
                  },
                  "valide_par_utilisateur": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction",
                    "email": "admin.cybastion@preprod.satelica.test"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "paiements.declarer",
          "paiements.valider",
          "paiements.payer_en_ligne"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/paiements/{id}/decision": {
      "post": {
        "operationId": "postPaiementsParIdDecision",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Valider ou rejeter un règlement",
        "description": "La Finance tranche un règlement « initie » ou « en_attente_validation » : il passe à « valide » ou à « rejete » (motif obligatoire pour un rejet). Une validation qui porterait l'encaissé au-delà du dû est refusée, chiffrée et avec le doublon probable, sauf avec `accepter_trop_percu: true` et un motif d’au moins cinq caractères. Validé, le règlement applique dans la même transaction les effets de l'encaissement sur sa commande : commissions réalisées au prorata (le partenaire en est prévenu), factures mises à jour et, si elle est soldée, passage de « attente_paiement » à « payee » avec ouverture de l’ordre d’installation dû ; le bilan est rendu dans `encaissement`.\n\n**Permission requise** : `paiements.valider`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "valide",
                      "rejete"
                    ]
                  },
                  "motif": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "accepter_trop_percu": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "rejete",
                "motif": "Virement introuvable sur le relevé."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 6 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "commande_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "facture_id": {
                      "type": "null"
                    },
                    "echeance_id": {
                      "type": "null"
                    },
                    "montant": {
                      "type": "integer"
                    },
                    "canal": {
                      "type": "string"
                    },
                    "moyen": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "reference_paystack": {
                      "type": "null"
                    },
                    "reference_externe": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "date_paiement": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "justificatif_fichier_id": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "declare_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "motif_rejet": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "cle_idempotence": {
                      "type": "string"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "frais_prestataire": {
                      "type": "null"
                    },
                    "montant_net": {
                      "type": "null"
                    },
                    "expire_le": {
                      "type": "null"
                    },
                    "adresse_paiement": {
                      "type": "null"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut"
                      ]
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "facture": {
                      "type": "null"
                    },
                    "encaissement": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "encaisse": {
                          "type": "integer"
                        },
                        "du": {
                          "type": "integer"
                        },
                        "soldee": {
                          "type": "boolean"
                        },
                        "commissionsRealisees": {
                          "type": "integer"
                        },
                        "nbCommissions": {
                          "type": "integer"
                        },
                        "ordreInstallation": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "numero": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "numero"
                          ]
                        }
                      },
                      "required": [
                        "encaisse",
                        "du",
                        "soldee",
                        "commissionsRealisees",
                        "nbCommissions",
                        "ordreInstallation"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "client_id",
                    "commande_id",
                    "facture_id",
                    "echeance_id",
                    "montant",
                    "canal",
                    "moyen",
                    "statut",
                    "reference_paystack",
                    "reference_externe",
                    "date_paiement",
                    "justificatif_fichier_id",
                    "declare_par",
                    "valide_par",
                    "valide_le",
                    "motif_rejet",
                    "cle_idempotence",
                    "cree_le",
                    "modifie_le",
                    "frais_prestataire",
                    "montant_net",
                    "expire_le",
                    "adresse_paiement",
                    "client",
                    "commande",
                    "facture",
                    "encaissement"
                  ]
                },
                "example": {
                  "id": "e178b154-320b-4d2c-87fc-c15ad71ac741",
                  "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                  "commande_id": "517790aa-ada4-451d-8a22-1a9b3bd2136e",
                  "facture_id": null,
                  "echeance_id": null,
                  "montant": 23600,
                  "canal": "virement",
                  "moyen": null,
                  "statut": "rejete",
                  "reference_paystack": null,
                  "reference_externe": "VIR-40a280",
                  "date_paiement": "2026-10-19T12:00:00.000Z",
                  "justificatif_fichier_id": null,
                  "declare_par": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                  "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "valide_le": "2026-10-19T10:44:20.363Z",
                  "motif_rejet": "Virement introuvable sur le relevé.",
                  "cle_idempotence": "9cc5d49a-ee0b-4085-8b96-c81a45f29243",
                  "cree_le": "2026-10-19T10:44:20.233Z",
                  "modifie_le": "2026-10-19T10:44:20.363Z",
                  "frais_prestataire": null,
                  "montant_net": null,
                  "expire_le": null,
                  "adresse_paiement": null,
                  "client": {
                    "id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                    "raison_sociale": "ZZ Recette Client 54587534",
                    "statut": "reserve"
                  },
                  "commande": {
                    "id": "517790aa-ada4-451d-8a22-1a9b3bd2136e",
                    "numero": "CMD-2026-000028",
                    "statut": "attente_paiement"
                  },
                  "facture": null,
                  "encaissement": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "paiements.valider",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/paiements/{id}/annulation": {
      "post": {
        "operationId": "postPaiementsParIdAnnulation",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Annuler un règlement validé",
        "description": "Défait un règlement hors ligne « valide », un doublon validé par erreur par exemple : il repasse à « rejete » avec le motif, les commissions qu’il avait fait acquérir sont retirées, les factures recalculées, la commande qui n’est plus soldée revient de « payee » à « attente_paiement » et l’ordre d’installation encore « à envoyer » qu’il avait ouvert est annulé. Refusée pour un règlement non validé, pour un encaissement en ligne (passer par un avoir), quand l’installation est déjà engagée sur la foi de ce paiement, ou quand il faudrait retirer des commissions déjà demandées ou versées.\n\n**Permission requise** : `paiements.valider`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "motif": {
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 500
                  }
                },
                "required": [
                  "motif"
                ]
              },
              "example": {
                "motif": "Virement enregistré deux fois."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "montant": {
                      "type": "integer"
                    },
                    "motif_rejet": {
                      "type": "string"
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statutAvant": {
                          "type": "string"
                        },
                        "statutApres": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statutAvant",
                        "statutApres"
                      ]
                    },
                    "annulation": {
                      "type": "object",
                      "properties": {
                        "encaisse": {
                          "type": "integer"
                        },
                        "du": {
                          "type": "integer"
                        },
                        "reste_a_payer": {
                          "type": "integer"
                        },
                        "trop_percu": {
                          "type": "integer"
                        },
                        "commissions_retirees": {
                          "type": "integer"
                        },
                        "lignes_commission": {
                          "type": "integer"
                        },
                        "ordres_annules": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      },
                      "required": [
                        "encaisse",
                        "du",
                        "reste_a_payer",
                        "trop_percu",
                        "commissions_retirees",
                        "lignes_commission",
                        "ordres_annules"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "statut",
                    "montant",
                    "motif_rejet",
                    "commande",
                    "annulation"
                  ]
                },
                "example": {
                  "id": "f3e545eb-c12f-494c-aa59-5f805cfe1844",
                  "statut": "rejete",
                  "montant": 23600,
                  "motif_rejet": "Virement enregistré deux fois.",
                  "commande": {
                    "id": "183c1dab-cc43-488d-bac5-1df62198157d",
                    "numero": "CMD-2026-000031",
                    "statutAvant": "payee",
                    "statutApres": "attente_paiement"
                  },
                  "annulation": {
                    "encaisse": 0,
                    "du": 23600,
                    "reste_a_payer": 23600,
                    "trop_percu": 0,
                    "commissions_retirees": 2000,
                    "lignes_commission": 1,
                    "ordres_annules": [
                      "INS-2026-000036"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "paiements.valider",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/factures": {
      "get": {
        "operationId": "getFactures",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Lister les factures",
        "description": "Factures, de la plus récente à la plus ancienne, filtrables par statut (plusieurs valeurs), client, commande et `en_retard` (échéance passée, facture ni payée ni annulée). Le montant payé et le reste à payer sont recalculés depuis les règlements validés de la facture et de sa commande, jamais lus en colonne. Chaque ligne porte aussi le trop-perçu, les paiements en attente, le retard en jours, le total des avoirs, le nombre de relances, le client et son partenaire.\n\n**Permission requise** : L'une de : `factures.emettre`, `paiements.payer_en_ligne`, `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "commande_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "en_retard",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 6 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "commande_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "contrat_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "echeance_id": {
                            "type": "null"
                          },
                          "date_emission": {
                            "type": "string",
                            "format": "date"
                          },
                          "date_echeance": {
                            "type": "string",
                            "format": "date"
                          },
                          "montant_ht": {
                            "type": "integer"
                          },
                          "montant_tva": {
                            "type": "integer"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "montant_paye": {
                            "type": "integer"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "reference_fne": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "pdf_fichier_id": {
                            "type": "null"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "reste_a_payer": {
                            "type": "integer"
                          },
                          "trop_percu": {
                            "type": "integer"
                          },
                          "partiellement_reglee": {
                            "type": "boolean"
                          },
                          "paiements_en_attente": {
                            "type": "integer"
                          },
                          "en_retard": {
                            "type": "boolean"
                          },
                          "jours_retard": {
                            "type": "integer"
                          },
                          "montant_avoirs": {
                            "type": "integer"
                          },
                          "nb_relances": {
                            "type": "integer"
                          },
                          "derniere_relance_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut"
                            ]
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "ville",
                              "code_confidentiel"
                            ]
                          },
                          "commande": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "client_id",
                          "commande_id",
                          "contrat_id",
                          "echeance_id",
                          "date_emission",
                          "date_echeance",
                          "montant_ht",
                          "montant_tva",
                          "montant_ttc",
                          "montant_paye",
                          "statut",
                          "reference_fne",
                          "pdf_fichier_id",
                          "cree_le",
                          "modifie_le",
                          "reste_a_payer",
                          "trop_percu",
                          "partiellement_reglee",
                          "paiements_en_attente",
                          "en_retard",
                          "jours_retard",
                          "montant_avoirs",
                          "nb_relances",
                          "derniere_relance_le",
                          "client",
                          "partenaire",
                          "commande"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "3f63aa9c-25f8-4cdc-8f2d-13790034a6d9",
                      "numero": "FAC-2026-000022",
                      "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                      "commande_id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                      "contrat_id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                      "echeance_id": null,
                      "date_emission": "2026-10-19",
                      "date_echeance": "2026-10-19",
                      "montant_ht": 20000,
                      "montant_tva": 3600,
                      "montant_ttc": 23600,
                      "montant_paye": 23600,
                      "statut": "payee",
                      "reference_fne": null,
                      "pdf_fichier_id": null,
                      "cree_le": "2026-10-19T10:45:49.759Z",
                      "modifie_le": "2026-10-19T10:45:49.759Z",
                      "reste_a_payer": 0,
                      "trop_percu": 0,
                      "partiellement_reglee": false,
                      "paiements_en_attente": 23600,
                      "en_retard": false,
                      "jours_retard": 0,
                      "montant_avoirs": 1000,
                      "nb_relances": 0,
                      "derniere_relance_le": null,
                      "client": {
                        "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                        "raison_sociale": "ZZ Recette Client 4D20EED1",
                        "statut": "actif"
                      },
                      "partenaire": {
                        "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                        "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                        "ville": "Abidjan",
                        "code_confidentiel": "C-0076"
                      },
                      "commande": {
                        "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                        "numero": "CMD-2026-000032",
                        "statut": "active"
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 1,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "factures.emettre",
          "paiements.payer_en_ligne",
          "espace_partenaire.acceder"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/factures/{id}": {
      "get": {
        "operationId": "getFacturesParId",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Lire la fiche d'une facture",
        "description": "La facture avec son client et le partenaire de celui-ci, ses règlements (ceux de la facture et ceux de sa commande qu’elle couvre), ses avoirs, ses relances, son échéance, son document PDF (`pdf_fichier`), sa commande et son contrat. Les soldes sont recalculés depuis les règlements validés ; `reste_a_declarer` dit ce qu’une déclaration de règlement peut encore porter.\n\n**Permission requise** : L'une de : `factures.emettre`, `paiements.payer_en_ligne`, `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "commande_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contrat_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "echeance_id": {
                      "type": "null"
                    },
                    "date_emission": {
                      "type": "string",
                      "format": "date"
                    },
                    "date_echeance": {
                      "type": "string",
                      "format": "date"
                    },
                    "montant_ht": {
                      "type": "integer"
                    },
                    "montant_tva": {
                      "type": "integer"
                    },
                    "montant_ttc": {
                      "type": "integer"
                    },
                    "montant_paye": {
                      "type": "integer"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "reference_fne": {
                      "type": "null"
                    },
                    "pdf_fichier_id": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "relances": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "facture_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "canal": {
                            "type": "string"
                          },
                          "destinataire": {
                            "type": "string"
                          },
                          "envoyee_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "facture_id",
                          "canal",
                          "destinataire",
                          "envoyee_le"
                        ]
                      }
                    },
                    "avoirs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "facture_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "motif": {
                            "type": "string"
                          },
                          "rembourse": {
                            "type": "boolean"
                          },
                          "moyen_remboursement": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "rembourse_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "facture_id",
                          "montant_ttc",
                          "motif",
                          "rembourse",
                          "moyen_remboursement",
                          "rembourse_le",
                          "cree_par",
                          "cree_le"
                        ]
                      }
                    },
                    "echeances": {
                      "type": "array",
                      "items": {}
                    },
                    "reste_a_payer": {
                      "type": "integer"
                    },
                    "trop_percu": {
                      "type": "integer"
                    },
                    "partiellement_reglee": {
                      "type": "boolean"
                    },
                    "paiements_en_attente": {
                      "type": "integer"
                    },
                    "montant_en_attente": {
                      "type": "integer"
                    },
                    "reste_a_declarer": {
                      "type": "integer"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "ville",
                        "code_confidentiel"
                      ]
                    },
                    "paiements": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "commande_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "facture_id": {
                            "type": "null"
                          },
                          "echeance_id": {
                            "type": "null"
                          },
                          "montant": {
                            "type": "integer"
                          },
                          "canal": {
                            "type": "string"
                          },
                          "moyen": {
                            "type": "null"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "reference_paystack": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "reference_externe": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "date_paiement": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "justificatif_fichier_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "declare_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "valide_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "valide_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "motif_rejet": {
                            "type": "null"
                          },
                          "cle_idempotence": {
                            "type": "string"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "frais_prestataire": {
                            "type": "null"
                          },
                          "montant_net": {
                            "type": "null"
                          },
                          "expire_le": {
                            "type": "null"
                          },
                          "adresse_paiement": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "declare_par_utilisateur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "valide_par_utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "client_id",
                          "commande_id",
                          "facture_id",
                          "echeance_id",
                          "montant",
                          "canal",
                          "moyen",
                          "statut",
                          "reference_paystack",
                          "reference_externe",
                          "date_paiement",
                          "justificatif_fichier_id",
                          "declare_par",
                          "valide_par",
                          "valide_le",
                          "motif_rejet",
                          "cle_idempotence",
                          "cree_le",
                          "modifie_le",
                          "frais_prestataire",
                          "montant_net",
                          "expire_le",
                          "adresse_paiement",
                          "declare_par_utilisateur",
                          "valide_par_utilisateur"
                        ]
                      }
                    },
                    "pdf": {
                      "type": "null"
                    },
                    "pdf_fichier": {
                      "type": "null"
                    },
                    "en_retard": {
                      "type": "boolean"
                    },
                    "jours_retard": {
                      "type": "integer"
                    },
                    "montant_avoirs": {
                      "type": "integer"
                    },
                    "nb_relances": {
                      "type": "integer"
                    },
                    "derniere_relance_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "contrat": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "client_id",
                    "commande_id",
                    "contrat_id",
                    "echeance_id",
                    "date_emission",
                    "date_echeance",
                    "montant_ht",
                    "montant_tva",
                    "montant_ttc",
                    "montant_paye",
                    "statut",
                    "reference_fne",
                    "pdf_fichier_id",
                    "cree_le",
                    "modifie_le",
                    "relances",
                    "avoirs",
                    "echeances",
                    "reste_a_payer",
                    "trop_percu",
                    "partiellement_reglee",
                    "paiements_en_attente",
                    "montant_en_attente",
                    "reste_a_declarer",
                    "client",
                    "partenaire",
                    "paiements",
                    "pdf",
                    "pdf_fichier",
                    "en_retard",
                    "jours_retard",
                    "montant_avoirs",
                    "nb_relances",
                    "derniere_relance_le",
                    "commande",
                    "contrat"
                  ]
                },
                "example": {
                  "id": "a4c1adae-118b-4c59-997c-ce7898f76a76",
                  "numero": "FAC-2026-000020",
                  "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                  "commande_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                  "contrat_id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                  "echeance_id": null,
                  "date_emission": "2026-10-19",
                  "date_echeance": "2026-10-12",
                  "montant_ht": 20000,
                  "montant_tva": 3600,
                  "montant_ttc": 23600,
                  "montant_paye": 11800,
                  "statut": "partiellement_payee",
                  "reference_fne": null,
                  "pdf_fichier_id": null,
                  "cree_le": "2026-10-19T10:44:34.232Z",
                  "modifie_le": "2026-10-19T10:44:34.881Z",
                  "relances": [
                    {
                      "id": "c9991a0b-95f9-4328-9c37-8656b8000679",
                      "facture_id": "a4c1adae-118b-4c59-997c-ce7898f76a76",
                      "canal": "email",
                      "destinataire": "recouvrement@exemple.ci",
                      "envoyee_le": "2026-10-19T10:44:34.619Z"
                    }
                  ],
                  "avoirs": [
                    {
                      "id": "5c75930f-30f5-451e-bc25-f7f176039d0c",
                      "numero": "AVO-2026-000013",
                      "facture_id": "a4c1adae-118b-4c59-997c-ce7898f76a76",
                      "montant_ttc": 5900,
                      "motif": "Recette WNCYUQRHJW : geste commercial.",
                      "rembourse": true,
                      "moyen_remboursement": "virement",
                      "rembourse_le": "2026-10-19T10:44:35.411Z",
                      "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "cree_le": "2026-10-19T10:44:34.882Z"
                    }
                  ],
                  "echeances": [],
                  "reste_a_payer": 11800,
                  "trop_percu": 0,
                  "partiellement_reglee": true,
                  "paiements_en_attente": 0,
                  "montant_en_attente": 0,
                  "reste_a_declarer": 11800,
                  "client": {
                    "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                    "raison_sociale": "ZZ Recette WNCYUQRHJW",
                    "statut": "reserve"
                  },
                  "partenaire": {
                    "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                    "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                    "ville": "Abidjan",
                    "code_confidentiel": "C-0071"
                  },
                  "paiements": [
                    {
                      "id": "3d4044fe-1433-47a5-92c4-1fd4368046b3",
                      "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                      "commande_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                      "facture_id": null,
                      "echeance_id": null,
                      "montant": 11800,
                      "canal": "virement",
                      "moyen": null,
                      "statut": "valide",
                      "reference_paystack": null,
                      "reference_externe": "VIR-WNCYUQRHJW",
                      "date_paiement": "2026-10-19T10:44:33.459Z",
                      "justificatif_fichier_id": "be3ed415-f6d4-463b-981a-8c1e18fbbbc6",
                      "declare_par": "d60b33fd-8d32-4475-a107-5d4bd82d6f3f",
                      "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "valide_le": "2026-10-19T10:44:33.459Z",
                      "motif_rejet": null,
                      "cle_idempotence": "recette-WNCYUQRHJW",
                      "cree_le": "2026-10-19T10:44:32.940Z",
                      "modifie_le": "2026-10-19T10:44:33.459Z",
                      "frais_prestataire": null,
                      "montant_net": null,
                      "expire_le": null,
                      "adresse_paiement": null,
                      "declare_par_utilisateur": {
                        "id": "d60b33fd-8d32-4475-a107-5d4bd82d6f3f",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A DFA45D10",
                        "email": "zz.recette.dfa45d10@exemple.invalide"
                      },
                      "valide_par_utilisateur": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction",
                        "email": "admin.cybastion@preprod.satelica.test"
                      }
                    }
                  ],
                  "pdf": null,
                  "pdf_fichier": null,
                  "en_retard": true,
                  "jours_retard": 7,
                  "montant_avoirs": 5900,
                  "nb_relances": 1,
                  "derniere_relance_le": "2026-10-19T10:44:34.619Z",
                  "commande": {
                    "id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                    "numero": "CMD-2026-000029",
                    "statut": "attente_paiement"
                  },
                  "contrat": {
                    "id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                    "numero": "CTR-2026-000029",
                    "statut": "projet"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "factures.emettre",
          "paiements.payer_en_ligne",
          "espace_partenaire.acceder"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/echeances": {
      "get": {
        "operationId": "getEcheances",
        "tags": [
          "Commandes et contrats"
        ],
        "summary": "Lister les échéances de règlement",
        "description": "Échéances des commandes, par date puis par rang, filtrables par statut (plusieurs valeurs), commande ou contrat. Chaque ligne porte sa commande et son contrat.\n\n**Permission requise** : L'une de : `factures.emettre`, `paiements.payer_en_ligne`, `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "commande_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "contrat_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 6 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "commande_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "contrat_id": {
                            "type": "null"
                          },
                          "type": {
                            "type": "string"
                          },
                          "rang": {
                            "type": "integer"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "date_echeance": {
                            "type": "string",
                            "format": "date"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "commande": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          },
                          "contrat": {
                            "type": "null"
                          }
                        },
                        "required": [
                          "id",
                          "commande_id",
                          "contrat_id",
                          "type",
                          "rang",
                          "montant_ttc",
                          "date_echeance",
                          "statut",
                          "cree_le",
                          "modifie_le",
                          "commande",
                          "contrat"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "72ba0d18-f887-4bbd-bef4-95697cdff413",
                      "commande_id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                      "contrat_id": null,
                      "type": "forfait",
                      "rang": 3,
                      "montant_ttc": 23600,
                      "date_echeance": "2026-10-19",
                      "statut": "due",
                      "cree_le": "2026-10-19T10:45:45.745Z",
                      "modifie_le": "2026-10-19T10:45:45.745Z",
                      "commande": {
                        "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                        "numero": "CMD-2026-000032",
                        "statut": "attente_paiement"
                      },
                      "contrat": null
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 20,
                    "total": 1,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "factures.emettre",
          "paiements.payer_en_ligne",
          "espace_partenaire.acceder"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/factures/{id}/avoirs": {
      "post": {
        "operationId": "postFacturesParIdAvoirs",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Émettre un avoir sur une facture",
        "description": "La Finance crédite une facture d’un montant TTC motivé, sans dépasser ce qui reste créditable (montant de la facture moins les avoirs déjà émis). L’avoir (numéro `AVO-…`) naît non remboursé ; dans la même transaction, la facture est recalculée, la commande payée passe à « annulee » (remboursée en totalité) ou à « attente_paiement », et la commission acquise sur la part remboursée est reprise (`commissions_reprises`). Le client est notifié.\n\n**Permission requise** : `remboursements.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "montant_ttc": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 1000000000
                  },
                  "motif": {
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "montant_ttc",
                  "motif"
                ]
              },
              "example": {
                "montant_ttc": 5900,
                "motif": "Recette WNCYUQRHJW : geste commercial."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "montant_ttc": {
                      "type": "integer"
                    },
                    "motif": {
                      "type": "string"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "facture": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "commissions_reprises": {
                      "type": "integer"
                    },
                    "lignes_reprises": {
                      "type": "integer"
                    },
                    "rembourse_total": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "montant_ttc",
                    "motif",
                    "cree_le",
                    "facture",
                    "commissions_reprises",
                    "lignes_reprises",
                    "rembourse_total"
                  ]
                },
                "example": {
                  "id": "5c75930f-30f5-451e-bc25-f7f176039d0c",
                  "numero": "AVO-2026-000013",
                  "montant_ttc": 5900,
                  "motif": "Recette WNCYUQRHJW : geste commercial.",
                  "cree_le": "2026-10-19T10:44:34.882Z",
                  "facture": {
                    "id": "a4c1adae-118b-4c59-997c-ce7898f76a76",
                    "numero": "FAC-2026-000020",
                    "statut": "partiellement_payee"
                  },
                  "commissions_reprises": 1000,
                  "lignes_reprises": 1,
                  "rembourse_total": 5900
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "remboursements.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/avoirs/{id}/remboursement": {
      "post": {
        "operationId": "postAvoirsParIdRemboursement",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Constater le remboursement d'un avoir",
        "description": "Marque l’avoir comme remboursé, avec le moyen employé et la date du remboursement (aujourd’hui par défaut). Un avoir déjà remboursé est refusé. Le client est notifié.\n\n**Permission requise** : `remboursements.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "moyen": {
                    "type": "string",
                    "enum": [
                      "orange_money",
                      "mtn_momo",
                      "wave",
                      "carte",
                      "especes",
                      "cheque",
                      "virement"
                    ]
                  },
                  "rembourse_le": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  }
                },
                "required": [
                  "moyen"
                ]
              },
              "example": {
                "moyen": "virement"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "montant_ttc": {
                      "type": "integer"
                    },
                    "rembourse": {
                      "type": "boolean"
                    },
                    "moyen_remboursement": {
                      "type": "string"
                    },
                    "rembourse_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "montant_ttc",
                    "rembourse",
                    "moyen_remboursement",
                    "rembourse_le"
                  ]
                },
                "example": {
                  "id": "5c75930f-30f5-451e-bc25-f7f176039d0c",
                  "numero": "AVO-2026-000013",
                  "montant_ttc": 5900,
                  "rembourse": true,
                  "moyen_remboursement": "virement",
                  "rembourse_le": "2026-10-19T10:44:35.411Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "remboursements.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/avoirs": {
      "get": {
        "operationId": "getAvoirs",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Lister les avoirs",
        "description": "Avoirs, du plus récent au plus ancien, filtrables par facture et par état de remboursement, avec leur facture et le client de celle-ci.\n\n**Permission requise** : L'une de : `remboursements.gerer`, `factures.emettre`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "facture_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "rembourse",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "motif": {
                            "type": "string"
                          },
                          "rembourse": {
                            "type": "boolean"
                          },
                          "moyen_remboursement": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "rembourse_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "facture": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "montant_ttc": {
                                "type": "integer"
                              },
                              "clients": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "raison_sociale": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "raison_sociale"
                                ]
                              },
                              "client": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "raison_sociale": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "raison_sociale"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut",
                              "montant_ttc",
                              "clients",
                              "client"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "montant_ttc",
                          "motif",
                          "rembourse",
                          "moyen_remboursement",
                          "rembourse_le",
                          "cree_le",
                          "facture"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "f33dd138-3b55-42fe-bee9-b2ab7b2db511",
                      "numero": "AVO-2026-000014",
                      "montant_ttc": 1000,
                      "motif": "Épreuve des sections : geste commercial.",
                      "rembourse": false,
                      "moyen_remboursement": null,
                      "rembourse_le": null,
                      "cree_le": "2026-10-19T10:45:56.699Z",
                      "facture": {
                        "id": "3f63aa9c-25f8-4cdc-8f2d-13790034a6d9",
                        "numero": "FAC-2026-000022",
                        "statut": "payee",
                        "montant_ttc": 23600,
                        "clients": {
                          "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                          "raison_sociale": "ZZ Recette Client 4D20EED1"
                        },
                        "client": {
                          "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                          "raison_sociale": "ZZ Recette Client 4D20EED1"
                        }
                      }
                    },
                    {
                      "id": "5c75930f-30f5-451e-bc25-f7f176039d0c",
                      "numero": "AVO-2026-000013",
                      "montant_ttc": 5900,
                      "motif": "Recette WNCYUQRHJW : geste commercial.",
                      "rembourse": true,
                      "moyen_remboursement": "virement",
                      "rembourse_le": "2026-10-19T10:44:35.411Z",
                      "cree_le": "2026-10-19T10:44:34.882Z",
                      "facture": {
                        "id": "a4c1adae-118b-4c59-997c-ce7898f76a76",
                        "numero": "FAC-2026-000020",
                        "statut": "payee",
                        "montant_ttc": 23600,
                        "clients": {
                          "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                          "raison_sociale": "ZZ Recette WNCYUQRHJW"
                        },
                        "client": {
                          "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                          "raison_sociale": "ZZ Recette WNCYUQRHJW"
                        }
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 4,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "remboursements.gerer",
          "factures.emettre"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/commandes/{id}/factures": {
      "post": {
        "operationId": "postCommandesParIdFactures",
        "tags": [
          "Commandes et contrats"
        ],
        "summary": "Émettre une facture sur une commande",
        "description": "Émet la facture (numéro `FAC-…`) de la commande entière, ou d’une de ses échéances (`echeance_id`) : les montants viennent de la commande ou de l’échéance, rien ne se saisit, et le corps est facultatif. Sans `date_echeance`, l’échéance de règlement est la date d’émission, ou celle-ci plus `paiement.postpaye_delai_echeance_jours` en postpayé ; le statut se déduit des règlements déjà validés, si bien qu’une facture émise après paiement naît « payee ». Une commande ou une échéance ne se facture qu’une fois ; le client est notifié, sauf si la facture naît payée.\n\n**Permission requise** : `factures.emettre`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "echeance_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "date_emission": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  },
                  "date_echeance": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  },
                  "reference_fne": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                }
              },
              "example": {
                "date_echeance": "2026-10-12"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "date_emission": {
                      "type": "string",
                      "format": "date"
                    },
                    "date_echeance": {
                      "type": "string",
                      "format": "date"
                    },
                    "montant_ht": {
                      "type": "integer"
                    },
                    "montant_tva": {
                      "type": "integer"
                    },
                    "montant_ttc": {
                      "type": "integer"
                    },
                    "montant_paye": {
                      "type": "integer"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "reference_fne": {
                      "type": "null"
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero"
                      ]
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "date_emission",
                    "date_echeance",
                    "montant_ht",
                    "montant_tva",
                    "montant_ttc",
                    "montant_paye",
                    "statut",
                    "reference_fne",
                    "commande",
                    "client"
                  ]
                },
                "example": {
                  "id": "a4c1adae-118b-4c59-997c-ce7898f76a76",
                  "numero": "FAC-2026-000020",
                  "date_emission": "2026-10-19",
                  "date_echeance": "2026-10-12",
                  "montant_ht": 20000,
                  "montant_tva": 3600,
                  "montant_ttc": 23600,
                  "montant_paye": 11800,
                  "statut": "en_retard",
                  "reference_fne": null,
                  "commande": {
                    "id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                    "numero": "CMD-2026-000029"
                  },
                  "client": {
                    "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                    "raison_sociale": "ZZ Recette WNCYUQRHJW",
                    "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "factures.emettre",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/factures/{id}/reference-fne": {
      "patch": {
        "operationId": "patchFacturesParIdReferenceFne",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Inscrire la référence de la facture normalisée",
        "description": "Pose la référence FNE revenue du portail fiscal après l’émission. Elle ne s’inscrit qu’une fois : une facture qui en porte déjà une est refusée. L’inscription est journalisée.\n\n**Permission requise** : `factures.emettre`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reference_fne": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                },
                "required": [
                  "reference_fne"
                ]
              },
              "example": {
                "reference_fne": "FNE-ZZR-20AFF6A8"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "reference_fne": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "reference_fne"
                  ]
                },
                "example": {
                  "id": "44049e5a-f8d7-4f9a-9180-1bdaa92c38c1",
                  "numero": "FAC-2026-000021",
                  "reference_fne": "FNE-ZZR-20AFF6A8"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "factures.emettre",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/demandes-credit": {
      "get": {
        "operationId": "getDemandesCredit",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Lister les demandes de crédit",
        "description": "La file de la Finance : les clients qui ont souhaité le postpayé à leur enregistrement, qu’une vente postpayée attend, ou qui détiennent un accord, par raison sociale. Une ligne par client (`id` est celui du client), avec le statut et l’origine de la demande, le montant en jeu, l’encours recalculé depuis les factures non soldées, le plafond, le disponible, les devis et commandes postpayés et l’historique de paiement.\n\n**Permission requise** : `clients.credit_approuver`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "rccm": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "statut_kyc": {
                                "type": "string"
                              },
                              "secteur": {
                                "type": "null"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "ville",
                              "rccm",
                              "statut",
                              "statut_kyc",
                              "secteur"
                            ]
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "ville",
                              "code_confidentiel"
                            ]
                          },
                          "statut": {
                            "type": "string"
                          },
                          "origine": {
                            "type": "string"
                          },
                          "montant_en_jeu": {
                            "type": "integer"
                          },
                          "encours": {
                            "type": "integer"
                          },
                          "plafond_encours": {
                            "type": "null"
                          },
                          "disponible": {
                            "type": "null"
                          },
                          "demandee_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "decision_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "motif_refus": {
                            "type": "string"
                          },
                          "approuve_par_utilisateur": {
                            "type": "null"
                          },
                          "devis_postpayes": {
                            "type": "array",
                            "items": {}
                          },
                          "commandes_postpayees": {
                            "type": "array",
                            "items": {}
                          },
                          "historique_paiements": {
                            "type": "object",
                            "properties": {
                              "nb_valides": {
                                "type": "integer"
                              },
                              "nb_rejetes": {
                                "type": "integer"
                              },
                              "montant_encaisse": {
                                "type": "integer"
                              },
                              "factures_en_retard": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "nb_valides",
                              "nb_rejetes",
                              "montant_encaisse",
                              "factures_en_retard"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "client",
                          "partenaire",
                          "statut",
                          "origine",
                          "montant_en_jeu",
                          "encours",
                          "plafond_encours",
                          "disponible",
                          "demandee_le",
                          "decision_le",
                          "motif_refus",
                          "approuve_par_utilisateur",
                          "devis_postpayes",
                          "commandes_postpayees",
                          "historique_paiements"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "a266cebb-fa52-4868-b5f6-27914d75fedd",
                      "client": {
                        "id": "a266cebb-fa52-4868-b5f6-27914d75fedd",
                        "raison_sociale": "ZZ Recette Client 14A4B9D7",
                        "ville": "Bouaké",
                        "rccm": "CI-ZZC-14A4B9D7",
                        "statut": "reserve",
                        "statut_kyc": "en_verification",
                        "secteur": null
                      },
                      "partenaire": {
                        "id": "bfb40438-1e20-4540-a7d8-1aad3766f64c",
                        "raison_sociale": "ZZ Recette Partenaire A F49DF3AA",
                        "ville": "Yamoussoukro",
                        "code_confidentiel": "C-0067"
                      },
                      "statut": "refuse",
                      "origine": "souhait_creation",
                      "montant_en_jeu": 0,
                      "encours": 0,
                      "plafond_encours": null,
                      "disponible": null,
                      "demandee_le": "2026-10-19T10:42:30.185Z",
                      "decision_le": "2026-10-19T10:42:44.276Z",
                      "motif_refus": "Dossier KYC incomplet : bilan du dernier exercice manquant.",
                      "approuve_par_utilisateur": null,
                      "devis_postpayes": [],
                      "commandes_postpayees": [],
                      "historique_paiements": {
                        "nb_valides": 1,
                        "nb_rejetes": 1,
                        "montant_encaisse": 23600,
                        "factures_en_retard": 0
                      }
                    },
                    {
                      "id": "41568bd5-57d9-4de6-9d9a-5d27eaf3868a",
                      "client": {
                        "id": "41568bd5-57d9-4de6-9d9a-5d27eaf3868a",
                        "raison_sociale": "ZZ Recette Client 2EEAF409",
                        "ville": "Bouaké",
                        "rccm": "CI-ZZC-2EEAF409",
                        "statut": "reserve",
                        "statut_kyc": "en_verification",
                        "secteur": null
                      },
                      "partenaire": {
                        "id": "6641d761-f1d3-4421-9391-7d5553244058",
                        "raison_sociale": "ZZ Recette Partenaire A A7B8701D",
                        "ville": "Yamoussoukro",
                        "code_confidentiel": "C-0061"
                      },
                      "statut": "refuse",
                      "origine": "souhait_creation",
                      "montant_en_jeu": 0,
                      "encours": 0,
                      "plafond_encours": null,
                      "disponible": null,
                      "demandee_le": "2026-10-19T10:41:08.945Z",
                      "decision_le": "2026-10-19T10:41:22.383Z",
                      "motif_refus": "Dossier KYC incomplet : bilan du dernier exercice manquant.",
                      "approuve_par_utilisateur": null,
                      "devis_postpayes": [],
                      "commandes_postpayees": [],
                      "historique_paiements": {
                        "nb_valides": 1,
                        "nb_rejetes": 1,
                        "montant_encaisse": 23600,
                        "factures_en_retard": 0
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 5,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.credit_approuver",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/clients/{id}/credit": {
      "patch": {
        "operationId": "patchClientsParIdCredit",
        "tags": [
          "Clients"
        ],
        "summary": "Accorder ou refuser le crédit à un client",
        "description": "La Finance accorde le postpayé avec un plafond d’encours, obligatoire, ou le refuse avec un motif, obligatoire. L’accord exige un dossier KYC « conforme » ; le refus remet le client au comptant sans effacer le plafond antérieur. La décision est journalisée et notifiée au client.\n\n**Permission requise** : `clients.credit_approuver`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "approuve",
                      "refuse"
                    ]
                  },
                  "plafond_encours": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 1000000000
                  },
                  "motif": {
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "refuse",
                "motif": "Dossier KYC incomplet : bilan du dernier exercice manquant."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "raison_sociale": {
                      "type": "string"
                    },
                    "credit_approuve": {
                      "type": "boolean"
                    },
                    "plafond_encours": {
                      "type": "null"
                    },
                    "credit_approuve_par": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "id",
                    "raison_sociale",
                    "credit_approuve",
                    "plafond_encours",
                    "credit_approuve_par"
                  ]
                },
                "example": {
                  "id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                  "raison_sociale": "ZZ Recette Client 62AAEFDF",
                  "credit_approuve": false,
                  "plafond_encours": null,
                  "credit_approuve_par": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "clients.credit_approuver",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/paiements/en-ligne": {
      "post": {
        "operationId": "postPaiementsEnLigne",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Ouvrir un règlement en ligne",
        "description": "Le client, ou CYBASTION pour lui, désigne une commande « attente_paiement » ou une facture ; aucun montant n’est transmis : la plateforme demande le reste dû, recalculé. Crée un règlement « initie » (référence `PAY-…`) et rend l’adresse de paiement Paystack à ouvrir et l’adresse de retour ; rien n’est encaissé avant la notification signée ou la vérification. `moyen` restreint les canaux présentés s’il est ouvert ; rejouer une `cle_idempotence` dont la tentative est encore « initie » rend cette tentative (`deja_ouverte: true`) sans en ouvrir une autre.\n\n**Permission requise** : L'une de : `paiements.payer_en_ligne`, `paiements.valider`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "commande_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "facture_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "email": {
                    "type": "string",
                    "maxLength": 200,
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "moyen": {
                    "type": "string",
                    "enum": [
                      "orange_money",
                      "mtn_momo",
                      "wave",
                      "carte"
                    ]
                  },
                  "cle_idempotence": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 120
                  }
                }
              },
              "example": {
                "commande_id": "183c1dab-cc43-488d-bac5-1df62198157d",
                "email": "client.essai@example.com",
                "cle_idempotence": "83891bf4-abfc-40db-af7a-4b6c5d038d08"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "paiement_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "reference": {
                      "type": "string"
                    },
                    "montant": {
                      "type": "integer"
                    },
                    "adresse_paiement": {
                      "type": "string"
                    },
                    "code_acces": {
                      "type": "string"
                    },
                    "moyen": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "facture_id": {
                      "type": "null"
                    },
                    "facture_numero": {
                      "type": "null"
                    },
                    "commande_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "commande_numero": {
                      "type": "string"
                    },
                    "deja_ouverte": {
                      "type": "boolean"
                    },
                    "adresse_retour": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "paiement_id",
                    "reference",
                    "montant",
                    "adresse_paiement",
                    "code_acces",
                    "moyen",
                    "statut",
                    "facture_id",
                    "facture_numero",
                    "commande_id",
                    "commande_numero",
                    "deja_ouverte",
                    "adresse_retour"
                  ]
                },
                "example": {
                  "paiement_id": "aca97346-ccff-41e9-ba68-31530db3bd13",
                  "reference": "PPAY-2026-000014",
                  "montant": 23600,
                  "adresse_paiement": "https://checkout.paystack.com/lkef54feqrxzdg5",
                  "code_acces": "lkef54feqrxzdg5",
                  "moyen": null,
                  "statut": "initie",
                  "facture_id": null,
                  "facture_numero": null,
                  "commande_id": "183c1dab-cc43-488d-bac5-1df62198157d",
                  "commande_numero": "CMD-2026-000031",
                  "deja_ouverte": false,
                  "adresse_retour": "https://preprod-admin.satelica.com/paiement/retour"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "paiements.payer_en_ligne",
          "paiements.valider"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/paiements/paystack/notification": {
      "post": {
        "operationId": "postPaiementsPaystackNotification",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Recevoir une notification de Paystack",
        "description": "Appelée par Paystack, sans jeton. La signature `x-paystack-signature` (HMAC SHA-512 du corps brut avec la clé secrète) et l’adresse d’expédition sont vérifiées : un refus est inscrit au journal d’audit, sans que la notification soit enregistrée ni traitée. Authentique, l’événement est enregistré une seule fois par identifiant (une relance ne crée rien de plus), `{ recu: true }` part aussitôt, puis seul `charge.success` est traité : le règlement de même référence est validé avec le montant et les frais constatés, et les effets de l’encaissement s’appliquent à sa commande. Le corps décrit ne retient que les champs lus ; le contenu complet est conservé.\n\n**Permission requise** : Aucune : route ouverte, sans jeton.\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "event": {
                    "type": "string"
                  },
                  "id": {
                    "type": [
                      "string",
                      "number"
                    ]
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "reference": {
                        "type": "string"
                      },
                      "id": {
                        "type": [
                          "string",
                          "number"
                        ]
                      },
                      "amount": {
                        "type": "number"
                      },
                      "fees": {
                        "type": "number"
                      },
                      "channel": {
                        "type": "string"
                      },
                      "paid_at": {
                        "type": "string"
                      }
                    },
                    "additionalProperties": {}
                  }
                },
                "additionalProperties": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "Signature invalide ou adresse d'expédition inconnue (`{ code: 'signature_invalide' }`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        },
        "security": [],
        "x-satelica-permission": null,
        "x-satelica-cloisonnement": "sans_objet"
      }
    },
    "/api/v1/evenements-paiement": {
      "get": {
        "operationId": "getEvenementsPaiement",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Lister les notifications de paiement reçues",
        "description": "Les notifications Paystack authentiques enregistrées, de la plus récente à la plus ancienne, filtrables par état de traitement et par référence de transaction, avec l’erreur de traitement éventuelle.\n\n**Permission requise** : `audit.consulter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "traite",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "reference",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 120
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {}
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [],
                  "pagination": {
                    "page": 1,
                    "taille": 20,
                    "total": 0,
                    "pages": 0
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "audit.consulter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/evenements-paiement/{id}/rejeu": {
      "post": {
        "operationId": "postEvenementsPaiementParIdRejeu",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Rejouer une notification de paiement",
        "description": "Remet à « non traité » puis retraite une notification enregistrée, désignée par l’identifiant d’événement du prestataire. Une notification sans signature valide est refusée. Le traitement est idempotent : un règlement déjà validé n’est pas modifié. Le rejeu est journalisé, et la réponse donne l’état de traitement qui en résulte.\n\n**Permission requise** : `paiements.valider`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "paiements.valider",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/paiements/{id}/verification": {
      "post": {
        "operationId": "postPaiementsParIdVerification",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Vérifier un règlement en ligne auprès de Paystack",
        "description": "Interroge Paystack sur un règlement ouvert en ligne et applique l’état constaté sans jamais le faire régresser : validé (montant et frais constatés, effets de l’encaissement sur la commande), échoué, remboursé ou toujours initié. Un règlement déjà validé est rendu tel quel (`deja_valide: true`) ; un règlement qui n’a pas été ouvert en ligne est refusé. La vérification est journalisée. Sans corps.\n\n**Permission requise** : L'une de : `paiements.payer_en_ligne`, `paiements.valider`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "montant": {
                      "type": "integer"
                    },
                    "frais": {
                      "type": "null"
                    },
                    "net": {
                      "type": "null"
                    },
                    "source": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "statut",
                    "montant",
                    "frais",
                    "net",
                    "source"
                  ]
                },
                "example": {
                  "id": "aca97346-ccff-41e9-ba68-31530db3bd13",
                  "statut": "echoue",
                  "montant": 23600,
                  "frais": null,
                  "net": null,
                  "source": "verification_active"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "paiements.payer_en_ligne",
          "paiements.valider"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/paiements/expiration": {
      "post": {
        "operationId": "postPaiementsExpiration",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Expirer les tentatives de paiement en ligne non confirmées",
        "description": "Passe à « expire » les règlements « initie » plus anciens que `paiement.expiration_minutes` (60 minutes par défaut), 500 au plus examinés par appel, et prévient chaque client que sa tentative n’a pas abouti. Idempotente : un second appel n’expire rien de plus. Paystack n’est pas interrogé, et une notification de succès reçue ensuite reste prise en compte. Sans corps.\n\n**Permission requise** : `paiements.valider`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "expirees": {
                      "type": "integer"
                    },
                    "delai_minutes": {
                      "type": "integer"
                    },
                    "examinees": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "expirees",
                    "delai_minutes",
                    "examinees"
                  ]
                },
                "example": {
                  "expirees": 0,
                  "delai_minutes": 60,
                  "examinees": 0
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "paiements.valider",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/paiements/rapprochement": {
      "get": {
        "operationId": "getPaiementsRapprochement",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Rapprocher les paiements en ligne d'une journée",
        "description": "Compare, pour un jour (aujourd’hui par défaut), les notifications Paystack authentiques reçues aux règlements Paystack en base, et nomme chaque écart sans rien corriger (`concordant`, `ecarts`). Donne aussi les encaissements du jour : brut, frais retenus, net attendu, nombre de lignes sans frais connus et, pour celles-ci, une estimation par canal.\n\n**Permission requise** : `paiements.valider`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "jour",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jour": {
                      "type": "string",
                      "format": "date"
                    },
                    "evenements_recus": {
                      "type": "integer"
                    },
                    "evenements_non_traites": {
                      "type": "integer"
                    },
                    "paiements_en_base": {
                      "type": "integer"
                    },
                    "encaissements": {
                      "type": "object",
                      "properties": {
                        "nombre": {
                          "type": "integer"
                        },
                        "brut": {
                          "type": "integer"
                        },
                        "frais_retenus": {
                          "type": "integer"
                        },
                        "net_attendu": {
                          "type": "integer"
                        },
                        "sans_frais_connus": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "nombre",
                        "brut",
                        "frais_retenus",
                        "net_attendu",
                        "sans_frais_connus"
                      ]
                    },
                    "concordant": {
                      "type": "boolean"
                    },
                    "ecarts": {
                      "type": "array",
                      "items": {}
                    }
                  },
                  "required": [
                    "jour",
                    "evenements_recus",
                    "evenements_non_traites",
                    "paiements_en_base",
                    "encaissements",
                    "concordant",
                    "ecarts"
                  ]
                },
                "example": {
                  "jour": "2026-10-19",
                  "evenements_recus": 0,
                  "evenements_non_traites": 0,
                  "paiements_en_base": 4,
                  "encaissements": {
                    "nombre": 0,
                    "brut": 0,
                    "frais_retenus": 0,
                    "net_attendu": 0,
                    "sans_frais_connus": 0
                  },
                  "concordant": true,
                  "ecarts": []
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "paiements.valider",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/ordres-installation": {
      "post": {
        "operationId": "postOrdresInstallation",
        "tags": [
          "Opérations"
        ],
        "summary": "Émettre un ordre d'installation",
        "description": "CYBASTION émet à la main l'ordre d'installation d'une commande. Il naît « a_envoyer », numéroté INS, avec une date cible et une date limite tirées des délais paramétrés, et la commande payée (ou en attente de paiement) passe « en_installation ». Refusé si l'installation n'est pas débloquée (commande non payée, ou crédit postpayé non approuvé), si un ordre est déjà ouvert sur la commande, ou si le technicien choisi n'est pas au registre ou n'est plus actif.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "commande_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "creneaux": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "date_cible": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  },
                  "commentaire": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "technicien_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "commande_id"
                ]
              },
              "example": {
                "commande_id": "9baafcab-4a8c-42b2-ba6c-3a5916d308cb",
                "creneaux": "Lundi après-midi",
                "commentaire": "Prévoir une nacelle."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "date_cible": {
                      "type": "string",
                      "format": "date"
                    },
                    "date_limite": {
                      "type": "string",
                      "format": "date"
                    },
                    "delai_jours_ouvres": {
                      "type": "object",
                      "properties": {
                        "minimum": {
                          "type": "integer"
                        },
                        "maximum": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "minimum",
                        "maximum"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "statut",
                    "date_cible",
                    "date_limite",
                    "delai_jours_ouvres"
                  ]
                },
                "example": {
                  "id": "1b544e00-a594-4334-9e31-a5a2abd124c1",
                  "numero": "INS-2026-000035",
                  "statut": "a_envoyer",
                  "date_cible": "2026-10-22",
                  "date_limite": "2026-10-26",
                  "delai_jours_ouvres": {
                    "minimum": 3,
                    "maximum": 5
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Installation non débloquée, ordre déjà ouvert, ou technicien retiré des actifs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "get": {
        "operationId": "getOrdresInstallation",
        "tags": [
          "Opérations"
        ],
        "summary": "Lister les ordres d'installation",
        "description": "Les ordres d'installation, par date limite croissante, avec leur commande, client, partenaire, site (avec sa `latitude` et sa `longitude`, en degrés décimaux, ou `null` si le site n'a pas été positionné), procès-verbaux et technicien (nom seulement). Sert aussi au client, qui y suit l'installation de son site. Filtres : `statut` (a_envoyer, envoye, planifie, realise, echoue, annule ; une ou plusieurs valeurs séparées par des virgules), `commande_id`, `en_retard` (ordres ouverts dont la date limite est passée) ; chaque ligne porte `en_retard`.\n\n**Permission requise** : L'une de : `installations.gerer`, `pv.valider`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "commande_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "en_retard",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 8 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "commande_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "site_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "destinataire_email": {
                            "type": "null"
                          },
                          "envoye_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "creneaux": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "date_cible": {
                            "type": "string",
                            "format": "date"
                          },
                          "date_limite": {
                            "type": "string",
                            "format": "date"
                          },
                          "technicien": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "reference_vipnet": {
                            "type": "null"
                          },
                          "commentaire": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "cree_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "technicien_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "canal_contact": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "technicien_contacte_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "proces_verbaux": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "statut": {
                                  "type": "string"
                                },
                                "type": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id",
                                "statut",
                                "type"
                              ]
                            }
                          },
                          "commande": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "clients": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "raison_sociale": {
                                    "type": "string"
                                  },
                                  "ville": {
                                    "type": "string"
                                  },
                                  "telephone": {
                                    "type": "null"
                                  }
                                },
                                "required": [
                                  "id",
                                  "raison_sociale",
                                  "ville",
                                  "telephone"
                                ]
                              },
                              "partenaires": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "raison_sociale": {
                                    "type": "string"
                                  },
                                  "telephone": {
                                    "type": "null"
                                  },
                                  "code_confidentiel": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "raison_sociale",
                                  "telephone",
                                  "code_confidentiel"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut",
                              "clients",
                              "partenaires"
                            ]
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "telephone": {
                                "type": "null"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "ville",
                              "telephone"
                            ]
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "telephone": {
                                "type": "null"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "telephone",
                              "code_confidentiel"
                            ]
                          },
                          "site": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "adresse": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "latitude": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "longitude": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "libelle",
                              "ville",
                              "adresse",
                              "latitude",
                              "longitude"
                            ]
                          },
                          "cree_par_utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "technicien_fiche": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom"
                            ]
                          },
                          "en_retard": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "commande_id",
                          "site_id",
                          "statut",
                          "destinataire_email",
                          "envoye_le",
                          "creneaux",
                          "date_cible",
                          "date_limite",
                          "technicien",
                          "reference_vipnet",
                          "commentaire",
                          "cree_par",
                          "cree_le",
                          "modifie_le",
                          "technicien_id",
                          "canal_contact",
                          "technicien_contacte_le",
                          "proces_verbaux",
                          "commande",
                          "client",
                          "partenaire",
                          "site",
                          "cree_par_utilisateur",
                          "technicien_fiche",
                          "en_retard"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "a331311f-7a98-4159-899c-6bc74808dbe9",
                      "numero": "INS-2026-000033",
                      "commande_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                      "site_id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                      "statut": "a_envoyer",
                      "destinataire_email": null,
                      "envoye_le": null,
                      "creneaux": null,
                      "date_cible": "2026-10-22",
                      "date_limite": "2026-10-26",
                      "technicien": null,
                      "reference_vipnet": null,
                      "commentaire": null,
                      "cree_par": null,
                      "cree_le": "2026-10-19T10:44:36.114Z",
                      "modifie_le": "2026-10-19T10:44:36.114Z",
                      "technicien_id": null,
                      "canal_contact": null,
                      "technicien_contacte_le": null,
                      "proces_verbaux": [],
                      "commande": {
                        "id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                        "numero": "CMD-2026-000029",
                        "statut": "payee",
                        "clients": {
                          "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                          "raison_sociale": "ZZ Recette WNCYUQRHJW",
                          "ville": "Abidjan",
                          "telephone": null
                        },
                        "partenaires": {
                          "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                          "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                          "telephone": null,
                          "code_confidentiel": "C-0071"
                        }
                      },
                      "client": {
                        "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                        "raison_sociale": "ZZ Recette WNCYUQRHJW",
                        "ville": "Abidjan",
                        "telephone": null
                      },
                      "partenaire": {
                        "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                        "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                        "telephone": null,
                        "code_confidentiel": "C-0071"
                      },
                      "site": {
                        "id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                        "libelle": "Siège",
                        "ville": "Abidjan",
                        "adresse": null,
                        "latitude": 5.3364,
                        "longitude": -4.0267
                      },
                      "cree_par_utilisateur": null,
                      "technicien_fiche": null,
                      "en_retard": false
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 20,
                    "total": 1,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "installations.gerer",
          "pv.valider"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/proces-verbaux": {
      "post": {
        "operationId": "postProcesVerbaux",
        "tags": [
          "Opérations"
        ],
        "summary": "Saisir le procès-verbal d'une intervention",
        "description": "CYBASTION saisit le procès-verbal rapporté par le technicien, à partir d'un fichier déposé au préalable par l'appelant et déclaré sain par l'antivirus. Le procès-verbal naît « charge », en attente de décision ; le nom du technicien, s'il est donné, est reporté sur l'ordre, et la réception est consignée dans les échanges VIP Net avec le commentaire. Refusé sur un ordre annulé.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ordre_installation_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "installation",
                      "activation"
                    ]
                  },
                  "fichier_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "date_intervention": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  },
                  "technicien": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "commentaire": {
                    "type": "string",
                    "maxLength": 1000
                  }
                },
                "required": [
                  "ordre_installation_id",
                  "type",
                  "fichier_id",
                  "date_intervention"
                ]
              },
              "example": {
                "ordre_installation_id": "a331311f-7a98-4159-899c-6bc74808dbe9",
                "type": "installation",
                "fichier_id": "0a9a7af9-e0a0-401d-87b0-9a3ebcb23235",
                "date_intervention": "2026-10-19",
                "technicien": "K. Yao"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string"
                    },
                    "date_intervention": {
                      "type": "string",
                      "format": "date"
                    },
                    "ordre": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "commentaire": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "id",
                    "statut",
                    "type",
                    "date_intervention",
                    "ordre",
                    "commentaire"
                  ]
                },
                "example": {
                  "id": "e4502c77-4b37-42c6-9e06-322a04bf96e7",
                  "statut": "charge",
                  "type": "installation",
                  "date_intervention": "2026-10-19",
                  "ordre": {
                    "id": "a331311f-7a98-4159-899c-6bc74808dbe9",
                    "numero": "INS-2026-000033",
                    "statut": "envoye"
                  },
                  "commentaire": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Ordre annulé, ou fichier non déclaré sain par l'antivirus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "get": {
        "operationId": "getProcesVerbaux",
        "tags": [
          "Opérations"
        ],
        "summary": "Lister les procès-verbaux",
        "description": "Les procès-verbaux d'installation et d'activation, du plus récent au plus ancien, avec leur fichier, leur ordre, leur activation, l'utilisateur qui les a saisis et celui qui les a tranchés. Filtres `statut` (charge, valide, conteste) et `type` (installation, activation), une ou plusieurs valeurs séparées par des virgules.\n\n**Permission requise** : L'une de : `installations.gerer`, `pv.valider`, `pv.charger`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "ordre_installation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "activation_id": {
                            "type": "null"
                          },
                          "fichier_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "date_intervention": {
                            "type": "string",
                            "format": "date"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "charge_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "valide_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "valide_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "motif_contestation": {
                            "type": "null"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "fichier": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "bucket": {
                                "type": "string"
                              },
                              "chemin": {
                                "type": "string"
                              },
                              "nom_original": {
                                "type": "string"
                              },
                              "type_mime": {
                                "type": "string"
                              },
                              "taille_octets": {
                                "type": "integer"
                              },
                              "empreinte_sha256": {
                                "type": "string"
                              },
                              "statut_scan": {
                                "type": "string"
                              },
                              "depose_par": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "bucket",
                              "chemin",
                              "nom_original",
                              "type_mime",
                              "taille_octets",
                              "empreinte_sha256",
                              "statut_scan",
                              "depose_par",
                              "cree_le"
                            ]
                          },
                          "ordre_installation": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          },
                          "activation": {
                            "type": "null"
                          },
                          "charge_par_utilisateur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "valide_par_utilisateur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "type",
                          "ordre_installation_id",
                          "activation_id",
                          "fichier_id",
                          "date_intervention",
                          "statut",
                          "charge_par",
                          "valide_par",
                          "valide_le",
                          "motif_contestation",
                          "cree_le",
                          "modifie_le",
                          "fichier",
                          "ordre_installation",
                          "activation",
                          "charge_par_utilisateur",
                          "valide_par_utilisateur"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 0,
                    "pages": 0
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "installations.gerer",
          "pv.valider",
          "pv.charger"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/ordres-installation/{id}/transmission": {
      "post": {
        "operationId": "postOrdresInstallationParIdTransmission",
        "tags": [
          "Opérations"
        ],
        "summary": "Transmettre un ordre d'installation à VIP Net",
        "description": "Compose le message de l'ordre (site, client, contact, créneaux, dates), le rend dans `message` et le consigne dans les échanges VIP Net. En mode manuel, rien ne part : l'appelant confirme l'envoi par `envoye: true`. L'envoi confirmé passe un ordre « a_envoyer » à « envoye » et la commande « en_installation » (si son installation est débloquée), et notifie le client et le partenaire. Destinataire par défaut : le paramètre `vipnet.destinataire_email` ; le corps est facultatif.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "envoye": {
                    "type": "boolean"
                  },
                  "destinataire_email": {
                    "type": "string",
                    "maxLength": 200,
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "commentaire": {
                    "type": "string",
                    "maxLength": 1000
                  }
                }
              },
              "example": {
                "envoye": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ordre": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "envoye_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "destinataire_email": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "envoye_le",
                        "destinataire_email"
                      ]
                    },
                    "mode": {
                      "type": "string"
                    },
                    "transmis": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "destinataire": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "ordre",
                    "mode",
                    "transmis",
                    "message",
                    "destinataire"
                  ]
                },
                "example": {
                  "ordre": {
                    "id": "a331311f-7a98-4159-899c-6bc74808dbe9",
                    "numero": "INS-2026-000033",
                    "statut": "envoye",
                    "envoye_le": "2026-10-19T10:44:37.599Z",
                    "destinataire_email": null
                  },
                  "mode": "manuel",
                  "transmis": true,
                  "message": "Ordre d'installation INS-2026-000033\n\nClient       : ZZ Recette WNCYUQRHJW\nTéléphone    : non renseigné\nContact site : Awa Koné\n\nSite         : Siège\nAdresse      : non renseignée, Abidjan\nPosition     : 5.3167, -4.0333 (https://www.openstreetmap.org/?mlat=5.3167&mlon=-4.0333#map=17/5.3167/-4.0333)\n…",
                  "destinataire": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "L'ordre n'est plus à transmettre (ni « a_envoyer » ni « envoye »).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/ordres-installation/{id}/echanges": {
      "get": {
        "operationId": "getOrdresInstallationParIdEchanges",
        "tags": [
          "Opérations"
        ],
        "summary": "Lister les échanges VIP Net d'un ordre",
        "description": "L'historique des échanges avec l'installateur sur cet ordre (message préparé ou transmis, procès-verbal reçu, validé ou contesté), du plus récent au plus ancien, avec leur contenu et leur auteur. Réponse `{ donnees: [...], total }`, non paginée.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "sens": {
                            "type": "string"
                          },
                          "mode": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          },
                          "reference_vipnet": {
                            "type": "null"
                          },
                          "contenu": {
                            "type": "object",
                            "properties": {
                              "type_pv": {
                                "type": "string"
                              },
                              "technicien": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "commentaire": {
                                "type": "null"
                              },
                              "date_intervention": {
                                "type": "string",
                                "format": "date"
                              },
                              "motif": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "numero_serie": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "numero": {
                                "type": "string"
                              },
                              "message": {
                                "type": "string"
                              },
                              "destinataire": {
                                "type": "null"
                              }
                            }
                          },
                          "survenu_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "utilisateurs": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "sens",
                          "mode",
                          "type",
                          "reference_vipnet",
                          "contenu",
                          "survenu_le",
                          "utilisateurs"
                        ]
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "donnees",
                    "total"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "1cd43177-1fc1-4317-8ebe-62b7299cb25d",
                      "sens": "entrant",
                      "mode": "manuel",
                      "type": "pv_recu",
                      "reference_vipnet": null,
                      "contenu": {
                        "type_pv": "installation",
                        "technicien": "K. Yao",
                        "commentaire": null,
                        "date_intervention": "2026-10-19"
                      },
                      "survenu_le": "2026-10-19T12:00:00.000Z",
                      "utilisateurs": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction"
                      }
                    },
                    {
                      "id": "36a50886-57a0-449b-920f-ab7565226d0b",
                      "sens": "entrant",
                      "mode": "manuel",
                      "type": "pv_valide",
                      "reference_vipnet": null,
                      "contenu": {
                        "motif": null,
                        "type_pv": "installation",
                        "numero_serie": "SL-WNCYUQRHJW"
                      },
                      "survenu_le": "2026-10-19T10:44:38.366Z",
                      "utilisateurs": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction"
                      }
                    }
                  ],
                  "total": 3
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/ordres-installation/{id}": {
      "get": {
        "operationId": "getOrdresInstallationParId",
        "tags": [
          "Opérations"
        ],
        "summary": "Lire la fiche d'un ordre d'installation",
        "description": "L'ordre avec sa commande, son client, son partenaire, le contrat et l'offre à installer, le site (adresse, `latitude` et `longitude` en degrés décimaux ou `null`, contact, zone), le technicien du registre avec son téléphone, et ses procès-verbaux. `contacte_le` date la prise de contact du technicien ; `en_retard` dit si la date limite est dépassée.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "commande_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "destinataire_email": {
                      "type": "null"
                    },
                    "envoye_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "creneaux": {
                      "type": "null"
                    },
                    "date_cible": {
                      "type": "string",
                      "format": "date"
                    },
                    "date_limite": {
                      "type": "string",
                      "format": "date"
                    },
                    "technicien": {
                      "type": "null"
                    },
                    "reference_vipnet": {
                      "type": "null"
                    },
                    "commentaire": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "technicien_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "canal_contact": {
                      "type": "string"
                    },
                    "technicien_contacte_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "proces_verbaux": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          },
                          "date_intervention": {
                            "type": "string",
                            "format": "date"
                          }
                        },
                        "required": [
                          "id",
                          "statut",
                          "type",
                          "date_intervention"
                        ]
                      }
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "clients": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "raison_sociale": {
                              "type": "string"
                            },
                            "ville": {
                              "type": "string"
                            },
                            "telephone": {
                              "type": "null"
                            }
                          },
                          "required": [
                            "id",
                            "raison_sociale",
                            "ville",
                            "telephone"
                          ]
                        },
                        "partenaires": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "raison_sociale": {
                              "type": "string"
                            },
                            "telephone": {
                              "type": "null"
                            },
                            "code_confidentiel": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "raison_sociale",
                            "telephone",
                            "code_confidentiel"
                          ]
                        },
                        "contrats": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "offres": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "code": {
                                    "type": "string"
                                  },
                                  "libelle": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "code",
                                  "libelle"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut",
                              "offres"
                            ]
                          }
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "clients",
                        "partenaires",
                        "contrats"
                      ]
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "ville",
                        "telephone"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "null"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "telephone",
                        "code_confidentiel"
                      ]
                    },
                    "contrat": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "offres": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "code": {
                              "type": "string"
                            },
                            "libelle": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "code",
                            "libelle"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "offres"
                      ]
                    },
                    "offre": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code": {
                          "type": "string"
                        },
                        "libelle": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "code",
                        "libelle"
                      ]
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "adresse": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "ville": {
                          "type": "string"
                        },
                        "latitude": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "longitude": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "contacts": {
                          "type": "object",
                          "properties": {
                            "nom": {
                              "type": "string"
                            },
                            "prenom": {
                              "type": "string"
                            },
                            "telephone": {
                              "type": "string"
                            },
                            "email": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "nom",
                            "prenom",
                            "telephone",
                            "email"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "adresse",
                        "ville",
                        "latitude",
                        "longitude",
                        "contacts"
                      ]
                    },
                    "zone": {
                      "type": "null"
                    },
                    "technicien_fiche": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "telephone"
                      ]
                    },
                    "contacte_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "cree_par_utilisateur": {
                      "type": "null"
                    },
                    "en_retard": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "commande_id",
                    "site_id",
                    "statut",
                    "destinataire_email",
                    "envoye_le",
                    "creneaux",
                    "date_cible",
                    "date_limite",
                    "technicien",
                    "reference_vipnet",
                    "commentaire",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "technicien_id",
                    "canal_contact",
                    "technicien_contacte_le",
                    "proces_verbaux",
                    "commande",
                    "client",
                    "partenaire",
                    "contrat",
                    "offre",
                    "site",
                    "zone",
                    "technicien_fiche",
                    "contacte_le",
                    "cree_par_utilisateur",
                    "en_retard"
                  ]
                },
                "example": {
                  "id": "cc9087c0-af2b-439c-86b6-c8b9339d8611",
                  "numero": "INS-2026-000037",
                  "commande_id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                  "site_id": "e114d094-6e40-45c9-913d-522133ed600a",
                  "statut": "realise",
                  "destinataire_email": null,
                  "envoye_le": "2026-10-19T10:45:51.046Z",
                  "creneaux": null,
                  "date_cible": "2026-10-22",
                  "date_limite": "2026-10-26",
                  "technicien": null,
                  "reference_vipnet": null,
                  "commentaire": null,
                  "cree_par": null,
                  "cree_le": "2026-10-19T10:45:49.166Z",
                  "modifie_le": "2026-10-19T10:45:52.438Z",
                  "technicien_id": "d9d3a67f-c335-4ab0-aeb9-5f906df0b38f",
                  "canal_contact": "whatsapp",
                  "technicien_contacte_le": "2026-10-19T10:45:51.046Z",
                  "proces_verbaux": [
                    {
                      "id": "a8f77fb8-8ba0-4aff-81e2-a6c79ab9bd81",
                      "statut": "valide",
                      "type": "installation",
                      "date_intervention": "2026-10-19"
                    }
                  ],
                  "commande": {
                    "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                    "numero": "CMD-2026-000032",
                    "statut": "active",
                    "clients": {
                      "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                      "raison_sociale": "ZZ Recette Client 4D20EED1",
                      "ville": "Abidjan",
                      "telephone": null
                    },
                    "partenaires": {
                      "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                      "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                      "telephone": null,
                      "code_confidentiel": "C-0076"
                    },
                    "contrats": [
                      {
                        "id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                        "numero": "CTR-2026-000032",
                        "statut": "actif",
                        "offres": {
                          "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                          "code": "DATA-50GO-HEBDO",
                          "libelle": "Forfait 50 Go hebdomadaire"
                        }
                      }
                    ]
                  },
                  "client": {
                    "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                    "raison_sociale": "ZZ Recette Client 4D20EED1",
                    "ville": "Abidjan",
                    "telephone": null
                  },
                  "partenaire": {
                    "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                    "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                    "telephone": null,
                    "code_confidentiel": "C-0076"
                  },
                  "contrat": {
                    "id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                    "numero": "CTR-2026-000032",
                    "statut": "actif",
                    "offres": {
                      "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                      "code": "DATA-50GO-HEBDO",
                      "libelle": "Forfait 50 Go hebdomadaire"
                    }
                  },
                  "offre": {
                    "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                    "code": "DATA-50GO-HEBDO",
                    "libelle": "Forfait 50 Go hebdomadaire"
                  },
                  "site": {
                    "id": "e114d094-6e40-45c9-913d-522133ed600a",
                    "libelle": "Site 4D20EED1",
                    "adresse": null,
                    "ville": "Abidjan",
                    "latitude": 5.3364,
                    "longitude": -4.0267,
                    "contacts": {
                      "nom": "Contact 4D20EED1",
                      "prenom": "ZZ Recette",
                      "telephone": "+225 07 00 00 00 00",
                      "email": "contact.4d20eed1@exemple.invalide"
                    }
                  },
                  "zone": null,
                  "technicien_fiche": {
                    "id": "d9d3a67f-c335-4ab0-aeb9-5f906df0b38f",
                    "prenom": "ZZ Recette",
                    "nom": "Technicien 06750010",
                    "telephone": "+2250706750010"
                  },
                  "contacte_le": "2026-10-19T10:45:51.046Z",
                  "cree_par_utilisateur": null,
                  "en_retard": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "applique"
      },
      "patch": {
        "operationId": "patchOrdresInstallationParId",
        "tags": [
          "Opérations"
        ],
        "summary": "Modifier un ordre d'installation",
        "description": "Change le statut, la date cible, les créneaux, la référence VIP Net, le commentaire ou le nom du technicien (texte libre). Les transitions de statut sont contrôlées, et « realise » exige un procès-verbal d'installation chargé ou validé. Passer « envoye » fait passer la commande « en_installation » (si son installation est débloquée) ; passer « annule » rend une commande « en_installation » à « payee » ou « attente_paiement », si aucun autre ordre ne la porte.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "statut": {
                    "type": "string",
                    "enum": [
                      "a_envoyer",
                      "envoye",
                      "planifie",
                      "realise",
                      "echoue",
                      "annule"
                    ]
                  },
                  "technicien": {
                    "type": "string",
                    "maxLength": 150
                  },
                  "date_cible": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  },
                  "creneaux": {
                    "type": "string",
                    "maxLength": 300
                  },
                  "reference_vipnet": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "commentaire": {
                    "type": "string",
                    "maxLength": 1000
                  }
                }
              },
              "example": {
                "creneaux": "Mardi ou jeudi matin",
                "commentaire": "Accès par le portail nord."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "commande_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "destinataire_email": {
                      "type": "null"
                    },
                    "envoye_le": {
                      "type": "null"
                    },
                    "creneaux": {
                      "type": "string"
                    },
                    "date_cible": {
                      "type": "string",
                      "format": "date"
                    },
                    "date_limite": {
                      "type": "string",
                      "format": "date"
                    },
                    "technicien": {
                      "type": "null"
                    },
                    "reference_vipnet": {
                      "type": "null"
                    },
                    "commentaire": {
                      "type": "string"
                    },
                    "cree_par": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "technicien_id": {
                      "type": "null"
                    },
                    "canal_contact": {
                      "type": "null"
                    },
                    "technicien_contacte_le": {
                      "type": "null"
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "adresse": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville",
                        "adresse"
                      ]
                    },
                    "en_retard": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "commande_id",
                    "site_id",
                    "statut",
                    "destinataire_email",
                    "envoye_le",
                    "creneaux",
                    "date_cible",
                    "date_limite",
                    "technicien",
                    "reference_vipnet",
                    "commentaire",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "technicien_id",
                    "canal_contact",
                    "technicien_contacte_le",
                    "commande",
                    "site",
                    "en_retard"
                  ]
                },
                "example": {
                  "id": "bfb23a3f-5bed-494c-b27d-565c1e9acf58",
                  "numero": "INS-2026-000034",
                  "commande_id": "9baafcab-4a8c-42b2-ba6c-3a5916d308cb",
                  "site_id": "01e18522-0666-4175-b960-ad1a6ff901d6",
                  "statut": "a_envoyer",
                  "destinataire_email": null,
                  "envoye_le": null,
                  "creneaux": "Mardi ou jeudi matin",
                  "date_cible": "2026-10-22",
                  "date_limite": "2026-10-26",
                  "technicien": null,
                  "reference_vipnet": null,
                  "commentaire": "Accès par le portail nord.",
                  "cree_par": null,
                  "cree_le": "2026-10-19T10:45:08.712Z",
                  "modifie_le": "2026-10-19T10:45:09.251Z",
                  "technicien_id": null,
                  "canal_contact": null,
                  "technicien_contacte_le": null,
                  "commande": {
                    "id": "9baafcab-4a8c-42b2-ba6c-3a5916d308cb",
                    "numero": "CMD-2026-000030",
                    "statut": "payee"
                  },
                  "site": {
                    "id": "01e18522-0666-4175-b960-ad1a6ff901d6",
                    "libelle": "Site 62AAEFDF",
                    "ville": "Abidjan",
                    "adresse": null
                  },
                  "en_retard": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Transition de statut interdite, ou réalisation sans procès-verbal d'installation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/techniciens": {
      "get": {
        "operationId": "getTechniciens",
        "tags": [
          "Opérations"
        ],
        "summary": "Lister les techniciens du registre",
        "description": "L'annuaire des techniciens installateurs, qui n'ont pas de compte sur la plateforme, actifs en premier, avec leur zone, leur organisation et le compte de leurs interventions : en cours, réalisées, échouées, et taux de réussite sur les interventions closes (nul quand aucune ne l’est). Filtres `actif` et `zone_id`. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "actif",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "zone_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "prenom": {
                            "type": "string"
                          },
                          "nom": {
                            "type": "string"
                          },
                          "telephone": {
                            "type": "string"
                          },
                          "zone_id": {
                            "type": "null"
                          },
                          "actif": {
                            "type": "boolean"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "zone": {
                            "type": "null"
                          },
                          "organisation": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "nom": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "nom"
                            ]
                          },
                          "ordres_en_cours": {
                            "type": "integer"
                          },
                          "installations_realisees": {
                            "type": "integer"
                          },
                          "echecs": {
                            "type": "integer"
                          },
                          "taux_reussite_pct": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "organisation_id",
                          "prenom",
                          "nom",
                          "telephone",
                          "zone_id",
                          "actif",
                          "cree_le",
                          "modifie_le",
                          "zone",
                          "organisation",
                          "ordres_en_cours",
                          "installations_realisees",
                          "echecs",
                          "taux_reussite_pct"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "d9d3a67f-c335-4ab0-aeb9-5f906df0b38f",
                      "organisation_id": "312c4fba-3da3-4f78-9af5-456eb3edafe2",
                      "prenom": "ZZ Recette",
                      "nom": "Technicien 06750010",
                      "telephone": "+2250706750010",
                      "zone_id": null,
                      "actif": true,
                      "cree_le": "2026-10-19T10:45:50.671Z",
                      "modifie_le": "2026-10-19T10:45:50.671Z",
                      "zone": null,
                      "organisation": {
                        "id": "312c4fba-3da3-4f78-9af5-456eb3edafe2",
                        "nom": "VIP Net"
                      },
                      "ordres_en_cours": 0,
                      "installations_realisees": 1,
                      "echecs": 0,
                      "taux_reussite_pct": 100
                    },
                    {
                      "id": "7af85e89-9cda-4032-9941-e40b63b131d7",
                      "organisation_id": "312c4fba-3da3-4f78-9af5-456eb3edafe2",
                      "prenom": "ZZ Recette",
                      "nom": "Technicien 91GQ8H",
                      "telephone": "+2250706311715",
                      "zone_id": null,
                      "actif": true,
                      "cree_le": "2026-10-19T10:38:32.374Z",
                      "modifie_le": "2026-10-19T10:38:32.374Z",
                      "zone": null,
                      "organisation": {
                        "id": "312c4fba-3da3-4f78-9af5-456eb3edafe2",
                        "nom": "VIP Net"
                      },
                      "ordres_en_cours": 0,
                      "installations_realisees": 1,
                      "echecs": 0,
                      "taux_reussite_pct": 100
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "post": {
        "operationId": "postTechniciens",
        "tags": [
          "Opérations"
        ],
        "summary": "Inscrire un technicien au registre",
        "description": "Crée une fiche d'annuaire, sans compte de connexion. Le téléphone (+225 suivi de dix chiffres, espaces tolérés) est unique au registre. Sans `organisation_id`, le technicien est rattaché à l'organisation de type VIP Net, et l'inscription est refusée s'il n'en existe aucune. Elle est inscrite au journal d'audit.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prenom": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 100
                  },
                  "nom": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 100
                  },
                  "telephone": {
                    "type": "string"
                  },
                  "zone_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "organisation_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "prenom",
                  "nom",
                  "telephone"
                ]
              },
              "example": {
                "prenom": "ZZ Recette",
                "nom": "Technicien RNU3BV",
                "telephone": "+2250706676423"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "prenom": {
                      "type": "string"
                    },
                    "nom": {
                      "type": "string"
                    },
                    "telephone": {
                      "type": "string"
                    },
                    "zone_id": {
                      "type": "null"
                    },
                    "actif": {
                      "type": "boolean"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "zone": {
                      "type": "null"
                    },
                    "organisation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom"
                      ]
                    },
                    "ordres_en_cours": {
                      "type": "integer"
                    },
                    "installations_realisees": {
                      "type": "integer"
                    },
                    "echecs": {
                      "type": "integer"
                    },
                    "taux_reussite_pct": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "prenom",
                    "nom",
                    "telephone",
                    "zone_id",
                    "actif",
                    "cree_le",
                    "modifie_le",
                    "zone",
                    "organisation",
                    "ordres_en_cours",
                    "installations_realisees",
                    "echecs",
                    "taux_reussite_pct"
                  ]
                },
                "example": {
                  "id": "edf13c4c-b5db-4af5-b2d2-dbd67c4a2198",
                  "organisation_id": "312c4fba-3da3-4f78-9af5-456eb3edafe2",
                  "prenom": "ZZ Recette",
                  "nom": "Technicien RNU3BV",
                  "telephone": "+2250706676423",
                  "zone_id": null,
                  "actif": true,
                  "cree_le": "2026-10-19T10:44:37.089Z",
                  "modifie_le": "2026-10-19T10:44:37.089Z",
                  "zone": null,
                  "organisation": {
                    "id": "312c4fba-3da3-4f78-9af5-456eb3edafe2",
                    "nom": "VIP Net"
                  },
                  "ordres_en_cours": 0,
                  "installations_realisees": 0,
                  "echecs": 0,
                  "taux_reussite_pct": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Numéro déjà au registre, ou aucune organisation installatrice enregistrée.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/techniciens/{id}": {
      "get": {
        "operationId": "getTechniciensParId",
        "tags": [
          "Opérations"
        ],
        "summary": "Lire la fiche d'un technicien",
        "description": "Le technicien et ses compteurs d’interventions, avec la liste de ses ordres du plus récent au plus ancien : commande, site, dates, prise de contact (date et canal) et retard.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "prenom": {
                      "type": "string"
                    },
                    "nom": {
                      "type": "string"
                    },
                    "telephone": {
                      "type": "string"
                    },
                    "zone_id": {
                      "type": "null"
                    },
                    "actif": {
                      "type": "boolean"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "zone": {
                      "type": "null"
                    },
                    "organisation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom"
                      ]
                    },
                    "ordres_en_cours": {
                      "type": "integer"
                    },
                    "installations_realisees": {
                      "type": "integer"
                    },
                    "echecs": {
                      "type": "integer"
                    },
                    "taux_reussite_pct": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "ordres": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "date_cible": {
                            "type": "string",
                            "format": "date"
                          },
                          "date_limite": {
                            "type": "string",
                            "format": "date"
                          },
                          "envoye_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "technicien_contacte_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "canal_contact": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "commande": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          },
                          "site": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "adresse": {
                                "type": "null"
                              }
                            },
                            "required": [
                              "id",
                              "libelle",
                              "ville",
                              "adresse"
                            ]
                          },
                          "en_retard": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "statut",
                          "date_cible",
                          "date_limite",
                          "envoye_le",
                          "technicien_contacte_le",
                          "canal_contact",
                          "commande",
                          "site",
                          "en_retard"
                        ]
                      }
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "prenom",
                    "nom",
                    "telephone",
                    "zone_id",
                    "actif",
                    "cree_le",
                    "modifie_le",
                    "zone",
                    "organisation",
                    "ordres_en_cours",
                    "installations_realisees",
                    "echecs",
                    "taux_reussite_pct",
                    "ordres"
                  ]
                },
                "example": {
                  "id": "edf13c4c-b5db-4af5-b2d2-dbd67c4a2198",
                  "organisation_id": "312c4fba-3da3-4f78-9af5-456eb3edafe2",
                  "prenom": "ZZ Recette",
                  "nom": "Technicien RNU3BV",
                  "telephone": "+2250706676423",
                  "zone_id": null,
                  "actif": true,
                  "cree_le": "2026-10-19T10:44:37.089Z",
                  "modifie_le": "2026-10-19T10:44:37.089Z",
                  "zone": null,
                  "organisation": {
                    "id": "312c4fba-3da3-4f78-9af5-456eb3edafe2",
                    "nom": "VIP Net"
                  },
                  "ordres_en_cours": 0,
                  "installations_realisees": 0,
                  "echecs": 0,
                  "taux_reussite_pct": null,
                  "ordres": [
                    {
                      "id": "a331311f-7a98-4159-899c-6bc74808dbe9",
                      "numero": "INS-2026-000033",
                      "statut": "a_envoyer",
                      "date_cible": "2026-10-22",
                      "date_limite": "2026-10-26",
                      "envoye_le": null,
                      "technicien_contacte_le": null,
                      "canal_contact": null,
                      "commande": {
                        "id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                        "numero": "CMD-2026-000029",
                        "statut": "payee"
                      },
                      "site": {
                        "id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                        "libelle": "Siège",
                        "ville": "Abidjan",
                        "adresse": null
                      },
                      "en_retard": false
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "patch": {
        "operationId": "patchTechniciensParId",
        "tags": [
          "Opérations"
        ],
        "summary": "Activer ou retirer un technicien",
        "description": "Passe le technicien actif ou inactif (`actif`). Retirer un technicien qui a des interventions en cours (ordres « envoye » ou « planifie ») est refusé : elles doivent d'abord être réaffectées. Le changement est inscrit au journal d'audit.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "actif": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "actif"
                ]
              },
              "example": {
                "actif": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "prenom": {
                      "type": "string"
                    },
                    "nom": {
                      "type": "string"
                    },
                    "telephone": {
                      "type": "string"
                    },
                    "zone_id": {
                      "type": "null"
                    },
                    "actif": {
                      "type": "boolean"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "zone": {
                      "type": "null"
                    },
                    "organisation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom"
                      ]
                    },
                    "ordres_en_cours": {
                      "type": "integer"
                    },
                    "installations_realisees": {
                      "type": "integer"
                    },
                    "echecs": {
                      "type": "integer"
                    },
                    "taux_reussite_pct": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "prenom",
                    "nom",
                    "telephone",
                    "zone_id",
                    "actif",
                    "cree_le",
                    "modifie_le",
                    "zone",
                    "organisation",
                    "ordres_en_cours",
                    "installations_realisees",
                    "echecs",
                    "taux_reussite_pct"
                  ]
                },
                "example": {
                  "id": "f4ed5e18-6629-4bea-b184-92ea0708ef17",
                  "organisation_id": "312c4fba-3da3-4f78-9af5-456eb3edafe2",
                  "prenom": "ZZ Recette",
                  "nom": "Technicien 75EBED27",
                  "telephone": "+2250710318478",
                  "zone_id": null,
                  "actif": false,
                  "cree_le": "2026-10-19T10:45:00.964Z",
                  "modifie_le": "2026-10-19T10:45:01.136Z",
                  "zone": null,
                  "organisation": {
                    "id": "312c4fba-3da3-4f78-9af5-456eb3edafe2",
                    "nom": "VIP Net"
                  },
                  "ordres_en_cours": 0,
                  "installations_realisees": 0,
                  "echecs": 0,
                  "taux_reussite_pct": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Le technicien a des interventions en cours.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "delete": {
        "operationId": "deleteTechniciensParId",
        "tags": [
          "Opérations"
        ],
        "summary": "Supprimer un technicien jamais employé",
        "description": "Supprime définitivement une fiche saisie par erreur. Refusé dès que le technicien figure sur un ordre : il se retire alors par `PATCH /techniciens/{id}`, pour que ses ordres le nomment encore. La suppression est inscrite au journal d'audit ; réponse `{ supprime: true }`.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "supprime"
                  ]
                },
                "example": {
                  "supprime": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Le technicien figure sur au moins un ordre : le désactiver plutôt.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/ordres-installation/{id}/technicien": {
      "post": {
        "operationId": "postOrdresInstallationParIdTechnicien",
        "tags": [
          "Opérations"
        ],
        "summary": "Confier un ordre à un technicien du registre",
        "description": "Affecte un technicien du registre (`technicien_id`) à l'ordre. Réaffecter l'ordre à un autre technicien efface la prise de contact précédente, à refaire. Refusé sur un ordre « realise » ou « annule », et pour un technicien inconnu ou inactif.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "technicien_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "technicien_id"
                ]
              },
              "example": {
                "technicien_id": "edf13c4c-b5db-4af5-b2d2-dbd67c4a2198"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "commande_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "destinataire_email": {
                      "type": "null"
                    },
                    "envoye_le": {
                      "type": "null"
                    },
                    "creneaux": {
                      "type": "null"
                    },
                    "date_cible": {
                      "type": "string",
                      "format": "date"
                    },
                    "date_limite": {
                      "type": "string",
                      "format": "date"
                    },
                    "technicien": {
                      "type": "null"
                    },
                    "reference_vipnet": {
                      "type": "null"
                    },
                    "commentaire": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "technicien_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "canal_contact": {
                      "type": "null"
                    },
                    "technicien_contacte_le": {
                      "type": "null"
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "adresse": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville",
                        "adresse"
                      ]
                    },
                    "technicien_fiche": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "string"
                        },
                        "actif": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "telephone",
                        "actif"
                      ]
                    },
                    "en_retard": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "commande_id",
                    "site_id",
                    "statut",
                    "destinataire_email",
                    "envoye_le",
                    "creneaux",
                    "date_cible",
                    "date_limite",
                    "technicien",
                    "reference_vipnet",
                    "commentaire",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "technicien_id",
                    "canal_contact",
                    "technicien_contacte_le",
                    "commande",
                    "site",
                    "technicien_fiche",
                    "en_retard"
                  ]
                },
                "example": {
                  "id": "a331311f-7a98-4159-899c-6bc74808dbe9",
                  "numero": "INS-2026-000033",
                  "commande_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                  "site_id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                  "statut": "a_envoyer",
                  "destinataire_email": null,
                  "envoye_le": null,
                  "creneaux": null,
                  "date_cible": "2026-10-22",
                  "date_limite": "2026-10-26",
                  "technicien": null,
                  "reference_vipnet": null,
                  "commentaire": null,
                  "cree_par": null,
                  "cree_le": "2026-10-19T10:44:36.114Z",
                  "modifie_le": "2026-10-19T10:44:37.344Z",
                  "technicien_id": "edf13c4c-b5db-4af5-b2d2-dbd67c4a2198",
                  "canal_contact": null,
                  "technicien_contacte_le": null,
                  "commande": {
                    "id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                    "numero": "CMD-2026-000029",
                    "statut": "payee"
                  },
                  "site": {
                    "id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                    "libelle": "Siège",
                    "ville": "Abidjan",
                    "adresse": null
                  },
                  "technicien_fiche": {
                    "id": "edf13c4c-b5db-4af5-b2d2-dbd67c4a2198",
                    "prenom": "ZZ Recette",
                    "nom": "Technicien RNU3BV",
                    "telephone": "+2250706676423",
                    "actif": true
                  },
                  "en_retard": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Ordre réalisé ou annulé, ou technicien retiré des actifs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/ordres-installation/{id}/technicien/contact": {
      "post": {
        "operationId": "postOrdresInstallationParIdTechnicienContact",
        "tags": [
          "Opérations"
        ],
        "summary": "Consigner la prise de contact du technicien",
        "description": "Déclare que CYBASTION a joint le technicien affecté (`canal` : appel ou WhatsApp ; `contacte_le`, maintenant par défaut) : la plateforme n'envoie rien. Un ordre « a_envoyer » passe alors « envoye », et la commande « en_installation » si son installation est débloquée. Refusé si aucun technicien n'est affecté.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "canal": {
                    "type": "string",
                    "enum": [
                      "appel",
                      "whatsapp"
                    ]
                  },
                  "contacte_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  }
                },
                "required": [
                  "canal"
                ]
              },
              "example": {
                "canal": "whatsapp"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "commande_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "destinataire_email": {
                      "type": "null"
                    },
                    "envoye_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "creneaux": {
                      "type": "null"
                    },
                    "date_cible": {
                      "type": "string",
                      "format": "date"
                    },
                    "date_limite": {
                      "type": "string",
                      "format": "date"
                    },
                    "technicien": {
                      "type": "null"
                    },
                    "reference_vipnet": {
                      "type": "null"
                    },
                    "commentaire": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "technicien_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "canal_contact": {
                      "type": "string"
                    },
                    "technicien_contacte_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "adresse": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville",
                        "adresse"
                      ]
                    },
                    "technicien_fiche": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "string"
                        },
                        "actif": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "telephone",
                        "actif"
                      ]
                    },
                    "en_retard": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "commande_id",
                    "site_id",
                    "statut",
                    "destinataire_email",
                    "envoye_le",
                    "creneaux",
                    "date_cible",
                    "date_limite",
                    "technicien",
                    "reference_vipnet",
                    "commentaire",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "technicien_id",
                    "canal_contact",
                    "technicien_contacte_le",
                    "commande",
                    "site",
                    "technicien_fiche",
                    "en_retard"
                  ]
                },
                "example": {
                  "id": "a331311f-7a98-4159-899c-6bc74808dbe9",
                  "numero": "INS-2026-000033",
                  "commande_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                  "site_id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                  "statut": "envoye",
                  "destinataire_email": null,
                  "envoye_le": "2026-10-19T10:44:37.599Z",
                  "creneaux": null,
                  "date_cible": "2026-10-22",
                  "date_limite": "2026-10-26",
                  "technicien": null,
                  "reference_vipnet": null,
                  "commentaire": null,
                  "cree_par": null,
                  "cree_le": "2026-10-19T10:44:36.114Z",
                  "modifie_le": "2026-10-19T10:44:37.599Z",
                  "technicien_id": "edf13c4c-b5db-4af5-b2d2-dbd67c4a2198",
                  "canal_contact": "whatsapp",
                  "technicien_contacte_le": "2026-10-19T10:44:37.599Z",
                  "commande": {
                    "id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                    "numero": "CMD-2026-000029",
                    "statut": "en_installation"
                  },
                  "site": {
                    "id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                    "libelle": "Siège",
                    "ville": "Abidjan",
                    "adresse": null
                  },
                  "technicien_fiche": {
                    "id": "edf13c4c-b5db-4af5-b2d2-dbd67c4a2198",
                    "prenom": "ZZ Recette",
                    "nom": "Technicien RNU3BV",
                    "telephone": "+2250706676423",
                    "actif": true
                  },
                  "en_retard": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Aucun technicien n'est affecté à cet ordre.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/proces-verbaux/{id}": {
      "get": {
        "operationId": "getProcesVerbauxParId",
        "tags": [
          "Opérations"
        ],
        "summary": "Lire la fiche d'un procès-verbal",
        "description": "Le procès-verbal avec son fichier, son ordre, la commande, le client, le partenaire, le site, le contrat et le dernier équipement posé (numéro de série), son activation, l'utilisateur qui l'a saisi et celui qui l'a tranché.\n\n**Permission requise** : L'une de : `installations.gerer`, `pv.valider`, `pv.charger`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string"
                    },
                    "ordre_installation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "activation_id": {
                      "type": "null"
                    },
                    "fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "date_intervention": {
                      "type": "string",
                      "format": "date"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "charge_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "motif_contestation": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "fichier": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "bucket": {
                          "type": "string"
                        },
                        "chemin": {
                          "type": "string"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        },
                        "taille_octets": {
                          "type": "integer"
                        },
                        "empreinte_sha256": {
                          "type": "string"
                        },
                        "statut_scan": {
                          "type": "string"
                        },
                        "depose_par": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "bucket",
                        "chemin",
                        "nom_original",
                        "type_mime",
                        "taille_octets",
                        "empreinte_sha256",
                        "statut_scan",
                        "depose_par",
                        "cree_le"
                      ]
                    },
                    "ordre_installation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "technicien": {
                          "type": "null"
                        },
                        "commandes": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "numero": {
                              "type": "string"
                            },
                            "statut": {
                              "type": "string"
                            },
                            "clients": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "raison_sociale": {
                                  "type": "string"
                                },
                                "ville": {
                                  "type": "string"
                                },
                                "telephone": {
                                  "type": "null"
                                }
                              },
                              "required": [
                                "id",
                                "raison_sociale",
                                "ville",
                                "telephone"
                              ]
                            },
                            "partenaires": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "raison_sociale": {
                                  "type": "string"
                                },
                                "telephone": {
                                  "type": "null"
                                },
                                "code_confidentiel": {
                                  "type": "string"
                                }
                              },
                              "required": [
                                "id",
                                "raison_sociale",
                                "telephone",
                                "code_confidentiel"
                              ]
                            },
                            "contrats": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "numero": {
                                    "type": "string"
                                  },
                                  "statut": {
                                    "type": "string"
                                  },
                                  "equipements": {
                                    "type": "array",
                                    "items": {}
                                  }
                                },
                                "required": [
                                  "id",
                                  "numero",
                                  "statut",
                                  "equipements"
                                ]
                              }
                            }
                          },
                          "required": [
                            "id",
                            "numero",
                            "statut",
                            "clients",
                            "partenaires",
                            "contrats"
                          ]
                        },
                        "sites": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "libelle": {
                              "type": "string"
                            },
                            "ville": {
                              "type": "string"
                            },
                            "adresse": {
                              "type": "null"
                            }
                          },
                          "required": [
                            "id",
                            "libelle",
                            "ville",
                            "adresse"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "technicien",
                        "commandes",
                        "sites"
                      ]
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "clients": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "raison_sociale": {
                              "type": "string"
                            },
                            "ville": {
                              "type": "string"
                            },
                            "telephone": {
                              "type": "null"
                            }
                          },
                          "required": [
                            "id",
                            "raison_sociale",
                            "ville",
                            "telephone"
                          ]
                        },
                        "partenaires": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "raison_sociale": {
                              "type": "string"
                            },
                            "telephone": {
                              "type": "null"
                            },
                            "code_confidentiel": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "raison_sociale",
                            "telephone",
                            "code_confidentiel"
                          ]
                        },
                        "contrats": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "equipements": {
                                "type": "array",
                                "items": {}
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut",
                              "equipements"
                            ]
                          }
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "clients",
                        "partenaires",
                        "contrats"
                      ]
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "ville",
                        "telephone"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "null"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "telephone",
                        "code_confidentiel"
                      ]
                    },
                    "contrat": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "equipements": {
                          "type": "array",
                          "items": {}
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "equipements"
                      ]
                    },
                    "equipement": {
                      "type": "null"
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "adresse": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville",
                        "adresse"
                      ]
                    },
                    "activation": {
                      "type": "null"
                    },
                    "charge_par_utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "valide_par_utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "type",
                    "ordre_installation_id",
                    "activation_id",
                    "fichier_id",
                    "date_intervention",
                    "statut",
                    "charge_par",
                    "valide_par",
                    "valide_le",
                    "motif_contestation",
                    "cree_le",
                    "modifie_le",
                    "fichier",
                    "ordre_installation",
                    "commande",
                    "client",
                    "partenaire",
                    "contrat",
                    "equipement",
                    "site",
                    "activation",
                    "charge_par_utilisateur",
                    "valide_par_utilisateur"
                  ]
                },
                "example": {
                  "id": "a8f77fb8-8ba0-4aff-81e2-a6c79ab9bd81",
                  "type": "installation",
                  "ordre_installation_id": "cc9087c0-af2b-439c-86b6-c8b9339d8611",
                  "activation_id": null,
                  "fichier_id": "8324bd4d-7657-47a8-a625-5e1832dc991c",
                  "date_intervention": "2026-10-19",
                  "statut": "valide",
                  "charge_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "valide_le": "2026-10-19T10:45:52.438Z",
                  "motif_contestation": null,
                  "cree_le": "2026-10-19T10:45:51.748Z",
                  "modifie_le": "2026-10-19T10:45:52.438Z",
                  "fichier": {
                    "id": "8324bd4d-7657-47a8-a625-5e1832dc991c",
                    "bucket": "proces-verbaux",
                    "chemin": "proces-verbaux/2026/10/9f7d9b51-8eab-42a3-b01d-6eb8f754dfc7.pdf",
                    "nom_original": "piece.pdf",
                    "type_mime": "application/pdf",
                    "taille_octets": 221,
                    "empreinte_sha256": "fb85fa375502946ece789f6ef552ce48806c456e3385e8f28fc5df0c8d793fc6",
                    "statut_scan": "sain",
                    "depose_par": "86ce3683-763a-4644-9b69-5412f153968f",
                    "cree_le": "2026-10-19T10:45:52.168Z"
                  },
                  "ordre_installation": {
                    "id": "cc9087c0-af2b-439c-86b6-c8b9339d8611",
                    "numero": "INS-2026-000037",
                    "statut": "realise",
                    "technicien": null,
                    "commandes": {
                      "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                      "numero": "CMD-2026-000032",
                      "statut": "active",
                      "clients": {
                        "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                        "raison_sociale": "ZZ Recette Client 4D20EED1",
                        "ville": "Abidjan",
                        "telephone": null
                      },
                      "partenaires": {
                        "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                        "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                        "telephone": null,
                        "code_confidentiel": "C-0076"
                      },
                      "contrats": [
                        {
                          "id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                          "numero": "CTR-2026-000032",
                          "statut": "actif",
                          "equipements": []
                        }
                      ]
                    },
                    "sites": {
                      "id": "e114d094-6e40-45c9-913d-522133ed600a",
                      "libelle": "Site 4D20EED1",
                      "ville": "Abidjan",
                      "adresse": null
                    }
                  },
                  "commande": {
                    "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                    "numero": "CMD-2026-000032",
                    "statut": "active",
                    "clients": {
                      "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                      "raison_sociale": "ZZ Recette Client 4D20EED1",
                      "ville": "Abidjan",
                      "telephone": null
                    },
                    "partenaires": {
                      "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                      "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                      "telephone": null,
                      "code_confidentiel": "C-0076"
                    },
                    "contrats": [
                      {
                        "id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                        "numero": "CTR-2026-000032",
                        "statut": "actif",
                        "equipements": []
                      }
                    ]
                  },
                  "client": {
                    "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                    "raison_sociale": "ZZ Recette Client 4D20EED1",
                    "ville": "Abidjan",
                    "telephone": null
                  },
                  "partenaire": {
                    "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                    "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                    "telephone": null,
                    "code_confidentiel": "C-0076"
                  },
                  "contrat": {
                    "id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                    "numero": "CTR-2026-000032",
                    "statut": "actif",
                    "equipements": []
                  },
                  "equipement": null,
                  "site": {
                    "id": "e114d094-6e40-45c9-913d-522133ed600a",
                    "libelle": "Site 4D20EED1",
                    "ville": "Abidjan",
                    "adresse": null
                  },
                  "activation": null,
                  "charge_par_utilisateur": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction",
                    "email": "admin.cybastion@preprod.satelica.test"
                  },
                  "valide_par_utilisateur": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction",
                    "email": "admin.cybastion@preprod.satelica.test"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "installations.gerer",
          "pv.valider",
          "pv.charger"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/proces-verbaux/{id}/rechargement": {
      "post": {
        "operationId": "postProcesVerbauxParIdRechargement",
        "tags": [
          "Opérations"
        ],
        "summary": "Remplacer la pièce d'un procès-verbal contesté",
        "description": "Remplace la pièce d'un procès-verbal « conteste » par un autre fichier, déposé au préalable par l'appelant et déclaré sain par l'antivirus ; `date_intervention` peut être corrigée. Le procès-verbal repasse « charge », à examiner de nouveau, et sa décision précédente est effacée. L'ancienne pièce reste au journal d'audit.\n\n**Permission requise** : `pv.charger`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fichier_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "date_intervention": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  }
                },
                "required": [
                  "fichier_id"
                ]
              },
              "example": {
                "fichier_id": "8324bd4d-7657-47a8-a625-5e1832dc991c"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string"
                    },
                    "ordre_installation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "activation_id": {
                      "type": "null"
                    },
                    "fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "date_intervention": {
                      "type": "string",
                      "format": "date"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "charge_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_par": {
                      "type": "null"
                    },
                    "valide_le": {
                      "type": "null"
                    },
                    "motif_contestation": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "fichier": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "bucket": {
                          "type": "string"
                        },
                        "chemin": {
                          "type": "string"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        },
                        "taille_octets": {
                          "type": "integer"
                        },
                        "empreinte_sha256": {
                          "type": "string"
                        },
                        "statut_scan": {
                          "type": "string"
                        },
                        "depose_par": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "bucket",
                        "chemin",
                        "nom_original",
                        "type_mime",
                        "taille_octets",
                        "empreinte_sha256",
                        "statut_scan",
                        "depose_par",
                        "cree_le"
                      ]
                    },
                    "ordre_installation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "activation": {
                      "type": "null"
                    },
                    "charge_par_utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "valide_par_utilisateur": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "id",
                    "type",
                    "ordre_installation_id",
                    "activation_id",
                    "fichier_id",
                    "date_intervention",
                    "statut",
                    "charge_par",
                    "valide_par",
                    "valide_le",
                    "motif_contestation",
                    "cree_le",
                    "modifie_le",
                    "fichier",
                    "ordre_installation",
                    "activation",
                    "charge_par_utilisateur",
                    "valide_par_utilisateur"
                  ]
                },
                "example": {
                  "id": "a8f77fb8-8ba0-4aff-81e2-a6c79ab9bd81",
                  "type": "installation",
                  "ordre_installation_id": "cc9087c0-af2b-439c-86b6-c8b9339d8611",
                  "activation_id": null,
                  "fichier_id": "8324bd4d-7657-47a8-a625-5e1832dc991c",
                  "date_intervention": "2026-10-19",
                  "statut": "charge",
                  "charge_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "valide_par": null,
                  "valide_le": null,
                  "motif_contestation": null,
                  "cree_le": "2026-10-19T10:45:51.748Z",
                  "modifie_le": "2026-10-19T10:45:52.297Z",
                  "fichier": {
                    "id": "8324bd4d-7657-47a8-a625-5e1832dc991c",
                    "bucket": "proces-verbaux",
                    "chemin": "proces-verbaux/2026/10/9f7d9b51-8eab-42a3-b01d-6eb8f754dfc7.pdf",
                    "nom_original": "piece.pdf",
                    "type_mime": "application/pdf",
                    "taille_octets": 221,
                    "empreinte_sha256": "fb85fa375502946ece789f6ef552ce48806c456e3385e8f28fc5df0c8d793fc6",
                    "statut_scan": "sain",
                    "depose_par": "86ce3683-763a-4644-9b69-5412f153968f",
                    "cree_le": "2026-10-19T10:45:52.168Z"
                  },
                  "ordre_installation": {
                    "id": "cc9087c0-af2b-439c-86b6-c8b9339d8611",
                    "numero": "INS-2026-000037",
                    "statut": "envoye"
                  },
                  "activation": null,
                  "charge_par_utilisateur": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction",
                    "email": "admin.cybastion@preprod.satelica.test"
                  },
                  "valide_par_utilisateur": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Procès-verbal non contesté, fichier non sain, ou même pièce que celle contestée.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "pv.charger",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/proces-verbaux/{id}/decision": {
      "post": {
        "operationId": "postProcesVerbauxParIdDecision",
        "tags": [
          "Opérations"
        ],
        "summary": "Valider ou contester un procès-verbal",
        "description": "Tranche un procès-verbal « charge » : `valide`, ou `conteste` avec un `motif` obligatoire. Validé, un procès-verbal d'installation rend l'ordre « realise », passe la commande « en_activation », crée l'activation à demander si le contrat n'en a pas, et enregistre au parc l'antenne de `numero_serie` s'il est donné. La décision est consignée dans les échanges VIP Net.\n\n**Permission requise** : `pv.valider`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "valide",
                      "conteste"
                    ]
                  },
                  "motif": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "numero_serie": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "valide",
                "numero_serie": "SL-WNCYUQRHJW"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string"
                    },
                    "ordre_installation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "activation_id": {
                      "type": "null"
                    },
                    "fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "date_intervention": {
                      "type": "string",
                      "format": "date"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "charge_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valide_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "motif_contestation": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "fichier": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "bucket": {
                          "type": "string"
                        },
                        "chemin": {
                          "type": "string"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        },
                        "taille_octets": {
                          "type": "integer"
                        },
                        "empreinte_sha256": {
                          "type": "string"
                        },
                        "statut_scan": {
                          "type": "string"
                        },
                        "depose_par": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "bucket",
                        "chemin",
                        "nom_original",
                        "type_mime",
                        "taille_octets",
                        "empreinte_sha256",
                        "statut_scan",
                        "depose_par",
                        "cree_le"
                      ]
                    },
                    "ordre_installation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "type",
                    "ordre_installation_id",
                    "activation_id",
                    "fichier_id",
                    "date_intervention",
                    "statut",
                    "charge_par",
                    "valide_par",
                    "valide_le",
                    "motif_contestation",
                    "cree_le",
                    "modifie_le",
                    "fichier",
                    "ordre_installation"
                  ]
                },
                "example": {
                  "id": "e4502c77-4b37-42c6-9e06-322a04bf96e7",
                  "type": "installation",
                  "ordre_installation_id": "a331311f-7a98-4159-899c-6bc74808dbe9",
                  "activation_id": null,
                  "fichier_id": "0a9a7af9-e0a0-401d-87b0-9a3ebcb23235",
                  "date_intervention": "2026-10-19",
                  "statut": "valide",
                  "charge_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "valide_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "valide_le": "2026-10-19T10:44:38.347Z",
                  "motif_contestation": null,
                  "cree_le": "2026-10-19T10:44:38.221Z",
                  "modifie_le": "2026-10-19T10:44:38.347Z",
                  "fichier": {
                    "id": "0a9a7af9-e0a0-401d-87b0-9a3ebcb23235",
                    "bucket": "proces-verbaux",
                    "chemin": "proces-verbaux/2026/10/6c0e4753-4f92-4fad-a65f-08e070206aee.pdf",
                    "nom_original": "pv-installation.pdf",
                    "type_mime": "application/pdf",
                    "taille_octets": 191,
                    "empreinte_sha256": "cf9f8c74b748cd6f0a1cecf17dbc38d2089427ac482ab3ec1001d4e80ccb3a8e",
                    "statut_scan": "sain",
                    "depose_par": "86ce3683-763a-4644-9b69-5412f153968f",
                    "cree_le": "2026-10-19T10:38:33.432Z"
                  },
                  "ordre_installation": {
                    "id": "a331311f-7a98-4159-899c-6bc74808dbe9",
                    "numero": "INS-2026-000033",
                    "statut": "envoye"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Ce procès-verbal a déjà été traité.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "pv.valider",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/activations": {
      "get": {
        "operationId": "getActivations",
        "tags": [
          "Opérations"
        ],
        "summary": "Lister les activations",
        "description": "Les activations de liaison, de la plus récente à la plus ancienne, avec leur contrat, leur site, leur connexion et l'utilisateur qui les a demandées. Filtres `statut` (a_demander, demandee, activee, echouee ; une ou plusieurs valeurs séparées par des virgules) et `contrat_id`.\n\n**Permission requise** : `activations.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "contrat_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "contrat_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "site_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "connexion_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "demandee_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "demandee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "activee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "reference_vipnet": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "commentaire": {
                            "type": "null"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "contrat": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          },
                          "site": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "adresse": {
                                "type": "null"
                              }
                            },
                            "required": [
                              "id",
                              "libelle",
                              "ville",
                              "adresse"
                            ]
                          },
                          "connexion": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "site_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "contrat_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "equipement_id": {
                                "type": "null"
                              },
                              "identifiant_vipnet": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "active_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "suspendue_le": {
                                "type": "null"
                              },
                              "resiliee_le": {
                                "type": "null"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "site_id",
                              "contrat_id",
                              "equipement_id",
                              "identifiant_vipnet",
                              "statut",
                              "active_le",
                              "suspendue_le",
                              "resiliee_le",
                              "cree_le",
                              "modifie_le"
                            ]
                          },
                          "demandee_par_utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "contrat_id",
                          "site_id",
                          "connexion_id",
                          "statut",
                          "demandee_par",
                          "demandee_le",
                          "activee_le",
                          "reference_vipnet",
                          "commentaire",
                          "cree_le",
                          "modifie_le",
                          "contrat",
                          "site",
                          "connexion",
                          "demandee_par_utilisateur"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "f0c4b68f-5411-4289-8626-973622d990d5",
                      "contrat_id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                      "site_id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                      "connexion_id": null,
                      "statut": "a_demander",
                      "demandee_par": null,
                      "demandee_le": null,
                      "activee_le": null,
                      "reference_vipnet": null,
                      "commentaire": null,
                      "cree_le": "2026-10-19T10:44:38.362Z",
                      "modifie_le": "2026-10-19T10:44:38.362Z",
                      "contrat": {
                        "id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                        "numero": "CTR-2026-000029",
                        "statut": "projet"
                      },
                      "site": {
                        "id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                        "libelle": "Siège",
                        "ville": "Abidjan",
                        "adresse": null
                      },
                      "connexion": null,
                      "demandee_par_utilisateur": null
                    },
                    {
                      "id": "378b18cc-1c34-4daa-b77c-e80983d5bbca",
                      "contrat_id": "563abd9f-27cb-45a0-8bad-20712b541b9c",
                      "site_id": "23df7d64-7c63-4b5f-be5e-f0470d712782",
                      "connexion_id": "cc26eb52-dbfa-4a32-8324-f118536333cd",
                      "statut": "activee",
                      "demandee_par": null,
                      "demandee_le": null,
                      "activee_le": "2026-10-19T10:42:11.451Z",
                      "reference_vipnet": "VIP-NDDKNBHRYB",
                      "commentaire": null,
                      "cree_le": "2026-10-19T10:42:11.073Z",
                      "modifie_le": "2026-10-19T10:42:11.451Z",
                      "contrat": {
                        "id": "563abd9f-27cb-45a0-8bad-20712b541b9c",
                        "numero": "CTR-2026-000025",
                        "statut": "actif"
                      },
                      "site": {
                        "id": "23df7d64-7c63-4b5f-be5e-f0470d712782",
                        "libelle": "Siège",
                        "ville": "Abidjan",
                        "adresse": null
                      },
                      "connexion": {
                        "id": "cc26eb52-dbfa-4a32-8324-f118536333cd",
                        "site_id": "23df7d64-7c63-4b5f-be5e-f0470d712782",
                        "contrat_id": "563abd9f-27cb-45a0-8bad-20712b541b9c",
                        "equipement_id": null,
                        "identifiant_vipnet": "SL-CNX-NDDKNBHRYB",
                        "statut": "active",
                        "active_le": "2026-10-19T10:42:11.463Z",
                        "suspendue_le": null,
                        "resiliee_le": null,
                        "cree_le": "2026-10-19T10:42:11.463Z",
                        "modifie_le": "2026-10-19T10:42:11.463Z"
                      },
                      "demandee_par_utilisateur": null
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 20,
                    "total": 3,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "activations.gerer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/activations/{id}": {
      "get": {
        "operationId": "getActivationsParId",
        "tags": [
          "Opérations"
        ],
        "summary": "Lire la fiche d'une activation",
        "description": "L'activation avec son contrat, son client, son partenaire, sa commande, son offre, son site, sa connexion, ses procès-verbaux (`pv_installation`, `pv_activation`) et l'historique des échanges avec VIP Net (`echanges`).\n\n**Permission requise** : `activations.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contrat_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "connexion_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "demandee_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "demandee_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "activee_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "reference_vipnet": {
                      "type": "string"
                    },
                    "commentaire": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "proces_verbaux": {
                      "type": "array",
                      "items": {}
                    },
                    "contrat": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "clients": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "raison_sociale": {
                              "type": "string"
                            },
                            "ville": {
                              "type": "string"
                            },
                            "telephone": {
                              "type": "null"
                            }
                          },
                          "required": [
                            "id",
                            "raison_sociale",
                            "ville",
                            "telephone"
                          ]
                        },
                        "partenaires": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "raison_sociale": {
                              "type": "string"
                            },
                            "telephone": {
                              "type": "null"
                            },
                            "code_confidentiel": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "raison_sociale",
                            "telephone",
                            "code_confidentiel"
                          ]
                        },
                        "offres": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "code": {
                              "type": "string"
                            },
                            "libelle": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "code",
                            "libelle"
                          ]
                        },
                        "commandes": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "numero": {
                              "type": "string"
                            },
                            "statut": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "numero",
                            "statut"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "clients",
                        "partenaires",
                        "offres",
                        "commandes"
                      ]
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "ville",
                        "telephone"
                      ]
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "telephone": {
                          "type": "null"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "telephone",
                        "code_confidentiel"
                      ]
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "offre": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code": {
                          "type": "string"
                        },
                        "libelle": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "code",
                        "libelle"
                      ]
                    },
                    "pv_installation": {
                      "type": "null"
                    },
                    "pv_activation": {
                      "type": "null"
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "adresse": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville",
                        "adresse"
                      ]
                    },
                    "connexion": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "site_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "contrat_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "equipement_id": {
                          "type": "null"
                        },
                        "identifiant_vipnet": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "active_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "suspendue_le": {
                          "type": "null"
                        },
                        "resiliee_le": {
                          "type": "null"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "modifie_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "site_id",
                        "contrat_id",
                        "equipement_id",
                        "identifiant_vipnet",
                        "statut",
                        "active_le",
                        "suspendue_le",
                        "resiliee_le",
                        "cree_le",
                        "modifie_le"
                      ]
                    },
                    "demandee_par_utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "echanges": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "sens": {
                            "type": "string"
                          },
                          "mode": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          },
                          "reference_vipnet": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "contenu": {
                            "type": "object",
                            "properties": {
                              "commentaire": {
                                "type": "null"
                              },
                              "identifiant_connexion": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "commentaire",
                              "identifiant_connexion"
                            ]
                          },
                          "survenu_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "sens",
                          "mode",
                          "type",
                          "reference_vipnet",
                          "contenu",
                          "survenu_le",
                          "cree_le"
                        ]
                      }
                    }
                  },
                  "required": [
                    "id",
                    "contrat_id",
                    "site_id",
                    "connexion_id",
                    "statut",
                    "demandee_par",
                    "demandee_le",
                    "activee_le",
                    "reference_vipnet",
                    "commentaire",
                    "cree_le",
                    "modifie_le",
                    "proces_verbaux",
                    "contrat",
                    "client",
                    "partenaire",
                    "commande",
                    "offre",
                    "pv_installation",
                    "pv_activation",
                    "site",
                    "connexion",
                    "demandee_par_utilisateur",
                    "echanges"
                  ]
                },
                "example": {
                  "id": "2c9db910-e993-4cb1-a5ba-4c39bd121dd7",
                  "contrat_id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                  "site_id": "e114d094-6e40-45c9-913d-522133ed600a",
                  "connexion_id": "b43b3acc-9521-4969-a93e-df94f1083709",
                  "statut": "activee",
                  "demandee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "demandee_le": "2026-10-19T10:45:52.706Z",
                  "activee_le": "2026-10-19T10:45:52.957Z",
                  "reference_vipnet": "VIP-1792406752042",
                  "commentaire": null,
                  "cree_le": "2026-10-19T10:45:52.450Z",
                  "modifie_le": "2026-10-19T10:45:52.957Z",
                  "proces_verbaux": [],
                  "contrat": {
                    "id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                    "numero": "CTR-2026-000032",
                    "statut": "actif",
                    "clients": {
                      "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                      "raison_sociale": "ZZ Recette Client 4D20EED1",
                      "ville": "Abidjan",
                      "telephone": null
                    },
                    "partenaires": {
                      "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                      "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                      "telephone": null,
                      "code_confidentiel": "C-0076"
                    },
                    "offres": {
                      "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                      "code": "DATA-50GO-HEBDO",
                      "libelle": "Forfait 50 Go hebdomadaire"
                    },
                    "commandes": {
                      "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                      "numero": "CMD-2026-000032",
                      "statut": "active"
                    }
                  },
                  "client": {
                    "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                    "raison_sociale": "ZZ Recette Client 4D20EED1",
                    "ville": "Abidjan",
                    "telephone": null
                  },
                  "partenaire": {
                    "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                    "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                    "telephone": null,
                    "code_confidentiel": "C-0076"
                  },
                  "commande": {
                    "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                    "numero": "CMD-2026-000032",
                    "statut": "active"
                  },
                  "offre": {
                    "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                    "code": "DATA-50GO-HEBDO",
                    "libelle": "Forfait 50 Go hebdomadaire"
                  },
                  "pv_installation": null,
                  "pv_activation": null,
                  "site": {
                    "id": "e114d094-6e40-45c9-913d-522133ed600a",
                    "libelle": "Site 4D20EED1",
                    "ville": "Abidjan",
                    "adresse": null
                  },
                  "connexion": {
                    "id": "b43b3acc-9521-4969-a93e-df94f1083709",
                    "site_id": "e114d094-6e40-45c9-913d-522133ed600a",
                    "contrat_id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                    "equipement_id": null,
                    "identifiant_vipnet": "LIAISON-1792406752295",
                    "statut": "active",
                    "active_le": "2026-10-19T10:45:52.969Z",
                    "suspendue_le": null,
                    "resiliee_le": null,
                    "cree_le": "2026-10-19T10:45:52.969Z",
                    "modifie_le": "2026-10-19T10:45:52.969Z"
                  },
                  "demandee_par_utilisateur": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction",
                    "email": "admin.cybastion@preprod.satelica.test"
                  },
                  "echanges": [
                    {
                      "id": "9d43c20f-9764-4d9b-a863-596421aa0f01",
                      "sens": "entrant",
                      "mode": "manuel",
                      "type": "activation_confirmee",
                      "reference_vipnet": null,
                      "contenu": {
                        "commentaire": null,
                        "identifiant_connexion": "LIAISON-1792406752295"
                      },
                      "survenu_le": "2026-10-19T10:45:53.167Z",
                      "cree_le": "2026-10-19T10:45:53.167Z"
                    },
                    {
                      "id": "b4cd2f90-271c-4f2b-a7ca-90c58b914221",
                      "sens": "entrant",
                      "mode": "manuel",
                      "type": "activation_demandee",
                      "reference_vipnet": "VIP-1792406752042",
                      "contenu": {
                        "commentaire": null,
                        "identifiant_connexion": null
                      },
                      "survenu_le": "2026-10-19T10:45:52.712Z",
                      "cree_le": "2026-10-19T10:45:52.712Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "activations.gerer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/activations/{id}/decision": {
      "post": {
        "operationId": "postActivationsParIdDecision",
        "tags": [
          "Opérations"
        ],
        "summary": "Enregistrer l'avancement d'une activation",
        "description": "Inscrit la demande d'activation à VIP Net (`demandee`), son succès (`activee`, `identifiant_connexion` obligatoire) ou son échec (`echouee`, `commentaire` obligatoire). Activée, elle met en service le contrat (début de la période d'abonnement), le site, le client et la liaison, passe la commande « active » et notifie le client et le partenaire. Chaque décision est consignée dans les échanges VIP Net.\n\n**Permission requise** : `activations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "demandee",
                      "activee",
                      "echouee"
                    ]
                  },
                  "reference_vipnet": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "identifiant_connexion": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "commentaire": {
                    "type": "string",
                    "maxLength": 1000
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "activee",
                "identifiant_connexion": "SL-CNX-WNCYUQRHJW",
                "reference_vipnet": "VIP-WNCYUQRHJW"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contrat_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "site_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "connexion_id": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "demandee_par": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "demandee_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "activee_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "reference_vipnet": {
                      "type": "string"
                    },
                    "commentaire": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "contrat": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "client_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut",
                        "client_id"
                      ]
                    },
                    "site": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "adresse": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "ville",
                        "adresse"
                      ]
                    },
                    "connexion": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "id",
                    "contrat_id",
                    "site_id",
                    "connexion_id",
                    "statut",
                    "demandee_par",
                    "demandee_le",
                    "activee_le",
                    "reference_vipnet",
                    "commentaire",
                    "cree_le",
                    "modifie_le",
                    "contrat",
                    "site",
                    "connexion"
                  ]
                },
                "example": {
                  "id": "f0c4b68f-5411-4289-8626-973622d990d5",
                  "contrat_id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                  "site_id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                  "connexion_id": null,
                  "statut": "activee",
                  "demandee_par": null,
                  "demandee_le": null,
                  "activee_le": "2026-10-19T10:44:38.743Z",
                  "reference_vipnet": "VIP-WNCYUQRHJW",
                  "commentaire": null,
                  "cree_le": "2026-10-19T10:44:38.362Z",
                  "modifie_le": "2026-10-19T10:44:38.743Z",
                  "contrat": {
                    "id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                    "numero": "CTR-2026-000029",
                    "statut": "projet",
                    "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2"
                  },
                  "site": {
                    "id": "b316b1ec-ecd3-463f-818b-1bccb8b94d69",
                    "libelle": "Siège",
                    "ville": "Abidjan",
                    "adresse": null
                  },
                  "connexion": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Cette connexion est déjà active.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "activations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/demandes-versement": {
      "post": {
        "operationId": "postDemandesVersement",
        "tags": [
          "Commissions"
        ],
        "summary": "Demander le versement de commissions",
        "description": "Le partenaire choisit des commissions et joint sa facture, qu’il a lui-même déposée (`POST /fichiers`) et qui a passé l’antivirus. Seules ses commissions « realisee » à montant net positif sont retenues, les autres écartées ; les retenues passent à « demandee » et la demande (numéro `DVS-…`) naît « soumise », au mode de versement choisi ou à celui du partenaire. Refusée si aucune commission n’est payable, si l’une d’elles figure déjà dans une demande en cours ou si le partenaire est suspendu. La réponse donne le nombre de commissions retenues et écartées, et le délai indicatif.\n\n**Permission requise** : `commissions.demander_versement`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "commission_ids": {
                    "minItems": 1,
                    "maxItems": 500,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  },
                  "facture_fichier_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "reference_facture": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "mode_versement": {
                    "type": "string",
                    "enum": [
                      "virement",
                      "mobile_money",
                      "wave"
                    ]
                  }
                },
                "required": [
                  "commission_ids",
                  "facture_fichier_id"
                ]
              },
              "example": {
                "commission_ids": [
                  "d08af5d0-eb96-4bc2-aebd-2abb211c3bcd"
                ],
                "facture_fichier_id": "eb1caf68-98e6-4439-8080-c0c5e21848ec",
                "reference_facture": "FAC-P-15CB4E4E"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "montant_total": {
                      "type": "integer"
                    },
                    "soumise_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "commissions_retenues": {
                      "type": "integer"
                    },
                    "commissions_ecartees": {
                      "type": "integer"
                    },
                    "delai_indicatif_heures": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "statut",
                    "montant_total",
                    "soumise_le",
                    "commissions_retenues",
                    "commissions_ecartees",
                    "delai_indicatif_heures"
                  ]
                },
                "example": {
                  "id": "e4a99d90-97c4-4756-8741-919a9f210b1d",
                  "numero": "DVS-2026-000010",
                  "statut": "soumise",
                  "montant_total": 4000,
                  "soumise_le": "2026-10-19T10:45:12.975Z",
                  "commissions_retenues": 1,
                  "commissions_ecartees": 0,
                  "delai_indicatif_heures": 48
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "commissions.demander_versement",
        "x-satelica-cloisonnement": "applique"
      },
      "get": {
        "operationId": "getDemandesVersement",
        "tags": [
          "Commissions"
        ],
        "summary": "Lister les demandes de versement",
        "description": "Demandes de versement, de la plus récente à la plus ancienne, filtrables par statut (plusieurs valeurs) et partenaire. Chaque ligne porte le partenaire, les coordonnées de versement selon le mode de la demande (RIB ou numéro mobile money), la facture du partenaire, les lignes de commission, les auteurs de chaque étape et `delai_restant_heures` (négatif une fois le délai dépassé, `null` hors « soumise » et « validee »).\n\n**Permission requise** : `commissions.consulter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "partenaire_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "montant_total": {
                            "type": "integer"
                          },
                          "facture_partenaire_fichier_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "soumise_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "soumise_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "validee_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "validee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "mode_versement": {
                            "type": "string"
                          },
                          "reference_versement": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "payee_par": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "payee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "mode_versement": {
                                "type": "string"
                              },
                              "rib": {
                                "type": "null"
                              },
                              "numero_mobile_money": {
                                "type": "null"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "ville",
                              "mode_versement",
                              "rib",
                              "numero_mobile_money"
                            ]
                          },
                          "coordonnees_versement": {
                            "type": "null"
                          },
                          "delai_restant_heures": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "facture_partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "bucket": {
                                "type": "string"
                              },
                              "chemin": {
                                "type": "string"
                              },
                              "nom_original": {
                                "type": "string"
                              },
                              "type_mime": {
                                "type": "string"
                              },
                              "taille_octets": {
                                "type": "integer"
                              },
                              "empreinte_sha256": {
                                "type": "string"
                              },
                              "statut_scan": {
                                "type": "string"
                              },
                              "depose_par": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "bucket",
                              "chemin",
                              "nom_original",
                              "type_mime",
                              "taille_octets",
                              "empreinte_sha256",
                              "statut_scan",
                              "depose_par",
                              "cree_le"
                            ]
                          },
                          "lignes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "commission_id": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "montant": {
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "commission_id",
                                "montant"
                              ]
                            }
                          },
                          "nb_commissions": {
                            "type": "integer"
                          },
                          "soumise_par_utilisateur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "validee_par_utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "payee_par_utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "partenaire_id",
                          "montant_total",
                          "facture_partenaire_fichier_id",
                          "statut",
                          "soumise_par",
                          "soumise_le",
                          "validee_par",
                          "validee_le",
                          "mode_versement",
                          "reference_versement",
                          "payee_par",
                          "payee_le",
                          "cree_le",
                          "modifie_le",
                          "partenaire",
                          "coordonnees_versement",
                          "delai_restant_heures",
                          "facture_partenaire",
                          "lignes",
                          "nb_commissions",
                          "soumise_par_utilisateur",
                          "validee_par_utilisateur",
                          "payee_par_utilisateur"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "a25d9ddb-15d7-4837-9c0b-e467e0e22743",
                      "numero": "DVS-2026-000011",
                      "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                      "montant_total": 4000,
                      "facture_partenaire_fichier_id": "274a7f0a-aa5c-42e0-897d-5f31d4bfdfd6",
                      "statut": "soumise",
                      "soumise_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                      "soumise_le": "2026-10-19T10:45:54.495Z",
                      "validee_par": null,
                      "validee_le": null,
                      "mode_versement": "virement",
                      "reference_versement": null,
                      "payee_par": null,
                      "payee_le": null,
                      "cree_le": "2026-10-19T10:45:54.495Z",
                      "modifie_le": "2026-10-19T10:45:54.495Z",
                      "partenaire": {
                        "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                        "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                        "statut": "actif",
                        "ville": "Abidjan",
                        "mode_versement": "virement",
                        "rib": null,
                        "numero_mobile_money": null
                      },
                      "coordonnees_versement": null,
                      "delai_restant_heures": 48,
                      "facture_partenaire": {
                        "id": "274a7f0a-aa5c-42e0-897d-5f31d4bfdfd6",
                        "bucket": "paiements",
                        "chemin": "paiements/2026/10/4bfcb4ae-7153-45d7-acd4-5833c8e0e254.pdf",
                        "nom_original": "piece.pdf",
                        "type_mime": "application/pdf",
                        "taille_octets": 192,
                        "empreinte_sha256": "9eb33abcffd14da9ff93ad8cc9c73ddd5ec0dc4c2d186315f0a2b0a9375ca479",
                        "statut_scan": "sain",
                        "depose_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                        "cree_le": "2026-10-19T10:45:54.366Z"
                      },
                      "lignes": [
                        {
                          "commission_id": "3cf3d7bc-d6be-4da3-a4eb-067155733dca",
                          "montant": 4000
                        }
                      ],
                      "nb_commissions": 1,
                      "soumise_par_utilisateur": {
                        "id": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A 856174D4",
                        "email": "zz.recette.856174d4@exemple.invalide"
                      },
                      "validee_par_utilisateur": null,
                      "payee_par_utilisateur": null
                    },
                    {
                      "id": "e4a99d90-97c4-4756-8741-919a9f210b1d",
                      "numero": "DVS-2026-000010",
                      "partenaire_id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                      "montant_total": 4000,
                      "facture_partenaire_fichier_id": "eb1caf68-98e6-4439-8080-c0c5e21848ec",
                      "statut": "payee",
                      "soumise_par": "10d90c38-c562-44ac-8908-a67fd6f725e4",
                      "soumise_le": "2026-10-19T10:45:12.975Z",
                      "validee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "validee_le": "2026-10-19T10:45:13.113Z",
                      "mode_versement": "virement",
                      "reference_versement": "VIR-ZZR-90ED956D",
                      "payee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "payee_le": "2026-10-19T10:45:13.259Z",
                      "cree_le": "2026-10-19T10:45:12.976Z",
                      "modifie_le": "2026-10-19T10:45:13.258Z",
                      "partenaire": {
                        "id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                        "raison_sociale": "ZZ Recette Partenaire A 137E8405",
                        "statut": "actif",
                        "ville": "Yamoussoukro",
                        "mode_versement": "virement",
                        "rib": null,
                        "numero_mobile_money": null
                      },
                      "coordonnees_versement": null,
                      "delai_restant_heures": null,
                      "facture_partenaire": {
                        "id": "eb1caf68-98e6-4439-8080-c0c5e21848ec",
                        "bucket": "versements",
                        "chemin": "versements/2026/10/df08ef05-2f37-4acf-9ce7-62e28b192f15.pdf",
                        "nom_original": "facture-commission.pdf",
                        "type_mime": "application/pdf",
                        "taille_octets": 225,
                        "empreinte_sha256": "825a17db070d91b3393e3f8fb7337220ba3e32b6237135d5a5cb53dae2d29316",
                        "statut_scan": "sain",
                        "depose_par": "10d90c38-c562-44ac-8908-a67fd6f725e4",
                        "cree_le": "2026-10-19T10:45:12.845Z"
                      },
                      "lignes": [
                        {
                          "commission_id": "d08af5d0-eb96-4bc2-aebd-2abb211c3bcd",
                          "montant": 4000
                        }
                      ],
                      "nb_commissions": 1,
                      "soumise_par_utilisateur": {
                        "id": "10d90c38-c562-44ac-8908-a67fd6f725e4",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A 137E8405",
                        "email": "zz.recette.137e8405@exemple.invalide"
                      },
                      "validee_par_utilisateur": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction",
                        "email": "admin.cybastion@preprod.satelica.test"
                      },
                      "payee_par_utilisateur": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction",
                        "email": "admin.cybastion@preprod.satelica.test"
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 4,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "commissions.consulter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/commissions": {
      "get": {
        "operationId": "getCommissions",
        "tags": [
          "Commissions"
        ],
        "summary": "Lister les commissions",
        "description": "Commissions des partenaires, de la plus récente à la plus ancienne, filtrables par statut (plusieurs valeurs), partenaire, commande et type de ligne. Chaque ligne porte le taux appliqué (celui du fait générateur), les montants latent, réalisé et annulé, le `montant_payable`, le partenaire, la commande, le contrat, la ligne de devis d’origine et la règle de commission.\n\n**Permission requise** : `commissions.consulter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "partenaire_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "commande_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "type_ligne",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "equipement",
                "installation",
                "forfait_data"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 13 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "commande_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "contrat_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "devis_ligne_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "regle_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type_ligne": {
                            "type": "string"
                          },
                          "base_ht": {
                            "type": "integer"
                          },
                          "taux_applique": {
                            "type": "integer"
                          },
                          "majoree": {
                            "type": "boolean"
                          },
                          "montant_latent": {
                            "type": "integer"
                          },
                          "montant_realise": {
                            "type": "integer"
                          },
                          "montant_annule": {
                            "type": "integer"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "realisee_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "ville": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut",
                              "ville"
                            ]
                          },
                          "commande": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          },
                          "contrat": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          },
                          "montant_payable": {
                            "type": "integer"
                          },
                          "devis_ligne": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "quantite": {
                                "type": "integer"
                              },
                              "prix_unitaire_ht": {
                                "type": "integer"
                              },
                              "remise_pct": {
                                "type": "integer"
                              },
                              "montant_ht": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "id",
                              "libelle",
                              "quantite",
                              "prix_unitaire_ht",
                              "remise_pct",
                              "montant_ht"
                            ]
                          },
                          "devis": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          },
                          "regle": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "rang_vente": {
                                "type": "string"
                              },
                              "taux_base": {
                                "type": "integer"
                              },
                              "taux_majore": {
                                "type": "integer"
                              },
                              "seuil_montant": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "id",
                              "rang_vente",
                              "taux_base",
                              "taux_majore",
                              "seuil_montant"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "partenaire_id",
                          "commande_id",
                          "contrat_id",
                          "devis_ligne_id",
                          "regle_id",
                          "type_ligne",
                          "base_ht",
                          "taux_applique",
                          "majoree",
                          "montant_latent",
                          "montant_realise",
                          "montant_annule",
                          "statut",
                          "realisee_le",
                          "cree_le",
                          "modifie_le",
                          "partenaire",
                          "commande",
                          "contrat",
                          "montant_payable",
                          "devis_ligne",
                          "devis",
                          "regle"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "46a7e9ab-fddf-4f64-bcd2-d5efc7be7227",
                      "partenaire_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                      "commande_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                      "contrat_id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                      "devis_ligne_id": "f9e6b4e9-3309-4a0c-838a-4fb68548bcb2",
                      "regle_id": "ff96d34b-b693-4e56-8fda-4c49ac0ed07e",
                      "type_ligne": "forfait_data",
                      "base_ht": 20000,
                      "taux_applique": 20,
                      "majoree": false,
                      "montant_latent": 4000,
                      "montant_realise": 0,
                      "montant_annule": 0,
                      "statut": "latente",
                      "realisee_le": null,
                      "cree_le": "2026-10-19T10:44:31.936Z",
                      "modifie_le": "2026-10-19T10:44:31.936Z",
                      "partenaire": {
                        "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                        "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                        "statut": "actif",
                        "ville": "Abidjan"
                      },
                      "commande": {
                        "id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                        "numero": "CMD-2026-000029",
                        "statut": "attente_paiement"
                      },
                      "contrat": {
                        "id": "bbeb3255-beb0-4078-ab20-8c910e33fb67",
                        "numero": "CTR-2026-000029",
                        "statut": "projet"
                      },
                      "montant_payable": 0,
                      "devis_ligne": {
                        "id": "f9e6b4e9-3309-4a0c-838a-4fb68548bcb2",
                        "libelle": "Forfait 50 Go hebdomadaire",
                        "quantite": 1,
                        "prix_unitaire_ht": 20000,
                        "remise_pct": 0,
                        "montant_ht": 20000
                      },
                      "devis": {
                        "id": "52764ad5-f498-419d-8732-f7aaf13cb517",
                        "numero": "DEV-2026-000061",
                        "statut": "signe"
                      },
                      "regle": {
                        "id": "ff96d34b-b693-4e56-8fda-4c49ac0ed07e",
                        "rang_vente": "premiere_vente",
                        "taux_base": 20,
                        "taux_majore": 22,
                        "seuil_montant": 25000000
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 50,
                    "total": 1,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "commissions.consulter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/commissions/totaux": {
      "get": {
        "operationId": "getCommissionsTotaux",
        "tags": [
          "Commissions"
        ],
        "summary": "Lire les totaux de commission",
        "description": "Montants et nombres de commissions par statut, avec le payable, ventilés par partenaire et par mois de création, sur une période (`du`, `au`, bornes incluses) et un partenaire facultatifs. Chaque statut compte le montant qui lui correspond : le latent pour une commission latente, le réalisé pour les suivantes. Tout est recalculé depuis les lignes.\n\n**Permission requise** : `commissions.consulter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "partenaire_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "du",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          },
          {
            "name": "au",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "latente": {
                      "type": "integer"
                    },
                    "realisee": {
                      "type": "integer"
                    },
                    "demandee": {
                      "type": "integer"
                    },
                    "payee": {
                      "type": "integer"
                    },
                    "annulee": {
                      "type": "integer"
                    },
                    "payable": {
                      "type": "integer"
                    },
                    "nombre": {
                      "type": "object",
                      "properties": {
                        "latente": {
                          "type": "integer"
                        },
                        "realisee": {
                          "type": "integer"
                        },
                        "demandee": {
                          "type": "integer"
                        },
                        "payee": {
                          "type": "integer"
                        },
                        "annulee": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "latente",
                        "realisee",
                        "demandee",
                        "payee",
                        "annulee"
                      ]
                    },
                    "par_partenaire": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "latente": {
                            "type": "integer"
                          },
                          "realisee": {
                            "type": "integer"
                          },
                          "demandee": {
                            "type": "integer"
                          },
                          "payee": {
                            "type": "integer"
                          },
                          "annulee": {
                            "type": "integer"
                          },
                          "payable": {
                            "type": "integer"
                          },
                          "partenaire": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut"
                            ]
                          }
                        },
                        "required": [
                          "latente",
                          "realisee",
                          "demandee",
                          "payee",
                          "annulee",
                          "payable",
                          "partenaire"
                        ]
                      }
                    },
                    "par_mois": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "mois": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "latente": {
                            "type": "integer"
                          },
                          "realisee": {
                            "type": "integer"
                          },
                          "payee": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "mois",
                          "libelle",
                          "latente",
                          "realisee",
                          "payee"
                        ]
                      }
                    }
                  },
                  "required": [
                    "latente",
                    "realisee",
                    "demandee",
                    "payee",
                    "annulee",
                    "payable",
                    "nombre",
                    "par_partenaire",
                    "par_mois"
                  ]
                },
                "example": {
                  "latente": 26000,
                  "realisee": 20000,
                  "demandee": 0,
                  "payee": 12000,
                  "annulee": 3000,
                  "payable": 17000,
                  "nombre": {
                    "latente": 9,
                    "realisee": 5,
                    "demandee": 0,
                    "payee": 3,
                    "annulee": 0
                  },
                  "par_partenaire": [
                    {
                      "latente": 0,
                      "realisee": 4000,
                      "demandee": 0,
                      "payee": 0,
                      "annulee": 1000,
                      "payable": 3000,
                      "partenaire": {
                        "id": "52db68b6-26de-4043-8665-8371b95672a7",
                        "raison_sociale": "ZZ Recette Partenaire A 0CB9B2BD",
                        "statut": "actif"
                      }
                    },
                    {
                      "latente": 0,
                      "realisee": 4000,
                      "demandee": 0,
                      "payee": 0,
                      "annulee": 1000,
                      "payable": 3000,
                      "partenaire": {
                        "id": "3c83b6db-00e2-4bdb-98ea-cb986c7b10e3",
                        "raison_sociale": "ZZ Recette Partenaire A 3E0115E1",
                        "statut": "actif"
                      }
                    }
                  ],
                  "par_mois": [
                    {
                      "mois": "2026-10",
                      "libelle": "octobre 2026",
                      "latente": 26000,
                      "realisee": 20000,
                      "payee": 12000
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "commissions.consulter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/commissions/{id}": {
      "get": {
        "operationId": "getCommissionsParId",
        "tags": [
          "Commissions"
        ],
        "summary": "Lire la fiche d'une commission",
        "description": "La commission présentée comme dans la liste (mêmes montants, ligne de devis et règle d’origine), avec les demandes de versement qui la portent.\n\n**Permission requise** : `commissions.consulter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "commande_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contrat_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "devis_ligne_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "regle_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type_ligne": {
                      "type": "string"
                    },
                    "base_ht": {
                      "type": "integer"
                    },
                    "taux_applique": {
                      "type": "integer"
                    },
                    "majoree": {
                      "type": "boolean"
                    },
                    "montant_latent": {
                      "type": "integer"
                    },
                    "montant_realise": {
                      "type": "integer"
                    },
                    "montant_annule": {
                      "type": "integer"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "realisee_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville"
                      ]
                    },
                    "commande": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "contrat": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "montant_payable": {
                      "type": "integer"
                    },
                    "devis_ligne": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "quantite": {
                          "type": "integer"
                        },
                        "prix_unitaire_ht": {
                          "type": "integer"
                        },
                        "remise_pct": {
                          "type": "integer"
                        },
                        "montant_ht": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "id",
                        "libelle",
                        "quantite",
                        "prix_unitaire_ht",
                        "remise_pct",
                        "montant_ht"
                      ]
                    },
                    "devis": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "regle": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "rang_vente": {
                          "type": "string"
                        },
                        "taux_base": {
                          "type": "integer"
                        },
                        "taux_majore": {
                          "type": "integer"
                        },
                        "seuil_montant": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "id",
                        "rang_vente",
                        "taux_base",
                        "taux_majore",
                        "seuil_montant"
                      ]
                    },
                    "versements": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "montant": {
                            "type": "integer"
                          },
                          "demande": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "reference_versement": {
                                "type": "null"
                              },
                              "payee_le": {
                                "type": "null"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut",
                              "reference_versement",
                              "payee_le",
                              "cree_le"
                            ]
                          }
                        },
                        "required": [
                          "montant",
                          "demande"
                        ]
                      }
                    }
                  },
                  "required": [
                    "id",
                    "partenaire_id",
                    "commande_id",
                    "contrat_id",
                    "devis_ligne_id",
                    "regle_id",
                    "type_ligne",
                    "base_ht",
                    "taux_applique",
                    "majoree",
                    "montant_latent",
                    "montant_realise",
                    "montant_annule",
                    "statut",
                    "realisee_le",
                    "cree_le",
                    "modifie_le",
                    "partenaire",
                    "commande",
                    "contrat",
                    "montant_payable",
                    "devis_ligne",
                    "devis",
                    "regle",
                    "versements"
                  ]
                },
                "example": {
                  "id": "3cf3d7bc-d6be-4da3-a4eb-067155733dca",
                  "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                  "commande_id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                  "contrat_id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                  "devis_ligne_id": "437c2d7e-ccfb-4f0d-b15a-7c8ebfba82c1",
                  "regle_id": "ff96d34b-b693-4e56-8fda-4c49ac0ed07e",
                  "type_ligne": "forfait_data",
                  "base_ht": 20000,
                  "taux_applique": 20,
                  "majoree": false,
                  "montant_latent": 4000,
                  "montant_realise": 4000,
                  "montant_annule": 169,
                  "statut": "demandee",
                  "realisee_le": "2026-10-19T10:45:49.157Z",
                  "cree_le": "2026-10-19T10:45:45.752Z",
                  "modifie_le": "2026-10-19T10:45:56.696Z",
                  "partenaire": {
                    "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                    "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                    "statut": "actif",
                    "ville": "Abidjan"
                  },
                  "commande": {
                    "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                    "numero": "CMD-2026-000032",
                    "statut": "active"
                  },
                  "contrat": {
                    "id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                    "numero": "CTR-2026-000032",
                    "statut": "actif"
                  },
                  "montant_payable": 0,
                  "devis_ligne": {
                    "id": "437c2d7e-ccfb-4f0d-b15a-7c8ebfba82c1",
                    "libelle": "Forfait 50 Go hebdomadaire",
                    "quantite": 1,
                    "prix_unitaire_ht": 20000,
                    "remise_pct": 0,
                    "montant_ht": 20000
                  },
                  "devis": {
                    "id": "21ff2ce1-1c6c-4f56-86b2-d0a0600b829b",
                    "numero": "DEV-2026-000067",
                    "statut": "signe"
                  },
                  "regle": {
                    "id": "ff96d34b-b693-4e56-8fda-4c49ac0ed07e",
                    "rang_vente": "premiere_vente",
                    "taux_base": 20,
                    "taux_majore": 22,
                    "seuil_montant": 25000000
                  },
                  "versements": [
                    {
                      "montant": 4000,
                      "demande": {
                        "id": "a25d9ddb-15d7-4837-9c0b-e467e0e22743",
                        "numero": "DVS-2026-000011",
                        "statut": "soumise",
                        "reference_versement": null,
                        "payee_le": null,
                        "cree_le": "2026-10-19T10:45:54.495Z"
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "commissions.consulter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/commissions/gains": {
      "get": {
        "operationId": "getCommissionsGains",
        "tags": [
          "Commissions"
        ],
        "summary": "Lire les gains d'un partenaire",
        "description": "Commissions latente, réalisée, annulée, perçue (versements payés) et payable (réalisée − perçue − annulée), chiffre d’affaires HT vendu, facturé et encaissé, et la série des douze derniers mois. Un partenaire est toujours ramené à son propre dossier : un `partenaire_id` désignant un autre est refusé comme introuvable. CYBASTION précise `partenaire_id`, ou obtient sans lui l’ensemble du réseau (`portee: reseau`).\n\n**Permission requise** : `commissions.consulter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "partenaire_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 5 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "partenaire_id": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "portee": {
                      "type": "string"
                    },
                    "ca_ht": {
                      "type": "object",
                      "properties": {
                        "vendu": {
                          "type": "integer"
                        },
                        "facture": {
                          "type": "integer"
                        },
                        "paye": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "vendu",
                        "facture",
                        "paye"
                      ]
                    },
                    "nb_commandes": {
                      "type": "integer"
                    },
                    "commission_latente": {
                      "type": "integer"
                    },
                    "commission_realisee": {
                      "type": "integer"
                    },
                    "commission_annulee": {
                      "type": "integer"
                    },
                    "commission_percue": {
                      "type": "integer"
                    },
                    "commission_payable": {
                      "type": "integer"
                    },
                    "nb_commissions": {
                      "type": "integer"
                    },
                    "par_mois": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "mois": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "latente": {
                            "type": "integer"
                          },
                          "realisee": {
                            "type": "integer"
                          },
                          "payee": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "mois",
                          "libelle",
                          "latente",
                          "realisee",
                          "payee"
                        ]
                      }
                    },
                    "formule": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "partenaire_id",
                    "portee",
                    "ca_ht",
                    "nb_commandes",
                    "commission_latente",
                    "commission_realisee",
                    "commission_annulee",
                    "commission_percue",
                    "commission_payable",
                    "nb_commissions",
                    "par_mois",
                    "formule"
                  ]
                },
                "example": {
                  "partenaire_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                  "portee": "partenaire",
                  "ca_ht": {
                    "vendu": 20000,
                    "facture": 0,
                    "paye": 10000
                  },
                  "nb_commandes": 1,
                  "commission_latente": 4000,
                  "commission_realisee": 2000,
                  "commission_annulee": 0,
                  "commission_percue": 0,
                  "commission_payable": 2000,
                  "nb_commissions": 1,
                  "par_mois": [
                    {
                      "mois": "2025-11",
                      "libelle": "novembre 2025",
                      "latente": 0,
                      "realisee": 0,
                      "payee": 0
                    },
                    {
                      "mois": "2025-12",
                      "libelle": "décembre 2025",
                      "latente": 0,
                      "realisee": 0,
                      "payee": 0
                    }
                  ],
                  "formule": "payable = réalisée − déjà perçue − annulée"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "commissions.consulter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/demandes-versement/{id}": {
      "get": {
        "operationId": "getDemandesVersementParId",
        "tags": [
          "Commissions"
        ],
        "summary": "Lire la fiche d'une demande de versement",
        "description": "La demande avec son partenaire, ses coordonnées de versement, la facture du partenaire, le délai restant et chacune de ses commissions présentée en entier.\n\n**Permission requise** : `commissions.consulter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "montant_total": {
                      "type": "integer"
                    },
                    "facture_partenaire_fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "soumise_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "soumise_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "validee_par": {
                      "type": "null"
                    },
                    "validee_le": {
                      "type": "null"
                    },
                    "mode_versement": {
                      "type": "string"
                    },
                    "reference_versement": {
                      "type": "null"
                    },
                    "payee_par": {
                      "type": "null"
                    },
                    "payee_le": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        },
                        "mode_versement": {
                          "type": "string"
                        },
                        "rib": {
                          "type": "null"
                        },
                        "numero_mobile_money": {
                          "type": "null"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville",
                        "mode_versement",
                        "rib",
                        "numero_mobile_money"
                      ]
                    },
                    "coordonnees_versement": {
                      "type": "null"
                    },
                    "delai_restant_heures": {
                      "type": "integer"
                    },
                    "facture_partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "bucket": {
                          "type": "string"
                        },
                        "chemin": {
                          "type": "string"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        },
                        "taille_octets": {
                          "type": "integer"
                        },
                        "empreinte_sha256": {
                          "type": "string"
                        },
                        "statut_scan": {
                          "type": "string"
                        },
                        "depose_par": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "cree_le": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "bucket",
                        "chemin",
                        "nom_original",
                        "type_mime",
                        "taille_octets",
                        "empreinte_sha256",
                        "statut_scan",
                        "depose_par",
                        "cree_le"
                      ]
                    },
                    "lignes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "commission_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "montant": {
                            "type": "integer"
                          },
                          "commission": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "partenaire_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "commande_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "contrat_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "devis_ligne_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "regle_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "type_ligne": {
                                "type": "string"
                              },
                              "base_ht": {
                                "type": "integer"
                              },
                              "taux_applique": {
                                "type": "integer"
                              },
                              "majoree": {
                                "type": "boolean"
                              },
                              "montant_latent": {
                                "type": "integer"
                              },
                              "montant_realise": {
                                "type": "integer"
                              },
                              "montant_annule": {
                                "type": "integer"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "realisee_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "partenaire": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "raison_sociale": {
                                    "type": "string"
                                  },
                                  "statut": {
                                    "type": "string"
                                  },
                                  "ville": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "raison_sociale",
                                  "statut",
                                  "ville"
                                ]
                              },
                              "commande": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "numero": {
                                    "type": "string"
                                  },
                                  "statut": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "numero",
                                  "statut"
                                ]
                              },
                              "contrat": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "numero": {
                                    "type": "string"
                                  },
                                  "statut": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "numero",
                                  "statut"
                                ]
                              },
                              "montant_payable": {
                                "type": "integer"
                              },
                              "devis_ligne": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "libelle": {
                                    "type": "string"
                                  },
                                  "quantite": {
                                    "type": "integer"
                                  },
                                  "prix_unitaire_ht": {
                                    "type": "integer"
                                  },
                                  "remise_pct": {
                                    "type": "integer"
                                  },
                                  "montant_ht": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "id",
                                  "libelle",
                                  "quantite",
                                  "prix_unitaire_ht",
                                  "remise_pct",
                                  "montant_ht"
                                ]
                              },
                              "devis": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "numero": {
                                    "type": "string"
                                  },
                                  "statut": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "numero",
                                  "statut"
                                ]
                              },
                              "regle": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "rang_vente": {
                                    "type": "string"
                                  },
                                  "taux_base": {
                                    "type": "integer"
                                  },
                                  "taux_majore": {
                                    "type": "integer"
                                  },
                                  "seuil_montant": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "id",
                                  "rang_vente",
                                  "taux_base",
                                  "taux_majore",
                                  "seuil_montant"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "partenaire_id",
                              "commande_id",
                              "contrat_id",
                              "devis_ligne_id",
                              "regle_id",
                              "type_ligne",
                              "base_ht",
                              "taux_applique",
                              "majoree",
                              "montant_latent",
                              "montant_realise",
                              "montant_annule",
                              "statut",
                              "realisee_le",
                              "cree_le",
                              "modifie_le",
                              "partenaire",
                              "commande",
                              "contrat",
                              "montant_payable",
                              "devis_ligne",
                              "devis",
                              "regle"
                            ]
                          }
                        },
                        "required": [
                          "commission_id",
                          "montant",
                          "commission"
                        ]
                      }
                    },
                    "nb_commissions": {
                      "type": "integer"
                    },
                    "soumise_par_utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "validee_par_utilisateur": {
                      "type": "null"
                    },
                    "payee_par_utilisateur": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "partenaire_id",
                    "montant_total",
                    "facture_partenaire_fichier_id",
                    "statut",
                    "soumise_par",
                    "soumise_le",
                    "validee_par",
                    "validee_le",
                    "mode_versement",
                    "reference_versement",
                    "payee_par",
                    "payee_le",
                    "cree_le",
                    "modifie_le",
                    "partenaire",
                    "coordonnees_versement",
                    "delai_restant_heures",
                    "facture_partenaire",
                    "lignes",
                    "nb_commissions",
                    "soumise_par_utilisateur",
                    "validee_par_utilisateur",
                    "payee_par_utilisateur"
                  ]
                },
                "example": {
                  "id": "a25d9ddb-15d7-4837-9c0b-e467e0e22743",
                  "numero": "DVS-2026-000011",
                  "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                  "montant_total": 4000,
                  "facture_partenaire_fichier_id": "274a7f0a-aa5c-42e0-897d-5f31d4bfdfd6",
                  "statut": "soumise",
                  "soumise_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                  "soumise_le": "2026-10-19T10:45:54.495Z",
                  "validee_par": null,
                  "validee_le": null,
                  "mode_versement": "virement",
                  "reference_versement": null,
                  "payee_par": null,
                  "payee_le": null,
                  "cree_le": "2026-10-19T10:45:54.495Z",
                  "modifie_le": "2026-10-19T10:45:54.495Z",
                  "partenaire": {
                    "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                    "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                    "statut": "actif",
                    "ville": "Abidjan",
                    "mode_versement": "virement",
                    "rib": null,
                    "numero_mobile_money": null
                  },
                  "coordonnees_versement": null,
                  "delai_restant_heures": 48,
                  "facture_partenaire": {
                    "id": "274a7f0a-aa5c-42e0-897d-5f31d4bfdfd6",
                    "bucket": "paiements",
                    "chemin": "paiements/2026/10/4bfcb4ae-7153-45d7-acd4-5833c8e0e254.pdf",
                    "nom_original": "piece.pdf",
                    "type_mime": "application/pdf",
                    "taille_octets": 192,
                    "empreinte_sha256": "9eb33abcffd14da9ff93ad8cc9c73ddd5ec0dc4c2d186315f0a2b0a9375ca479",
                    "statut_scan": "sain",
                    "depose_par": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                    "cree_le": "2026-10-19T10:45:54.366Z"
                  },
                  "lignes": [
                    {
                      "commission_id": "3cf3d7bc-d6be-4da3-a4eb-067155733dca",
                      "montant": 4000,
                      "commission": {
                        "id": "3cf3d7bc-d6be-4da3-a4eb-067155733dca",
                        "partenaire_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                        "commande_id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                        "contrat_id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                        "devis_ligne_id": "437c2d7e-ccfb-4f0d-b15a-7c8ebfba82c1",
                        "regle_id": "ff96d34b-b693-4e56-8fda-4c49ac0ed07e",
                        "type_ligne": "forfait_data",
                        "base_ht": 20000,
                        "taux_applique": 20,
                        "majoree": false,
                        "montant_latent": 4000,
                        "montant_realise": 4000,
                        "montant_annule": 169,
                        "statut": "demandee",
                        "realisee_le": "2026-10-19T10:45:49.157Z",
                        "cree_le": "2026-10-19T10:45:45.752Z",
                        "modifie_le": "2026-10-19T10:45:56.696Z",
                        "partenaire": {
                          "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                          "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                          "statut": "actif",
                          "ville": "Abidjan"
                        },
                        "commande": {
                          "id": "20a1afd7-d431-4f26-99d0-2b91371f2b67",
                          "numero": "CMD-2026-000032",
                          "statut": "active"
                        },
                        "contrat": {
                          "id": "93255a3a-882d-4140-89e4-f02f89f57c7a",
                          "numero": "CTR-2026-000032",
                          "statut": "actif"
                        },
                        "montant_payable": 0,
                        "devis_ligne": {
                          "id": "437c2d7e-ccfb-4f0d-b15a-7c8ebfba82c1",
                          "libelle": "Forfait 50 Go hebdomadaire",
                          "quantite": 1,
                          "prix_unitaire_ht": 20000,
                          "remise_pct": 0,
                          "montant_ht": 20000
                        },
                        "devis": {
                          "id": "21ff2ce1-1c6c-4f56-86b2-d0a0600b829b",
                          "numero": "DEV-2026-000067",
                          "statut": "signe"
                        },
                        "regle": {
                          "id": "ff96d34b-b693-4e56-8fda-4c49ac0ed07e",
                          "rang_vente": "premiere_vente",
                          "taux_base": 20,
                          "taux_majore": 22,
                          "seuil_montant": 25000000
                        }
                      }
                    }
                  ],
                  "nb_commissions": 1,
                  "soumise_par_utilisateur": {
                    "id": "535398fe-8a8f-453e-8109-7dd8adb42cab",
                    "prenom": "ZZ Recette",
                    "nom": "Partenaire A 856174D4",
                    "email": "zz.recette.856174d4@exemple.invalide"
                  },
                  "validee_par_utilisateur": null,
                  "payee_par_utilisateur": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "commissions.consulter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/demandes-versement/{id}/decision": {
      "post": {
        "operationId": "postDemandesVersementParIdDecision",
        "tags": [
          "Commissions"
        ],
        "summary": "Valider ou rejeter une demande de versement",
        "description": "CYBASTION fait passer une demande « soumise » à « validee » ou à « rejetee ». Un rejet exige un motif, inscrit avec la décision au journal d’audit ; une validation exige la facture du partenaire. Seule la demande change de statut : ses commissions restent « demandee ».\n\n**Permission requise** : `commissions.verser`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "validee",
                      "rejetee"
                    ]
                  },
                  "motif": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "validee"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "montant_total": {
                      "type": "integer"
                    },
                    "facture_partenaire_fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "soumise_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "soumise_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "validee_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "validee_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "mode_versement": {
                      "type": "string"
                    },
                    "reference_versement": {
                      "type": "string"
                    },
                    "payee_par": {
                      "type": "null"
                    },
                    "payee_le": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "partenaire_id",
                    "montant_total",
                    "facture_partenaire_fichier_id",
                    "statut",
                    "soumise_par",
                    "soumise_le",
                    "validee_par",
                    "validee_le",
                    "mode_versement",
                    "reference_versement",
                    "payee_par",
                    "payee_le",
                    "cree_le",
                    "modifie_le",
                    "partenaire"
                  ]
                },
                "example": {
                  "id": "e4a99d90-97c4-4756-8741-919a9f210b1d",
                  "numero": "DVS-2026-000010",
                  "partenaire_id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                  "montant_total": 4000,
                  "facture_partenaire_fichier_id": "eb1caf68-98e6-4439-8080-c0c5e21848ec",
                  "statut": "validee",
                  "soumise_par": "10d90c38-c562-44ac-8908-a67fd6f725e4",
                  "soumise_le": "2026-10-19T10:45:12.975Z",
                  "validee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "validee_le": "2026-10-19T10:45:13.113Z",
                  "mode_versement": "virement",
                  "reference_versement": "FAC-P-15CB4E4E",
                  "payee_par": null,
                  "payee_le": null,
                  "cree_le": "2026-10-19T10:45:12.976Z",
                  "modifie_le": "2026-10-19T10:45:13.113Z",
                  "partenaire": {
                    "id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                    "raison_sociale": "ZZ Recette Partenaire A 137E8405",
                    "statut": "actif",
                    "ville": "Yamoussoukro"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "commissions.verser",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/demandes-versement/{id}/versement": {
      "post": {
        "operationId": "postDemandesVersementParIdVersement",
        "tags": [
          "Commissions"
        ],
        "summary": "Enregistrer le versement d'une demande",
        "description": "Constate le paiement d’une demande « validee » avec la référence du mouvement : la demande et ses commissions passent à « payee », dans la même transaction. `mode_versement` ne sert qu’à corriger le mode retenu sur la demande. Le versement est journalisé.\n\n**Permission requise** : `commissions.verser`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reference_versement": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 150
                  },
                  "mode_versement": {
                    "type": "string",
                    "enum": [
                      "virement",
                      "mobile_money",
                      "wave"
                    ]
                  }
                },
                "required": [
                  "reference_versement"
                ]
              },
              "example": {
                "reference_versement": "VIR-ZZR-90ED956D"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "partenaire_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "montant_total": {
                      "type": "integer"
                    },
                    "facture_partenaire_fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "soumise_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "soumise_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "validee_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "validee_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "mode_versement": {
                      "type": "string"
                    },
                    "reference_versement": {
                      "type": "string"
                    },
                    "payee_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "payee_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "partenaire": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        },
                        "ville": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "statut",
                        "ville"
                      ]
                    },
                    "nb_commissions_payees": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "partenaire_id",
                    "montant_total",
                    "facture_partenaire_fichier_id",
                    "statut",
                    "soumise_par",
                    "soumise_le",
                    "validee_par",
                    "validee_le",
                    "mode_versement",
                    "reference_versement",
                    "payee_par",
                    "payee_le",
                    "cree_le",
                    "modifie_le",
                    "partenaire",
                    "nb_commissions_payees"
                  ]
                },
                "example": {
                  "id": "e4a99d90-97c4-4756-8741-919a9f210b1d",
                  "numero": "DVS-2026-000010",
                  "partenaire_id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                  "montant_total": 4000,
                  "facture_partenaire_fichier_id": "eb1caf68-98e6-4439-8080-c0c5e21848ec",
                  "statut": "payee",
                  "soumise_par": "10d90c38-c562-44ac-8908-a67fd6f725e4",
                  "soumise_le": "2026-10-19T10:45:12.975Z",
                  "validee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "validee_le": "2026-10-19T10:45:13.113Z",
                  "mode_versement": "virement",
                  "reference_versement": "VIR-ZZR-90ED956D",
                  "payee_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "payee_le": "2026-10-19T10:45:13.259Z",
                  "cree_le": "2026-10-19T10:45:12.976Z",
                  "modifie_le": "2026-10-19T10:45:13.258Z",
                  "partenaire": {
                    "id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                    "raison_sociale": "ZZ Recette Partenaire A 137E8405",
                    "statut": "actif",
                    "ville": "Yamoussoukro"
                  },
                  "nb_commissions_payees": 1
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "commissions.verser",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/tableaux-de-bord/tendance": {
      "get": {
        "operationId": "getTableauxDeBordTendance",
        "tags": [
          "Pilotage"
        ],
        "summary": "Lire la courbe mensuelle des partenaires et clients entrés",
        "description": "Le nombre de partenaires et de clients créés chaque mois, sur les `mois` derniers mois (12 par défaut, 36 au plus), mois en cours compris et mois sans entrée à zéro. Le comptage porte sur la date de création, jamais sur le statut courant. Réponse `{ donnees: [{ mois, libelle, partenaires, clients }] }`.\n\n**Permission requise** : `tableau_de_bord.consulter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "mois",
            "in": "query",
            "required": false,
            "schema": {
              "default": 12,
              "type": "integer",
              "minimum": 1,
              "maximum": 36
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "mois": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "partenaires": {
                            "type": "integer"
                          },
                          "clients": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "mois",
                          "libelle",
                          "partenaires",
                          "clients"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "mois": "2026-08",
                      "libelle": "août 2026",
                      "partenaires": 0,
                      "clients": 0
                    },
                    {
                      "mois": "2026-09",
                      "libelle": "septembre 2026",
                      "partenaires": 0,
                      "clients": 0
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "tableau_de_bord.consulter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/tableaux-de-bord/indicateurs": {
      "get": {
        "operationId": "getTableauxDeBordIndicateurs",
        "tags": [
          "Pilotage"
        ],
        "summary": "Lire les indicateurs du tableau de bord",
        "description": "Cinq indicateurs (partenaires actifs, clients, pièces KYC à vérifier, réservations à valider, CA HT signé du mois), chacun avec sa variation par rapport au mois précédent. S'y ajoutent la courbe mensuelle du CA HT signé depuis janvier, les ventes signées du mois, le CA HT du mois par partenaire et les pièces validées qui expirent dans le délai d'alerte réglé (`kyc.alerte_expiration_jours`). `performance_partenaires` est vide.\n\n**Permission requise** : `tableau_de_bord.consulter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "arrete_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "periode": {
                      "type": "object",
                      "properties": {
                        "mois": {
                          "type": "string"
                        },
                        "libelle": {
                          "type": "string"
                        },
                        "mois_precedent": {
                          "type": "string"
                        },
                        "libelle_mois_precedent": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "mois",
                        "libelle",
                        "mois_precedent",
                        "libelle_mois_precedent"
                      ]
                    },
                    "indicateurs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "valeur": {
                            "type": "integer"
                          },
                          "unite": {
                            "type": "string"
                          },
                          "complement": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "tendance": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "variation": {
                                "type": "integer"
                              },
                              "unite": {
                                "type": "string"
                              },
                              "sens": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "variation",
                              "unite",
                              "sens",
                              "libelle"
                            ]
                          }
                        },
                        "required": [
                          "code",
                          "libelle",
                          "valeur",
                          "unite",
                          "complement",
                          "tendance"
                        ]
                      }
                    },
                    "evolution_ca_ht": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "mois": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "libelle_court": {
                            "type": "string"
                          },
                          "montant_ht": {
                            "type": "integer"
                          },
                          "mois_en_cours": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "mois",
                          "libelle",
                          "libelle_court",
                          "montant_ht",
                          "mois_en_cours"
                        ]
                      }
                    },
                    "ventes_du_mois": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "site_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type_transaction": {
                            "type": "string"
                          },
                          "signe_le": {
                            "type": "string",
                            "format": "date"
                          },
                          "lignes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "libelle": {
                                  "type": "string"
                                },
                                "quantite": {
                                  "type": "integer"
                                },
                                "type_ligne": {
                                  "type": "string"
                                },
                                "montant_ht": {
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "libelle",
                                "quantite",
                                "type_ligne",
                                "montant_ht"
                              ]
                            }
                          }
                        },
                        "required": [
                          "client_id",
                          "partenaire_id",
                          "site_id",
                          "type_transaction",
                          "signe_le",
                          "lignes"
                        ]
                      }
                    },
                    "ca_ht_par_partenaire_mois": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "partenaire_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "montant_ht": {
                            "type": "integer"
                          },
                          "nb_ventes": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "partenaire_id",
                          "montant_ht",
                          "nb_ventes"
                        ]
                      }
                    },
                    "performance_partenaires": {
                      "type": "array",
                      "items": {}
                    },
                    "alertes_conformite": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "document_kyc_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "date_expiration": {
                            "type": "string",
                            "format": "date"
                          },
                          "jours_restants": {
                            "type": "integer"
                          },
                          "niveau": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "document_kyc_id",
                          "organisation_id",
                          "date_expiration",
                          "jours_restants",
                          "niveau"
                        ]
                      }
                    }
                  },
                  "required": [
                    "arrete_le",
                    "periode",
                    "indicateurs",
                    "evolution_ca_ht",
                    "ventes_du_mois",
                    "ca_ht_par_partenaire_mois",
                    "performance_partenaires",
                    "alertes_conformite"
                  ]
                },
                "example": {
                  "arrete_le": "2026-10-19T10:45:38.249Z",
                  "periode": {
                    "mois": "2026-10",
                    "libelle": "octobre 2026",
                    "mois_precedent": "2026-09",
                    "libelle_mois_precedent": "septembre 2026"
                  },
                  "indicateurs": [
                    {
                      "code": "partenaires_actifs",
                      "libelle": "Partenaires actifs",
                      "valeur": 22,
                      "unite": "nombre",
                      "complement": null,
                      "tendance": {
                        "variation": 22,
                        "unite": "nombre",
                        "sens": "hausse",
                        "libelle": "par rapport à septembre 2026"
                      }
                    },
                    {
                      "code": "clients",
                      "libelle": "Clients",
                      "valeur": 17,
                      "unite": "nombre",
                      "complement": "dont 3 actifs",
                      "tendance": {
                        "variation": 17,
                        "unite": "nombre",
                        "sens": "hausse",
                        "libelle": "par rapport à septembre 2026"
                      }
                    }
                  ],
                  "evolution_ca_ht": [
                    {
                      "mois": "2026-01",
                      "libelle": "janvier 2026",
                      "libelle_court": "janv.",
                      "montant_ht": 0,
                      "mois_en_cours": false
                    },
                    {
                      "mois": "2026-02",
                      "libelle": "février 2026",
                      "libelle_court": "févr.",
                      "montant_ht": 0,
                      "mois_en_cours": false
                    }
                  ],
                  "ventes_du_mois": [
                    {
                      "client_id": "5ab0a2a8-702b-442f-be2b-9a12fa524311",
                      "partenaire_id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                      "site_id": "83b0497e-9931-4957-a633-225afa68ab61",
                      "type_transaction": "nouveau_besoin",
                      "signe_le": "2026-10-19",
                      "lignes": [
                        {
                          "libelle": "Forfait 50 Go hebdomadaire",
                          "quantite": 1,
                          "type_ligne": "forfait_data",
                          "montant_ht": 20000
                        }
                      ]
                    },
                    {
                      "client_id": "72439d3d-0a08-4379-8a59-cd1192e1c8d1",
                      "partenaire_id": "52db68b6-26de-4043-8665-8371b95672a7",
                      "site_id": "23df7d64-7c63-4b5f-be5e-f0470d712782",
                      "type_transaction": "nouveau_besoin",
                      "signe_le": "2026-10-19",
                      "lignes": [
                        {
                          "libelle": "Forfait 50 Go hebdomadaire",
                          "quantite": 1,
                          "type_ligne": "forfait_data",
                          "montant_ht": 20000
                        }
                      ]
                    }
                  ],
                  "ca_ht_par_partenaire_mois": [
                    {
                      "partenaire_id": "62eb4451-c1de-4ae4-9188-7a856426f7a6",
                      "montant_ht": 20000,
                      "nb_ventes": 1
                    },
                    {
                      "partenaire_id": "52db68b6-26de-4043-8665-8371b95672a7",
                      "montant_ht": 20000,
                      "nb_ventes": 1
                    }
                  ],
                  "performance_partenaires": [],
                  "alertes_conformite": [
                    {
                      "document_kyc_id": "de160087-4ca3-4d2b-af65-311778e7b100",
                      "organisation_id": "a97aac5d-459c-4c08-a60a-2f6b09d51af1",
                      "date_expiration": "2026-10-29",
                      "jours_restants": 10,
                      "niveau": "critique"
                    },
                    {
                      "document_kyc_id": "b941a1f0-db98-430a-ac43-3dce3dfe004e",
                      "organisation_id": "940332f6-b108-47ff-b65d-d60e63a87a20",
                      "date_expiration": "2026-10-29",
                      "jours_restants": 10,
                      "niveau": "critique"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "tableau_de_bord.consulter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/tableaux-de-bord/orientation": {
      "get": {
        "operationId": "getTableauxDeBordOrientation",
        "tags": [
          "Pilotage"
        ],
        "summary": "Lire les compteurs des tuiles d'orientation",
        "description": "Les compteurs des tuiles du tableau de bord, comptés en base sous les clés des tuiles (`11` à `44`) : opportunités à vérifier, devis envoyés, commandes en attente de paiement, paiements à valider, factures en retard, versements à traiter, pièces à vérifier, partenaires en référencement, réservations à valider ou en conflit, clients sans partenaire, ordres à envoyer ou en retard, PV chargés. Avec les pièces validées qui expirent sous les seuils critique et d’alerte réglés en paramètres.\n\n**Permission requise** : `tableau_de_bord.consulter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "compteurs": {
                      "type": "object",
                      "properties": {
                        "11": {
                          "type": "integer"
                        },
                        "12": {
                          "type": "integer"
                        },
                        "13": {
                          "type": "integer"
                        },
                        "21": {
                          "type": "integer"
                        },
                        "22": {
                          "type": "integer"
                        },
                        "23": {
                          "type": "integer"
                        },
                        "31": {
                          "type": "integer"
                        },
                        "32": {
                          "type": "integer"
                        },
                        "33": {
                          "type": "integer"
                        },
                        "34": {
                          "type": "integer"
                        },
                        "41": {
                          "type": "integer"
                        },
                        "42": {
                          "type": "integer"
                        },
                        "43": {
                          "type": "integer"
                        },
                        "44": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "11",
                        "12",
                        "13",
                        "21",
                        "22",
                        "23",
                        "31",
                        "32",
                        "33",
                        "34",
                        "41",
                        "42",
                        "43",
                        "44"
                      ]
                    },
                    "expirations": {
                      "type": "object",
                      "properties": {
                        "sous10": {
                          "type": "integer"
                        },
                        "sous30": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "sous10",
                        "sous30"
                      ]
                    },
                    "seuils": {
                      "type": "object",
                      "properties": {
                        "critique": {
                          "type": "integer"
                        },
                        "alerte": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "critique",
                        "alerte"
                      ]
                    }
                  },
                  "required": [
                    "compteurs",
                    "expirations",
                    "seuils"
                  ]
                },
                "example": {
                  "compteurs": {
                    "11": 36,
                    "12": 0,
                    "13": 8,
                    "21": 0,
                    "22": 0,
                    "23": 1,
                    "31": 80,
                    "32": 0,
                    "33": 1,
                    "34": 0,
                    "41": 0,
                    "42": 5,
                    "43": 0,
                    "44": 0
                  },
                  "expirations": {
                    "sous10": 3,
                    "sous30": 3
                  },
                  "seuils": {
                    "critique": 10,
                    "alerte": 30
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "tableau_de_bord.consulter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/tableaux-de-bord/cybastion": {
      "get": {
        "operationId": "getTableauxDeBordCybastion",
        "tags": [
          "Pilotage"
        ],
        "summary": "Lire les comptages du tableau de bord CYBASTION",
        "description": "Comptages instantanés : partenaires (total, actifs, en cours de référencement), clients (total, actifs, prospects), pièces à vérifier, réservations à valider et en conflit, offres actives, comptes actifs. Sans variation ni série : celles-ci sont rendues par `/tableaux-de-bord/indicateurs`.\n\n**Permission requise** : `tableau_de_bord.consulter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 5 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "partenaires": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "actifs": {
                          "type": "integer"
                        },
                        "en_cours_referencement": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total",
                        "actifs",
                        "en_cours_referencement"
                      ]
                    },
                    "clients": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "actifs": {
                          "type": "integer"
                        },
                        "prospects": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total",
                        "actifs",
                        "prospects"
                      ]
                    },
                    "documents_a_verifier": {
                      "type": "integer"
                    },
                    "reservations_a_valider": {
                      "type": "integer"
                    },
                    "reservations_en_conflit": {
                      "type": "integer"
                    },
                    "offres_actives": {
                      "type": "integer"
                    },
                    "utilisateurs_actifs": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "partenaires",
                    "clients",
                    "documents_a_verifier",
                    "reservations_a_valider",
                    "reservations_en_conflit",
                    "offres_actives",
                    "utilisateurs_actifs"
                  ]
                },
                "example": {
                  "partenaires": {
                    "total": 22,
                    "actifs": 22,
                    "en_cours_referencement": 0
                  },
                  "clients": {
                    "total": 17,
                    "actifs": 3,
                    "prospects": 0
                  },
                  "documents_a_verifier": 68,
                  "reservations_a_valider": 0,
                  "reservations_en_conflit": 0,
                  "offres_actives": 26,
                  "utilisateurs_actifs": 69
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "tableau_de_bord.consulter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/validations": {
      "get": {
        "operationId": "getValidations",
        "tags": [
          "Pilotage"
        ],
        "summary": "Lister la file des validations en attente",
        "description": "Tout ce qui attend une décision de CYBASTION : remises exceptionnelles demandées, pièces KYC déposées, réservations demandées ou en conflit, paiements initiés ou à valider, demandes de versement soumises, procès-verbaux chargés. Chaque élément porte son type, son ancienneté (`jours_attente`) et la permission qui le traite, sans que la liste soit filtrée selon celles de l'appelant. Du plus ancien au plus récent ; réponse `{ donnees: [...], total }`, non paginée.\n\n**Permission requise** : `tableau_de_bord.consulter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "cle": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          },
                          "objet_type": {
                            "type": "string"
                          },
                          "objet_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "titre": {
                            "type": "string"
                          },
                          "reference": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "description": {
                            "type": "string"
                          },
                          "partenaire": {
                            "type": "null"
                          },
                          "client": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "statut"
                            ]
                          },
                          "montant": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "statut": {
                            "type": "string"
                          },
                          "statut_domaine": {
                            "type": "string"
                          },
                          "depuis": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "jours_attente": {
                            "type": "integer"
                          },
                          "permission": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "cle",
                          "type",
                          "objet_type",
                          "objet_id",
                          "titre",
                          "reference",
                          "description",
                          "partenaire",
                          "client",
                          "montant",
                          "statut",
                          "statut_domaine",
                          "depuis",
                          "jours_attente",
                          "permission"
                        ]
                      }
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "donnees",
                    "total"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "cle": "document_kyc:7664a6a3-d2f9-409f-984b-9137714f156f",
                      "type": "document_kyc",
                      "objet_type": "documents_kyc",
                      "objet_id": "7664a6a3-d2f9-409f-984b-9137714f156f",
                      "titre": "Photo du client",
                      "reference": "Entreprise de démonstration Odoo",
                      "description": "Pièce déposée par Entreprise de démonstration Odoo, à vérifier.",
                      "partenaire": null,
                      "client": null,
                      "montant": null,
                      "statut": "depose",
                      "statut_domaine": "statut_document",
                      "depuis": "2026-10-12T19:06:52.420Z",
                      "jours_attente": 6,
                      "permission": "partenaires.documents_verifier"
                    },
                    {
                      "cle": "document_kyc:881dc5e6-1855-4ff6-b4ca-ba58bdc3f1e8",
                      "type": "document_kyc",
                      "objet_type": "documents_kyc",
                      "objet_id": "881dc5e6-1855-4ff6-b4ca-ba58bdc3f1e8",
                      "titre": "Pièce d'identité du signataire — recto",
                      "reference": "Entreprise de démonstration Odoo",
                      "description": "Pièce déposée par Entreprise de démonstration Odoo, à vérifier.",
                      "partenaire": null,
                      "client": null,
                      "montant": null,
                      "statut": "depose",
                      "statut_domaine": "statut_document",
                      "depuis": "2026-10-12T19:06:52.431Z",
                      "jours_attente": 6,
                      "permission": "partenaires.documents_verifier"
                    }
                  ],
                  "total": 73
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "tableau_de_bord.consulter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/journal-audit": {
      "get": {
        "operationId": "getJournalAudit",
        "tags": [
          "Pilotage"
        ],
        "summary": "Consulter le journal d'audit",
        "description": "Les entrées du journal, de la plus récente à la plus ancienne, avec leur auteur et son organisation quand ils existent encore (`null` sinon). Filtrables par période (`du`, `au`, bornes incluses), auteur, type d'objet et action (recherche partielle, sans tenir compte de la casse). L'identifiant d'une entrée est rendu en texte.\n\n**Permission requise** : `audit.consulter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "du",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          },
          {
            "name": "au",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          },
          {
            "name": "utilisateur_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "objet_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          },
          {
            "name": "action",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 80
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 20 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "utilisateur_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "action": {
                            "type": "string"
                          },
                          "objet_type": {
                            "type": "string"
                          },
                          "objet_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "valeur_avant": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "statut": {
                                "type": "string"
                              },
                              "partenaire": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "ncc": {
                                "type": "string"
                              },
                              "rccm": {
                                "type": "string"
                              },
                              "email": {
                                "type": "null"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "origine": {
                                "type": "string"
                              },
                              "zone_id": {
                                "type": "null"
                              },
                              "cree_par": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "telephone": {
                                "type": "null"
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "secteur_id": {
                                "type": "null"
                              },
                              "statut_kyc": {
                                "type": "string"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "credit_approuve": {
                                "type": "boolean"
                              },
                              "forme_juridique": {
                                "type": "null"
                              },
                              "logo_fichier_id": {
                                "type": "null"
                              },
                              "organisation_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "plafond_encours": {
                                "type": "null"
                              },
                              "adresse_facturation": {
                                "type": "null"
                              },
                              "credit_approuve_par": {
                                "type": "null"
                              },
                              "partenaire_actuel_id": {
                                "type": "null"
                              },
                              "mode_paiement_souhaite": {
                                "type": "null"
                              }
                            },
                            "required": [
                              "statut"
                            ]
                          },
                          "valeur_apres": {
                            "type": "object",
                            "properties": {
                              "motif": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "adresse": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "type_annonce": {
                                "type": "string"
                              },
                              "reference_annoncee": {
                                "type": "string"
                              },
                              "reservation": {
                                "type": "string"
                              },
                              "partenaire_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "pieces_jointes": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "mode_paiement_souhaite": {
                                "type": "null"
                              },
                              "client_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "type_transaction": {
                                "type": "string"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "total_ttc": {
                                "type": "integer"
                              },
                              "commission_prevue": {
                                "type": "integer"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "commande": {
                                "type": "string"
                              },
                              "commission_latente": {
                                "type": "integer"
                              },
                              "canal": {
                                "type": "string"
                              },
                              "montant": {
                                "type": "integer"
                              },
                              "facture_id": {
                                "type": "null"
                              },
                              "commande_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "echeance": {
                                "type": "null"
                              },
                              "montant_ttc": {
                                "type": "integer"
                              },
                              "facture": {
                                "type": "string"
                              },
                              "commissions_reprises": {
                                "type": "integer"
                              },
                              "partenaire": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "alertees": {
                                "type": "integer"
                              },
                              "organisations": {
                                "type": "integer"
                              },
                              "pieces_alertees": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "format": "uuid"
                                }
                              },
                              "prevenance_jours": {
                                "type": "integer"
                              },
                              "sans_destinataire": {
                                "type": "integer"
                              },
                              "ncc": {
                                "type": "string"
                              },
                              "rccm": {
                                "type": "string"
                              },
                              "organisation_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "email": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "role_code": {
                                "type": "string"
                              },
                              "mot_de_passe_impose": {
                                "type": "boolean"
                              },
                              "automatique": {
                                "type": "boolean"
                              },
                              "declencheur": {
                                "type": "string"
                              },
                              "site_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "ville": {
                                "type": "string"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "zone_id": {
                                "type": "null"
                              },
                              "latitude": {
                                "type": "null"
                              },
                              "longitude": {
                                "type": "null"
                              },
                              "contact_id": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "uuid"
                              },
                              "modifie_le": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "besoin": {
                                "type": "object",
                                "properties": {
                                  "duree": {
                                    "type": "string"
                                  },
                                  "sites": {
                                    "type": "integer"
                                  },
                                  "usage": {
                                    "type": "string"
                                  },
                                  "connexions": {
                                    "type": "integer"
                                  },
                                  "cle_idempotence": {
                                    "type": "string"
                                  },
                                  "exprime_par_le_client": {
                                    "type": "boolean"
                                  }
                                },
                                "required": [
                                  "duree",
                                  "sites",
                                  "usage",
                                  "connexions",
                                  "cle_idempotence",
                                  "exprime_par_le_client"
                                ]
                              },
                              "cree_par": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "description": {
                                "type": "string"
                              },
                              "eligibilite": {
                                "type": "string"
                              },
                              "motif_perte": {
                                "type": "null"
                              },
                              "eligibilite_verifiee_le": {
                                "type": "null"
                              },
                              "eligibilite_verifiee_par": {
                                "type": "null"
                              },
                              "fichier_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "type_document": {
                                "type": "string"
                              },
                              "pieces_remplacees": {
                                "type": "array",
                                "items": {}
                              },
                              "origine": {
                                "type": "string"
                              },
                              "telephone": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "secteur_id": {
                                "type": "null"
                              },
                              "statut_kyc": {
                                "type": "string"
                              },
                              "credit_approuve": {
                                "type": "boolean"
                              },
                              "forme_juridique": {
                                "type": "null"
                              },
                              "logo_fichier_id": {
                                "type": "null"
                              },
                              "plafond_encours": {
                                "type": "null"
                              },
                              "adresse_facturation": {
                                "type": "null"
                              },
                              "credit_approuve_par": {
                                "type": "null"
                              },
                              "partenaire_actuel_id": {
                                "type": "null"
                              },
                              "verifie_le": {
                                "type": "null"
                              },
                              "verifie_par": {
                                "type": "null"
                              },
                              "date_emission": {
                                "type": "null"
                              },
                              "date_expiration": {
                                "type": "null"
                              },
                              "type_document_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "fonction": {
                                "type": "null"
                              },
                              "principal": {
                                "type": "boolean"
                              },
                              "traitee_le": {
                                "type": "null"
                              },
                              "traitee_par": {
                                "type": "null"
                              },
                              "demandee_par": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "motif_decision": {
                                "type": "null"
                              },
                              "doublons_detectes": {
                                "type": "null"
                              },
                              "bucket": {
                                "type": "string"
                              },
                              "taille": {
                                "type": "integer"
                              },
                              "empreinte": {
                                "type": "string"
                              },
                              "statut_scan": {
                                "type": "string"
                              }
                            }
                          },
                          "adresse_ip": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "utilisateur": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "organisation": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "nom",
                              "type"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "utilisateur_id",
                          "organisation_id",
                          "action",
                          "objet_type",
                          "objet_id",
                          "valeur_avant",
                          "valeur_apres",
                          "adresse_ip",
                          "cree_le",
                          "utilisateur",
                          "organisation"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "6377",
                      "utilisateur_id": null,
                      "organisation_id": null,
                      "action": "paiement.notification_refusee",
                      "objet_type": "evenements_paystack",
                      "objet_id": null,
                      "valeur_avant": null,
                      "valeur_apres": {
                        "motif": "adresse",
                        "adresse": "102.207.9.195",
                        "type_annonce": "charge.success",
                        "reference_annoncee": "PAY-INCONNUE-WNCYUQRHJW"
                      },
                      "adresse_ip": "102.207.9.195",
                      "cree_le": "2026-10-19T10:44:39.588Z",
                      "utilisateur": null,
                      "organisation": null
                    },
                    {
                      "id": "6376",
                      "utilisateur_id": null,
                      "organisation_id": null,
                      "action": "paiement.notification_refusee",
                      "objet_type": "evenements_paystack",
                      "objet_id": null,
                      "valeur_avant": null,
                      "valeur_apres": {
                        "motif": "signature",
                        "adresse": "102.207.9.195",
                        "type_annonce": "charge.success",
                        "reference_annoncee": "PAY-INCONNUE-WNCYUQRHJW"
                      },
                      "adresse_ip": "102.207.9.195",
                      "cree_le": "2026-10-19T10:44:39.472Z",
                      "utilisateur": null,
                      "organisation": null
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 5,
                    "total": 8,
                    "pages": 2
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "audit.consulter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/journal-audit/{id}": {
      "get": {
        "operationId": "getJournalAuditParId",
        "tags": [
          "Pilotage"
        ],
        "summary": "Lire une entrée du journal d'audit",
        "description": "Une entrée du journal, désignée par son numéro entier, avec son auteur et son organisation quand ils existent encore (`null` sinon). L'identifiant est rendu en texte.\n\n**Permission requise** : `audit.consulter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 9007199254740991
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "utilisateur_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "action": {
                      "type": "string"
                    },
                    "objet_type": {
                      "type": "string"
                    },
                    "objet_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "valeur_avant": {
                      "type": "null"
                    },
                    "valeur_apres": {
                      "type": "object",
                      "properties": {
                        "site_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "client_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "type_transaction": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "site_id",
                        "client_id",
                        "type_transaction"
                      ]
                    },
                    "adresse_ip": {
                      "type": "string"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "utilisateur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "organisation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom",
                        "type"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "utilisateur_id",
                    "organisation_id",
                    "action",
                    "objet_type",
                    "objet_id",
                    "valeur_avant",
                    "valeur_apres",
                    "adresse_ip",
                    "cree_le",
                    "utilisateur",
                    "organisation"
                  ]
                },
                "example": {
                  "id": "6927",
                  "utilisateur_id": "596208bc-80f2-4f32-951d-e40ff9b23af5",
                  "organisation_id": "7482ca09-01b5-4f39-9430-7d6b0b82c33f",
                  "action": "besoin.exprimer",
                  "objet_type": "opportunites",
                  "objet_id": "e7375b41-9ae4-4cea-8f3d-49e30857e8da",
                  "valeur_avant": null,
                  "valeur_apres": {
                    "site_id": "0ec47790-5761-48a2-b312-3f0f5f8bc869",
                    "client_id": "d0340284-d849-479a-8b15-89c1d0da08cc",
                    "type_transaction": "nouveau_besoin"
                  },
                  "adresse_ip": "102.207.9.195",
                  "cree_le": "2026-10-19T10:46:23.537Z",
                  "utilisateur": {
                    "id": "596208bc-80f2-4f32-951d-e40ff9b23af5",
                    "prenom": "ZZ Recette",
                    "nom": "Client 87E9A884",
                    "email": "zz.client.87e9a884@exemple.invalide"
                  },
                  "organisation": {
                    "id": "7482ca09-01b5-4f39-9430-7d6b0b82c33f",
                    "nom": "ZZ Recette Client 87E9A884",
                    "type": "client"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "audit.consulter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/historique": {
      "get": {
        "operationId": "getHistorique",
        "tags": [
          "Pilotage"
        ],
        "summary": "Lire l'historique d'activité récent",
        "description": "Les dernières entrées de l'historique d'activité (30 par défaut, 200 au plus), de la plus récente à la plus ancienne, avec leur auteur. Filtrables par type et identifiant d'objet. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : `tableau_de_bord.consulter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "limite",
            "in": "query",
            "required": false,
            "schema": {
              "default": 30,
              "type": "integer",
              "minimum": 1,
              "maximum": 200
            }
          },
          {
            "name": "objet_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 60
            }
          },
          {
            "name": "objet_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "objet_type": {
                            "type": "string"
                          },
                          "objet_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "statut_avant": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "statut_apres": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "fichier_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "action_id": {
                            "type": "null"
                          },
                          "utilisateur_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "utilisateur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "objet_type",
                          "objet_id",
                          "type",
                          "message",
                          "statut_avant",
                          "statut_apres",
                          "fichier_id",
                          "action_id",
                          "utilisateur_id",
                          "cree_le",
                          "utilisateur"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "0aafd4ae-1ae4-4293-b427-c563704a5561",
                      "objet_type": "devis",
                      "objet_id": "52d4a985-023c-4590-8b05-a2cdea3abba8",
                      "type": "appel",
                      "message": "Relance appel : Recette",
                      "statut_avant": null,
                      "statut_apres": null,
                      "fichier_id": null,
                      "action_id": null,
                      "utilisateur_id": "edcb444f-7e37-4cc7-b2e1-bf5c8bef0cb4",
                      "cree_le": "2026-10-19T10:46:24.525Z",
                      "utilisateur": {
                        "id": "edcb444f-7e37-4cc7-b2e1-bf5c8bef0cb4",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A 60446FF3",
                        "email": "zz.recette.60446ff3@exemple.invalide"
                      }
                    },
                    {
                      "id": "94a93268-3bc4-4120-b2d1-13befeb806ff",
                      "objet_type": "devis",
                      "objet_id": "52d4a985-023c-4590-8b05-a2cdea3abba8",
                      "type": "appel",
                      "message": "Relance appel : Recette",
                      "statut_avant": null,
                      "statut_apres": null,
                      "fichier_id": null,
                      "action_id": null,
                      "utilisateur_id": "edcb444f-7e37-4cc7-b2e1-bf5c8bef0cb4",
                      "cree_le": "2026-10-19T10:46:24.399Z",
                      "utilisateur": {
                        "id": "edcb444f-7e37-4cc7-b2e1-bf5c8bef0cb4",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A 60446FF3",
                        "email": "zz.recette.60446ff3@exemple.invalide"
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "tableau_de_bord.consulter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/reporting": {
      "get": {
        "operationId": "getReporting",
        "tags": [
          "Pilotage"
        ],
        "summary": "Lire le reporting de la période",
        "description": "Indicateurs commerciaux, opérationnels, financiers, partenaires et de conformité sur la période `du`–`au` (bornes incluses ; par défaut du 1er janvier à maintenant) : CA HT signé, taux de transformation, délai prospect-signature, installations, activations, facturé, encaissé, retards, commissions dues et payées, pièces et expirations. Le classement des partenaires n’est rempli que pour CYBASTION ; `score_performance` est nul.\n\n**Permission requise** : `reporting.consulter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "du",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          },
          {
            "name": "au",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 8 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "periode": {
                      "type": "object",
                      "properties": {
                        "du": {
                          "type": "string",
                          "format": "date"
                        },
                        "au": {
                          "type": "string",
                          "format": "date"
                        }
                      },
                      "required": [
                        "du",
                        "au"
                      ]
                    },
                    "commercial": {
                      "type": "object",
                      "properties": {
                        "ca_ht_signe": {
                          "type": "integer"
                        },
                        "devis_emis": {
                          "type": "integer"
                        },
                        "devis_signes": {
                          "type": "integer"
                        },
                        "taux_transformation_pct": {
                          "type": "integer"
                        },
                        "panier_moyen_ht": {
                          "type": "integer"
                        },
                        "ventes_par_offre": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "offre": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "code": {
                                    "type": "string"
                                  },
                                  "libelle": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "code",
                                  "libelle"
                                ]
                              },
                              "nb": {
                                "type": "integer"
                              },
                              "montant_ht": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "offre",
                              "nb",
                              "montant_ht"
                            ]
                          }
                        },
                        "ca_ht_par_mois": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "mois": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "montant": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "mois",
                              "libelle",
                              "montant"
                            ]
                          }
                        },
                        "devis_par_statut": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "statut": {
                                "type": "string"
                              },
                              "nb": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "statut",
                              "nb"
                            ]
                          }
                        },
                        "delai_moyen_prospect_signature_jours": {
                          "type": "null"
                        },
                        "delai_median_prospect_signature_jours": {
                          "type": "null"
                        },
                        "clients_mesures_prospect_signature": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "ca_ht_signe",
                        "devis_emis",
                        "devis_signes",
                        "taux_transformation_pct",
                        "panier_moyen_ht",
                        "ventes_par_offre",
                        "ca_ht_par_mois",
                        "devis_par_statut",
                        "delai_moyen_prospect_signature_jours",
                        "delai_median_prospect_signature_jours",
                        "clients_mesures_prospect_signature"
                      ]
                    },
                    "operationnel": {
                      "type": "object",
                      "properties": {
                        "installations_realisees": {
                          "type": "integer"
                        },
                        "delai_moyen_installation_jours": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "installations_en_retard": {
                          "type": "integer"
                        },
                        "activations_confirmees": {
                          "type": "integer"
                        },
                        "activations_en_attente": {
                          "type": "integer"
                        },
                        "ordres_par_statut": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "statut": {
                                "type": "string"
                              },
                              "nb": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "statut",
                              "nb"
                            ]
                          }
                        },
                        "techniciens": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "technicien": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "prenom": {
                                    "type": "string"
                                  },
                                  "nom": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "prenom",
                                  "nom"
                                ]
                              },
                              "realisees": {
                                "type": "integer"
                              },
                              "echecs": {
                                "type": "integer"
                              },
                              "taux_reussite_pct": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "technicien",
                              "realisees",
                              "echecs",
                              "taux_reussite_pct"
                            ]
                          }
                        }
                      },
                      "required": [
                        "installations_realisees",
                        "delai_moyen_installation_jours",
                        "installations_en_retard",
                        "activations_confirmees",
                        "activations_en_attente",
                        "ordres_par_statut",
                        "techniciens"
                      ]
                    },
                    "financier": {
                      "type": "object",
                      "properties": {
                        "facture_ttc": {
                          "type": "integer"
                        },
                        "encaisse": {
                          "type": "integer"
                        },
                        "en_retard": {
                          "type": "integer"
                        },
                        "reste_a_encaisser": {
                          "type": "integer"
                        },
                        "commissions_dues": {
                          "type": "integer"
                        },
                        "commissions_payees": {
                          "type": "integer"
                        },
                        "encaissements_par_mois": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "mois": {
                                "type": "string"
                              },
                              "libelle": {
                                "type": "string"
                              },
                              "montant": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "mois",
                              "libelle",
                              "montant"
                            ]
                          }
                        },
                        "paiements_par_canal": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "canal": {
                                "type": "string"
                              },
                              "nb": {
                                "type": "integer"
                              },
                              "montant": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "canal",
                              "nb",
                              "montant"
                            ]
                          }
                        }
                      },
                      "required": [
                        "facture_ttc",
                        "encaisse",
                        "en_retard",
                        "reste_a_encaisser",
                        "commissions_dues",
                        "commissions_payees",
                        "encaissements_par_mois",
                        "paiements_par_canal"
                      ]
                    },
                    "partenaires": {
                      "type": "object",
                      "properties": {
                        "classement": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "partenaire": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "raison_sociale": {
                                    "type": "string"
                                  },
                                  "statut": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "raison_sociale",
                                  "statut"
                                ]
                              },
                              "ca_ht": {
                                "type": "integer"
                              },
                              "nb_ventes": {
                                "type": "integer"
                              },
                              "clients_geres": {
                                "type": "integer"
                              },
                              "score_performance": {
                                "type": "null"
                              },
                              "commissions": {
                                "type": "integer"
                              },
                              "delai_moyen_prospect_signature_jours": {
                                "type": "null"
                              },
                              "clients_mesures_prospect_signature": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "partenaire",
                              "ca_ht",
                              "nb_ventes",
                              "clients_geres",
                              "score_performance",
                              "commissions",
                              "delai_moyen_prospect_signature_jours",
                              "clients_mesures_prospect_signature"
                            ]
                          }
                        }
                      },
                      "required": [
                        "classement"
                      ]
                    },
                    "conformite": {
                      "type": "object",
                      "properties": {
                        "pieces_par_statut": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "statut": {
                                "type": "string"
                              },
                              "nb": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "statut",
                              "nb"
                            ]
                          }
                        },
                        "expirations_a_venir": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "document_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "titulaire": {
                                "type": "string"
                              },
                              "type_document": {
                                "type": "string"
                              },
                              "date_expiration": {
                                "type": "string",
                                "format": "date"
                              },
                              "jours_restants": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "document_id",
                              "titulaire",
                              "type_document",
                              "date_expiration",
                              "jours_restants"
                            ]
                          }
                        },
                        "reservations_par_statut": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "statut": {
                                "type": "string"
                              },
                              "nb": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "statut",
                              "nb"
                            ]
                          }
                        },
                        "pieces_a_completer": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "pieces_par_statut",
                        "expirations_a_venir",
                        "reservations_par_statut",
                        "pieces_a_completer"
                      ]
                    }
                  },
                  "required": [
                    "periode",
                    "commercial",
                    "operationnel",
                    "financier",
                    "partenaires",
                    "conformite"
                  ]
                },
                "example": {
                  "periode": {
                    "du": "2026-01-01",
                    "au": "2026-10-19"
                  },
                  "commercial": {
                    "ca_ht_signe": 320000,
                    "devis_emis": 29,
                    "devis_signes": 16,
                    "taux_transformation_pct": 55,
                    "panier_moyen_ht": 20000,
                    "ventes_par_offre": [
                      {
                        "offre": {
                          "id": "ba211cc4-df38-4b23-9683-8725a0c72ff6",
                          "code": "DATA-50GO-HEBDO",
                          "libelle": "Forfait 50 Go hebdomadaire"
                        },
                        "nb": 16,
                        "montant_ht": 320000
                      }
                    ],
                    "ca_ht_par_mois": [
                      {
                        "mois": "2026-01",
                        "libelle": "janvier 2026",
                        "montant": 0
                      },
                      {
                        "mois": "2026-02",
                        "libelle": "février 2026",
                        "montant": 0
                      }
                    ],
                    "devis_par_statut": [
                      {
                        "statut": "signe",
                        "nb": 16
                      },
                      {
                        "statut": "annule",
                        "nb": 5
                      }
                    ],
                    "delai_moyen_prospect_signature_jours": null,
                    "delai_median_prospect_signature_jours": null,
                    "clients_mesures_prospect_signature": 0
                  },
                  "operationnel": {
                    "installations_realisees": 3,
                    "delai_moyen_installation_jours": 0,
                    "installations_en_retard": 0,
                    "activations_confirmees": 3,
                    "activations_en_attente": 0,
                    "ordres_par_statut": [
                      {
                        "statut": "a_envoyer",
                        "nb": 5
                      },
                      {
                        "statut": "annule",
                        "nb": 10
                      }
                    ],
                    "techniciens": [
                      {
                        "technicien": {
                          "id": "7af85e89-9cda-4032-9941-e40b63b131d7",
                          "prenom": "ZZ Recette",
                          "nom": "Technicien 91GQ8H"
                        },
                        "realisees": 1,
                        "echecs": 0,
                        "taux_reussite_pct": 100
                      },
                      {
                        "technicien": {
                          "id": "19a26b3c-9692-4c1d-9e68-419cbe62ada2",
                          "prenom": "ZZ Recette",
                          "nom": "Technicien CMXGPP"
                        },
                        "realisees": 1,
                        "echecs": 0,
                        "taux_reussite_pct": 100
                      }
                    ]
                  },
                  "financier": {
                    "facture_ttc": 188800,
                    "encaisse": 188800,
                    "en_retard": 0,
                    "reste_a_encaisser": 0,
                    "commissions_dues": 17000,
                    "commissions_payees": 12000,
                    "encaissements_par_mois": [
                      {
                        "mois": "2026-01",
                        "libelle": "janvier 2026",
                        "montant": 0
                      },
                      {
                        "mois": "2026-02",
                        "libelle": "février 2026",
                        "montant": 0
                      }
                    ],
                    "paiements_par_canal": [
                      {
                        "canal": "virement",
                        "nb": 8,
                        "montant": 153400
                      },
                      {
                        "canal": "especes",
                        "nb": 3,
                        "montant": 35400
                      }
                    ]
                  },
                  "partenaires": {
                    "classement": [
                      {
                        "partenaire": {
                          "id": "785d3b3d-6457-4550-89b7-e13844eac8a1",
                          "raison_sociale": "ZZ Recette Partenaire A 7E35C6EB",
                          "statut": "actif"
                        },
                        "ca_ht": 40000,
                        "nb_ventes": 2,
                        "clients_geres": 1,
                        "score_performance": null,
                        "commissions": 4000,
                        "delai_moyen_prospect_signature_jours": null,
                        "clients_mesures_prospect_signature": 0
                      },
                      {
                        "partenaire": {
                          "id": "6641d761-f1d3-4421-9391-7d5553244058",
                          "raison_sociale": "ZZ Recette Partenaire A A7B8701D",
                          "statut": "actif"
                        },
                        "ca_ht": 40000,
                        "nb_ventes": 2,
                        "clients_geres": 1,
                        "score_performance": null,
                        "commissions": 4000,
                        "delai_moyen_prospect_signature_jours": null,
                        "clients_mesures_prospect_signature": 0
                      }
                    ]
                  },
                  "conformite": {
                    "pieces_par_statut": [
                      {
                        "statut": "valide",
                        "nb": 3
                      },
                      {
                        "statut": "depose",
                        "nb": 68
                      }
                    ],
                    "expirations_a_venir": [
                      {
                        "document_id": "de160087-4ca3-4d2b-af65-311778e7b100",
                        "titulaire": "ZZ Recette VTUKFKBFPT",
                        "type_document": "Document KYC complémentaire",
                        "date_expiration": "2026-10-29",
                        "jours_restants": 10
                      },
                      {
                        "document_id": "b941a1f0-db98-430a-ac43-3dce3dfe004e",
                        "titulaire": "ZZ Recette NDDKNBHRYB",
                        "type_document": "Document KYC complémentaire",
                        "date_expiration": "2026-10-29",
                        "jours_restants": 10
                      }
                    ],
                    "reservations_par_statut": [
                      {
                        "statut": "validee",
                        "nb": 17
                      },
                      {
                        "statut": "refusee",
                        "nb": 5
                      }
                    ],
                    "pieces_a_completer": 0
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "reporting.consulter",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/tableaux-de-bord/finance": {
      "get": {
        "operationId": "getTableauxDeBordFinance",
        "tags": [
          "Pilotage"
        ],
        "summary": "Lire le tableau de bord de la Finance",
        "description": "Calculé en base : paiements à valider (nombre et montant), encaissé du mois et part reçue en ligne, paiements rejetés du mois, facturé et encaissé des factures ouvertes, reste à encaisser, factures en retard et leur montant, ancienneté des créances sur le reste à payer (0-30, 31-60, plus de 60 jours) et demandes de crédit à examiner.\n\n**Permission requise** : `factures.emettre`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "paiements_a_valider": {
                      "type": "integer"
                    },
                    "montant_a_valider": {
                      "type": "integer"
                    },
                    "encaisse_mois": {
                      "type": "integer"
                    },
                    "nb_encaissements_mois": {
                      "type": "integer"
                    },
                    "paiements_rejetes_mois": {
                      "type": "integer"
                    },
                    "part_en_ligne_pct": {
                      "type": "integer"
                    },
                    "montant_facture": {
                      "type": "integer"
                    },
                    "montant_encaisse": {
                      "type": "integer"
                    },
                    "reste_a_encaisser": {
                      "type": "integer"
                    },
                    "factures_en_retard": {
                      "type": "integer"
                    },
                    "montant_en_retard": {
                      "type": "integer"
                    },
                    "anciennete_creances": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "tranche": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "montant": {
                            "type": "integer"
                          },
                          "nb": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "tranche",
                          "libelle",
                          "montant",
                          "nb"
                        ]
                      }
                    },
                    "demandes_credit_a_examiner": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "paiements_a_valider",
                    "montant_a_valider",
                    "encaisse_mois",
                    "nb_encaissements_mois",
                    "paiements_rejetes_mois",
                    "part_en_ligne_pct",
                    "montant_facture",
                    "montant_encaisse",
                    "reste_a_encaisser",
                    "factures_en_retard",
                    "montant_en_retard",
                    "anciennete_creances",
                    "demandes_credit_a_examiner"
                  ]
                },
                "example": {
                  "paiements_a_valider": 1,
                  "montant_a_valider": 23600,
                  "encaisse_mois": 188800,
                  "nb_encaissements_mois": 11,
                  "paiements_rejetes_mois": 8,
                  "part_en_ligne_pct": 0,
                  "montant_facture": 0,
                  "montant_encaisse": 0,
                  "reste_a_encaisser": 0,
                  "factures_en_retard": 0,
                  "montant_en_retard": 0,
                  "anciennete_creances": [
                    {
                      "tranche": "0_30",
                      "libelle": "0 à 30 jours",
                      "montant": 0,
                      "nb": 0
                    },
                    {
                      "tranche": "31_60",
                      "libelle": "31 à 60 jours",
                      "montant": 0,
                      "nb": 0
                    }
                  ],
                  "demandes_credit_a_examiner": 0
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "factures.emettre",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/tableaux-de-bord/operations": {
      "get": {
        "operationId": "getTableauxDeBordOperations",
        "tags": [
          "Pilotage"
        ],
        "summary": "Lire le tableau de bord des Opérations",
        "description": "Calculé en base : commandes payées sans ordre d'installation actif, ordres à envoyer, envoyés, planifiés et en retard, ordres réalisés du mois, ordres réalisés sans procès-verbal, PV contestés, activations à demander, demandées et confirmées du mois, techniciens actifs.\n\n**Permission requise** : `installations.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "commandes_a_installer": {
                      "type": "integer"
                    },
                    "ordres_a_envoyer": {
                      "type": "integer"
                    },
                    "ordres_envoyes": {
                      "type": "integer"
                    },
                    "ordres_planifies": {
                      "type": "integer"
                    },
                    "ordres_en_retard": {
                      "type": "integer"
                    },
                    "realises_mois": {
                      "type": "integer"
                    },
                    "pv_a_saisir": {
                      "type": "integer"
                    },
                    "pv_contestes": {
                      "type": "integer"
                    },
                    "activations_a_demander": {
                      "type": "integer"
                    },
                    "activations_demandees": {
                      "type": "integer"
                    },
                    "activations_mois": {
                      "type": "integer"
                    },
                    "techniciens_actifs": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "commandes_a_installer",
                    "ordres_a_envoyer",
                    "ordres_envoyes",
                    "ordres_planifies",
                    "ordres_en_retard",
                    "realises_mois",
                    "pv_a_saisir",
                    "pv_contestes",
                    "activations_a_demander",
                    "activations_demandees",
                    "activations_mois",
                    "techniciens_actifs"
                  ]
                },
                "example": {
                  "commandes_a_installer": 0,
                  "ordres_a_envoyer": 6,
                  "ordres_envoyes": 0,
                  "ordres_planifies": 0,
                  "ordres_en_retard": 0,
                  "realises_mois": 3,
                  "pv_a_saisir": 0,
                  "pv_contestes": 0,
                  "activations_a_demander": 0,
                  "activations_demandees": 0,
                  "activations_mois": 3,
                  "techniciens_actifs": 3
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "installations.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/tickets": {
      "get": {
        "operationId": "getTickets",
        "tags": [
          "Support"
        ],
        "summary": "Lister les tickets de support",
        "description": "Les tickets, par priorité puis par ancienneté, avec l'organisation, le demandeur, l'assigné, le nombre de messages et `en_retard` (échéance de résolution passée sans résolution). Hors CYBASTION, une organisation ne voit que les tickets qu’elle a ouverts. Filtres `statut`, `categorie`, `priorite` (valeurs de l'ouverture et du traitement d’un ticket ; une ou plusieurs, séparées par des virgules) et `en_retard`.\n\n**Permission requise** : L'une de : `tickets.creer`, `tickets.traiter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "categorie",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "priorite",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "en_retard",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "demandeur_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "categorie": {
                            "type": "string"
                          },
                          "priorite": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "sujet": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "objet_type": {
                            "type": "string"
                          },
                          "objet_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "assigne_a": {
                            "type": "null"
                          },
                          "equipe": {
                            "type": "null"
                          },
                          "echeance_reponse": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "echeance_resolution": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "niveau_escalade": {
                            "type": "integer"
                          },
                          "resolution": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "clos_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "en_retard": {
                            "type": "boolean"
                          },
                          "organisation": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "nom",
                              "type"
                            ]
                          },
                          "demandeur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "assigne": {
                            "type": "null"
                          },
                          "nb_messages": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "organisation_id",
                          "demandeur_id",
                          "categorie",
                          "priorite",
                          "statut",
                          "sujet",
                          "description",
                          "objet_type",
                          "objet_id",
                          "assigne_a",
                          "equipe",
                          "echeance_reponse",
                          "echeance_resolution",
                          "niveau_escalade",
                          "resolution",
                          "clos_le",
                          "cree_le",
                          "modifie_le",
                          "en_retard",
                          "organisation",
                          "demandeur",
                          "assigne",
                          "nb_messages"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "5bcc6ec8-cdbb-4b8e-9a9d-a03c4b99fe14",
                      "numero": "TIC-2026-000011",
                      "organisation_id": "88d4a189-8e8b-4b19-b51e-7ac45dfdbf4e",
                      "demandeur_id": "cbec19cf-7d16-491f-b4d3-c930b752af2f",
                      "categorie": "connectivite",
                      "priorite": "urgente",
                      "statut": "clos",
                      "sujet": "Liaison instable — recette VTUKFKBFPT",
                      "description": "La liaison tombe plusieurs fois par jour depuis la mise en service.",
                      "objet_type": "commandes",
                      "objet_id": "f1523492-9bd1-44d3-b8d1-c29d3f8c42d2",
                      "assigne_a": null,
                      "equipe": null,
                      "echeance_reponse": "2026-10-20T18:00:00.000Z",
                      "echeance_resolution": "2026-10-22T18:00:00.000Z",
                      "niveau_escalade": 0,
                      "resolution": "Antenne réorientée, débit stable depuis 48 h.",
                      "clos_le": "2026-10-19T10:38:36.564Z",
                      "cree_le": "2026-10-19T10:38:35.506Z",
                      "modifie_le": "2026-10-19T10:38:36.563Z",
                      "en_retard": false,
                      "organisation": {
                        "id": "88d4a189-8e8b-4b19-b51e-7ac45dfdbf4e",
                        "nom": "ZZ Recette Partenaire A 3E0115E1",
                        "type": "partenaire"
                      },
                      "demandeur": {
                        "id": "cbec19cf-7d16-491f-b4d3-c930b752af2f",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A 3E0115E1",
                        "email": "zz.recette.3e0115e1@exemple.invalide"
                      },
                      "assigne": null,
                      "nb_messages": 2
                    },
                    {
                      "id": "72a2efbd-34bb-446d-9bf1-faa3db5e5bbc",
                      "numero": "TIC-2026-000012",
                      "organisation_id": "5ac10311-ce8d-4802-a589-c6def38521d6",
                      "demandeur_id": "c9d3dcfa-f9a2-4c20-9904-12edcf7c5ddc",
                      "categorie": "connectivite",
                      "priorite": "urgente",
                      "statut": "clos",
                      "sujet": "Liaison instable — recette NDDKNBHRYB",
                      "description": "La liaison tombe plusieurs fois par jour depuis la mise en service.",
                      "objet_type": "commandes",
                      "objet_id": "fca5285d-4c08-49f0-be4e-1579f8ecf1df",
                      "assigne_a": null,
                      "equipe": null,
                      "echeance_reponse": "2026-10-20T18:00:00.000Z",
                      "echeance_resolution": "2026-10-22T18:00:00.000Z",
                      "niveau_escalade": 0,
                      "resolution": "Antenne réorientée, débit stable depuis 48 h.",
                      "clos_le": "2026-10-19T10:42:13.903Z",
                      "cree_le": "2026-10-19T10:42:12.809Z",
                      "modifie_le": "2026-10-19T10:42:13.903Z",
                      "en_retard": false,
                      "organisation": {
                        "id": "5ac10311-ce8d-4802-a589-c6def38521d6",
                        "nom": "ZZ Recette Partenaire A 0CB9B2BD",
                        "type": "partenaire"
                      },
                      "demandeur": {
                        "id": "c9d3dcfa-f9a2-4c20-9904-12edcf7c5ddc",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A 0CB9B2BD",
                        "email": "zz.recette.0cb9b2bd@exemple.invalide"
                      },
                      "assigne": null,
                      "nb_messages": 2
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 4,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "tickets.creer",
          "tickets.traiter"
        ],
        "x-satelica-cloisonnement": "applique"
      },
      "post": {
        "operationId": "postTickets",
        "tags": [
          "Support"
        ],
        "summary": "Ouvrir un ticket de support",
        "description": "Ouvre un ticket « ouvert », numéroté TIC, au nom de l’organisation de l’appelant (CYBASTION, partenaire, client ou VIP Net), rattaché ou non à un objet (`objet_type`, `objet_id`). Les échéances de réponse et de résolution sont posées en jours ouvrés selon la priorité (paramètres `support.delai_*`). La description devient le premier message du fil.\n\n**Permission requise** : `tickets.creer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "categorie": {
                    "type": "string",
                    "enum": [
                      "commercial",
                      "facturation",
                      "paiement",
                      "installation",
                      "activation",
                      "connectivite",
                      "contrat",
                      "commission",
                      "plateforme"
                    ]
                  },
                  "priorite": {
                    "default": "normale",
                    "type": "string",
                    "enum": [
                      "normale",
                      "urgente",
                      "critique"
                    ]
                  },
                  "sujet": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "minLength": 10,
                    "maxLength": 5000
                  },
                  "objet_type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "objet_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "categorie",
                  "sujet",
                  "description"
                ]
              },
              "example": {
                "categorie": "connectivite",
                "priorite": "urgente",
                "sujet": "Liaison instable — recette WNCYUQRHJW",
                "description": "La liaison tombe plusieurs fois par jour depuis la mise en service.",
                "objet_type": "commandes",
                "objet_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "priorite": {
                      "type": "string"
                    },
                    "echeance_reponse": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "echeance_resolution": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "statut",
                    "priorite",
                    "echeance_reponse",
                    "echeance_resolution"
                  ]
                },
                "example": {
                  "id": "98a76dfe-aca2-4b87-953c-7e5d8a9606b3",
                  "numero": "TIC-2026-000013",
                  "statut": "ouvert",
                  "priorite": "urgente",
                  "echeance_reponse": "2026-10-20T18:00:00.000Z",
                  "echeance_resolution": "2026-10-22T18:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "tickets.creer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/tickets/{id}": {
      "get": {
        "operationId": "getTicketsParId",
        "tags": [
          "Support"
        ],
        "summary": "Lire un ticket et son fil de messages",
        "description": "Le ticket, son organisation, son demandeur, son assigné et ses messages dans l'ordre chronologique, avec leur auteur et leur pièce jointe. Les notes internes ne sont servies qu’aux comptes qui traitent les tickets.\n\n**Permission requise** : L'une de : `tickets.creer`, `tickets.traiter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "demandeur_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "categorie": {
                      "type": "string"
                    },
                    "priorite": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "sujet": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "objet_type": {
                      "type": "string"
                    },
                    "objet_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "assigne_a": {
                      "type": "null"
                    },
                    "equipe": {
                      "type": "null"
                    },
                    "echeance_reponse": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "echeance_resolution": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "niveau_escalade": {
                      "type": "integer"
                    },
                    "resolution": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "clos_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "en_retard": {
                      "type": "boolean"
                    },
                    "organisation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom",
                        "type"
                      ]
                    },
                    "demandeur": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "assigne": {
                      "type": "null"
                    },
                    "messages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "ticket_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "auteur_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "message": {
                            "type": "string"
                          },
                          "fichier_id": {
                            "type": "null"
                          },
                          "interne": {
                            "type": "boolean"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "auteur": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "fichier": {
                            "type": "null"
                          }
                        },
                        "required": [
                          "id",
                          "ticket_id",
                          "auteur_id",
                          "message",
                          "fichier_id",
                          "interne",
                          "cree_le",
                          "auteur",
                          "fichier"
                        ]
                      }
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "organisation_id",
                    "demandeur_id",
                    "categorie",
                    "priorite",
                    "statut",
                    "sujet",
                    "description",
                    "objet_type",
                    "objet_id",
                    "assigne_a",
                    "equipe",
                    "echeance_reponse",
                    "echeance_resolution",
                    "niveau_escalade",
                    "resolution",
                    "clos_le",
                    "cree_le",
                    "modifie_le",
                    "en_retard",
                    "organisation",
                    "demandeur",
                    "assigne",
                    "messages"
                  ]
                },
                "example": {
                  "id": "98a76dfe-aca2-4b87-953c-7e5d8a9606b3",
                  "numero": "TIC-2026-000013",
                  "organisation_id": "934a4f65-f131-43c7-8f16-93262ee7472f",
                  "demandeur_id": "d60b33fd-8d32-4475-a107-5d4bd82d6f3f",
                  "categorie": "connectivite",
                  "priorite": "urgente",
                  "statut": "ouvert",
                  "sujet": "Liaison instable — recette WNCYUQRHJW",
                  "description": "La liaison tombe plusieurs fois par jour depuis la mise en service.",
                  "objet_type": "commandes",
                  "objet_id": "e556dae0-1957-496c-9e6c-de3eeecdb9ab",
                  "assigne_a": null,
                  "equipe": null,
                  "echeance_reponse": "2026-10-20T18:00:00.000Z",
                  "echeance_resolution": "2026-10-22T18:00:00.000Z",
                  "niveau_escalade": 0,
                  "resolution": null,
                  "clos_le": null,
                  "cree_le": "2026-10-19T10:44:40.097Z",
                  "modifie_le": "2026-10-19T10:44:40.097Z",
                  "en_retard": false,
                  "organisation": {
                    "id": "934a4f65-f131-43c7-8f16-93262ee7472f",
                    "nom": "ZZ Recette Partenaire A DFA45D10",
                    "type": "partenaire"
                  },
                  "demandeur": {
                    "id": "d60b33fd-8d32-4475-a107-5d4bd82d6f3f",
                    "prenom": "ZZ Recette",
                    "nom": "Partenaire A DFA45D10",
                    "email": "zz.recette.dfa45d10@exemple.invalide"
                  },
                  "assigne": null,
                  "messages": [
                    {
                      "id": "9deff494-4b22-4a69-9eb2-a14a06c8bcfe",
                      "ticket_id": "98a76dfe-aca2-4b87-953c-7e5d8a9606b3",
                      "auteur_id": "d60b33fd-8d32-4475-a107-5d4bd82d6f3f",
                      "message": "La liaison tombe plusieurs fois par jour depuis la mise en service.",
                      "fichier_id": null,
                      "interne": false,
                      "cree_le": "2026-10-19T10:44:40.100Z",
                      "auteur": {
                        "id": "d60b33fd-8d32-4475-a107-5d4bd82d6f3f",
                        "prenom": "ZZ Recette",
                        "nom": "Partenaire A DFA45D10",
                        "email": "zz.recette.dfa45d10@exemple.invalide"
                      },
                      "fichier": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "tickets.creer",
          "tickets.traiter"
        ],
        "x-satelica-cloisonnement": "applique"
      },
      "patch": {
        "operationId": "patchTicketsParId",
        "tags": [
          "Support"
        ],
        "summary": "Traiter un ticket de support",
        "description": "Change le statut d'un ticket, et au besoin son assigné ou son équipe. Les transitions sont contrôlées (un ticket clos ne se rouvre pas) et `resolution` est obligatoire pour passer « resolu ». Le demandeur est notifié quand le ticket est résolu ou clos.\n\n**Permission requise** : `tickets.traiter`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "statut": {
                    "type": "string",
                    "enum": [
                      "ouvert",
                      "en_cours",
                      "en_attente_demandeur",
                      "resolu",
                      "clos"
                    ]
                  },
                  "assigne_a": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "equipe": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "resolution": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000
                  }
                },
                "required": [
                  "statut"
                ]
              },
              "example": {
                "statut": "resolu",
                "resolution": "Antenne réorientée, débit stable depuis 48 h."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "assigne_a": {
                      "type": "null"
                    },
                    "equipe": {
                      "type": "null"
                    },
                    "resolution": {
                      "type": "string"
                    },
                    "clos_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "statut",
                    "assigne_a",
                    "equipe",
                    "resolution",
                    "clos_le"
                  ]
                },
                "example": {
                  "id": "98a76dfe-aca2-4b87-953c-7e5d8a9606b3",
                  "numero": "TIC-2026-000013",
                  "statut": "resolu",
                  "assigne_a": null,
                  "equipe": null,
                  "resolution": "Antenne réorientée, débit stable depuis 48 h.",
                  "clos_le": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Transition de statut interdite : un ticket clos ne se rouvre pas.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "tickets.traiter",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/tickets/{id}/messages": {
      "post": {
        "operationId": "postTicketsParIdMessages",
        "tags": [
          "Support"
        ],
        "summary": "Répondre sur un ticket",
        "description": "Ajoute un message au fil, avec une pièce jointe facultative (fichier déposé au préalable par l'appelant et déclaré sain par l'antivirus). Une note `interne` est réservée à qui traite les tickets et ne prévient personne. Sinon l'autre partie (demandeur ou assigné) est notifiée, et le statut suit la conversation : une réponse du support passe « ouvert » à « en_cours », une réponse du demandeur passe « en_attente_demandeur » à « en_cours ».\n\n**Permission requise** : L'une de : `tickets.creer`, `tickets.traiter`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 5000
                  },
                  "fichier_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "interne": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "message"
                ]
              },
              "example": {
                "message": "Vérifier le débit chez VIP Net avant de répondre.",
                "interne": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "interne": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "cree_le",
                    "interne"
                  ]
                },
                "example": {
                  "id": "afa96856-168d-4a0a-9792-9bcf558d19ac",
                  "cree_le": "2026-10-19T10:44:40.352Z",
                  "interne": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Ticket clos, ou pièce jointe non déclarée saine par l'antivirus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "tickets.creer",
          "tickets.traiter"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/notifications": {
      "get": {
        "operationId": "getNotifications",
        "tags": [
          "Notifications"
        ],
        "summary": "Lister mes notifications",
        "description": "Les notifications de l'appelant, et seulement les siennes, de la plus récente à la plus ancienne. Filtre `non_lues`. La réponse ajoute `non_lues`, le nombre total de notifications non lues de l'appelant.\n\n**Permission requise** : Être connecté (aucune permission particulière).\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "non_lues",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 7 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "non_lues": {
                      "type": "integer"
                    },
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "canal": {
                            "type": "string"
                          },
                          "titre": {
                            "type": "string"
                          },
                          "message": {
                            "type": "string"
                          },
                          "lien": {
                            "type": "string"
                          },
                          "envoyee_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "lue_le": {
                            "type": "null"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "canal",
                          "titre",
                          "message",
                          "lien",
                          "envoyee_le",
                          "lue_le",
                          "cree_le"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "acb531fb-c647-4d41-855a-c1b29df9f93c",
                      "canal": "plateforme",
                      "titre": "Ticket TIC-2026-000013 clos",
                      "message": "Votre demande « Liaison instable — recette WNCYUQRHJW » a été close.",
                      "lien": "/espace-partenaire/support?‹paramètres signés›",
                      "envoyee_le": "2026-10-19T10:44:41.161Z",
                      "lue_le": null,
                      "cree_le": "2026-10-19T10:44:41.161Z"
                    },
                    {
                      "id": "75f8bba6-bf2e-4a7a-bc4c-aa7a2e62b7b7",
                      "canal": "plateforme",
                      "titre": "Ticket TIC-2026-000013 résolu",
                      "message": "Votre demande « Liaison instable — recette WNCYUQRHJW » a été résolue. Antenne réorientée, débit stable depuis 48 h.",
                      "lien": "/espace-partenaire/support?‹paramètres signés›",
                      "envoyee_le": "2026-10-19T10:44:40.987Z",
                      "lue_le": null,
                      "cree_le": "2026-10-19T10:44:40.988Z"
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 50,
                    "total": 7,
                    "pages": 1
                  },
                  "non_lues": 7
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "connecte",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/notifications/lues": {
      "post": {
        "operationId": "postNotificationsLues",
        "tags": [
          "Notifications"
        ],
        "summary": "Marquer des notifications comme lues",
        "description": "Marque comme lues les notifications désignées par `identifiants` ou, sans liste, toutes les non lues de l'appelant ; seules les siennes sont touchées. Le corps est facultatif. Réponse `{ marquees, non_lues }`.\n\n**Permission requise** : Être connecté (aucune permission particulière).\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "identifiants": {
                    "minItems": 1,
                    "maxItems": 200,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  }
                }
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "marquees": {
                      "type": "integer"
                    },
                    "non_lues": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "marquees",
                    "non_lues"
                  ]
                },
                "example": {
                  "marquees": 7,
                  "non_lues": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "connecte",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/relances/a-faire": {
      "get": {
        "operationId": "getRelancesAFaire",
        "tags": [
          "Notifications"
        ],
        "summary": "Lister la file de relance du jour",
        "description": "Les factures échues « emise », « partiellement_payee » ou « en_retard », par échéance croissante, avec reste à payer, jours de retard, relances déjà faites, rang de la prochaine et `a_relancer`. Répond même hors jour de relance : la réponse ajoute `jour`, `jour_de_relance`, `jours_de_relance` (paramètre `paiement.relances_jours`, mardi et jeudi par défaut) et `a_relancer_aujourdhui`.\n\n**Permission requise** : `factures.emettre`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "jour": {
                      "type": "string",
                      "format": "date"
                    },
                    "jour_de_la_semaine": {
                      "type": "string"
                    },
                    "jour_de_relance": {
                      "type": "boolean"
                    },
                    "jours_de_relance": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "a_relancer_aujourdhui": {
                      "type": "integer"
                    },
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "date_echeance": {
                            "type": "string",
                            "format": "date"
                          },
                          "montant_ttc": {
                            "type": "integer"
                          },
                          "montant_paye": {
                            "type": "integer"
                          },
                          "reste_a_payer": {
                            "type": "integer"
                          },
                          "jours_de_retard": {
                            "type": "integer"
                          },
                          "derniere_relance": {
                            "type": "null"
                          },
                          "relances_envoyees": {
                            "type": "integer"
                          },
                          "rang_prochaine_relance": {
                            "type": "integer"
                          },
                          "a_relancer": {
                            "type": "boolean"
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "telephone": {
                                "type": "null"
                              },
                              "email": {
                                "type": "string"
                              },
                              "partenaire_actuel_id": {
                                "type": "string",
                                "format": "uuid"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "telephone",
                              "email",
                              "partenaire_actuel_id"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "statut",
                          "date_echeance",
                          "montant_ttc",
                          "montant_paye",
                          "reste_a_payer",
                          "jours_de_retard",
                          "derniere_relance",
                          "relances_envoyees",
                          "rang_prochaine_relance",
                          "a_relancer",
                          "client"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "a4c1adae-118b-4c59-997c-ce7898f76a76",
                      "numero": "FAC-2026-000020",
                      "statut": "en_retard",
                      "date_echeance": "2026-10-12",
                      "montant_ttc": 23600,
                      "montant_paye": 11800,
                      "reste_a_payer": 11800,
                      "jours_de_retard": 7,
                      "derniere_relance": null,
                      "relances_envoyees": 0,
                      "rang_prochaine_relance": 1,
                      "a_relancer": true,
                      "client": {
                        "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                        "raison_sociale": "ZZ Recette WNCYUQRHJW",
                        "telephone": null,
                        "email": "contact.wncyuqrhjw@recette.satelica.test",
                        "partenaire_actuel_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e"
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 1,
                    "pages": 1
                  },
                  "jour": "2026-10-19",
                  "jour_de_la_semaine": "lundi",
                  "jour_de_relance": false,
                  "jours_de_relance": [
                    "mardi",
                    "jeudi"
                  ],
                  "a_relancer_aujourdhui": 1
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "factures.emettre",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/relances": {
      "get": {
        "operationId": "getRelances",
        "tags": [
          "Notifications"
        ],
        "summary": "Lister l'historique des relances",
        "description": "Les relances enregistrées, de la plus récente à la plus ancienne, avec leur canal, leur destinataire et leur facture (client compris). Filtres `facture_id` et `canal`.\n\n**Permission requise** : L'une de : `factures.emettre`, `espace_partenaire.acceder`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "facture_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "canal",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "plateforme",
                "email",
                "whatsapp",
                "sms"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "canal": {
                            "type": "string"
                          },
                          "destinataire": {
                            "type": "string"
                          },
                          "envoyee_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "facture": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              },
                              "date_echeance": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "montant_ttc": {
                                "type": "string"
                              },
                              "montant_paye": {
                                "type": "string"
                              },
                              "clients": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "raison_sociale": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "raison_sociale"
                                ]
                              },
                              "client": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "format": "uuid"
                                  },
                                  "raison_sociale": {
                                    "type": "string"
                                  }
                                },
                                "required": [
                                  "id",
                                  "raison_sociale"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut",
                              "date_echeance",
                              "montant_ttc",
                              "montant_paye",
                              "clients",
                              "client"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "canal",
                          "destinataire",
                          "envoyee_le",
                          "facture"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "c9991a0b-95f9-4328-9c37-8656b8000679",
                      "canal": "email",
                      "destinataire": "recouvrement@exemple.ci",
                      "envoyee_le": "2026-10-19T10:44:34.619Z",
                      "facture": {
                        "id": "a4c1adae-118b-4c59-997c-ce7898f76a76",
                        "numero": "FAC-2026-000020",
                        "statut": "payee",
                        "date_echeance": "2026-10-12T00:00:00.000Z",
                        "montant_ttc": "23600",
                        "montant_paye": "23600",
                        "clients": {
                          "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                          "raison_sociale": "ZZ Recette WNCYUQRHJW"
                        },
                        "client": {
                          "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                          "raison_sociale": "ZZ Recette WNCYUQRHJW"
                        }
                      }
                    },
                    {
                      "id": "a3c82d63-4bc7-4682-8eff-4480a2e1634f",
                      "canal": "email",
                      "destinataire": "recouvrement@exemple.ci",
                      "envoyee_le": "2026-10-19T10:42:07.391Z",
                      "facture": {
                        "id": "05493f3f-5435-415c-ab4c-fd3c927ab32a",
                        "numero": "FAC-2026-000018",
                        "statut": "payee",
                        "date_echeance": "2026-10-12T00:00:00.000Z",
                        "montant_ttc": "23600",
                        "montant_paye": "23600",
                        "clients": {
                          "id": "72439d3d-0a08-4379-8a59-cd1192e1c8d1",
                          "raison_sociale": "ZZ Recette NDDKNBHRYB"
                        },
                        "client": {
                          "id": "72439d3d-0a08-4379-8a59-cd1192e1c8d1",
                          "raison_sociale": "ZZ Recette NDDKNBHRYB"
                        }
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 3,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "factures.emettre",
          "espace_partenaire.acceder"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/factures/{id}/relances": {
      "post": {
        "operationId": "postFacturesParIdRelances",
        "tags": [
          "Paiements et factures"
        ],
        "summary": "Enregistrer la relance d'une facture",
        "description": "Déclare une relance déjà faite par le gestionnaire (`canal`, et `destinataire` réellement employé) : la plateforme n'envoie rien d'autre qu'une notification. La facture passe « en_retard » si elle ne l'était pas, et les utilisateurs actifs du client sont notifiés du reste à payer. Refusé pour une facture soldée, payée, annulée ou pas encore échue.\n\n**Permission requise** : `factures.emettre`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "canal": {
                    "type": "string",
                    "enum": [
                      "plateforme",
                      "email",
                      "whatsapp",
                      "sms"
                    ]
                  },
                  "destinataire": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 200
                  }
                },
                "required": [
                  "canal",
                  "destinataire"
                ]
              },
              "example": {
                "canal": "email",
                "destinataire": "recouvrement@exemple.ci"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "canal": {
                      "type": "string"
                    },
                    "destinataire": {
                      "type": "string"
                    },
                    "envoyee_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "rang": {
                      "type": "integer"
                    },
                    "facture": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "numero": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "numero",
                        "statut"
                      ]
                    },
                    "notifies": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "id",
                    "canal",
                    "destinataire",
                    "envoyee_le",
                    "rang",
                    "facture",
                    "notifies"
                  ]
                },
                "example": {
                  "id": "c9991a0b-95f9-4328-9c37-8656b8000679",
                  "canal": "email",
                  "destinataire": "recouvrement@exemple.ci",
                  "envoyee_le": "2026-10-19T10:44:34.619Z",
                  "rang": 1,
                  "facture": {
                    "id": "a4c1adae-118b-4c59-997c-ce7898f76a76",
                    "numero": "FAC-2026-000020",
                    "statut": "en_retard"
                  },
                  "notifies": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "factures.emettre",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/transferts": {
      "get": {
        "operationId": "getTransferts",
        "tags": [
          "Transferts de partenaire"
        ],
        "summary": "Lister les transferts de client entre partenaires",
        "description": "Les transferts d'un client d'un partenaire à un autre, du plus récent au plus ancien, filtrables par statut et par client, avec le client, les partenaires cédant et repreneur, le contrat de cession et l'auteur de l'ouverture. Un partenaire voit ceux où il cède comme ceux où il reprend ; un client n’en voit aucun.\n\n**Permission requise** : L'une de : `transferts.gerer`, `transferts.signer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "brouillon",
                "contrat_genere",
                "signe_sortant",
                "signe_entrant",
                "effectif",
                "annule"
              ]
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "client_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_sortant_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "partenaire_entrant_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "contrat_cession_fichier_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          },
                          "signe_sortant_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "signe_entrant_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "prise_effet_le": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "motif": {
                            "type": "string"
                          },
                          "cree_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "client": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "organisation_id": {
                                "type": "string",
                                "format": "uuid"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "organisation_id"
                            ]
                          },
                          "partenaire_sortant": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "organisation_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "organisation_id",
                              "code_confidentiel"
                            ]
                          },
                          "partenaire_entrant": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "raison_sociale": {
                                "type": "string"
                              },
                              "organisation_id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "code_confidentiel": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "raison_sociale",
                              "organisation_id",
                              "code_confidentiel"
                            ]
                          },
                          "contrat_cession": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "nom_original": {
                                "type": "string"
                              },
                              "type_mime": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "nom_original",
                              "type_mime"
                            ]
                          },
                          "ouvert_par": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "client_id",
                          "partenaire_sortant_id",
                          "partenaire_entrant_id",
                          "contrat_cession_fichier_id",
                          "signe_sortant_le",
                          "signe_entrant_le",
                          "prise_effet_le",
                          "statut",
                          "motif",
                          "cree_par",
                          "cree_le",
                          "modifie_le",
                          "client",
                          "partenaire_sortant",
                          "partenaire_entrant",
                          "contrat_cession",
                          "ouvert_par"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "397089dc-0c3f-4f02-91a8-e7b2fb6e7198",
                      "numero": "TRF-2026-000023",
                      "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                      "partenaire_sortant_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                      "partenaire_entrant_id": "73ead9a5-5d14-407b-b5b6-2d67785df304",
                      "contrat_cession_fichier_id": null,
                      "signe_sortant_le": null,
                      "signe_entrant_le": null,
                      "prise_effet_le": null,
                      "statut": "brouillon",
                      "motif": "Épreuve des sections : cession du portefeuille.",
                      "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "cree_le": "2026-10-19T10:46:03.271Z",
                      "modifie_le": "2026-10-19T10:46:03.271Z",
                      "client": {
                        "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                        "raison_sociale": "ZZ Recette Client 4D20EED1",
                        "organisation_id": "aa4b5620-ff71-4295-a415-f4680703972e"
                      },
                      "partenaire_sortant": {
                        "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                        "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                        "organisation_id": "e14808c3-7c52-49b5-a22f-4220bd39eeb9",
                        "code_confidentiel": "C-0076"
                      },
                      "partenaire_entrant": {
                        "id": "73ead9a5-5d14-407b-b5b6-2d67785df304",
                        "raison_sociale": "ZZ Recette Partenaire B 3B47802A",
                        "organisation_id": "258e1cf6-b0f5-497d-8b55-34ef9db4dfdf",
                        "code_confidentiel": "C-0077"
                      },
                      "contrat_cession": null,
                      "ouvert_par": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction"
                      }
                    },
                    {
                      "id": "b6a150b0-205c-4bf8-a91c-fb4e864308b7",
                      "numero": "TRF-2026-000022",
                      "client_id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                      "partenaire_sortant_id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                      "partenaire_entrant_id": "bacf2aec-2059-465e-ae6f-c83ad2e94600",
                      "contrat_cession_fichier_id": null,
                      "signe_sortant_le": null,
                      "signe_entrant_le": null,
                      "prise_effet_le": null,
                      "statut": "annule",
                      "motif": "Le client déménage dans la zone du repreneur.\n\nAnnulé : Le client reste finalement à Bouaké.",
                      "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "cree_le": "2026-10-19T10:45:13.397Z",
                      "modifie_le": "2026-10-19T10:45:13.738Z",
                      "client": {
                        "id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                        "raison_sociale": "ZZ Recette Client 62AAEFDF",
                        "organisation_id": "43237729-97df-4670-a6c5-45b1d6b404e2"
                      },
                      "partenaire_sortant": {
                        "id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                        "raison_sociale": "ZZ Recette Partenaire A 137E8405",
                        "organisation_id": "e7b69fac-9d3d-47b1-8598-3d1446631729",
                        "code_confidentiel": "C-0073"
                      },
                      "partenaire_entrant": {
                        "id": "bacf2aec-2059-465e-ae6f-c83ad2e94600",
                        "raison_sociale": "ZZ Recette Partenaire B 3FC944FA",
                        "organisation_id": "837dfa0a-42f0-4869-ab1e-dc4960a40498",
                        "code_confidentiel": "C-0074"
                      },
                      "contrat_cession": null,
                      "ouvert_par": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction"
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 100,
                    "total": 9,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "transferts.gerer",
          "transferts.signer"
        ],
        "x-satelica-cloisonnement": "applique"
      },
      "post": {
        "operationId": "postTransferts",
        "tags": [
          "Transferts de partenaire"
        ],
        "summary": "Ouvrir un transfert de client",
        "description": "CYBASTION ouvre la cession d'un client à un partenaire repreneur : le transfert naît `brouillon`, numéroté TRF, et les deux partenaires sont notifiés. Le partenaire cédant n'est pas transmis : il est lu sur le client. Un repreneur inexistant, ou déjà partenaire du client, est refusé en 400.\n\n**Permission requise** : `transferts.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "client_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "partenaire_entrant_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "motif": {
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "client_id",
                  "partenaire_entrant_id",
                  "motif"
                ]
              },
              "example": {
                "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                "partenaire_entrant_id": "8f3adb0b-7dd8-4a70-a64a-f57f9910ccc6",
                "motif": "Recette WNCYUQRHJW : cession du portefeuille."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_sortant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_entrant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contrat_cession_fichier_id": {
                      "type": "null"
                    },
                    "signe_sortant_le": {
                      "type": "null"
                    },
                    "signe_entrant_le": {
                      "type": "null"
                    },
                    "prise_effet_le": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "motif": {
                      "type": "string"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id"
                      ]
                    },
                    "partenaire_sortant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "partenaire_entrant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "contrat_cession": {
                      "type": "null"
                    },
                    "ouvert_par": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "client_id",
                    "partenaire_sortant_id",
                    "partenaire_entrant_id",
                    "contrat_cession_fichier_id",
                    "signe_sortant_le",
                    "signe_entrant_le",
                    "prise_effet_le",
                    "statut",
                    "motif",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "client",
                    "partenaire_sortant",
                    "partenaire_entrant",
                    "contrat_cession",
                    "ouvert_par"
                  ]
                },
                "example": {
                  "id": "ac5206a7-953c-486d-8c23-3b9d9c403fe1",
                  "numero": "TRF-2026-000021",
                  "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                  "partenaire_sortant_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                  "partenaire_entrant_id": "8f3adb0b-7dd8-4a70-a64a-f57f9910ccc6",
                  "contrat_cession_fichier_id": null,
                  "signe_sortant_le": null,
                  "signe_entrant_le": null,
                  "prise_effet_le": null,
                  "statut": "brouillon",
                  "motif": "Recette WNCYUQRHJW : cession du portefeuille.",
                  "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "cree_le": "2026-10-19T10:44:42.459Z",
                  "modifie_le": "2026-10-19T10:44:42.459Z",
                  "client": {
                    "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                    "raison_sociale": "ZZ Recette WNCYUQRHJW",
                    "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc"
                  },
                  "partenaire_sortant": {
                    "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                    "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                    "organisation_id": "934a4f65-f131-43c7-8f16-93262ee7472f",
                    "code_confidentiel": "C-0071"
                  },
                  "partenaire_entrant": {
                    "id": "8f3adb0b-7dd8-4a70-a64a-f57f9910ccc6",
                    "raison_sociale": "ZZ Recette Partenaire B 4B8BCA43",
                    "organisation_id": "1201717a-4f10-40c1-beff-b749a042d917",
                    "code_confidentiel": "C-0072"
                  },
                  "contrat_cession": null,
                  "ouvert_par": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "description": "Ce client n'existe pas.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "409": {
            "description": "Client sans partenaire, repreneur inactif, ou transfert déjà en cours sur ce client.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "transferts.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/transferts/{id}": {
      "get": {
        "operationId": "getTransfertsParId",
        "tags": [
          "Transferts de partenaire"
        ],
        "summary": "Lire le détail d'un transfert",
        "description": "Le transfert, avec ses parties et son contrat de cession, plus `mon_cote` (`sortant`, `entrant`, ou nul hors des deux partenaires) et `signatures_completes`, calculés par la règle même qui décide des signatures.\n\n**Permission requise** : L'une de : `transferts.gerer`, `transferts.signer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_sortant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_entrant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contrat_cession_fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "signe_sortant_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "signe_entrant_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "prise_effet_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "motif": {
                      "type": "string"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id"
                      ]
                    },
                    "partenaire_sortant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "partenaire_entrant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "contrat_cession": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom_original",
                        "type_mime"
                      ]
                    },
                    "ouvert_par": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom"
                      ]
                    },
                    "mon_cote": {
                      "type": "null"
                    },
                    "signatures_completes": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "client_id",
                    "partenaire_sortant_id",
                    "partenaire_entrant_id",
                    "contrat_cession_fichier_id",
                    "signe_sortant_le",
                    "signe_entrant_le",
                    "prise_effet_le",
                    "statut",
                    "motif",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "client",
                    "partenaire_sortant",
                    "partenaire_entrant",
                    "contrat_cession",
                    "ouvert_par",
                    "mon_cote",
                    "signatures_completes"
                  ]
                },
                "example": {
                  "id": "397089dc-0c3f-4f02-91a8-e7b2fb6e7198",
                  "numero": "TRF-2026-000023",
                  "client_id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                  "partenaire_sortant_id": "c999fdd2-4592-4b8b-938b-837af6193076",
                  "partenaire_entrant_id": "73ead9a5-5d14-407b-b5b6-2d67785df304",
                  "contrat_cession_fichier_id": "15e40f57-3623-4642-a534-fd9866dc6bc8",
                  "signe_sortant_le": "2026-10-19T10:46:04.828Z",
                  "signe_entrant_le": "2026-10-19T10:46:05.102Z",
                  "prise_effet_le": "2026-10-19T10:46:05.243Z",
                  "statut": "effectif",
                  "motif": "Épreuve des sections : cession du portefeuille.",
                  "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "cree_le": "2026-10-19T10:46:03.271Z",
                  "modifie_le": "2026-10-19T10:46:05.244Z",
                  "client": {
                    "id": "d7dc6195-5c7d-4d60-879f-e516740b576a",
                    "raison_sociale": "ZZ Recette Client 4D20EED1",
                    "organisation_id": "aa4b5620-ff71-4295-a415-f4680703972e"
                  },
                  "partenaire_sortant": {
                    "id": "c999fdd2-4592-4b8b-938b-837af6193076",
                    "raison_sociale": "ZZ Recette Partenaire A 856174D4",
                    "organisation_id": "e14808c3-7c52-49b5-a22f-4220bd39eeb9",
                    "code_confidentiel": "C-0076"
                  },
                  "partenaire_entrant": {
                    "id": "73ead9a5-5d14-407b-b5b6-2d67785df304",
                    "raison_sociale": "ZZ Recette Partenaire B 3B47802A",
                    "organisation_id": "258e1cf6-b0f5-497d-8b55-34ef9db4dfdf",
                    "code_confidentiel": "C-0077"
                  },
                  "contrat_cession": {
                    "id": "15e40f57-3623-4642-a534-fd9866dc6bc8",
                    "nom_original": "piece.pdf",
                    "type_mime": "application/pdf"
                  },
                  "ouvert_par": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction"
                  },
                  "mon_cote": null,
                  "signatures_completes": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "transferts.gerer",
          "transferts.signer"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/transferts/{id}/contrat": {
      "post": {
        "operationId": "postTransfertsParIdContrat",
        "tags": [
          "Transferts de partenaire"
        ],
        "summary": "Rattacher le contrat de cession",
        "description": "CYBASTION rattache le contrat de cession (`fichier_id`), déposé au préalable par le même compte ; un fichier inexistant ou déposé par un autre est refusé en 400. Le transfert passe de `brouillon` à `contrat_genere`, et les deux partenaires sont notifiés que leur signature est attendue.\n\n**Permission requise** : `transferts.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "fichier_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "fichier_id"
                ]
              },
              "example": {
                "fichier_id": "73062f1e-6391-4a3b-88f1-b53e5b70dbce"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_sortant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_entrant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contrat_cession_fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "signe_sortant_le": {
                      "type": "null"
                    },
                    "signe_entrant_le": {
                      "type": "null"
                    },
                    "prise_effet_le": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "motif": {
                      "type": "string"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id"
                      ]
                    },
                    "partenaire_sortant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "partenaire_entrant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "contrat_cession": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom_original",
                        "type_mime"
                      ]
                    },
                    "ouvert_par": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "client_id",
                    "partenaire_sortant_id",
                    "partenaire_entrant_id",
                    "contrat_cession_fichier_id",
                    "signe_sortant_le",
                    "signe_entrant_le",
                    "prise_effet_le",
                    "statut",
                    "motif",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "client",
                    "partenaire_sortant",
                    "partenaire_entrant",
                    "contrat_cession",
                    "ouvert_par"
                  ]
                },
                "example": {
                  "id": "ac5206a7-953c-486d-8c23-3b9d9c403fe1",
                  "numero": "TRF-2026-000021",
                  "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                  "partenaire_sortant_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                  "partenaire_entrant_id": "8f3adb0b-7dd8-4a70-a64a-f57f9910ccc6",
                  "contrat_cession_fichier_id": "73062f1e-6391-4a3b-88f1-b53e5b70dbce",
                  "signe_sortant_le": null,
                  "signe_entrant_le": null,
                  "prise_effet_le": null,
                  "statut": "contrat_genere",
                  "motif": "Recette WNCYUQRHJW : cession du portefeuille.",
                  "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "cree_le": "2026-10-19T10:44:42.459Z",
                  "modifie_le": "2026-10-19T10:44:43.155Z",
                  "client": {
                    "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                    "raison_sociale": "ZZ Recette WNCYUQRHJW",
                    "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc"
                  },
                  "partenaire_sortant": {
                    "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                    "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                    "organisation_id": "934a4f65-f131-43c7-8f16-93262ee7472f",
                    "code_confidentiel": "C-0071"
                  },
                  "partenaire_entrant": {
                    "id": "8f3adb0b-7dd8-4a70-a64a-f57f9910ccc6",
                    "raison_sociale": "ZZ Recette Partenaire B 4B8BCA43",
                    "organisation_id": "1201717a-4f10-40c1-beff-b749a042d917",
                    "code_confidentiel": "C-0072"
                  },
                  "contrat_cession": {
                    "id": "73062f1e-6391-4a3b-88f1-b53e5b70dbce",
                    "nom_original": "cession.pdf",
                    "type_mime": "application/pdf"
                  },
                  "ouvert_par": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Le transfert n'attend plus de contrat, ou le fichier n'a pas passé l'antivirus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "transferts.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/transferts/{id}/signature": {
      "post": {
        "operationId": "postTransfertsParIdSignature",
        "tags": [
          "Transferts de partenaire"
        ],
        "summary": "Signer un transfert de client",
        "description": "Un partenaire partie au transfert accepte la cession (`accepte: true`). Son côté, cédant ou repreneur, se déduit de son compte et jamais du corps ; un partenaire étranger au transfert reçoit 404. Le statut passe à `signe_sortant` ou `signe_entrant` selon ce côté, et la réponse dit si les deux signatures sont réunies (`signatures_completes`).\n\n**Permission requise** : `transferts.signer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "accepte": {
                    "type": "boolean",
                    "const": true
                  }
                },
                "required": [
                  "accepte"
                ]
              },
              "example": {
                "accepte": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 4 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_sortant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_entrant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contrat_cession_fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "signe_sortant_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "signe_entrant_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "prise_effet_le": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "motif": {
                      "type": "string"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id"
                      ]
                    },
                    "partenaire_sortant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "partenaire_entrant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "contrat_cession": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom_original",
                        "type_mime"
                      ]
                    },
                    "ouvert_par": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom"
                      ]
                    },
                    "mon_cote": {
                      "type": "string"
                    },
                    "signatures_completes": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "client_id",
                    "partenaire_sortant_id",
                    "partenaire_entrant_id",
                    "contrat_cession_fichier_id",
                    "signe_sortant_le",
                    "signe_entrant_le",
                    "prise_effet_le",
                    "statut",
                    "motif",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "client",
                    "partenaire_sortant",
                    "partenaire_entrant",
                    "contrat_cession",
                    "ouvert_par",
                    "mon_cote",
                    "signatures_completes"
                  ]
                },
                "example": {
                  "id": "ac5206a7-953c-486d-8c23-3b9d9c403fe1",
                  "numero": "TRF-2026-000021",
                  "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                  "partenaire_sortant_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                  "partenaire_entrant_id": "8f3adb0b-7dd8-4a70-a64a-f57f9910ccc6",
                  "contrat_cession_fichier_id": "73062f1e-6391-4a3b-88f1-b53e5b70dbce",
                  "signe_sortant_le": null,
                  "signe_entrant_le": "2026-10-19T10:44:43.601Z",
                  "prise_effet_le": null,
                  "statut": "signe_entrant",
                  "motif": "Recette WNCYUQRHJW : cession du portefeuille.",
                  "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "cree_le": "2026-10-19T10:44:42.459Z",
                  "modifie_le": "2026-10-19T10:44:43.600Z",
                  "client": {
                    "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                    "raison_sociale": "ZZ Recette WNCYUQRHJW",
                    "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc"
                  },
                  "partenaire_sortant": {
                    "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                    "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                    "organisation_id": "934a4f65-f131-43c7-8f16-93262ee7472f",
                    "code_confidentiel": "C-0071"
                  },
                  "partenaire_entrant": {
                    "id": "8f3adb0b-7dd8-4a70-a64a-f57f9910ccc6",
                    "raison_sociale": "ZZ Recette Partenaire B 4B8BCA43",
                    "organisation_id": "1201717a-4f10-40c1-beff-b749a042d917",
                    "code_confidentiel": "C-0072"
                  },
                  "contrat_cession": {
                    "id": "73062f1e-6391-4a3b-88f1-b53e5b70dbce",
                    "nom_original": "cession.pdf",
                    "type_mime": "application/pdf"
                  },
                  "ouvert_par": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction"
                  },
                  "mon_cote": "entrant",
                  "signatures_completes": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Contrat de cession absent, déjà signé de ce côté, ou transfert qui ne se signe plus.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "transferts.signer",
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/transferts/{id}/effet": {
      "post": {
        "operationId": "postTransfertsParIdEffet",
        "tags": [
          "Transferts de partenaire"
        ],
        "summary": "Faire prendre effet un transfert",
        "description": "Les deux signatures réunies, CYBASTION fait passer le client au repreneur, à la date `prise_effet_le` ou aujourd'hui (corps facultatif) : l'affectation en cours se ferme, une nouvelle s'ouvre avec l'origine `transfert`, et le transfert devient `effectif`. Les commissions déjà nées restent au cédant. Le client est notifié par la référence confidentielle du repreneur, jamais par son nom ; les deux partenaires le sont aussi.\n\n**Permission requise** : `transferts.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prise_effet_le": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  }
                }
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_sortant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_entrant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contrat_cession_fichier_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "signe_sortant_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "signe_entrant_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "prise_effet_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "motif": {
                      "type": "string"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id"
                      ]
                    },
                    "partenaire_sortant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "partenaire_entrant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "contrat_cession": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom_original": {
                          "type": "string"
                        },
                        "type_mime": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom_original",
                        "type_mime"
                      ]
                    },
                    "ouvert_par": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "client_id",
                    "partenaire_sortant_id",
                    "partenaire_entrant_id",
                    "contrat_cession_fichier_id",
                    "signe_sortant_le",
                    "signe_entrant_le",
                    "prise_effet_le",
                    "statut",
                    "motif",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "client",
                    "partenaire_sortant",
                    "partenaire_entrant",
                    "contrat_cession",
                    "ouvert_par"
                  ]
                },
                "example": {
                  "id": "ac5206a7-953c-486d-8c23-3b9d9c403fe1",
                  "numero": "TRF-2026-000021",
                  "client_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                  "partenaire_sortant_id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                  "partenaire_entrant_id": "8f3adb0b-7dd8-4a70-a64a-f57f9910ccc6",
                  "contrat_cession_fichier_id": "73062f1e-6391-4a3b-88f1-b53e5b70dbce",
                  "signe_sortant_le": "2026-10-19T10:44:43.855Z",
                  "signe_entrant_le": "2026-10-19T10:44:43.601Z",
                  "prise_effet_le": "2026-10-19T10:44:43.985Z",
                  "statut": "effectif",
                  "motif": "Recette WNCYUQRHJW : cession du portefeuille.",
                  "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "cree_le": "2026-10-19T10:44:42.459Z",
                  "modifie_le": "2026-10-19T10:44:43.985Z",
                  "client": {
                    "id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                    "raison_sociale": "ZZ Recette WNCYUQRHJW",
                    "organisation_id": "a491d8ea-5829-445e-9419-90455eeefccc"
                  },
                  "partenaire_sortant": {
                    "id": "a89cf671-44d7-49ae-83e0-51c91b68de7e",
                    "raison_sociale": "ZZ Recette Partenaire A DFA45D10",
                    "organisation_id": "934a4f65-f131-43c7-8f16-93262ee7472f",
                    "code_confidentiel": "C-0071"
                  },
                  "partenaire_entrant": {
                    "id": "8f3adb0b-7dd8-4a70-a64a-f57f9910ccc6",
                    "raison_sociale": "ZZ Recette Partenaire B 4B8BCA43",
                    "organisation_id": "1201717a-4f10-40c1-beff-b749a042d917",
                    "code_confidentiel": "C-0072"
                  },
                  "contrat_cession": {
                    "id": "73062f1e-6391-4a3b-88f1-b53e5b70dbce",
                    "nom_original": "cession.pdf",
                    "type_mime": "application/pdf"
                  },
                  "ouvert_par": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Signatures incomplètes, statut incompatible, ou client qui n’est plus détenu par le cédant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "transferts.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/transferts/{id}/annulation": {
      "post": {
        "operationId": "postTransfertsParIdAnnulation",
        "tags": [
          "Transferts de partenaire"
        ],
        "summary": "Annuler un transfert",
        "description": "CYBASTION annule un transfert qui n'a pas encore pris effet : il passe `annule`, et le motif d'annulation s'ajoute au motif d'ouverture au lieu de le remplacer. Les deux partenaires sont notifiés.\n\n**Permission requise** : `transferts.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "motif": {
                    "type": "string",
                    "minLength": 5,
                    "maxLength": 1000
                  }
                },
                "required": [
                  "motif"
                ]
              },
              "example": {
                "motif": "Le client reste finalement à Bouaké."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "numero": {
                      "type": "string"
                    },
                    "client_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_sortant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "partenaire_entrant_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "contrat_cession_fichier_id": {
                      "type": "null"
                    },
                    "signe_sortant_le": {
                      "type": "null"
                    },
                    "signe_entrant_le": {
                      "type": "null"
                    },
                    "prise_effet_le": {
                      "type": "null"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "motif": {
                      "type": "string"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "client": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id"
                      ]
                    },
                    "partenaire_sortant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "partenaire_entrant": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "raison_sociale": {
                          "type": "string"
                        },
                        "organisation_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "code_confidentiel": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "raison_sociale",
                        "organisation_id",
                        "code_confidentiel"
                      ]
                    },
                    "contrat_cession": {
                      "type": "null"
                    },
                    "ouvert_par": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "numero",
                    "client_id",
                    "partenaire_sortant_id",
                    "partenaire_entrant_id",
                    "contrat_cession_fichier_id",
                    "signe_sortant_le",
                    "signe_entrant_le",
                    "prise_effet_le",
                    "statut",
                    "motif",
                    "cree_par",
                    "cree_le",
                    "modifie_le",
                    "client",
                    "partenaire_sortant",
                    "partenaire_entrant",
                    "contrat_cession",
                    "ouvert_par"
                  ]
                },
                "example": {
                  "id": "b6a150b0-205c-4bf8-a91c-fb4e864308b7",
                  "numero": "TRF-2026-000022",
                  "client_id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                  "partenaire_sortant_id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                  "partenaire_entrant_id": "bacf2aec-2059-465e-ae6f-c83ad2e94600",
                  "contrat_cession_fichier_id": null,
                  "signe_sortant_le": null,
                  "signe_entrant_le": null,
                  "prise_effet_le": null,
                  "statut": "annule",
                  "motif": "Le client déménage dans la zone du repreneur.\n\nAnnulé : Le client reste finalement à Bouaké.",
                  "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "cree_le": "2026-10-19T10:45:13.397Z",
                  "modifie_le": "2026-10-19T10:45:13.738Z",
                  "client": {
                    "id": "9dacf77d-25e9-4412-8460-0121995e84d2",
                    "raison_sociale": "ZZ Recette Client 62AAEFDF",
                    "organisation_id": "43237729-97df-4670-a6c5-45b1d6b404e2"
                  },
                  "partenaire_sortant": {
                    "id": "c0d0f4c4-e246-4e71-8212-6afcb3b2decf",
                    "raison_sociale": "ZZ Recette Partenaire A 137E8405",
                    "organisation_id": "e7b69fac-9d3d-47b1-8598-3d1446631729",
                    "code_confidentiel": "C-0073"
                  },
                  "partenaire_entrant": {
                    "id": "bacf2aec-2059-465e-ae6f-c83ad2e94600",
                    "raison_sociale": "ZZ Recette Partenaire B 3FC944FA",
                    "organisation_id": "837dfa0a-42f0-4869-ab1e-dc4960a40498",
                    "code_confidentiel": "C-0074"
                  },
                  "contrat_cession": null,
                  "ouvert_par": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Transfert déjà effectif ou déjà annulé.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "transferts.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/delais-traitement": {
      "get": {
        "operationId": "getDelaisTraitement",
        "tags": [
          "Actions et suivi"
        ],
        "summary": "Lister les délais de traitement des actions",
        "description": "Les délais configurés par type d'objet et par priorité (heures accordées, heures de dépassement avant escalade), et `defauts` : le délai en heures appliqué à chaque priorité quand aucun n'est configuré (normale 72, urgente 24, critique 4). Réponse `{ donnees: [...], defauts }`, non paginée.\n\n**Permission requise** : L'une de : `actions.gerer`, `parametres.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "objet_type": {
                            "type": "string"
                          },
                          "priorite": {
                            "type": "string"
                          },
                          "delai_heures": {
                            "type": "integer"
                          },
                          "escalade_apres_heures": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "objet_type",
                          "priorite",
                          "delai_heures",
                          "escalade_apres_heures",
                          "modifie_le"
                        ]
                      }
                    },
                    "defauts": {
                      "type": "object",
                      "properties": {
                        "normale": {
                          "type": "integer"
                        },
                        "urgente": {
                          "type": "integer"
                        },
                        "critique": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "normale",
                        "urgente",
                        "critique"
                      ]
                    }
                  },
                  "required": [
                    "donnees",
                    "defauts"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "52445990-adae-4e4f-8fd0-782867d24bda",
                      "objet_type": "actions",
                      "priorite": "normale",
                      "delai_heures": 72,
                      "escalade_apres_heures": null,
                      "modifie_le": "2026-10-12T13:24:07.166Z"
                    },
                    {
                      "id": "f4bb9b94-b37f-401b-8e09-09281cbe4cac",
                      "objet_type": "clients",
                      "priorite": "normale",
                      "delai_heures": 72,
                      "escalade_apres_heures": null,
                      "modifie_le": "2026-10-12T13:20:12.284Z"
                    }
                  ],
                  "defauts": {
                    "normale": 72,
                    "urgente": 24,
                    "critique": 4
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "actions.gerer",
          "parametres.gerer"
        ],
        "x-satelica-cloisonnement": "cybastion"
      },
      "put": {
        "operationId": "putDelaisTraitement",
        "tags": [
          "Actions et suivi"
        ],
        "summary": "Régler le délai de traitement d'un type d'objet",
        "description": "Crée ou remplace le délai du couple (type d'objet, priorité) : heures accordées et, facultativement, heures de dépassement avant escalade (nul : pas d'escalade). Le réglage est inscrit au journal d'audit.\n\n**Permission requise** : `parametres.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "objet_type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "priorite": {
                    "type": "string",
                    "enum": [
                      "normale",
                      "urgente",
                      "critique"
                    ]
                  },
                  "delai_heures": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 8760
                  },
                  "escalade_apres_heures": {
                    "anyOf": [
                      {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 8760
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "objet_type",
                  "priorite",
                  "delai_heures"
                ]
              },
              "example": {
                "objet_type": "recette",
                "priorite": "critique",
                "delai_heures": 4,
                "escalade_apres_heures": 2
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "objet_type": {
                      "type": "string"
                    },
                    "priorite": {
                      "type": "string"
                    },
                    "delai_heures": {
                      "type": "integer"
                    },
                    "escalade_apres_heures": {
                      "type": "integer"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "required": [
                    "id",
                    "objet_type",
                    "priorite",
                    "delai_heures",
                    "escalade_apres_heures",
                    "modifie_le"
                  ]
                },
                "example": {
                  "id": "fc5a0a31-7635-4bc3-bc34-e0f05d6c3104",
                  "objet_type": "recette",
                  "priorite": "critique",
                  "delai_heures": 4,
                  "escalade_apres_heures": 2,
                  "modifie_le": "2026-10-19T10:44:44.714Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "parametres.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/actions": {
      "get": {
        "operationId": "getActions",
        "tags": [
          "Actions et suivi"
        ],
        "summary": "Lister les actions internes",
        "description": "La file des actions de CYBASTION, triée par priorité puis par échéance. Filtres : `statut`, `priorite`, `type` (valeurs de l'ouverture et du traitement d'une action ; une ou plusieurs, séparées par des virgules), `objet_type`, `objet_id`, `assigne_a`, `mes_actions` (celles de l'appelant, prioritaire sur `assigne_a`) et `en_retard`. Chaque ligne porte `en_retard`, `heures_de_retard` et `a_escalader` ; la réponse ajoute les compteurs `en_retard` et `a_escalader` de la page.\n\n**Permission requise** : `actions.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "priorite",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          },
          {
            "name": "objet_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 60
            }
          },
          {
            "name": "objet_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "assigne_a",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "mes_actions",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "en_retard",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "en_retard": {
                      "type": "integer"
                    },
                    "a_escalader": {
                      "type": "integer"
                    },
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "titre": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "objet_type": {
                            "type": "string"
                          },
                          "objet_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "priorite": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "assigne_a": {
                            "type": "null"
                          },
                          "equipe": {
                            "type": "null"
                          },
                          "echeance": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "niveau_escalade": {
                            "type": "integer"
                          },
                          "escalade_le": {
                            "type": "null"
                          },
                          "cree_par": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "terminee_par": {
                            "type": "null"
                          },
                          "terminee_le": {
                            "type": "null"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "en_retard": {
                            "type": "boolean"
                          },
                          "heures_de_retard": {
                            "type": "integer"
                          },
                          "a_escalader": {
                            "type": "boolean"
                          },
                          "assigne": {
                            "type": "null"
                          },
                          "ouvert_par": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "prenom": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "email": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "prenom",
                              "nom",
                              "email"
                            ]
                          },
                          "termine_par": {
                            "type": "null"
                          }
                        },
                        "required": [
                          "id",
                          "type",
                          "titre",
                          "description",
                          "objet_type",
                          "objet_id",
                          "priorite",
                          "statut",
                          "assigne_a",
                          "equipe",
                          "echeance",
                          "niveau_escalade",
                          "escalade_le",
                          "cree_par",
                          "terminee_par",
                          "terminee_le",
                          "cree_le",
                          "modifie_le",
                          "en_retard",
                          "heures_de_retard",
                          "a_escalader",
                          "assigne",
                          "ouvert_par",
                          "termine_par"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "0cff9539-ae82-402c-a985-bb60d0b0ae13",
                      "type": "appel",
                      "titre": "Rappeler le client — recette WNCYUQRHJW",
                      "description": "Vérifier la satisfaction après la mise en service.",
                      "objet_type": "recette",
                      "objet_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                      "priorite": "critique",
                      "statut": "a_faire",
                      "assigne_a": null,
                      "equipe": null,
                      "echeance": "2026-10-19T16:44:44.997Z",
                      "niveau_escalade": 0,
                      "escalade_le": null,
                      "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                      "terminee_par": null,
                      "terminee_le": null,
                      "cree_le": "2026-10-19T10:44:44.999Z",
                      "modifie_le": "2026-10-19T10:44:44.999Z",
                      "en_retard": false,
                      "heures_de_retard": 0,
                      "a_escalader": false,
                      "assigne": null,
                      "ouvert_par": {
                        "id": "86ce3683-763a-4644-9b69-5412f153968f",
                        "prenom": "Administrateur",
                        "nom": "Préproduction",
                        "email": "admin.cybastion@preprod.satelica.test"
                      },
                      "termine_par": null
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 20,
                    "total": 1,
                    "pages": 1
                  },
                  "en_retard": 0,
                  "a_escalader": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "actions.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "post": {
        "operationId": "postActions",
        "tags": [
          "Actions et suivi"
        ],
        "summary": "Ouvrir une action interne",
        "description": "Crée une action « a_faire » sur un objet du métier (`objet_type`, `objet_id`). Sans `echeance`, l'échéance découle du délai configuré pour ce type d'objet et cette priorité, ou du délai par défaut. L'ouverture est tracée sur l'objet, et la personne assignée, si ce n'est pas l'appelant, est notifiée.\n\n**Permission requise** : `actions.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "appel",
                      "rendez_vous",
                      "note",
                      "email",
                      "document",
                      "validation",
                      "changement_statut",
                      "installation",
                      "incident",
                      "paiement",
                      "commission",
                      "alerte"
                    ]
                  },
                  "titre": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 5000
                  },
                  "objet_type": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "objet_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "priorite": {
                    "default": "normale",
                    "type": "string",
                    "enum": [
                      "normale",
                      "urgente",
                      "critique"
                    ]
                  },
                  "assigne_a": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "equipe": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "echeance": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  }
                },
                "required": [
                  "type",
                  "titre",
                  "objet_type",
                  "objet_id"
                ]
              },
              "example": {
                "type": "appel",
                "titre": "Rappeler le client — recette WNCYUQRHJW",
                "description": "Vérifier la satisfaction après la mise en service.",
                "objet_type": "recette",
                "objet_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                "priorite": "critique"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string"
                    },
                    "titre": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "objet_type": {
                      "type": "string"
                    },
                    "objet_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "priorite": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "assigne_a": {
                      "type": "null"
                    },
                    "equipe": {
                      "type": "null"
                    },
                    "echeance": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "niveau_escalade": {
                      "type": "integer"
                    },
                    "escalade_le": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "terminee_par": {
                      "type": "null"
                    },
                    "terminee_le": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "en_retard": {
                      "type": "boolean"
                    },
                    "heures_de_retard": {
                      "type": "integer"
                    },
                    "a_escalader": {
                      "type": "boolean"
                    },
                    "assigne": {
                      "type": "null"
                    },
                    "ouvert_par": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "termine_par": {
                      "type": "null"
                    }
                  },
                  "required": [
                    "id",
                    "type",
                    "titre",
                    "description",
                    "objet_type",
                    "objet_id",
                    "priorite",
                    "statut",
                    "assigne_a",
                    "equipe",
                    "echeance",
                    "niveau_escalade",
                    "escalade_le",
                    "cree_par",
                    "terminee_par",
                    "terminee_le",
                    "cree_le",
                    "modifie_le",
                    "en_retard",
                    "heures_de_retard",
                    "a_escalader",
                    "assigne",
                    "ouvert_par",
                    "termine_par"
                  ]
                },
                "example": {
                  "id": "0cff9539-ae82-402c-a985-bb60d0b0ae13",
                  "type": "appel",
                  "titre": "Rappeler le client — recette WNCYUQRHJW",
                  "description": "Vérifier la satisfaction après la mise en service.",
                  "objet_type": "recette",
                  "objet_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                  "priorite": "critique",
                  "statut": "a_faire",
                  "assigne_a": null,
                  "equipe": null,
                  "echeance": "2026-10-19T16:44:44.997Z",
                  "niveau_escalade": 0,
                  "escalade_le": null,
                  "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "terminee_par": null,
                  "terminee_le": null,
                  "cree_le": "2026-10-19T10:44:44.999Z",
                  "modifie_le": "2026-10-19T10:44:44.999Z",
                  "en_retard": false,
                  "heures_de_retard": 0,
                  "a_escalader": false,
                  "assigne": null,
                  "ouvert_par": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction",
                    "email": "admin.cybastion@preprod.satelica.test"
                  },
                  "termine_par": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "actions.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/actions/{id}": {
      "patch": {
        "operationId": "patchActionsParId",
        "tags": [
          "Actions et suivi"
        ],
        "summary": "Faire avancer une action",
        "description": "Change en un seul appel le statut, l'assignation, l'équipe ou la priorité d'une action, ou la remonte d'un niveau (`escalader`). Les transitions de statut sont contrôlées ; terminer inscrit qui et quand, reprendre une action terminée l’efface. Un nouvel assigné autre que l'appelant est notifié.\n\n**Permission requise** : `actions.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "statut": {
                    "type": "string",
                    "enum": [
                      "a_faire",
                      "en_cours",
                      "terminee",
                      "annulee"
                    ]
                  },
                  "assigne_a": {
                    "anyOf": [
                      {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "equipe": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 100
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "priorite": {
                    "type": "string",
                    "enum": [
                      "normale",
                      "urgente",
                      "critique"
                    ]
                  },
                  "escalader": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "statut": "en_cours"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "type": {
                      "type": "string"
                    },
                    "titre": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "objet_type": {
                      "type": "string"
                    },
                    "objet_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "priorite": {
                      "type": "string"
                    },
                    "statut": {
                      "type": "string"
                    },
                    "assigne_a": {
                      "type": "null"
                    },
                    "equipe": {
                      "type": "null"
                    },
                    "echeance": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "niveau_escalade": {
                      "type": "integer"
                    },
                    "escalade_le": {
                      "type": "null"
                    },
                    "cree_par": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "terminee_par": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "uuid"
                    },
                    "terminee_le": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "en_retard": {
                      "type": "boolean"
                    },
                    "heures_de_retard": {
                      "type": "integer"
                    },
                    "a_escalader": {
                      "type": "boolean"
                    },
                    "assigne": {
                      "type": "null"
                    },
                    "ouvert_par": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    },
                    "termine_par": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "prenom": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "prenom",
                        "nom",
                        "email"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "type",
                    "titre",
                    "description",
                    "objet_type",
                    "objet_id",
                    "priorite",
                    "statut",
                    "assigne_a",
                    "equipe",
                    "echeance",
                    "niveau_escalade",
                    "escalade_le",
                    "cree_par",
                    "terminee_par",
                    "terminee_le",
                    "cree_le",
                    "modifie_le",
                    "en_retard",
                    "heures_de_retard",
                    "a_escalader",
                    "assigne",
                    "ouvert_par",
                    "termine_par"
                  ]
                },
                "example": {
                  "id": "0cff9539-ae82-402c-a985-bb60d0b0ae13",
                  "type": "appel",
                  "titre": "Rappeler le client — recette WNCYUQRHJW",
                  "description": "Vérifier la satisfaction après la mise en service.",
                  "objet_type": "recette",
                  "objet_id": "1395964f-56ca-4a20-83ee-cb55a26e07d2",
                  "priorite": "critique",
                  "statut": "en_cours",
                  "assigne_a": null,
                  "equipe": null,
                  "echeance": "2026-10-19T16:44:44.997Z",
                  "niveau_escalade": 0,
                  "escalade_le": null,
                  "cree_par": "86ce3683-763a-4644-9b69-5412f153968f",
                  "terminee_par": null,
                  "terminee_le": null,
                  "cree_le": "2026-10-19T10:44:44.999Z",
                  "modifie_le": "2026-10-19T10:44:45.381Z",
                  "en_retard": false,
                  "heures_de_retard": 0,
                  "a_escalader": false,
                  "assigne": null,
                  "ouvert_par": {
                    "id": "86ce3683-763a-4644-9b69-5412f153968f",
                    "prenom": "Administrateur",
                    "nom": "Préproduction",
                    "email": "admin.cybastion@preprod.satelica.test"
                  },
                  "termine_par": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Transition de statut interdite : une action annulée ne revient pas.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "actions.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/zones": {
      "get": {
        "operationId": "getZones",
        "tags": [
          "Référentiels"
        ],
        "summary": "Lister les zones géographiques",
        "description": "Les zones géographiques (code, libellé, type, zone parente), triées par type puis libellé. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : Être connecté (aucune permission particulière).\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          },
                          "parent_id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "uuid"
                          }
                        },
                        "required": [
                          "id",
                          "code",
                          "libelle",
                          "type",
                          "parent_id"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "f9b4dbca-87d9-4f11-a748-882560e2b21d",
                      "code": "CI-BAS-SASSANDRA",
                      "libelle": "Bas-Sassandra",
                      "type": "region",
                      "parent_id": null
                    },
                    {
                      "id": "a2d81e17-1db7-41c2-850f-3e5b22983585",
                      "code": "CI-COMOE",
                      "libelle": "Comoé",
                      "type": "region",
                      "parent_id": null
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "connecte",
        "x-satelica-cloisonnement": "sans_objet"
      }
    },
    "/api/v1/secteurs": {
      "get": {
        "operationId": "getSecteurs",
        "tags": [
          "Référentiels"
        ],
        "summary": "Lister les secteurs d'activité",
        "description": "Les secteurs d'activité (code, libellé), par ordre alphabétique. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : Être connecté (aucune permission particulière).\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "code",
                          "libelle"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "77100ede-d73d-482e-98fb-2e2fe85001cf",
                      "code": "administration_public",
                      "libelle": "Administration / public"
                    },
                    {
                      "id": "382367d8-6caf-4a01-bd28-44e1588b1a9c",
                      "code": "agriculture_agro_industrie",
                      "libelle": "Agriculture / agro-industrie"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "connecte",
        "x-satelica-cloisonnement": "sans_objet"
      }
    },
    "/api/v1/types-documents": {
      "get": {
        "operationId": "getTypesDocuments",
        "tags": [
          "Référentiels"
        ],
        "summary": "Lister les types de pièces justificatives",
        "description": "Les types de pièces du dossier : code, libellé, cible, caractère obligatoire, durée de validité en mois, pièce exigée dès la création du client, état actif. Tous les types, actifs ou non, triés par code. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : Être connecté (aucune permission particulière).\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 14 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "cible": {
                            "type": "string"
                          },
                          "obligatoire": {
                            "type": "boolean"
                          },
                          "validite_mois": {
                            "type": "null"
                          },
                          "actif": {
                            "type": "boolean"
                          },
                          "exigee_creation": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "code",
                          "libelle",
                          "cible",
                          "obligatoire",
                          "validite_mois",
                          "actif",
                          "exigee_creation"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "667a07d3-90d6-4b45-9430-ef1f215e331c",
                      "code": "client_document_complementaire",
                      "libelle": "Document KYC complémentaire",
                      "cible": "client",
                      "obligatoire": false,
                      "validite_mois": null,
                      "actif": true,
                      "exigee_creation": false
                    },
                    {
                      "id": "65112411-529e-4bcd-908a-c87e88a601c8",
                      "code": "client_identifiant_fiscal",
                      "libelle": "Identifiant fiscal (NCC)",
                      "cible": "client",
                      "obligatoire": true,
                      "validite_mois": null,
                      "actif": true,
                      "exigee_creation": false
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "connecte",
        "x-satelica-cloisonnement": "sans_objet"
      }
    },
    "/api/v1/roles": {
      "get": {
        "operationId": "getRoles",
        "tags": [
          "Administration"
        ],
        "summary": "Lister les rôles et leurs permissions",
        "description": "Les rôles avec leur type d’organisation, leurs permissions et leur nombre de titulaires (`nb_utilisateurs`). CYBASTION les voit tous ; une autre organisation ne voit que les rôles de son type. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : L'une de : `roles.gerer`, `utilisateurs_organisation.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 5 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "type_organisation": {
                            "type": "string"
                          },
                          "systeme": {
                            "type": "boolean"
                          },
                          "permissions": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "nb_utilisateurs": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "code",
                          "libelle",
                          "type_organisation",
                          "systeme",
                          "permissions",
                          "nb_utilisateurs"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "edbc2322-7e46-4ce3-8d39-71728d29c710",
                      "code": "cybastion_administrateur",
                      "libelle": "Administrateur CYBASTION",
                      "type_organisation": "cybastion",
                      "systeme": true,
                      "permissions": [
                        "actions.gerer",
                        "activations.gerer"
                      ],
                      "nb_utilisateurs": 2
                    },
                    {
                      "id": "6c5744cd-832b-4dbd-9ee2-4b37e8ebe361",
                      "code": "cybastion_compliance",
                      "libelle": "Compliance / KYC",
                      "type_organisation": "cybastion",
                      "systeme": true,
                      "permissions": [
                        "actions.gerer",
                        "audit.consulter"
                      ],
                      "nb_utilisateurs": 0
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "roles.gerer",
          "utilisateurs_organisation.gerer"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/permissions": {
      "get": {
        "operationId": "getPermissions",
        "tags": [
          "Référentiels"
        ],
        "summary": "Lister les permissions de la plateforme",
        "description": "Toutes les permissions (code, libellé, module), triées par module puis par code : la liste dans laquelle se choisissent les droits d'un rôle. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : `roles.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "module": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "code",
                          "libelle",
                          "module"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "a64554fa-ed7b-427f-8bc3-b59168b84a7f",
                      "code": "audit.consulter",
                      "libelle": "Consulter le journal d'audit",
                      "module": "administration"
                    },
                    {
                      "id": "cbb748cc-7acb-47ab-ad8f-c2a4514a3448",
                      "code": "backoffice.acceder",
                      "libelle": "Accéder au back-office CYBASTION",
                      "module": "administration"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "roles.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/organisations": {
      "get": {
        "operationId": "getOrganisations",
        "tags": [
          "Référentiels"
        ],
        "summary": "Lister les organisations",
        "description": "CYBASTION, les partenaires, les clients et VIP Net : type, nom, statut et nombre de comptes (`nb_utilisateurs`), triés par type puis par nom. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : `utilisateurs.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "type": {
                            "type": "string"
                          },
                          "nom": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "nb_utilisateurs": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "id",
                          "type",
                          "nom",
                          "statut",
                          "cree_le",
                          "modifie_le",
                          "nb_utilisateurs"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "180a06ad-6872-45e7-a5b6-d7c23799fde9",
                      "type": "cybastion",
                      "nom": "CYBASTION",
                      "statut": "active",
                      "cree_le": "2026-10-12T13:18:08.116Z",
                      "modifie_le": "2026-10-12T13:18:08.116Z",
                      "nb_utilisateurs": 2
                    },
                    {
                      "id": "935bd040-8eae-4dc8-87e4-7ed05a41d615",
                      "type": "partenaire",
                      "nom": "Distributeur de démonstration Odoo",
                      "statut": "active",
                      "cree_le": "2026-10-12T19:06:50.197Z",
                      "modifie_le": "2026-10-12T19:06:50.197Z",
                      "nb_utilisateurs": 2
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "utilisateurs.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/utilisateurs": {
      "get": {
        "operationId": "getUtilisateurs",
        "tags": [
          "Administration"
        ],
        "summary": "Lister les comptes utilisateurs",
        "description": "Les comptes avec leur organisation, leur rôle (rendu en liste `roles`), leur état et leur dernière connexion, triés par nom puis prénom. Filtrables par état actif ; `organisation_id` n'est retenu que pour CYBASTION, une autre organisation ne voyant que ses propres comptes. Réponse `{ donnees: [...] }`, non paginée.\n\n**Permission requise** : L'une de : `utilisateurs.gerer`, `utilisateurs_organisation.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "organisation_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "actif",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 5 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "organisation_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "role_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "prenom": {
                            "type": "string"
                          },
                          "nom": {
                            "type": "string"
                          },
                          "email": {
                            "type": "string"
                          },
                          "telephone": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "fonction": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "actif": {
                            "type": "boolean"
                          },
                          "double_authentification": {
                            "type": "boolean"
                          },
                          "derniere_connexion": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "roles": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "code": {
                                  "type": "string"
                                },
                                "libelle": {
                                  "type": "string"
                                },
                                "type_organisation": {
                                  "type": "string"
                                },
                                "systeme": {
                                  "type": "boolean"
                                }
                              },
                              "required": [
                                "id",
                                "code",
                                "libelle",
                                "type_organisation",
                                "systeme"
                              ]
                            }
                          },
                          "organisation": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "type": {
                                "type": "string"
                              },
                              "nom": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "type",
                              "nom",
                              "statut"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "organisation_id",
                          "role_id",
                          "prenom",
                          "nom",
                          "email",
                          "telephone",
                          "fonction",
                          "actif",
                          "double_authentification",
                          "derniere_connexion",
                          "cree_le",
                          "modifie_le",
                          "roles",
                          "organisation"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "id": "247dd9f4-3c42-474a-9aad-e0a5f7b89c51",
                      "organisation_id": "d585efb9-064a-4729-a718-16b29b2cc852",
                      "role_id": "e87d575d-7da6-436b-a84e-49f9a2de8d1e",
                      "prenom": "ZZ Recette",
                      "nom": "Client 14A4B9D7",
                      "email": "zz.client.14a4b9d7@exemple.invalide",
                      "telephone": null,
                      "fonction": null,
                      "actif": true,
                      "double_authentification": false,
                      "derniere_connexion": "2026-10-19T10:42:37.950Z",
                      "cree_le": "2026-10-19T10:42:31.093Z",
                      "modifie_le": "2026-10-19T10:42:37.951Z",
                      "roles": [
                        {
                          "id": "e87d575d-7da6-436b-a84e-49f9a2de8d1e",
                          "code": "client_validateur",
                          "libelle": "Validateur / Administrateur",
                          "type_organisation": "client",
                          "systeme": true
                        }
                      ],
                      "organisation": {
                        "id": "d585efb9-064a-4729-a718-16b29b2cc852",
                        "type": "client",
                        "nom": "ZZ Recette Client 14A4B9D7",
                        "statut": "active"
                      }
                    },
                    {
                      "id": "edfef6ee-b1d4-4b2e-b1b0-cb7f47d5ad2b",
                      "organisation_id": "b09fd0c9-c7d3-4f86-9648-cc26135ebc44",
                      "role_id": "e87d575d-7da6-436b-a84e-49f9a2de8d1e",
                      "prenom": "ZZ Recette",
                      "nom": "Client 2EEAF409",
                      "email": "zz.client.2eeaf409@exemple.invalide",
                      "telephone": null,
                      "fonction": null,
                      "actif": true,
                      "double_authentification": false,
                      "derniere_connexion": "2026-10-19T10:41:16.715Z",
                      "cree_le": "2026-10-19T10:41:09.828Z",
                      "modifie_le": "2026-10-19T10:41:16.715Z",
                      "roles": [
                        {
                          "id": "e87d575d-7da6-436b-a84e-49f9a2de8d1e",
                          "code": "client_validateur",
                          "libelle": "Validateur / Administrateur",
                          "type_organisation": "client",
                          "systeme": true
                        }
                      ],
                      "organisation": {
                        "id": "b09fd0c9-c7d3-4f86-9648-cc26135ebc44",
                        "type": "client",
                        "nom": "ZZ Recette Client 2EEAF409",
                        "statut": "active"
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "utilisateurs.gerer",
          "utilisateurs_organisation.gerer"
        ],
        "x-satelica-cloisonnement": "applique"
      },
      "post": {
        "operationId": "postUtilisateurs",
        "tags": [
          "Administration"
        ],
        "summary": "Ouvrir un compte utilisateur",
        "description": "Crée le compte d'authentification et sa fiche, avec le rôle désigné par `role_code`, qui doit convenir au type de l'organisation. `organisation_id` n'est retenu que pour CYBASTION ; ailleurs, c'est l'organisation de l'appelant. Sans `mot_de_passe`, un mot de passe est tiré au hasard et rendu une seule fois (`mot_de_passe_initial`).\n\n**Permission requise** : L'une de : `utilisateurs.gerer`, `utilisateurs_organisation.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prenom": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 100
                  },
                  "nom": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 100
                  },
                  "email": {
                    "type": "string",
                    "maxLength": 200,
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "role_code": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 80
                  },
                  "organisation_id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "telephone": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "fonction": {
                    "type": "string",
                    "maxLength": 120
                  },
                  "mot_de_passe": {
                    "type": "string",
                    "minLength": 12,
                    "maxLength": 200
                  }
                },
                "required": [
                  "prenom",
                  "nom",
                  "email",
                  "role_code"
                ]
              },
              "example": {
                "prenom": "ZZ Recette",
                "nom": "Partenaire W 8E10C2F1",
                "email": "zz.recette.8e10c2f1@exemple.invalide",
                "role_code": "partenaire_administrateur",
                "organisation_id": "7d86069a-804c-433e-ba25-cabf6ca7bb63",
                "mot_de_passe": "‹mot de passe›"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 14 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "prenom": {
                      "type": "string"
                    },
                    "nom": {
                      "type": "string"
                    },
                    "email": {
                      "type": "string"
                    },
                    "telephone": {
                      "type": "null"
                    },
                    "fonction": {
                      "type": "null"
                    },
                    "actif": {
                      "type": "boolean"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "roles": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "code",
                          "libelle"
                        ]
                      }
                    },
                    "organisation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "nom",
                        "type"
                      ]
                    },
                    "mot_de_passe_initial": {
                      "type": "string"
                    },
                    "mot_de_passe_a_transmettre": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "prenom",
                    "nom",
                    "email",
                    "telephone",
                    "fonction",
                    "actif",
                    "cree_le",
                    "roles",
                    "organisation",
                    "mot_de_passe_initial",
                    "mot_de_passe_a_transmettre"
                  ]
                },
                "example": {
                  "id": "a1d27872-79d1-4f06-8ff6-8a96279e3737",
                  "prenom": "ZZ Recette",
                  "nom": "Partenaire W 8E10C2F1",
                  "email": "zz.recette.8e10c2f1@exemple.invalide",
                  "telephone": null,
                  "fonction": null,
                  "actif": true,
                  "cree_le": "2026-10-19T10:44:14.420Z",
                  "roles": [
                    {
                      "id": "d4d9b5da-4cf4-4c3c-8932-a40a541e991f",
                      "code": "partenaire_administrateur",
                      "libelle": "Administrateur partenaire"
                    }
                  ],
                  "organisation": {
                    "id": "7d86069a-804c-433e-ba25-cabf6ca7bb63",
                    "nom": "ZZ Recette Partenaire W 8E10C2F1",
                    "type": "partenaire"
                  },
                  "mot_de_passe_initial": "‹mot de passe›",
                  "mot_de_passe_a_transmettre": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Organisation inactive, adresse ou téléphone déjà pris, ou ouverture non configurée.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "utilisateurs.gerer",
          "utilisateurs_organisation.gerer"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/utilisateurs/{id}/invitation": {
      "post": {
        "operationId": "postUtilisateursParIdInvitation",
        "tags": [
          "Administration"
        ],
        "summary": "Renvoyer le lien d'accès d'un compte",
        "description": "Envoie au compte un courriel de bienvenue portant un lien pour définir son mot de passe. Réservé aux comptes actifs qui ne se sont jamais connectés : un compte déjà connecté passe par « mot de passe oublié ». Renvoie `{ envoye, email }`.\n\n**Permission requise** : L'une de : `utilisateurs.gerer`, `utilisateurs_organisation.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "envoye": {
                      "type": "boolean"
                    },
                    "email": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "envoye",
                    "email"
                  ]
                },
                "example": {
                  "envoye": true,
                  "email": "zz.recette.compte.8416658d@satelica.test"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Compte suspendu ou déjà connecté, ou courriel non parti.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "utilisateurs.gerer",
          "utilisateurs_organisation.gerer"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/utilisateurs/{id}": {
      "patch": {
        "operationId": "patchUtilisateursParId",
        "tags": [
          "Administration"
        ],
        "summary": "Modifier un compte utilisateur",
        "description": "Corrige le prénom, le nom, le téléphone, la fonction, le rôle (par son code, adapté au type de l'organisation) ou l'état actif ; un champ absent reste inchangé, `null` vide le téléphone ou la fonction. L'adresse e-mail ne se modifie pas. On ne peut ni se désactiver soi-même ni changer son propre rôle. Inscrit au journal d'audit.\n\n**Permission requise** : L'une de : `utilisateurs.gerer`, `utilisateurs_organisation.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prenom": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 100
                  },
                  "nom": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 100
                  },
                  "telephone": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 6,
                        "maxLength": 30
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "fonction": {
                    "anyOf": [
                      {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 120
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "role_code": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "actif": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "prenom": "Corrigé",
                "fonction": "Fonction corrigée",
                "telephone": "+225 07 8416658d"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 5 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "organisation_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "role_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "prenom": {
                      "type": "string"
                    },
                    "nom": {
                      "type": "string"
                    },
                    "email": {
                      "type": "string"
                    },
                    "telephone": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "fonction": {
                      "type": "string"
                    },
                    "actif": {
                      "type": "boolean"
                    },
                    "double_authentification": {
                      "type": "boolean"
                    },
                    "derniere_connexion": {
                      "type": "null"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "roles": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "type_organisation": {
                            "type": "string"
                          },
                          "systeme": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "code",
                          "libelle",
                          "type_organisation",
                          "systeme"
                        ]
                      }
                    },
                    "organisation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "type": {
                          "type": "string"
                        },
                        "nom": {
                          "type": "string"
                        },
                        "statut": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "type",
                        "nom",
                        "statut"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "organisation_id",
                    "role_id",
                    "prenom",
                    "nom",
                    "email",
                    "telephone",
                    "fonction",
                    "actif",
                    "double_authentification",
                    "derniere_connexion",
                    "cree_le",
                    "modifie_le",
                    "roles",
                    "organisation"
                  ]
                },
                "example": {
                  "id": "f749078b-178b-4cfb-8799-ef8ebdec30f4",
                  "organisation_id": "180a06ad-6872-45e7-a5b6-d7c23799fde9",
                  "role_id": "edbc2322-7e46-4ce3-8d39-71728d29c710",
                  "prenom": "Corrigé",
                  "nom": "Recette 8416658d",
                  "email": "zz.recette.compte.8416658d@satelica.test",
                  "telephone": "+225 07 8416658d",
                  "fonction": "Fonction corrigée",
                  "actif": true,
                  "double_authentification": false,
                  "derniere_connexion": null,
                  "cree_le": "2026-10-13T06:48:50.529Z",
                  "modifie_le": "2026-10-13T06:48:50.839Z",
                  "roles": [
                    {
                      "id": "edbc2322-7e46-4ce3-8d39-71728d29c710",
                      "code": "cybastion_administrateur",
                      "libelle": "Administrateur CYBASTION",
                      "type_organisation": "cybastion",
                      "systeme": true
                    }
                  ],
                  "organisation": {
                    "id": "180a06ad-6872-45e7-a5b6-d7c23799fde9",
                    "type": "cybastion",
                    "nom": "CYBASTION",
                    "statut": "active"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Désactivation ou changement de rôle de son propre compte, ou téléphone déjà pris.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "utilisateurs.gerer",
          "utilisateurs_organisation.gerer"
        ],
        "x-satelica-cloisonnement": "applique"
      },
      "delete": {
        "operationId": "deleteUtilisateursParId",
        "tags": [
          "Administration"
        ],
        "summary": "Supprimer une invitation jamais utilisée",
        "description": "Efface un compte qui ne s'est jamais connecté et ne figure sur aucun enregistrement (journal, historique, fichiers, pièces KYC), avec ses notifications, puis retire son compte d'authentification. Un compte qui a servi se désactive à la place. Impossible sur le compte de l'appelant. Renvoie `{ supprime, email }`.\n\n**Permission requise** : L'une de : `utilisateurs.gerer`, `utilisateurs_organisation.gerer`.\n\n**Cloisonnement** : filtré par le périmètre de l'appelant — un partenaire ne voit que son portefeuille, un client que son dossier.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean"
                    },
                    "email": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "supprime",
                    "email"
                  ]
                },
                "example": {
                  "supprime": true,
                  "email": "zz.recette.compte.8416658d@satelica.test"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Compte déjà connecté, porteur de traces, ou compte de l'appelant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": [
          "utilisateurs.gerer",
          "utilisateurs_organisation.gerer"
        ],
        "x-satelica-cloisonnement": "applique"
      }
    },
    "/api/v1/roles/{id}/permissions": {
      "put": {
        "operationId": "putRolesParIdPermissions",
        "tags": [
          "Administration"
        ],
        "summary": "Redéfinir les permissions d'un rôle",
        "description": "Remplace la liste complète des permissions du rôle : ce qui n’y figure pas est retiré. Une permission inconnue est refusée, et un rôle système ne se modifie pas. La modification est inscrite au journal d'audit.\n\n**Permission requise** : `roles.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "permissions": {
                    "maxItems": 200,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 80
                    }
                  }
                },
                "required": [
                  "permissions"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Rôle système : ses permissions ne se modifient pas.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "roles.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/webhooks/evenements": {
      "get": {
        "operationId": "getWebhooksEvenements",
        "tags": [
          "Webhooks : adresses de réception"
        ],
        "summary": "Lister les événements disponibles",
        "description": "Le catalogue des événements que la plateforme annonce par webhook : type, groupe, phrase, objet désigné et exemple de données. Le format complet de chaque message est décrit dans la section **Webhooks** de cette référence.\n\n**Permission requise** : `webhooks.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string"
                          },
                          "groupe": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "objet_type": {
                            "type": "string"
                          },
                          "exemple": {
                            "type": "object",
                            "propertyNames": {
                              "type": "string"
                            },
                            "additionalProperties": {}
                          }
                        },
                        "required": [
                          "type",
                          "groupe",
                          "description",
                          "objet_type",
                          "exemple"
                        ]
                      }
                    }
                  },
                  "required": [
                    "version",
                    "donnees"
                  ]
                },
                "example": {
                  "version": 1,
                  "donnees": [
                    {
                      "type": "partenaire.reference",
                      "groupe": "Partenaires",
                      "description": "Un partenaire distributeur est référencé.",
                      "objet_type": "partenaires",
                      "exemple": {
                        "raison_sociale": "Connect Plus Abidjan",
                        "rccm": "CI-ABJ-2026-B-01234",
                        "ncc": "2601234A",
                        "ville": "Abidjan",
                        "statut": "candidat"
                      }
                    },
                    {
                      "type": "partenaire.statut_modifie",
                      "groupe": "Partenaires",
                      "description": "Un partenaire est validé, activé, suspendu ou retiré.",
                      "objet_type": "partenaires",
                      "exemple": {
                        "raison_sociale": "Connect Plus Abidjan",
                        "statut_avant": "valide",
                        "statut_apres": "actif",
                        "motif": null
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "webhooks.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/webhooks": {
      "post": {
        "operationId": "postWebhooks",
        "tags": [
          "Webhooks : adresses de réception"
        ],
        "summary": "Déclarer une adresse de réception",
        "description": "Enregistre une adresse HTTPS et les événements qu’elle reçoit. L’adresse doit se résoudre vers des adresses publiques : un réseau privé ou local est refusé (400). La réponse rend le **secret de signature, une seule fois** ; il ne se relit plus ensuite et se renouvelle par `POST /webhooks/{id}/secret`. Au plus 20 adresses. La déclaration est inscrite au journal d’audit.\n\n**Permission requise** : `webhooks.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500,
                    "description": "Adresse de réception, en HTTPS."
                  },
                  "evenements": {
                    "minItems": 1,
                    "maxItems": 30,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 80
                    },
                    "description": "Types d’événement à recevoir (`GET /webhooks/evenements`), ou `[\"*\"]` pour tous, y compris ceux à venir."
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 300
                  }
                },
                "required": [
                  "url",
                  "evenements"
                ]
              },
              "example": {
                "url": "https://preprod-api.satelica.com/_recepteur/recette-b081746536b4",
                "evenements": [
                  "*"
                ],
                "description": "ZZ Recette webhooks"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "url": {
                      "type": "string"
                    },
                    "description": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "evenements": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "actif": {
                      "type": "boolean"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "secret": {
                      "type": "string",
                      "description": "Secret de signature, affiché une seule fois."
                    }
                  },
                  "required": [
                    "id",
                    "url",
                    "description",
                    "evenements",
                    "actif",
                    "cree_le",
                    "modifie_le",
                    "secret"
                  ]
                },
                "example": {
                  "id": "c5a83d90-b33a-4851-a86a-ae26caf1552f",
                  "url": "https://preprod-api.satelica.com/_recepteur/recette-b081746536b4",
                  "description": "ZZ Recette webhooks",
                  "evenements": [
                    "*"
                  ],
                  "actif": true,
                  "cree_le": "2026-10-19T10:44:11.596Z",
                  "modifie_le": "2026-10-19T10:44:11.596Z",
                  "secret": "‹secret›"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "409": {
            "description": "Le nombre maximal d’adresses (20) est atteint.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "webhooks.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "get": {
        "operationId": "getWebhooks",
        "tags": [
          "Webhooks : adresses de réception"
        ],
        "summary": "Lister les adresses de réception",
        "description": "Les adresses déclarées, avec leurs événements et les compteurs de leurs livraisons. Le secret n’y figure jamais.\n\n**Permission requise** : `webhooks.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "url": {
                            "type": "string"
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "evenements": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "actif": {
                            "type": "boolean"
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "modifie_le": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "livraisons": {
                            "type": "object",
                            "properties": {
                              "en_attente": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "livree": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "echec": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "abandonnee": {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              "derniere_livree_le": {
                                "anyOf": [
                                  {
                                    "type": "string",
                                    "format": "date-time",
                                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                                  },
                                  {
                                    "type": "null"
                                  }
                                ]
                              }
                            },
                            "required": [
                              "en_attente",
                              "livree",
                              "echec",
                              "abandonnee",
                              "derniere_livree_le"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "url",
                          "description",
                          "evenements",
                          "actif",
                          "cree_le",
                          "modifie_le",
                          "livraisons"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "c5a83d90-b33a-4851-a86a-ae26caf1552f",
                      "url": "https://preprod-api.satelica.com/_recepteur/recette-b081746536b4",
                      "description": "ZZ Recette webhooks",
                      "evenements": [
                        "*"
                      ],
                      "actif": true,
                      "cree_le": "2026-10-19T10:44:11.596Z",
                      "modifie_le": "2026-10-19T10:44:11.596Z",
                      "livraisons": {
                        "en_attente": 0,
                        "livree": 0,
                        "echec": 0,
                        "abandonnee": 0,
                        "derniere_livree_le": null
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 20,
                    "total": 1,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "webhooks.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/webhooks/{id}": {
      "get": {
        "operationId": "getWebhooksParId",
        "tags": [
          "Webhooks : adresses de réception"
        ],
        "summary": "Lire une adresse de réception",
        "description": "L’adresse, ses événements et les compteurs de ses livraisons. Le secret n’y figure jamais.\n\n**Permission requise** : `webhooks.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "url": {
                      "type": "string"
                    },
                    "description": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "evenements": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "actif": {
                      "type": "boolean"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "livraisons": {
                      "type": "object",
                      "properties": {
                        "en_attente": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "livree": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "echec": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "abandonnee": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "derniere_livree_le": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "en_attente",
                        "livree",
                        "echec",
                        "abandonnee",
                        "derniere_livree_le"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "url",
                    "description",
                    "evenements",
                    "actif",
                    "cree_le",
                    "modifie_le",
                    "livraisons"
                  ]
                },
                "example": {
                  "id": "c5a83d90-b33a-4851-a86a-ae26caf1552f",
                  "url": "https://preprod-api.satelica.com/_recepteur/recette-b081746536b4",
                  "description": "ZZ Recette webhooks",
                  "evenements": [
                    "*"
                  ],
                  "actif": true,
                  "cree_le": "2026-10-19T10:44:11.596Z",
                  "modifie_le": "2026-10-19T10:44:11.596Z",
                  "livraisons": {
                    "en_attente": 0,
                    "livree": 0,
                    "echec": 0,
                    "abandonnee": 0,
                    "derniere_livree_le": null
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "webhooks.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "patch": {
        "operationId": "patchWebhooksParId",
        "tags": [
          "Webhooks : adresses de réception"
        ],
        "summary": "Modifier une adresse de réception",
        "description": "Change l’adresse, les événements ou la description, ou suspend l’adresse (`actif: false`). Suspendue, elle ne reçoit plus rien et ses envois en attente sont abandonnés ; ils se rejouent une fois l’adresse réactivée. Une nouvelle adresse est contrôlée comme à la déclaration. La modification est inscrite au journal d’audit.\n\n**Permission requise** : `webhooks.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "evenements": {
                    "minItems": 1,
                    "maxItems": 30,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 80
                    },
                    "description": "Types d’événement à recevoir (`GET /webhooks/evenements`), ou `[\"*\"]` pour tous, y compris ceux à venir."
                  },
                  "description": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 300
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "actif": {
                    "description": "`false` suspend l’adresse : les envois en attente sont abandonnés.",
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "url": "https://preprod-api.satelica.com/_recepteur/recette-b081746536b4-panne"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "url": {
                      "type": "string"
                    },
                    "description": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "evenements": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "actif": {
                      "type": "boolean"
                    },
                    "cree_le": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "modifie_le": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    },
                    "livraisons": {
                      "type": "object",
                      "properties": {
                        "en_attente": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "livree": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "echec": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "abandonnee": {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        "derniere_livree_le": {
                          "anyOf": [
                            {
                              "type": "string",
                              "format": "date-time",
                              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      },
                      "required": [
                        "en_attente",
                        "livree",
                        "echec",
                        "abandonnee",
                        "derniere_livree_le"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "url",
                    "description",
                    "evenements",
                    "actif",
                    "cree_le",
                    "modifie_le",
                    "livraisons"
                  ]
                },
                "example": {
                  "id": "c6a4e76d-05e1-4406-bb41-f2968e281ed9",
                  "url": "https://preprod-api.satelica.com/_recepteur/recette-b081746536b4-panne",
                  "description": "ZZ Recette webhooks (panne)",
                  "evenements": [
                    "webhook.test"
                  ],
                  "actif": true,
                  "cree_le": "2026-10-19T10:44:12.263Z",
                  "modifie_le": "2026-10-19T10:44:12.675Z",
                  "livraisons": {
                    "en_attente": 1,
                    "livree": 0,
                    "echec": 0,
                    "abandonnee": 0,
                    "derniere_livree_le": null
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "webhooks.gerer",
        "x-satelica-cloisonnement": "cybastion"
      },
      "delete": {
        "operationId": "deleteWebhooksParId",
        "tags": [
          "Webhooks : adresses de réception"
        ],
        "summary": "Supprimer une adresse de réception",
        "description": "Supprime l’adresse et son journal de livraisons ; les envois en attente ne partiront pas. La suppression est inscrite au journal d’audit. Réponse `{ supprime: true }`.\n\n**Permission requise** : `webhooks.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "supprime": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "supprime"
                  ]
                },
                "example": {
                  "supprime": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "webhooks.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/webhooks/{id}/secret": {
      "post": {
        "operationId": "postWebhooksParIdSecret",
        "tags": [
          "Webhooks : adresses de réception"
        ],
        "summary": "Renouveler le secret de signature",
        "description": "Tire un nouveau secret, rendu **une seule fois**. Pendant 24 heures, chaque envoi porte deux signatures `v1` : l’une avec le nouveau secret, l’autre avec l’ancien, le temps que le destinataire bascule. Le renouvellement est inscrit au journal d’audit.\n\n**Permission requise** : `webhooks.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "secret": {
                      "type": "string"
                    },
                    "secret_precedent_expire_le": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                    }
                  },
                  "required": [
                    "id",
                    "secret",
                    "secret_precedent_expire_le"
                  ]
                },
                "example": {
                  "id": "c6a4e76d-05e1-4406-bb41-f2968e281ed9",
                  "secret": "‹secret›",
                  "secret_precedent_expire_le": "2026-10-20T10:44:12.958Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "webhooks.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/webhooks/{id}/test": {
      "post": {
        "operationId": "postWebhooksParIdTest",
        "tags": [
          "Webhooks : adresses de réception"
        ],
        "summary": "Envoyer un événement d’essai",
        "description": "Envoie tout de suite un événement `webhook.test` à cette seule adresse et rend le résultat de la tentative : statut, code HTTP reçu, erreur. Sans réponse 2xx, l’envoi suit les relances habituelles. L’adresse doit être active (409 sinon). L’essai est inscrit au journal d’audit.\n\n**Permission requise** : `webhooks.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 3 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "livraison_id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "statut": {
                      "type": "string",
                      "enum": [
                        "en_attente",
                        "livree",
                        "echec",
                        "abandonnee"
                      ]
                    },
                    "tentatives": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "dernier_statut_http": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "derniere_erreur": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "prochaine_tentative_le": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "evenement_id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  },
                  "required": [
                    "livraison_id",
                    "statut",
                    "tentatives",
                    "dernier_statut_http",
                    "derniere_erreur",
                    "prochaine_tentative_le",
                    "evenement_id"
                  ]
                },
                "example": {
                  "livraison_id": "e2c27f76-ec86-4e8a-8f91-0333d41283dd",
                  "statut": "livree",
                  "tentatives": 1,
                  "dernier_statut_http": 200,
                  "derniere_erreur": null,
                  "prochaine_tentative_le": null,
                  "evenement_id": "35901192-5c37-4308-8ca1-f47d6e59f426"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Adresse suspendue : réactivez-la avant l’essai.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "webhooks.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/webhooks/{id}/livraisons": {
      "get": {
        "operationId": "getWebhooksParIdLivraisons",
        "tags": [
          "Webhooks : adresses de réception"
        ],
        "summary": "Consulter le journal des livraisons",
        "description": "Les envois faits à cette adresse, du plus récent au plus ancien : événement, statut, nombre de tentatives, dernier code HTTP reçu, dernière erreur et prochaine tentative. Filtrable par statut et par type d’événement.\n\n**Permission requise** : `webhooks.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "default": 1,
              "type": "integer",
              "minimum": 1,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "taille",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "statut",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "en_attente",
                "livree",
                "echec",
                "abandonnee"
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Ne garder qu’un type d’événement.",
            "schema": {
              "description": "Ne garder qu’un type d’événement.",
              "type": "string",
              "maxLength": 80
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Liste paginée. Schéma et exemple relevés sur 2 réponses réelles de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "donnees",
                    "pagination"
                  ],
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "statut": {
                            "type": "string",
                            "enum": [
                              "en_attente",
                              "livree",
                              "echec",
                              "abandonnee"
                            ]
                          },
                          "tentatives": {
                            "type": "integer",
                            "minimum": -9007199254740991,
                            "maximum": 9007199254740991
                          },
                          "dernier_statut_http": {
                            "anyOf": [
                              {
                                "type": "integer",
                                "minimum": -9007199254740991,
                                "maximum": 9007199254740991
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "derniere_erreur": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "prochaine_tentative_le": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "derniere_tentative_le": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "livree_le": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "cree_le": {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          "evenement": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              "type": {
                                "type": "string"
                              },
                              "objet_type": {
                                "type": "string"
                              },
                              "objet_id": {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              "cree_le": {
                                "type": "string",
                                "format": "date-time",
                                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                              }
                            },
                            "required": [
                              "id",
                              "type",
                              "objet_type",
                              "objet_id",
                              "cree_le"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "statut",
                          "tentatives",
                          "dernier_statut_http",
                          "derniere_erreur",
                          "prochaine_tentative_le",
                          "derniere_tentative_le",
                          "livree_le",
                          "cree_le",
                          "evenement"
                        ]
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                },
                "example": {
                  "donnees": [
                    {
                      "id": "ef371285-8230-4377-b1ee-3bfea00130b1",
                      "statut": "en_attente",
                      "tentatives": 1,
                      "dernier_statut_http": 503,
                      "derniere_erreur": "réponse HTTP 503",
                      "prochaine_tentative_le": "2026-10-19T10:45:12.408Z",
                      "derniere_tentative_le": "2026-10-19T10:44:12.404Z",
                      "livree_le": null,
                      "cree_le": "2026-10-19T10:44:12.397Z",
                      "evenement": {
                        "id": "85dbd889-b846-487d-8f54-c1de82e1e96d",
                        "type": "webhook.test",
                        "objet_type": "webhook_abonnements",
                        "objet_id": "c6a4e76d-05e1-4406-bb41-f2968e281ed9",
                        "cree_le": "2026-10-19T10:44:12.396Z"
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "taille": 20,
                    "total": 1,
                    "pages": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "webhooks.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/webhook-livraisons/{id}/rejeu": {
      "post": {
        "operationId": "postWebhookLivraisonsParIdRejeu",
        "tags": [
          "Webhooks : adresses de réception"
        ],
        "summary": "Rejouer une livraison",
        "description": "Renvoie tout de suite une livraison, quel que soit son statut (en échec, abandonnée, ou déjà livrée et à recevoir de nouveau), et rend le résultat de la tentative. Le compteur de tentatives repart de zéro. L’adresse doit être active (409 sinon). Le rejeu est inscrit au journal d’audit.\n\n**Permission requise** : `webhooks.gerer`.\n\n**Cloisonnement** : ressource interne à CYBASTION ; refusée à toute autre organisation.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "livraison_id": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "statut": {
                      "type": "string",
                      "enum": [
                        "en_attente",
                        "livree",
                        "echec",
                        "abandonnee"
                      ]
                    },
                    "tentatives": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    },
                    "dernier_statut_http": {
                      "anyOf": [
                        {
                          "type": "integer",
                          "minimum": -9007199254740991,
                          "maximum": 9007199254740991
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "derniere_erreur": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "prochaine_tentative_le": {
                      "anyOf": [
                        {
                          "type": "string",
                          "format": "date-time",
                          "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "livraison_id",
                    "statut",
                    "tentatives",
                    "dernier_statut_http",
                    "derniere_erreur",
                    "prochaine_tentative_le"
                  ]
                },
                "example": {
                  "livraison_id": "ef371285-8230-4377-b1ee-3bfea00130b1",
                  "statut": "livree",
                  "tentatives": 1,
                  "dernier_statut_http": 200,
                  "derniere_erreur": null,
                  "prochaine_tentative_le": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "401": {
            "$ref": "#/components/responses/NonAuthentifie"
          },
          "403": {
            "$ref": "#/components/responses/PermissionRefusee"
          },
          "404": {
            "$ref": "#/components/responses/Introuvable"
          },
          "409": {
            "description": "Adresse suspendue : réactivez-la avant de rejouer.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erreur"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [
          {
            "jetonAcces": []
          }
        ],
        "x-satelica-permission": "webhooks.gerer",
        "x-satelica-cloisonnement": "cybastion"
      }
    },
    "/api/v1/public/offres": {
      "get": {
        "operationId": "getPublicOffres",
        "tags": [
          "Site public"
        ],
        "summary": "Lister les offres publiques du site",
        "description": "Les offres actives du catalogue, telles que le site satelica.com les affiche : code, libellé, produit, volume, période, débit, nombre d’appareils et d’accès. Sans authentification ni prix. Réponse `{ donnees: [...] }`, mise en cache cinq minutes.\n\n**Permission requise** : Aucune : route ouverte, sans jeton.\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "responses": {
          "200": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "donnees": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "libelle": {
                            "type": "string"
                          },
                          "produit": {
                            "type": "string"
                          },
                          "volume_go": {
                            "type": "integer"
                          },
                          "periode": {
                            "type": "string"
                          },
                          "debit": {
                            "type": "string"
                          },
                          "nb_appareils": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          },
                          "nb_acces": {
                            "type": [
                              "integer",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "code",
                          "libelle",
                          "produit",
                          "volume_go",
                          "periode",
                          "debit",
                          "nb_appareils",
                          "nb_acces"
                        ]
                      }
                    }
                  },
                  "required": [
                    "donnees"
                  ]
                },
                "example": {
                  "donnees": [
                    {
                      "code": "DATA-50GO-HEBDO",
                      "libelle": "Forfait 50 Go hebdomadaire",
                      "produit": "Forfait data",
                      "volume_go": 50,
                      "periode": "hebdomadaire",
                      "debit": "Selon capacité",
                      "nb_appareils": null,
                      "nb_acces": null
                    },
                    {
                      "code": "DATA-50GO-MENS",
                      "libelle": "Forfait 50 Go mensuel",
                      "produit": "Forfait data",
                      "volume_go": 50,
                      "periode": "mensuelle",
                      "debit": "Selon capacité",
                      "nb_appareils": null,
                      "nb_acces": null
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [],
        "x-satelica-permission": null,
        "x-satelica-cloisonnement": "sans_objet"
      }
    },
    "/api/v1/public/mot-de-passe/lien": {
      "post": {
        "operationId": "postPublicMotDePasseLien",
        "tags": [
          "Site public"
        ],
        "summary": "Demander un lien de nouveau mot de passe",
        "description": "Envoie, si l'adresse a un compte, un lien pour choisir un nouveau mot de passe (valable 20 minutes ; seul le dernier demandé fonctionne). La réponse est la même que l’adresse ait un compte ou non : elle ne renseigne sur personne. Limitée par adresse IP.\n\n**Permission requise** : Aucune : route ouverte, sans jeton.\n\n**Cloisonnement** : la même ressource pour tous (référentiel, catalogue, profil de l’appelant).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string"
                  }
                },
                "required": [
                  "email"
                ]
              },
              "example": {
                "email": "zz.client.62aaefdf@exemple.invalide"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Succès. Schéma et exemple relevés sur 1 réponse réelle de la préproduction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "message"
                  ]
                },
                "example": {
                  "message": "Si cette adresse est celle d’un compte SATELICA, un lien vient d’y être envoyé. Il est valable 20 minutes."
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/RequeteInvalide"
          },
          "409": {
            "$ref": "#/components/responses/Conflit"
          },
          "429": {
            "$ref": "#/components/responses/DebitDepasse"
          }
        },
        "security": [],
        "x-satelica-permission": null,
        "x-satelica-cloisonnement": "sans_objet"
      }
    }
  },
  "webhooks": {
    "partenaire.reference": {
      "post": {
        "operationId": "webhookPartenaireReference",
        "summary": "partenaire.reference — Un partenaire distributeur est référencé.",
        "description": "Un partenaire distributeur est référencé.\n\n**Groupe** : Partenaires.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "partenaire.reference"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "partenaires"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "raison_sociale": {
                        "type": "string"
                      },
                      "rccm": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "ncc": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "ville": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "statut": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "raison_sociale",
                      "rccm",
                      "ncc",
                      "ville",
                      "statut"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "partenaire.reference",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "partenaires",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/partenaires/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "raison_sociale": "Connect Plus Abidjan",
                  "rccm": "CI-ABJ-2026-B-01234",
                  "ncc": "2601234A",
                  "ville": "Abidjan",
                  "statut": "candidat"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "partenaire.statut_modifie": {
      "post": {
        "operationId": "webhookPartenaireStatutModifie",
        "summary": "partenaire.statut_modifie — Un partenaire est validé, activé, suspendu ou retiré.",
        "description": "Un partenaire est validé, activé, suspendu ou retiré.\n\n**Groupe** : Partenaires.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "partenaire.statut_modifie"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "partenaires"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "raison_sociale": {
                        "type": "string"
                      },
                      "statut_avant": {
                        "type": "string"
                      },
                      "statut_apres": {
                        "type": "string"
                      },
                      "motif": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "raison_sociale",
                      "statut_avant",
                      "statut_apres",
                      "motif"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "partenaire.statut_modifie",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "partenaires",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/partenaires/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "raison_sociale": "Connect Plus Abidjan",
                  "statut_avant": "valide",
                  "statut_apres": "actif",
                  "motif": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "client.cree": {
      "post": {
        "operationId": "webhookClientCree",
        "summary": "client.cree — Un client est enregistré.",
        "description": "Un client est enregistré.\n\n**Groupe** : Clients.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "client.cree"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "clients"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "raison_sociale": {
                        "type": "string"
                      },
                      "rccm": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "ncc": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "ville": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "partenaire_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "reservation": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "statut"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "raison_sociale",
                      "rccm",
                      "ncc",
                      "ville",
                      "partenaire_id",
                      "reservation"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "client.cree",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "clients",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/clients/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "raison_sociale": "Société Ivoirienne de Logistique",
                  "rccm": "CI-ABJ-2025-B-56789",
                  "ncc": "2556789B",
                  "ville": "Abidjan",
                  "partenaire_id": "59314c3c-e509-46a2-a8c2-f280e6f19a64",
                  "reservation": {
                    "id": "1d2e3f40-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
                    "statut": "demandee"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "client.modifie": {
      "post": {
        "operationId": "webhookClientModifie",
        "summary": "client.modifie — La fiche d’un client est corrigée.",
        "description": "La fiche d’un client est corrigée.\n\n**Groupe** : Clients.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "client.modifie"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "clients"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "raison_sociale": {
                        "type": "string"
                      },
                      "champs_modifies": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      }
                    },
                    "required": [
                      "raison_sociale",
                      "champs_modifies"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "client.modifie",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "clients",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/clients/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "raison_sociale": "Société Ivoirienne de Logistique",
                  "champs_modifies": [
                    "ville",
                    "adresse_facturation"
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "client.partenaire_attribue": {
      "post": {
        "operationId": "webhookClientPartenaireAttribue",
        "summary": "client.partenaire_attribue — Un client entre au portefeuille d’un partenaire : réservation validée, attribution par CYBASTION ou transfert.",
        "description": "Un client entre au portefeuille d’un partenaire : réservation validée, attribution par CYBASTION ou transfert.\n\n**Groupe** : Clients.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "client.partenaire_attribue"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "clients"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "raison_sociale": {
                        "type": "string"
                      },
                      "partenaire_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "partenaire_precedent_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "origine": {
                        "type": "string",
                        "enum": [
                          "reservation",
                          "attribution",
                          "transfert"
                        ]
                      }
                    },
                    "required": [
                      "raison_sociale",
                      "partenaire_id",
                      "partenaire_precedent_id",
                      "origine"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "client.partenaire_attribue",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "clients",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/clients/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "raison_sociale": "Société Ivoirienne de Logistique",
                  "partenaire_id": "59314c3c-e509-46a2-a8c2-f280e6f19a64",
                  "partenaire_precedent_id": null,
                  "origine": "reservation"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "client.kyc_tranche": {
      "post": {
        "operationId": "webhookClientKycTranche",
        "summary": "client.kyc_tranche — La conformité du dossier d’un client est tranchée.",
        "description": "La conformité du dossier d’un client est tranchée.\n\n**Groupe** : Clients.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "client.kyc_tranche"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "clients"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "raison_sociale": {
                        "type": "string"
                      },
                      "statut_kyc": {
                        "type": "string"
                      },
                      "motif": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "raison_sociale",
                      "statut_kyc",
                      "motif"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "client.kyc_tranche",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "clients",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/clients/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "raison_sociale": "Société Ivoirienne de Logistique",
                  "statut_kyc": "a_completer",
                  "motif": "RCCM illisible."
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "client.supprime": {
      "post": {
        "operationId": "webhookClientSupprime",
        "summary": "client.supprime — Un client sans aucun fait (vente, règlement, facture…) est supprimé.",
        "description": "Un client sans aucun fait (vente, règlement, facture…) est supprimé.\n\n**Groupe** : Clients.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "client.supprime"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "clients"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "raison_sociale": {
                        "type": "string"
                      },
                      "motif": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "raison_sociale",
                      "motif"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "client.supprime",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "clients",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": null
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "raison_sociale": "Société Ivoirienne de Logistique",
                  "motif": "Saisi en double."
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "devis.envoye": {
      "post": {
        "operationId": "webhookDevisEnvoye",
        "summary": "devis.envoye — Un devis part au client.",
        "description": "Un devis part au client.\n\n**Groupe** : Ventes.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "devis.envoye"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "devis"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "partenaire_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "total_ht": {
                        "type": "number"
                      },
                      "total_ttc": {
                        "type": "number"
                      },
                      "valide_jusquau": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "numero",
                      "client_id",
                      "partenaire_id",
                      "total_ht",
                      "total_ttc",
                      "valide_jusquau"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "devis.envoye",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "devis",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/devis/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "DEV-2026-000010",
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "partenaire_id": "59314c3c-e509-46a2-a8c2-f280e6f19a64",
                  "total_ht": 20000,
                  "total_ttc": 23600,
                  "valide_jusquau": "2026-11-04"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "devis.accepte": {
      "post": {
        "operationId": "webhookDevisAccepte",
        "summary": "devis.accepte — Le client accepte un devis (la signature vient ensuite).",
        "description": "Le client accepte un devis (la signature vient ensuite).\n\n**Groupe** : Ventes.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "devis.accepte"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "devis"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      }
                    },
                    "required": [
                      "numero",
                      "client_id"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "devis.accepte",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "devis",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/devis/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "DEV-2026-000010",
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "devis.refuse": {
      "post": {
        "operationId": "webhookDevisRefuse",
        "summary": "devis.refuse — Le client refuse un devis.",
        "description": "Le client refuse un devis.\n\n**Groupe** : Ventes.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "devis.refuse"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "devis"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "motif": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "numero",
                      "client_id",
                      "motif"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "devis.refuse",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "devis",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/devis/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "DEV-2026-000010",
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "motif": "Budget reporté."
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "devis.signe": {
      "post": {
        "operationId": "webhookDevisSigne",
        "summary": "devis.signe — Un devis est signé, électroniquement ou sur papier : la vente est conclue.",
        "description": "Un devis est signé, électroniquement ou sur papier : la vente est conclue.\n\n**Groupe** : Ventes.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "devis.signe"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "devis"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "mode_signature": {
                        "type": "string",
                        "enum": [
                          "electronique",
                          "papier"
                        ]
                      },
                      "commande": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          "numero": {
                            "type": "string"
                          },
                          "statut": {
                            "type": "string"
                          },
                          "total_ttc": {
                            "type": "number"
                          },
                          "mode_paiement": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "numero",
                          "statut",
                          "total_ttc",
                          "mode_paiement"
                        ]
                      },
                      "contrat": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              "numero": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "numero",
                      "client_id",
                      "mode_signature",
                      "commande",
                      "contrat"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "devis.signe",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "devis",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/devis/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "DEV-2026-000010",
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "mode_signature": "electronique",
                  "commande": {
                    "id": "700604b5-c3f3-47fc-940d-39d15699d194",
                    "numero": "CMD-2026-000007",
                    "statut": "attente_paiement",
                    "total_ttc": 23600,
                    "mode_paiement": "prepaye"
                  },
                  "contrat": {
                    "id": "dcca4efd-e587-41cc-8165-ec3997208109",
                    "numero": "CTR-2026-000007"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "devis.annule": {
      "post": {
        "operationId": "webhookDevisAnnule",
        "summary": "devis.annule — Un devis est annulé.",
        "description": "Un devis est annulé.\n\n**Groupe** : Ventes.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "devis.annule"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "devis"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "motif": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "numero",
                      "client_id",
                      "motif"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "devis.annule",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "devis",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/devis/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "DEV-2026-000011",
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "motif": "Le client a changé de site."
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "paiement.valide": {
      "post": {
        "operationId": "webhookPaiementValide",
        "summary": "paiement.valide — Un règlement est validé : par la Finance, ou constaté auprès de Paystack.",
        "description": "Un règlement est validé : par la Finance, ou constaté auprès de Paystack.\n\n**Groupe** : Paiements et factures.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "paiement.valide"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "paiements"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "reference": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "canal": {
                        "type": "string"
                      },
                      "montant": {
                        "type": "number"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "commande_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "facture_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "date_paiement": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "reference",
                      "canal",
                      "montant",
                      "client_id",
                      "commande_id",
                      "facture_id",
                      "date_paiement"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "paiement.valide",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "paiements",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/paiements/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "reference": "PAY-2026-000012",
                  "canal": "mobile_money",
                  "montant": 23600,
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "commande_id": "700604b5-c3f3-47fc-940d-39d15699d194",
                  "facture_id": null,
                  "date_paiement": "2026-10-20T10:12:44.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "paiement.rejete": {
      "post": {
        "operationId": "webhookPaiementRejete",
        "summary": "paiement.rejete — Un règlement déclaré est rejeté par la Finance.",
        "description": "Un règlement déclaré est rejeté par la Finance.\n\n**Groupe** : Paiements et factures.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "paiement.rejete"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "paiements"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "reference": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "montant": {
                        "type": "number"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "motif": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "reference",
                      "montant",
                      "client_id",
                      "motif"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "paiement.rejete",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "paiements",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/paiements/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "reference": null,
                  "montant": 23600,
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "motif": "Virement introuvable sur le relevé."
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "paiement.annule": {
      "post": {
        "operationId": "webhookPaiementAnnule",
        "summary": "paiement.annule — Un règlement validé par erreur est annulé.",
        "description": "Un règlement validé par erreur est annulé.\n\n**Groupe** : Paiements et factures.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "paiement.annule"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "paiements"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "reference": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "montant": {
                        "type": "number"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "motif": {
                        "type": "string"
                      },
                      "commande": {
                        "anyOf": [
                          {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              "numero": {
                                "type": "string"
                              },
                              "statut": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "id",
                              "numero",
                              "statut"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "reference",
                      "montant",
                      "client_id",
                      "motif",
                      "commande"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "paiement.annule",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "paiements",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/paiements/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "reference": null,
                  "montant": 23600,
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "motif": "Virement enregistré deux fois.",
                  "commande": {
                    "id": "700604b5-c3f3-47fc-940d-39d15699d194",
                    "numero": "CMD-2026-000007",
                    "statut": "attente_paiement"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "facture.emise": {
      "post": {
        "operationId": "webhookFactureEmise",
        "summary": "facture.emise — Une facture est émise.",
        "description": "Une facture est émise.\n\n**Groupe** : Paiements et factures.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "facture.emise"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "factures"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "commande_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "montant_ht": {
                        "type": "number"
                      },
                      "montant_tva": {
                        "type": "number"
                      },
                      "montant_ttc": {
                        "type": "number"
                      },
                      "date_emission": {
                        "type": "string",
                        "format": "date",
                        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                      },
                      "date_echeance": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "statut": {
                        "type": "string"
                      },
                      "reference_fne": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "numero",
                      "client_id",
                      "commande_id",
                      "montant_ht",
                      "montant_tva",
                      "montant_ttc",
                      "date_emission",
                      "date_echeance",
                      "statut",
                      "reference_fne"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "facture.emise",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "factures",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/factures/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "FAC-2026-000007",
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "commande_id": "700604b5-c3f3-47fc-940d-39d15699d194",
                  "montant_ht": 20000,
                  "montant_tva": 3600,
                  "montant_ttc": 23600,
                  "date_emission": "2026-10-20",
                  "date_echeance": "2026-10-20",
                  "statut": "payee",
                  "reference_fne": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "facture.reference_fne": {
      "post": {
        "operationId": "webhookFactureReferenceFne",
        "summary": "facture.reference_fne — La référence de la facture normalisée (FNE) est inscrite sur une facture.",
        "description": "La référence de la facture normalisée (FNE) est inscrite sur une facture.\n\n**Groupe** : Paiements et factures.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "facture.reference_fne"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "factures"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "reference_fne": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "numero",
                      "client_id",
                      "reference_fne"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "facture.reference_fne",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "factures",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/factures/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "FAC-2026-000007",
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "reference_fne": "FNE-2026-0045871"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "avoir.emis": {
      "post": {
        "operationId": "webhookAvoirEmis",
        "summary": "avoir.emis — Un avoir est émis sur une facture.",
        "description": "Un avoir est émis sur une facture.\n\n**Groupe** : Paiements et factures.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "avoir.emis"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "avoirs"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "facture_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "montant_ttc": {
                        "type": "number"
                      },
                      "motif": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "numero",
                      "facture_id",
                      "client_id",
                      "montant_ttc",
                      "motif"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "avoir.emis",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "avoirs",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": null
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "AVO-2026-000002",
                  "facture_id": "141f4729-7171-4acd-85a6-c49ac787eb0e",
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "montant_ttc": 5900,
                  "motif": "Geste commercial sur l’installation."
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "avoir.rembourse": {
      "post": {
        "operationId": "webhookAvoirRembourse",
        "summary": "avoir.rembourse — Le remboursement d’un avoir est constaté.",
        "description": "Le remboursement d’un avoir est constaté.\n\n**Groupe** : Paiements et factures.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "avoir.rembourse"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "avoirs"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "facture_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "montant_ttc": {
                        "type": "number"
                      },
                      "moyen": {
                        "type": "string"
                      },
                      "rembourse_le": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "numero",
                      "facture_id",
                      "client_id",
                      "montant_ttc",
                      "moyen",
                      "rembourse_le"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "avoir.rembourse",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "avoirs",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": null
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "AVO-2026-000002",
                  "facture_id": "141f4729-7171-4acd-85a6-c49ac787eb0e",
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "montant_ttc": 5900,
                  "moyen": "virement",
                  "rembourse_le": "2026-10-24"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "ordre_installation.cree": {
      "post": {
        "operationId": "webhookOrdreInstallationCree",
        "summary": "ordre_installation.cree — Un ordre d’installation s’ouvre, automatiquement au paiement ou à la main.",
        "description": "Un ordre d’installation s’ouvre, automatiquement au paiement ou à la main.\n\n**Groupe** : Installation et mise en service.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "ordre_installation.cree"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "ordres_installation"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "commande_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "site_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "date_cible": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "date_limite": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "origine": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "numero",
                      "commande_id",
                      "site_id",
                      "date_cible",
                      "date_limite",
                      "origine"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "ordre_installation.cree",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "ordres_installation",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/ordres-installation/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "INS-2026-000007",
                  "commande_id": "700604b5-c3f3-47fc-940d-39d15699d194",
                  "site_id": "df1b850c-f6ee-4bf4-948f-e9e94f142004",
                  "date_cible": "2026-10-23",
                  "date_limite": "2026-10-27",
                  "origine": "automatique"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "ordre_installation.transmis": {
      "post": {
        "operationId": "webhookOrdreInstallationTransmis",
        "summary": "ordre_installation.transmis — L’ordre d’installation est transmis à VIP Net.",
        "description": "L’ordre d’installation est transmis à VIP Net.\n\n**Groupe** : Installation et mise en service.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "ordre_installation.transmis"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "ordres_installation"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "commande_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "envoye_le": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "numero",
                      "commande_id",
                      "envoye_le"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "ordre_installation.transmis",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "ordres_installation",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/ordres-installation/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "INS-2026-000007",
                  "commande_id": "700604b5-c3f3-47fc-940d-39d15699d194",
                  "envoye_le": "2026-10-21T08:05:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "pv.valide": {
      "post": {
        "operationId": "webhookPvValide",
        "summary": "pv.valide — Un procès-verbal est validé : d’installation (avec le numéro de série du kit posé) ou d’activation.",
        "description": "Un procès-verbal est validé : d’installation (avec le numéro de série du kit posé) ou d’activation.\n\n**Groupe** : Installation et mise en service.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "pv.valide"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "proces_verbaux"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "type_pv": {
                        "type": "string"
                      },
                      "ordre_installation_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "commande_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "site_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "numero_serie": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "date_intervention": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "type_pv",
                      "ordre_installation_id",
                      "commande_id",
                      "site_id",
                      "numero_serie",
                      "date_intervention"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "pv.valide",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "proces_verbaux",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/proces-verbaux/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "type_pv": "installation",
                  "ordre_installation_id": "7358968a-5551-461d-91e9-b8bfabb4a796",
                  "commande_id": "700604b5-c3f3-47fc-940d-39d15699d194",
                  "site_id": "df1b850c-f6ee-4bf4-948f-e9e94f142004",
                  "numero_serie": "SL-UT-2026-77341",
                  "date_intervention": "2026-10-22"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "activation.realisee": {
      "post": {
        "operationId": "webhookActivationRealisee",
        "summary": "activation.realisee — La connexion est mise en service.",
        "description": "La connexion est mise en service.\n\n**Groupe** : Installation et mise en service.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "activation.realisee"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "activations"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "commande_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "contrat_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "identifiant_connexion": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "reference_vipnet": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "active_le": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "date-time",
                            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "commande_id",
                      "contrat_id",
                      "identifiant_connexion",
                      "reference_vipnet",
                      "active_le"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "activation.realisee",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "activations",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/activations/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "commande_id": "700604b5-c3f3-47fc-940d-39d15699d194",
                  "contrat_id": "dcca4efd-e587-41cc-8165-ec3997208109",
                  "identifiant_connexion": "SL-CNX-0042",
                  "reference_vipnet": "VIP-2026-1187",
                  "active_le": "2026-10-22T15:40:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "commission.realisee": {
      "post": {
        "operationId": "webhookCommissionRealisee",
        "summary": "commission.realisee — Une commission devient due au partenaire, après encaissement. `montant` est ce que cet encaissement vient de lui faire acquérir, `montant_cumule` ce qui est acquis au total sur la ligne.",
        "description": "Une commission devient due au partenaire, après encaissement. `montant` est ce que cet encaissement vient de lui faire acquérir, `montant_cumule` ce qui est acquis au total sur la ligne.\n\n**Groupe** : Commissions.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "commission.realisee"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "commissions"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "partenaire_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "commande_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "montant": {
                        "type": "number"
                      },
                      "montant_cumule": {
                        "type": "number"
                      },
                      "type_ligne": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "partenaire_id",
                      "commande_id",
                      "montant",
                      "montant_cumule",
                      "type_ligne"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "commission.realisee",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "commissions",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/commissions/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "partenaire_id": "59314c3c-e509-46a2-a8c2-f280e6f19a64",
                  "commande_id": "700604b5-c3f3-47fc-940d-39d15699d194",
                  "montant": 4000,
                  "montant_cumule": 4000,
                  "type_ligne": "forfait_data"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "versement.demande": {
      "post": {
        "operationId": "webhookVersementDemande",
        "summary": "versement.demande — Un partenaire demande le versement de ses commissions.",
        "description": "Un partenaire demande le versement de ses commissions.\n\n**Groupe** : Commissions.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "versement.demande"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "demandes_versement"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "partenaire_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "montant_total": {
                        "type": "number"
                      },
                      "mode_versement": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "numero",
                      "partenaire_id",
                      "montant_total",
                      "mode_versement"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "versement.demande",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "demandes_versement",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/demandes-versement/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "DVS-2026-000005",
                  "partenaire_id": "59314c3c-e509-46a2-a8c2-f280e6f19a64",
                  "montant_total": 4000,
                  "mode_versement": "virement"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "versement.decide": {
      "post": {
        "operationId": "webhookVersementDecide",
        "summary": "versement.decide — CYBASTION valide ou rejette une demande de versement.",
        "description": "CYBASTION valide ou rejette une demande de versement.\n\n**Groupe** : Commissions.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "versement.decide"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "demandes_versement"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "partenaire_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "decision": {
                        "type": "string",
                        "enum": [
                          "validee",
                          "rejetee"
                        ]
                      },
                      "motif": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "numero",
                      "partenaire_id",
                      "decision",
                      "motif"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "versement.decide",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "demandes_versement",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/demandes-versement/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "DVS-2026-000005",
                  "partenaire_id": "59314c3c-e509-46a2-a8c2-f280e6f19a64",
                  "decision": "validee",
                  "motif": null
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "versement.paye": {
      "post": {
        "operationId": "webhookVersementPaye",
        "summary": "versement.paye — Le versement d’une demande est fait.",
        "description": "Le versement d’une demande est fait.\n\n**Groupe** : Commissions.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "versement.paye"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "demandes_versement"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "partenaire_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "montant_total": {
                        "type": "number"
                      },
                      "reference_versement": {
                        "type": "string"
                      },
                      "mode_versement": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "numero",
                      "partenaire_id",
                      "montant_total",
                      "reference_versement",
                      "mode_versement"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "versement.paye",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "demandes_versement",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/demandes-versement/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "DVS-2026-000005",
                  "partenaire_id": "59314c3c-e509-46a2-a8c2-f280e6f19a64",
                  "montant_total": 4000,
                  "reference_versement": "VIR-2026-10-90011",
                  "mode_versement": "virement"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "transfert.effectif": {
      "post": {
        "operationId": "webhookTransfertEffectif",
        "summary": "transfert.effectif — Un client change de partenaire : le transfert prend effet.",
        "description": "Un client change de partenaire : le transfert prend effet.\n\n**Groupe** : Transferts.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "transfert.effectif"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "transferts_partenaire"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "numero": {
                        "type": "string"
                      },
                      "client_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "partenaire_sortant_id": {
                        "anyOf": [
                          {
                            "type": "string",
                            "format": "uuid",
                            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "partenaire_entrant_id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      }
                    },
                    "required": [
                      "numero",
                      "client_id",
                      "partenaire_sortant_id",
                      "partenaire_entrant_id"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "transfert.effectif",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "transferts_partenaire",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/transferts/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "numero": "TRF-2026-000003",
                  "client_id": "8f09cee2-8df4-4041-8033-5b1df9f94650",
                  "partenaire_sortant_id": "59314c3c-e509-46a2-a8c2-f280e6f19a64",
                  "partenaire_entrant_id": "c7c46129-5f6c-4918-9dcd-3014ddbca337"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    },
    "webhook.test": {
      "post": {
        "operationId": "webhookWebhookTest",
        "summary": "webhook.test — Envoyé à la demande (`POST /webhooks/{id}/test`), pour vérifier la réception et la signature.",
        "description": "Envoyé à la demande (`POST /webhooks/{id}/test`), pour vérifier la réception et la signature.\n\n**Groupe** : Technique.\n\nSATELICA envoie ce message en `POST` à chaque adresse abonnée à cet événement (ou à `*`), dans les secondes qui suivent l’action. Déclarer une adresse : `POST /api/v1/webhooks`.",
        "parameters": [
          {
            "name": "Satelica-Evenement",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Type de l’événement, par exemple `devis.signe`."
          },
          {
            "name": "Satelica-Evenement-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Identifiant unique de l’événement : la clé de dédoublonnage (livraison au moins une fois)."
          },
          {
            "name": "Satelica-Tentative",
            "in": "header",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 8
            },
            "description": "Numéro de la tentative : 1 au premier envoi."
          },
          {
            "name": "Satelica-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "example": "t=1760000000,v1=5f2b…"
            },
            "description": "`t=<horodatage>,v1=<signature>` avec `v1 = hex(HMAC_SHA256(secret, t + \".\" + corps_brut))`. Refusez un message dont la signature ne correspond pas, ou dont l’horodatage a plus de 5 minutes. Pendant 24 heures après un renouvellement du secret, deux valeurs `v1` sont présentes."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                    "description": "Identifiant unique de l’événement."
                  },
                  "type": {
                    "type": "string",
                    "const": "webhook.test"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991,
                    "description": "Version du format de l’événement."
                  },
                  "cree_le": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
                  },
                  "environnement": {
                    "type": "string",
                    "enum": [
                      "preproduction",
                      "exploitation"
                    ]
                  },
                  "objet": {
                    "type": "object",
                    "properties": {
                      "type": {
                        "type": "string",
                        "const": "webhook_abonnements"
                      },
                      "id": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "adresse": {
                        "description": "Où relire l’objet complet par l’API (jeton CYBASTION), ou null.",
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    },
                    "required": [
                      "type",
                      "id",
                      "adresse"
                    ]
                  },
                  "auteur": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "utilisateur_id": {
                            "anyOf": [
                              {
                                "type": "string",
                                "format": "uuid",
                                "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "organisation_type": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "utilisateur_id",
                          "organisation_type"
                        ]
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "description": "Qui a fait l’action ; `plateforme` pour un traitement automatique."
                  },
                  "donnees": {
                    "type": "object",
                    "properties": {
                      "message": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "message"
                    ]
                  }
                },
                "required": [
                  "id",
                  "type",
                  "version",
                  "cree_le",
                  "environnement",
                  "objet",
                  "auteur",
                  "donnees"
                ]
              },
              "example": {
                "id": "0b7e9c52-3f1a-4d2e-9a8b-7c6d5e4f3a21",
                "type": "webhook.test",
                "version": 1,
                "cree_le": "2026-10-20T09:31:12.418Z",
                "environnement": "exploitation",
                "objet": {
                  "type": "webhook_abonnements",
                  "id": "ca34df86-916c-44b6-92ff-42768fea1322",
                  "adresse": "https://api.satelica.com/api/v1/webhooks/ca34df86-916c-44b6-92ff-42768fea1322"
                },
                "auteur": {
                  "utilisateur_id": "6638b260-1677-410c-ac1f-abefadfd0390",
                  "organisation_type": "cybastion"
                },
                "donnees": {
                  "message": "Essai de réception envoyé par SATELICA."
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reçu. Toute réponse 2xx en moins de 10 secondes vaut accusé de réception ; sinon, relance après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h (8 tentatives)."
          }
        },
        "security": []
      }
    }
  },
  "components": {
    "securitySchemes": {
      "jetonAcces": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Jeton d'accès obtenu auprès du service d'authentification (voir « S'authentifier »)."
      },
      "cleApi": {
        "type": "apiKey",
        "in": "header",
        "name": "apikey",
        "description": "Clé publique du service d’authentification de l’environnement. Publique par nature (le back-office et l’application l’embarquent) : elle identifie l’environnement, elle n’ouvre aucun droit à elle seule."
      }
    },
    "schemas": {
      "Erreur": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "requete_invalide",
              "authentification_requise",
              "jeton_invalide",
              "compte_inactif",
              "permission_refusee",
              "introuvable",
              "conflit",
              "debit_depasse",
              "erreur_interne",
              "service_indisponible"
            ]
          },
          "message": {
            "type": "string",
            "description": "Message en français, destiné à être affiché."
          },
          "details": {
            "description": "Précisions propres au refus (champs en cause, objet en conflit…)."
          }
        }
      },
      "Pagination": {
        "type": "object",
        "required": [
          "page",
          "taille",
          "total",
          "pages"
        ],
        "properties": {
          "page": {
            "type": "integer",
            "minimum": 1
          },
          "taille": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "total": {
            "type": "integer",
            "minimum": 0
          },
          "pages": {
            "type": "integer",
            "minimum": 0
          }
        }
      }
    },
    "responses": {
      "RequeteInvalide": {
        "description": "Requête invalide : un champ manque ou ne convient pas (`requete_invalide`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erreur"
            },
            "example": {
              "code": "requete_invalide",
              "message": "La demande de règlement est invalide.",
              "details": [
                {
                  "origin": "string",
                  "code": "invalid_format",
                  "format": "uuid",
                  "path": [
                    "commande_id"
                  ],
                  "message": "Invalid UUID"
                },
                {
                  "code": "custom",
                  "path": [],
                  "message": "Précisez la commande ou la facture à régler."
                }
              ]
            }
          }
        }
      },
      "NonAuthentifie": {
        "description": "Jeton absent, expiré ou invalide (`authentification_requise`, `jeton_invalide`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erreur"
            },
            "example": {
              "code": "jeton_invalide",
              "message": "La session a expiré ou n’est plus valide. Reconnectez-vous."
            }
          }
        }
      },
      "PermissionRefusee": {
        "description": "Le compte n'a pas la permission requise, ou il est désactivé (`permission_refusee`, `compte_inactif`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erreur"
            },
            "example": {
              "code": "permission_refusee",
              "message": "Vous n'avez pas le droit d'effectuer cette opération."
            }
          }
        }
      },
      "Introuvable": {
        "description": "La ressource n'existe pas, ou n'est pas visible de ce compte (`introuvable`). Une ressource hors du périmètre de l'appelant répond 404, jamais 403 : son existence même n'est pas divulguée.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erreur"
            },
            "example": {
              "code": "introuvable",
              "message": "Ce client n'existe pas ou ne vous est pas accessible."
            }
          }
        }
      },
      "Conflit": {
        "description": "L'opération contredit l'état de la ressource : statut, doublon, règle métier (`conflit`).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erreur"
            },
            "example": {
              "code": "conflit",
              "message": "Cette entreprise est déjà enregistrée (RCCM ou NCC identique) : la création est refusée."
            }
          }
        }
      },
      "DebitDepasse": {
        "description": "Trop de requêtes : patienter avant de réessayer (`debit_depasse`). Les en-têtes `retry-after` et `x-ratelimit-*` donnent la cadence.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erreur"
            },
            "example": {
              "code": "debit_depasse",
              "message": "Trop de demandes en peu de temps. Réessayez dans 42 secondes."
            }
          }
        }
      }
    }
  }
}
