meta { name: 01 Upload (mock) type: http seq: 1 } post { url: {{baseUrl}}/api/v1/invoices/upload body: json auth: inherit } body:json { { "filenames": [ "facture-martin-042.pdf", "atelier-durand-2026-039.pdf", "studio-lefevre-12.pdf" ] } } script:post-response { if (res.getStatus() === 201) { const batch = res.getBody().data; bru.setEnvVar("batchId", batch.id); if (batch.drafts && batch.drafts.length > 0) { // Premier draft pending pour les requêtes "validate" / "skip" const firstPending = batch.drafts.find(d => d.status === "pending") || batch.drafts[0]; bru.setEnvVar("draftId", firstPending.id); } } } tests { test("201 Created", function () { expect(res.getStatus()).to.equal(201); }); test("3 drafts créés", function () { expect(res.getBody().data.drafts).to.have.lengthOf(3); }); test("Chaque draft a extracted + edited + confidence", function () { const d = res.getBody().data.drafts[0]; expect(d).to.have.property("extracted"); expect(d).to.have.property("edited"); expect(d).to.have.property("confidence"); expect(d.status).to.equal("pending"); }); } docs { POST /api/v1/invoices/upload V1 mock : on envoie un body JSON `{ filenames: [...] }` (pas de fichier réel). Le service crée un ImportBatch + 1 ImportDraft par filename, en appelant le `MockOcrProvider` qui invente des champs plausibles depuis le nom du fichier. Quand Mistral sera branché : on basculera sur multipart `files[]` avec upload effectif vers MinIO. Le contrat de réponse reste identique. Capture `batchId` et `draftId` (le 1er pending) pour les requêtes suivantes. Validation : - 1 à 20 filenames - Chaque filename ≤ 500 chars }