fix(openapi): declare the duplicate flags and the missing-link 404 of a document upload

A duplicate upload has always answered meta.duplicate (and meta.deleted for
a deleted source key) beside the row, as the description says, but the
envelope schema declared neither. An episode or visit id that is not the
caller's has always answered 404, which no response declared.
This commit is contained in:
Marc-André Bombeck committed 2026-10-23 15:04:37 +02:00
1 parent de96891ff5
commit b75219d704
2 files changed
+46 -5

No files matched your search

+16
View File
@@ -19188,6 +19188,13 @@ paths:
$ref: "#/components/schemas/DocumentUploadEnvelope"
"401": *a1
"403": *a9
"404":
description: An `episodeIds` or `encounterIds` id is not a live episode or visit of the caller
(`documents.inbound.episodeNotFound` / `documents.inbound.encounterNotFound`). Nothing was stored.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"409":
description: The same bytes are already stored under 20 other import source ids (`documents.inbound.sourceAliasLimit`).
Nothing was stored or remembered.
@@ -78996,6 +79003,15 @@ components:
properties:
requestId:
type: string
duplicate:
description: "Present on a 200: the bytes or the source key were already stored, and `data` is the existing row (or the
receipt)."
type: boolean
const: true
deleted:
description: Present with `duplicate` when the source key belongs to a document the owner deleted. Nothing was stored.
type: boolean
const: true
additionalProperties: false
required:
- data
+30 -5
View File
@@ -379,11 +379,31 @@ const documentUploadReceipt = z
});
// Shared by the POST 200 (duplicate) and 201 (created) responses — the
// envelope id must be registered exactly once.
const documentUploadEnvelope = dataEnvelope(
z.union([inboundDocument, documentUploadReceipt]),
"DocumentUploadEnvelope",
);
// envelope id must be registered exactly once. The duplicate answer flags
// itself at the envelope level, beside the request id.
const documentUploadEnvelope = z
.object({
data: z.union([inboundDocument, documentUploadReceipt]),
error: z.null(),
meta: z
.object({
requestId: z.string().optional(),
duplicate: z
.literal(true)
.optional()
.describe(
"Present on a 200: the bytes or the source key were already stored, and `data` is the existing row (or the receipt).",
),
deleted: z
.literal(true)
.optional()
.describe(
"Present with `duplicate` when the source key belongs to a document the owner deleted. Nothing was stored.",
),
})
.optional(),
})
.meta({ id: "DocumentUploadEnvelope" });
/**
* A `DOCUMENT_EXTRACT` run's result. Smaller than the synchronous extract
@@ -672,6 +692,11 @@ export const inboundDocumentPaths: NonNullable<ZodOpenApiObject["paths"]> = {
'Unsupported or unidentifiable type (`meta.reason = "unsupportedType"`). Executables, HTML/SVG, and generic archives are always refused.',
content: { "application/json": { schema: errorEnvelope } },
},
"404": {
description:
"An `episodeIds` or `encounterIds` id is not a live episode or visit of the caller (`documents.inbound.episodeNotFound` / `documents.inbound.encounterNotFound`). Nothing was stored.",
content: { "application/json": { schema: errorEnvelope } },
},
...stdResponses,
},
},