{
  "openapi": "3.0.0",
  "paths": {
    "/api/v1/public/me": {
      "get": {
        "operationId": "PublicMeController_me",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicMe"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Profil du client associé à la clé API",
        "tags": [
          "Compte"
        ]
      }
    },
    "/api/v1/public/debtors": {
      "get": {
        "operationId": "PublicDebtorsController_findAll",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "type": "number"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 0,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedMeta"
                    },
                    {
                      "required": [
                        "data"
                      ],
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/PublicDebtor"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Lister les débiteurs",
        "tags": [
          "Débiteurs"
        ]
      },
      "post": {
        "operationId": "PublicDebtorsController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDebtorDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicDebtor"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Créer un débiteur (SIREN fourni → enrichissement societe.com automatique)",
        "tags": [
          "Débiteurs"
        ]
      }
    },
    "/api/v1/public/debtors/with-portfolio": {
      "get": {
        "description": "Vue calculée par débiteur : displayName, contact principal, indicateurs (hasActiveCase, hasOrphans, doublons potentiels), agrégats stock/en-cours et liste des factures (sans clé de fichier).",
        "operationId": "PublicDebtorsController_findAllWithPortfolio",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "type": "number"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 0,
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Lister les débiteurs avec leur portefeuille (stock + dossiers en cours)",
        "tags": [
          "Débiteurs"
        ]
      }
    },
    "/api/v1/public/debtors/{id}": {
      "get": {
        "operationId": "PublicDebtorsController_findOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicDebtor"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Détail d'un débiteur",
        "tags": [
          "Débiteurs"
        ]
      },
      "patch": {
        "operationId": "PublicDebtorsController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateDebtorDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicDebtor"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mettre à jour un débiteur",
        "tags": [
          "Débiteurs"
        ]
      },
      "delete": {
        "operationId": "PublicDebtorsController_delete",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Débiteur supprimé"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Supprimer un débiteur",
        "tags": [
          "Débiteurs"
        ]
      }
    },
    "/api/v1/public/debtors/{id}/primary-contact": {
      "patch": {
        "operationId": "PublicDebtorsController_updatePrimaryContact",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdatePrimaryContactDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicDebtor"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mettre à jour le contact principal",
        "tags": [
          "Débiteurs"
        ]
      }
    },
    "/api/v1/public/debtors/{id}/enrich": {
      "post": {
        "operationId": "PublicDebtorsController_enrich",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicDebtor"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Enrichir un débiteur depuis son SIREN",
        "tags": [
          "Débiteurs"
        ]
      }
    },
    "/api/v1/public/invoices": {
      "get": {
        "operationId": "PublicInvoicesController_findByCaseId",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "type": "number"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 0,
              "type": "number"
            }
          },
          {
            "name": "caseId",
            "required": true,
            "in": "query",
            "description": "Dossier dont on liste les factures (obligatoire)",
            "schema": {
              "minLength": 1,
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedMeta"
                    },
                    {
                      "required": [
                        "data"
                      ],
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/PublicInvoice"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Lister les factures d'un dossier (query caseId obligatoire)",
        "tags": [
          "Factures"
        ]
      },
      "post": {
        "operationId": "PublicInvoicesController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInvoiceDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicInvoice"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Créer une facture",
        "tags": [
          "Factures"
        ]
      }
    },
    "/api/v1/public/invoices/{id}": {
      "get": {
        "operationId": "PublicInvoicesController_findOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicInvoice"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Détail d'une facture",
        "tags": [
          "Factures"
        ]
      },
      "patch": {
        "operationId": "PublicInvoicesController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateInvoiceDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicInvoice"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mettre à jour une facture",
        "tags": [
          "Factures"
        ]
      },
      "delete": {
        "operationId": "PublicInvoicesController_delete",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Facture supprimée"
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Supprimer une facture",
        "tags": [
          "Factures"
        ]
      }
    },
    "/api/v1/public/invoices/{id}/pdf": {
      "post": {
        "operationId": "PublicInvoicesController_uploadPdf",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "PDF, 10 Mo max"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicInvoice"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Joindre le PDF d'une facture (multipart, champ file, 10 Mo max)",
        "tags": [
          "Factures"
        ]
      }
    },
    "/api/v1/public/cases": {
      "get": {
        "operationId": "PublicCasesController_findAll",
        "parameters": [
          {
            "name": "limit",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 1,
              "maximum": 200,
              "type": "number"
            }
          },
          {
            "name": "offset",
            "required": false,
            "in": "query",
            "schema": {
              "minimum": 0,
              "type": "number"
            }
          },
          {
            "name": "status",
            "required": false,
            "in": "query",
            "description": "Filtrer par statut de dossier (DRAFT, STOCK, ACTIVE, ARCHIVED…)",
            "schema": {
              "$ref": "#/components/schemas/Object"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PaginatedMeta"
                    },
                    {
                      "required": [
                        "data"
                      ],
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/PublicCase"
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Lister les dossiers (filtre status optionnel)",
        "tags": [
          "Dossiers"
        ]
      },
      "post": {
        "operationId": "PublicCasesController_create",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCaseDto"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCase"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Créer un dossier (statut DRAFT — le workflow n'est pas lancé)",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/launch-readiness": {
      "get": {
        "operationId": "PublicCasesController_getLaunchReadiness",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LaunchReadinessItem"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Dossiers DRAFT et raisons bloquant leur lancement",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/ref/{reference}": {
      "get": {
        "operationId": "PublicCasesController_findByReference",
        "parameters": [
          {
            "name": "reference",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCase"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Détail d'un dossier par sa référence (ex: A3K9PZ)",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}": {
      "get": {
        "operationId": "PublicCasesController_findOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCase"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Détail d'un dossier",
        "tags": [
          "Dossiers"
        ]
      },
      "patch": {
        "operationId": "PublicCasesController_update",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCaseDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCase"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Mettre à jour un dossier",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/events": {
      "get": {
        "operationId": "PublicCasesController_getCaseEvents",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PublicEvent"
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Timeline des événements d'un dossier (hors événements techniques)",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/invoices/{invoiceId}/download": {
      "get": {
        "operationId": "PublicCasesController_getInvoiceDownloadUrl",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "invoiceId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UrlResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "URL de téléchargement temporaire du PDF d'une facture",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/action-file": {
      "get": {
        "operationId": "PublicCasesController_getActionFileUrl",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "key",
            "required": true,
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UrlResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "URL de téléchargement d'une pièce jointe d'action débiteur",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/communications/{commId}": {
      "get": {
        "description": "Retour variable selon le canal : sujet et corps HTML pour un email, texte pour un SMS, PDF pour un courrier.",
        "operationId": "PublicCasesController_getCommunicationContent",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "commId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Contenu d'une communication envoyée (email, SMS, courrier)",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/regroup": {
      "post": {
        "operationId": "PublicCasesController_regroup",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegroupCasesDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegroupResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Regrouper plusieurs dossiers d'un même débiteur",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/bulk-launch": {
      "post": {
        "operationId": "PublicCasesController_bulkLaunch",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkLaunchDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BulkLaunchResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Lancer plusieurs dossiers DRAFT (les incomplets sont ignorés)",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/recover-from-stock": {
      "post": {
        "description": "Retour variable selon le cas : rattachement à un dossier en cours ({ caseId, attachedToOngoing, targetIsDraft }) ou création/lancement ({ casesCreated, casesLaunched, casesAttached, movedInvoiceCount }).",
        "operationId": "PublicCasesController_recoverFromStock",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecoverFromStockDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Ressortir des factures du stock (DRAFT ou lancement direct)",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/assign-invoices": {
      "post": {
        "operationId": "PublicCasesController_assignInvoices",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignInvoicesDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MoveInvoicesResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Affecter des factures du stock à un dossier",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/remove-invoices": {
      "post": {
        "operationId": "PublicCasesController_removeInvoices",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RemoveInvoicesDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MoveInvoicesResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Retirer des factures d'un dossier vers le stock",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/launch": {
      "post": {
        "operationId": "PublicCasesController_launchCase",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LaunchCaseDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCase"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Lancer le workflow de recouvrement d'un dossier DRAFT",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/suspend": {
      "post": {
        "operationId": "PublicCasesController_suspendCase",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SuspendCaseDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCase"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Suspendre un dossier (temporaire ou définitif)",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/resume": {
      "post": {
        "operationId": "PublicCasesController_resumeCase",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResumeCaseDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCase"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Reprendre un dossier suspendu",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/mark-paid": {
      "post": {
        "operationId": "PublicCasesController_markAsPaid",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarkAsPaidDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCase"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Marquer un dossier comme intégralement payé",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/record-payment": {
      "post": {
        "operationId": "PublicCasesController_recordPayment",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordPaymentDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordPaymentResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Déclarer un paiement partiel reçu",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/validate-escalation": {
      "post": {
        "operationId": "PublicCasesController_validateEscalation",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValidateEscalationResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Valider le passage à l'étape suivante (mode manuel)",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/reject-escalation": {
      "post": {
        "operationId": "PublicCasesController_rejectEscalation",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArchiveCaseDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RejectEscalationResult"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Refuser l'escalade et clôturer le dossier",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/cases/{id}/archive": {
      "post": {
        "operationId": "PublicCasesController_archiveCase",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ArchiveCaseDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicCase"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Archiver un dossier",
        "tags": [
          "Dossiers"
        ]
      }
    },
    "/api/v1/public/actions": {
      "get": {
        "operationId": "PublicActionsController_list",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PendingActionsResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Actions en attente de décision du créancier",
        "tags": [
          "Actions"
        ]
      }
    },
    "/api/v1/public/actions/count": {
      "get": {
        "operationId": "PublicActionsController_count",
        "parameters": [],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CountResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Nombre total d'actions en attente",
        "tags": [
          "Actions"
        ]
      }
    },
    "/api/v1/public/actions/summary": {
      "get": {
        "description": "Agrégat : { activeCases, amountDue, amountRecovered, pendingActions, debtorActions: PublicAction[], awaitingCases: PublicCase[], recentEvents: (PublicEvent + case { id, reference, debtor })[] }.",
        "operationId": "PublicActionsController_summary",
        "parameters": [],
        "responses": {
          "200": {
            "description": ""
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Résumé du recouvrement (dossiers actifs, encours, récupéré, actions)",
        "tags": [
          "Actions"
        ]
      }
    },
    "/api/v1/public/actions/{actionId}/respond": {
      "post": {
        "operationId": "PublicActionsController_respond",
        "parameters": [
          {
            "name": "actionId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RespondActionDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Répondre à une action débiteur (accepter, refuser, répondre)",
        "tags": [
          "Actions"
        ]
      }
    },
    "/api/v1/public/actions/cases/{caseId}/validate-escalation": {
      "post": {
        "operationId": "PublicActionsController_validateEscalation",
        "parameters": [
          {
            "name": "caseId",
            "required": true,
            "in": "path",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearer": []
          }
        ],
        "summary": "Valider l'escalade d'un dossier en attente (étapes 1-2)",
        "tags": [
          "Actions"
        ]
      }
    }
  },
  "info": {
    "title": "API Société Recouvrement",
    "description": "\nAPI REST pour intégrer et piloter votre recouvrement de créances depuis vos propres outils\n(CRM, ERP, scripts internes) : création de débiteurs et de factures, lancement et suivi des\ndossiers, réponse aux actions, déclaration de paiements.\n\n**URL de base :** `https://api.rec-societe.com/api/v1/public` — Format : JSON (UTF-8), dates ISO 8601.\n\n---\n\n## Concepts\n\n| Concept | Description |\n|---|---|\n| **Débiteur** | L'entreprise ou le particulier qui vous doit de l'argent. Porte les coordonnées et contacts. |\n| **Facture** | Une créance rattachée à un dossier : montants, échéance, PDF justificatif. |\n| **Dossier** (case) | L'unité de recouvrement pour un débiteur. Créé en statut `DRAFT`, il ne démarre **jamais** tout seul : le workflow (relances email/SMS/courrier en 4 étapes) ne commence qu'au **lancement explicite** (`POST /cases/{id}/launch`). |\n| **Stock** | Les factures « en réserve » (statut de dossier `STOCK`) : suivies mais sans relances. Affectables à un dossier ou ressortables à tout moment. |\n| **Action** | Une décision attendue de votre part : contestation du débiteur, proposition d'échéancier, déclaration de paiement, validation d'escalade… |\n| **Escalade** | Le passage d'une étape de relance à la suivante (1 → 2 → 3 → 4). Selon votre réglage, elle peut attendre votre validation. |\n\n## Authentification\n\nChaque requête doit porter une **clé API** dans l'en-tête `Authorization` :\n\n```\nAuthorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n```\n\n- **Créer une clé :** application web → **Paramètres → Clés API** → « Créer une clé ».\n  Le secret complet (`sk_live_…`) n'est affiché **qu'une seule fois**, à la création.\n- **Révoquer une clé :** même écran, bouton « Révoquer ». Effet immédiat.\n- L'accès API est inclus dans les abonnements payants (à partir du palier TPE).\n\n### Sécurité de la clé — à lire absolument\n\nUne clé donne un **accès complet** à votre compte : lecture, écriture, actions financières\n(déclaration de paiements), suppression. Traitez-la comme un mot de passe :\n\n- elle ne doit voyager **qu'en HTTPS**, dans l'en-tête `Authorization` — **jamais** en query\n  string (`?key=…`), jamais dans une URL, jamais dans un log ;\n- ne la committez **jamais** dans un dépôt de code (utilisez des variables d'environnement) ;\n- définissez une **expiration** (90 jours recommandés) à la création ;\n- en cas de doute (fuite, poste compromis, départ d'un collaborateur) : **révoquez immédiatement**\n  et créez une nouvelle clé.\n\n> **À venir (V1.5) :** distinction clé **lecture seule** / **lecture-écriture**, pour appliquer\n> le principe du moindre privilège à vos intégrations. Non disponible en V1.\n\n## Pagination\n\nLes endpoints de liste acceptent `limit` (1-200, défaut 50) et `offset` (défaut 0), et\nrenvoient une enveloppe stable :\n\n```json\n{ \"data\": [ … ], \"total\": 123, \"limit\": 50, \"offset\": 0 }\n```\n\n## Erreurs\n\nToutes les erreurs suivent le même format :\n\n```json\n{ \"statusCode\": 401, \"code\": \"UNAUTHORIZED\", \"message\": \"Clé API invalide ou révoquée.\" }\n```\n\n| Code HTTP | Signification |\n|---|---|\n| `400` | Requête invalide (champ manquant ou mal formé). |\n| `401` | Clé absente, mal formée, inconnue, révoquée ou expirée. |\n| `403` | Votre abonnement n'inclut pas l'accès API (`API_ACCESS`). |\n| `404` | Ressource introuvable (ou n'appartenant pas à votre compte). |\n| `429` | Quota de requêtes dépassé — réessayez dans une minute. |\n| `500` | Erreur interne — aucun détail technique n'est exposé ; réessayez, puis contactez le support. |\n\n## Limites de débit (rate limits)\n\nLe quota s'applique **par clé et par minute**, selon votre palier :\n\n| Palier | Requêtes / minute |\n|---|---|\n| TPE | 60 |\n| PE | 120 |\n| PME | 300 |\n| Sur-mesure | 600 |\n\nAu-delà : réponse `429`. Prévoyez un retry avec backoff (attendre ~60 s).\n\n## Exemple : chaîne complète de recouvrement\n\n```bash\nBASE=\"https://api.rec-societe.com/api/v1/public\"\nAUTH=\"Authorization: Bearer sk_live_votre_cle\"\n\n# 1. Créer le débiteur (au moins un contact requis ; SIREN → enrichissement societe.com automatique)\ncurl -s -X POST \"$BASE/debtors\" -H \"$AUTH\" -H \"Content-Type: application/json\" -d '{\n  \"isCompany\": true,\n  \"companyName\": \"Client Mauvais Payeur SARL\",\n  \"siren\": \"552081317\",\n  \"address\": \"1 rue de la Paix\", \"postalCode\": \"75002\", \"city\": \"Paris\",\n  \"contacts\": [{ \"name\": \"Jean Dupont\", \"email\": \"compta@mauvais-payeur.fr\", \"isPrimary\": true }]\n}'\n# → { \"id\": \"DEBTOR_ID\", ... }\n\n# 2. Créer le dossier (statut DRAFT — rien n'est envoyé au débiteur)\ncurl -s -X POST \"$BASE/cases\" -H \"$AUTH\" -H \"Content-Type: application/json\" \\\n  -d '{ \"debtorId\": \"DEBTOR_ID\" }'\n# → { \"id\": \"CASE_ID\", \"reference\": \"A3K9PZ\", \"status\": \"DRAFT\", ... }\n\n# 3. Ajouter une facture au dossier\ncurl -s -X POST \"$BASE/invoices\" -H \"$AUTH\" -H \"Content-Type: application/json\" -d '{\n  \"caseId\": \"CASE_ID\",\n  \"invoiceNumber\": \"F-2026-042\",\n  \"issueDate\": \"2026-05-01\", \"dueDate\": \"2026-06-01\",\n  \"totalAmount\": 1200.00, \"vatAmount\": 200.00\n}'\n# → { \"id\": \"INVOICE_ID\", ... }\n\n# 4. Joindre le PDF de la facture (multipart — requis pour pouvoir lancer le dossier)\ncurl -s -X POST \"$BASE/invoices/INVOICE_ID/pdf\" -H \"$AUTH\" \\\n  -F \"file=@facture-F-2026-042.pdf\"\n\n# 5. Vérifier que le dossier est prêt à être lancé\ncurl -s \"$BASE/cases/launch-readiness\" -H \"$AUTH\"\n# → [{ \"id\": \"CASE_ID\", \"blockingReasons\": [], ... }]  ← vide = prêt\n\n# 6. Lancer le workflow de relances\ncurl -s -X POST \"$BASE/cases/CASE_ID/launch\" -H \"$AUTH\" \\\n  -H \"Content-Type: application/json\" -d '{}'\n# → { \"status\": \"ACTIVE\", ... }\n\n# 7. Suivre la timeline (emails, SMS, courriers envoyés…)\ncurl -s \"$BASE/cases/CASE_ID/events\" -H \"$AUTH\"\n\n# 8. Consulter les actions en attente de votre décision\ncurl -s \"$BASE/actions\" -H \"$AUTH\"\n\n# 9. Répondre à une action (ex : accepter un échéancier proposé)\ncurl -s -X POST \"$BASE/actions/ACTION_ID/respond\" -H \"$AUTH\" \\\n  -H \"Content-Type: application/json\" -d '{ \"decision\": \"ACCEPTED\" }'\n\n# 10. Valider une escalade en attente (si mode manuel)\ncurl -s -X POST \"$BASE/actions/cases/CASE_ID/validate-escalation\" -H \"$AUTH\"\n\n# 11. Déclarer un paiement reçu en direct (virement sur votre compte)\ncurl -s -X POST \"$BASE/cases/CASE_ID/record-payment\" -H \"$AUTH\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"amount\": 600.00, \"source\": \"BANK_TRANSFER\" }'\n\n# 12. Solde complet → marquer payé, ou archiver le dossier\ncurl -s -X POST \"$BASE/cases/CASE_ID/mark-paid\" -H \"$AUTH\" -H \"Content-Type: application/json\" -d '{}'\ncurl -s -X POST \"$BASE/cases/CASE_ID/archive\"   -H \"$AUTH\" -H \"Content-Type: application/json\" -d '{}'\n```\n\n## Versionnement\n\nL'API est versionnée par le préfixe d'URL (`/api/v1/`). Les évolutions rétro-compatibles\n(nouveaux champs, nouveaux endpoints) peuvent survenir sans changement de version ; les\nchangements cassants donneront lieu à un `/api/v2/` annoncé à l'avance.\n",
    "version": "1.0",
    "contact": {
      "name": "Société Recouvrement",
      "url": "https://rec-societe.com",
      "email": "contact@rec-societe.com"
    }
  },
  "tags": [
    {
      "name": "Compte",
      "description": "Profil du client associé à la clé API (raison sociale, SIREN, palier d'abonnement)."
    },
    {
      "name": "Débiteurs",
      "description": "CRUD débiteurs, contact principal, enrichissement SIREN automatique (societe.com), vue portefeuille (stock + dossiers en cours)."
    },
    {
      "name": "Factures",
      "description": "CRUD factures rattachées à un dossier, upload du PDF justificatif (multipart, 10 Mo max — requis pour lancer le dossier)."
    },
    {
      "name": "Dossiers",
      "description": "CRUD dossiers + cycle de vie complet : lancement, suspension, reprise, paiements, escalade, archivage, timeline d'événements (hors événements techniques)."
    },
    {
      "name": "Actions",
      "description": "Actions en attente de votre décision (contestations, échéanciers, paiements déclarés, escalades) + résumé global du recouvrement."
    }
  ],
  "servers": [
    {
      "url": "https://api.rec-societe.com",
      "description": "Production"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "scheme": "bearer",
        "bearerFormat": "sk_live_",
        "type": "http"
      }
    },
    "schemas": {
      "PublicMe": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "companyName": {
            "type": "string",
            "description": "Raison sociale du créancier"
          },
          "siren": {
            "type": "string",
            "nullable": true
          },
          "siret": {
            "type": "string",
            "nullable": true
          },
          "vatNumber": {
            "type": "string",
            "nullable": true
          },
          "legalForm": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "postalCode": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          },
          "contactName": {
            "type": "string"
          },
          "contactEmail": {
            "type": "string"
          },
          "contactPhone": {
            "type": "string",
            "nullable": true
          },
          "subscriptionTier": {
            "type": "string",
            "nullable": true,
            "description": "Palier d'abonnement (FREE, TPE, PE, PME, CUSTOM)"
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "companyName",
          "siren",
          "siret",
          "vatNumber",
          "legalForm",
          "address",
          "city",
          "postalCode",
          "country",
          "contactName",
          "contactEmail",
          "contactPhone",
          "subscriptionTier",
          "createdAt"
        ]
      },
      "PaginatedMeta": {
        "type": "object",
        "properties": {
          "total": {
            "type": "number",
            "description": "Nombre total d'éléments (avant découpage)"
          },
          "limit": {
            "type": "number",
            "description": "Taille de page demandée (1-200, défaut 50)"
          },
          "offset": {
            "type": "number",
            "description": "Décalage demandé (défaut 0)"
          }
        },
        "required": [
          "total",
          "limit",
          "offset"
        ]
      },
      "PublicDebtorContact": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "isPrimary": {
            "type": "boolean",
            "description": "Contact destinataire des relances"
          }
        },
        "required": [
          "id",
          "name",
          "email",
          "phone",
          "isPrimary"
        ]
      },
      "PublicDebtor": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "isCompany": {
            "type": "boolean",
            "description": "true = société, false = particulier"
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "siren": {
            "type": "string",
            "nullable": true,
            "description": "SIREN — déclenche l'enrichissement automatique societe.com à la création"
          },
          "siret": {
            "type": "string",
            "nullable": true
          },
          "vatNumber": {
            "type": "string",
            "nullable": true
          },
          "legalForm": {
            "type": "string",
            "nullable": true
          },
          "nafCode": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "type": "string"
          },
          "postalCode": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicDebtorContact"
            }
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "isCompany",
          "companyName",
          "firstName",
          "lastName",
          "siren",
          "siret",
          "vatNumber",
          "legalForm",
          "nafCode",
          "address",
          "postalCode",
          "city",
          "country",
          "contacts",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateDebtorContactDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string",
            "maxLength": 20
          },
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "isPrimary": {
            "type": "boolean"
          }
        }
      },
      "CreateDebtorDto": {
        "type": "object",
        "properties": {
          "isCompany": {
            "type": "boolean"
          },
          "companyName": {
            "type": "string",
            "maxLength": 255
          },
          "siren": {
            "type": "string",
            "pattern": "/^\\d{9}$/"
          },
          "firstName": {
            "type": "string",
            "maxLength": 100
          },
          "lastName": {
            "type": "string",
            "maxLength": 100
          },
          "address": {
            "type": "string",
            "maxLength": 255
          },
          "city": {
            "type": "string",
            "maxLength": 100
          },
          "postalCode": {
            "type": "string",
            "pattern": "/^\\d{5}$/"
          },
          "country": {
            "type": "string",
            "maxLength": 2
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateDebtorContactDto"
            }
          }
        },
        "required": [
          "isCompany",
          "address",
          "city",
          "postalCode",
          "contacts"
        ]
      },
      "UpdateDebtorDto": {
        "type": "object",
        "properties": {
          "companyName": {
            "type": "string",
            "maxLength": 255
          },
          "siren": {
            "type": "string",
            "pattern": "/^\\d{9}$/"
          },
          "firstName": {
            "type": "string",
            "maxLength": 100
          },
          "lastName": {
            "type": "string",
            "maxLength": 100
          },
          "address": {
            "type": "string",
            "maxLength": 255
          },
          "city": {
            "type": "string",
            "maxLength": 100
          },
          "postalCode": {
            "type": "string",
            "pattern": "/^\\d{5}$/"
          },
          "country": {
            "type": "string",
            "maxLength": 2
          },
          "isCompany": {
            "type": "boolean"
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateDebtorContactDto"
            }
          }
        }
      },
      "UpdatePrimaryContactDto": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string",
            "maxLength": 20
          },
          "name": {
            "type": "string",
            "maxLength": 255
          }
        }
      },
      "PublicInvoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "caseId": {
            "type": "string"
          },
          "invoiceNumber": {
            "type": "string"
          },
          "issueDate": {
            "format": "date-time",
            "type": "string"
          },
          "dueDate": {
            "format": "date-time",
            "type": "string"
          },
          "totalAmount": {
            "type": "number",
            "description": "Montant TTC en euros"
          },
          "vatAmount": {
            "type": "number"
          },
          "paidAmount": {
            "type": "number",
            "description": "Montant déjà encaissé en euros"
          },
          "interestAmount": {
            "type": "number",
            "description": "Intérêts de retard courus en euros"
          },
          "flatFee": {
            "type": "number",
            "description": "Indemnité forfaitaire de recouvrement (40 € par défaut)"
          },
          "interestRate": {
            "type": "number",
            "nullable": true
          },
          "isActive": {
            "type": "boolean",
            "description": "false = facture sortie du dossier (retirée au lancement ou supprimée)"
          },
          "hasPdf": {
            "type": "boolean",
            "description": "Un PDF justificatif est joint (requis pour lancer le dossier)"
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "caseId",
          "invoiceNumber",
          "issueDate",
          "dueDate",
          "totalAmount",
          "vatAmount",
          "paidAmount",
          "interestAmount",
          "flatFee",
          "interestRate",
          "isActive",
          "hasPdf",
          "createdAt",
          "updatedAt"
        ]
      },
      "CreateInvoiceDto": {
        "type": "object",
        "properties": {
          "caseId": {
            "type": "string"
          },
          "invoiceNumber": {
            "type": "string",
            "maxLength": 100
          },
          "issueDate": {
            "type": "string"
          },
          "dueDate": {
            "type": "string"
          },
          "totalAmount": {
            "type": "number",
            "description": "Montant TTC",
            "minimum": 0.01
          },
          "vatAmount": {
            "type": "number",
            "description": "Montant TVA",
            "minimum": 0
          }
        },
        "required": [
          "caseId",
          "invoiceNumber",
          "issueDate",
          "dueDate",
          "totalAmount"
        ]
      },
      "UpdateInvoiceDto": {
        "type": "object",
        "properties": {
          "invoiceNumber": {
            "type": "string",
            "maxLength": 100
          },
          "issueDate": {
            "type": "string"
          },
          "dueDate": {
            "type": "string"
          },
          "totalAmount": {
            "type": "number",
            "minimum": 0
          },
          "vatAmount": {
            "type": "number",
            "minimum": 0
          },
          "paidAmount": {
            "type": "number",
            "minimum": 0
          },
          "isActive": {
            "type": "boolean"
          }
        }
      },
      "PublicEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "description": "Type d'événement (STEP_STARTED, EMAIL_SENT, SMS_SENT, LETTER_SENT, PAYMENT_DECLARED…)"
          },
          "channel": {
            "type": "string",
            "nullable": true,
            "description": "Canal de communication (EMAIL, SMS, LETTER, LRAR)"
          },
          "step": {
            "type": "number",
            "nullable": true,
            "description": "Étape du workflow (1 à 4)"
          },
          "day": {
            "type": "number",
            "nullable": true,
            "description": "Jour ouvré relatif dans l'étape (J0, J+1…)"
          },
          "arReceivedAt": {
            "format": "date-time",
            "type": "string",
            "nullable": true,
            "description": "Date de réception de l'accusé de réception (LRAR uniquement)"
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "type",
          "channel",
          "step",
          "day",
          "arReceivedAt",
          "createdAt"
        ]
      },
      "PublicPayment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "amount": {
            "type": "number",
            "description": "Montant en euros"
          },
          "feeAmount": {
            "type": "number",
            "nullable": true
          },
          "paymentDate": {
            "format": "date-time",
            "type": "string"
          },
          "source": {
            "type": "string",
            "description": "Origine du paiement (BANK_TRANSFER, CARD…)"
          },
          "status": {
            "type": "string"
          },
          "declaredBy": {
            "type": "string"
          },
          "notes": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          }
        },
        "required": [
          "id",
          "amount",
          "feeAmount",
          "paymentDate",
          "source",
          "status",
          "declaredBy",
          "notes",
          "createdAt"
        ]
      },
      "PublicCase": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "reference": {
            "type": "string",
            "description": "Référence courte du dossier (ex: A3K9PZ)"
          },
          "status": {
            "type": "string",
            "description": "Statut (DRAFT, STOCK, ACTIVE, SUSPENDED_TEMP, SUSPENDED_PERM, AWAITING_ESCALATION, COMPLETED, ARCHIVED…)"
          },
          "currentStep": {
            "type": "number",
            "description": "Étape de relance courante (1 à 4)"
          },
          "sereniteMode": {
            "type": "boolean"
          },
          "suspendedReason": {
            "type": "string",
            "nullable": true
          },
          "suspendedAt": {
            "format": "date-time",
            "type": "string",
            "nullable": true
          },
          "resumeScheduledAt": {
            "format": "date-time",
            "type": "string",
            "nullable": true
          },
          "stepCompletedAt": {
            "format": "date-time",
            "type": "string",
            "nullable": true
          },
          "debtorId": {
            "type": "string"
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "updatedAt": {
            "format": "date-time",
            "type": "string"
          },
          "archivedAt": {
            "format": "date-time",
            "type": "string",
            "nullable": true
          },
          "judicialStatus": {
            "type": "string",
            "nullable": true
          },
          "debtor": {
            "description": "Débiteur (présent sur le détail et certaines opérations)",
            "allOf": [
              {
                "$ref": "#/components/schemas/PublicDebtor"
              }
            ]
          },
          "invoices": {
            "description": "Factures actives du dossier (présent sur le détail)",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicInvoice"
            }
          },
          "events": {
            "description": "Timeline (présent sur le détail, hors événements techniques)",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicEvent"
            }
          },
          "payments": {
            "description": "Paiements enregistrés (présent sur le détail)",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicPayment"
            }
          }
        },
        "required": [
          "id",
          "reference",
          "status",
          "currentStep",
          "sereniteMode",
          "suspendedReason",
          "suspendedAt",
          "resumeScheduledAt",
          "stepCompletedAt",
          "debtorId",
          "createdAt",
          "updatedAt",
          "archivedAt",
          "judicialStatus"
        ]
      },
      "Object": {
        "type": "object",
        "properties": {}
      },
      "LaunchReadinessItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "reference": {
            "type": "string"
          },
          "debtorName": {
            "type": "string"
          },
          "blockingReasons": {
            "description": "Vide = prêt à lancer. Sinon, raisons bloquantes en français.",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "invoiceCount": {
            "type": "number"
          },
          "netAmount": {
            "type": "number",
            "description": "Montant net restant dû en euros"
          }
        },
        "required": [
          "id",
          "reference",
          "debtorName",
          "blockingReasons",
          "invoiceCount",
          "netAmount"
        ]
      },
      "UrlResponse": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string"
          }
        },
        "required": [
          "url"
        ]
      },
      "CreateCaseDto": {
        "type": "object",
        "properties": {
          "debtorId": {
            "type": "string"
          },
          "sereniteMode": {
            "type": "boolean"
          },
          "force": {
            "type": "boolean"
          }
        },
        "required": [
          "debtorId"
        ]
      },
      "UpdateCaseDto": {
        "type": "object",
        "properties": {
          "status": {
            "type": "object"
          },
          "sereniteMode": {
            "type": "boolean"
          }
        }
      },
      "RegroupCasesDto": {
        "type": "object",
        "properties": {
          "sourceCaseIds": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "targetCaseId": {
            "type": "string",
            "description": "Dossier ACTIVE cible pour l'imputation. Absent = créer un nouveau dossier DRAFT."
          }
        },
        "required": [
          "sourceCaseIds"
        ]
      },
      "RegroupResult": {
        "type": "object",
        "properties": {
          "targetCaseId": {
            "type": "string"
          },
          "targetReference": {
            "type": "string"
          },
          "movedInvoiceCount": {
            "type": "number"
          },
          "archivedCount": {
            "type": "number"
          },
          "createdNewCase": {
            "type": "boolean"
          }
        },
        "required": [
          "targetCaseId",
          "targetReference",
          "movedInvoiceCount",
          "archivedCount",
          "createdNewCase"
        ]
      },
      "BulkLaunchDto": {
        "type": "object",
        "properties": {
          "caseIds": {
            "description": "Ids des dossiers DRAFT à lancer",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "caseIds"
        ]
      },
      "BulkLaunchSkippedItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "reference": {
            "type": "string"
          },
          "reasons": {
            "description": "Raisons pour lesquelles ce dossier n'a pas été lancé",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "id",
          "reference",
          "reasons"
        ]
      },
      "BulkLaunchResult": {
        "type": "object",
        "properties": {
          "launched": {
            "description": "Ids des dossiers effectivement lancés",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "skipped": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkLaunchSkippedItem"
            }
          }
        },
        "required": [
          "launched",
          "skipped"
        ]
      },
      "RecoverFromStockDto": {
        "type": "object",
        "properties": {
          "invoiceIds": {
            "description": "Ids des factures du stock à ressortir",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "mode": {
            "type": "object",
            "description": "DRAFT = préparer sans lancer ; LAUNCH = lancer immédiatement"
          }
        },
        "required": [
          "invoiceIds",
          "mode"
        ]
      },
      "AssignInvoicesDto": {
        "type": "object",
        "properties": {
          "invoiceIds": {
            "description": "Ids des factures du stock à affecter",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "targetCaseId": {
            "type": "string",
            "description": "Dossier de destination"
          }
        },
        "required": [
          "invoiceIds",
          "targetCaseId"
        ]
      },
      "MoveInvoicesResult": {
        "type": "object",
        "properties": {
          "movedInvoiceCount": {
            "type": "number"
          },
          "casesArchived": {
            "type": "number",
            "description": "Dossiers archivés car vidés de leurs factures (retrait vers le stock uniquement)"
          }
        },
        "required": [
          "movedInvoiceCount"
        ]
      },
      "RemoveInvoicesDto": {
        "type": "object",
        "properties": {
          "invoiceIds": {
            "description": "Ids des factures à retirer du dossier (retour au stock)",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "invoiceIds"
        ]
      },
      "LaunchCaseDto": {
        "type": "object",
        "properties": {
          "invoiceIds": {
            "description": "Sous-ensemble de factures à lancer — les autres restent dans un nouveau dossier DRAFT. Omis = toutes.",
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "SuspendCaseDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "description": "Motif de suspension (affiché dans la timeline)"
          },
          "permanent": {
            "type": "boolean",
            "description": "true = suspension définitive ; false/omis = temporaire"
          }
        },
        "required": [
          "reason"
        ]
      },
      "ResumeCaseDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string"
          }
        }
      },
      "MarkAsPaidDto": {
        "type": "object",
        "properties": {
          "notes": {
            "type": "string"
          }
        }
      },
      "RecordPaymentDto": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "number",
            "description": "Montant reçu en euros",
            "minimum": 0.01
          },
          "invoiceIds": {
            "description": "Factures sur lesquelles imputer — omis = imputation automatique (plus anciennes d'abord)",
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "source": {
            "type": "string",
            "description": "Origine du paiement (ex: BANK_TRANSFER)"
          },
          "paymentDate": {
            "type": "string",
            "description": "Date du paiement (ISO 8601) — omis = maintenant"
          },
          "notes": {
            "type": "string"
          }
        },
        "required": [
          "amount",
          "source"
        ]
      },
      "RecordPaymentResult": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "isFullyPaid": {
            "type": "boolean",
            "description": "true si le principal est intégralement soldé"
          },
          "remainingPrincipal": {
            "type": "number",
            "description": "Principal restant dû en euros après imputation"
          },
          "totalApplied": {
            "type": "number",
            "description": "Montant effectivement imputé en euros"
          }
        },
        "required": [
          "ok",
          "isFullyPaid",
          "remainingPrincipal",
          "totalApplied"
        ]
      },
      "ValidateEscalationResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "newStep": {
            "type": "number",
            "description": "Nouvelle étape courante (2, 3 ou 4)"
          }
        },
        "required": [
          "success",
          "newStep"
        ]
      },
      "ArchiveCaseDto": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string"
          }
        }
      },
      "RejectEscalationResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "status": {
            "type": "string"
          }
        },
        "required": [
          "success",
          "status"
        ]
      },
      "PublicActionDebtorRef": {
        "type": "object",
        "properties": {
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "companyName",
          "firstName",
          "lastName"
        ]
      },
      "PublicActionInvoiceRef": {
        "type": "object",
        "properties": {
          "totalAmount": {
            "type": "number"
          },
          "paidAmount": {
            "type": "number"
          }
        },
        "required": [
          "totalAmount",
          "paidAmount"
        ]
      },
      "PublicActionCaseRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "reference": {
            "type": "string"
          },
          "debtor": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/PublicActionDebtorRef"
              }
            ]
          },
          "invoices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicActionInvoiceRef"
            }
          }
        },
        "required": [
          "id",
          "reference",
          "debtor",
          "invoices"
        ]
      },
      "PublicAction": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "description": "Type d'action (DISPUTE, PAYMENT_DECLARATION, PAYMENT_COMMITMENT, SCHEDULE_PROPOSAL, WRONG_CONTACT)"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "caseId": {
            "type": "string"
          },
          "payload": {
            "type": "object",
            "description": "Données soumises par le débiteur (proposition, contestation…) — destinées au créancier"
          },
          "createdAt": {
            "format": "date-time",
            "type": "string"
          },
          "case": {
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/PublicActionCaseRef"
              }
            ]
          }
        },
        "required": [
          "id",
          "type",
          "status",
          "caseId",
          "payload",
          "createdAt",
          "case"
        ]
      },
      "PendingActionsResponse": {
        "type": "object",
        "properties": {
          "debtorActions": {
            "description": "Actions soumises par les débiteurs (contestations, échéanciers, paiements déclarés…)",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicAction"
            }
          },
          "awaitingCases": {
            "description": "Dossiers en attente de votre validation d'escalade",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicCase"
            }
          }
        },
        "required": [
          "debtorActions",
          "awaitingCases"
        ]
      },
      "CountResponse": {
        "type": "object",
        "properties": {
          "count": {
            "type": "number"
          }
        },
        "required": [
          "count"
        ]
      },
      "RespondActionDto": {
        "type": "object",
        "properties": {
          "decision": {
            "type": "string",
            "description": "ACCEPTED = accepter, REJECTED = refuser, RESPOND = répondre sans trancher",
            "enum": [
              "ACCEPTED",
              "REJECTED",
              "RESPOND"
            ]
          },
          "message": {
            "type": "string",
            "description": "Message accompagnant la décision (transmis au débiteur selon le type d'action)"
          }
        },
        "required": [
          "decision"
        ]
      },
      "SuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          }
        },
        "required": [
          "success"
        ]
      }
    }
  }
}