cognee_http_server/dto/add.rs
1//! DTOs for `POST /api/v1/add`.
2
3use serde::{Deserialize, Serialize};
4use utoipa::ToSchema;
5use uuid::Uuid;
6
7// Re-export the shared pipeline-run DTOs so callers only need one import path.
8pub use super::pipeline_run::{DataIngestionInfoDTO, PipelineRunInfoDTO};
9
10/// Multipart form for `POST /api/v1/add`.
11///
12/// `axum::extract::Multipart` does not derive into a struct directly; this DTO
13/// exists primarily for OpenAPI documentation. The handler reads parts
14/// explicitly, populating an internal `AddRequest` that mirrors this shape.
15#[derive(Debug, ToSchema)]
16#[allow(dead_code)] // OpenAPI-only
17pub struct AddMultipart {
18 /// One or more files. Empty (zero parts) is allowed but is then a no-op.
19 #[schema(format = "binary")]
20 pub data: Vec<Vec<u8>>,
21
22 /// Dataset name. Either this or `dataset_id` is required.
23 #[schema(example = "research_papers", rename = "datasetName")]
24 pub dataset_name: Option<String>,
25
26 /// Dataset UUID. Either this or `dataset_name` is required. Empty string
27 /// is treated as absent.
28 #[schema(example = "", rename = "datasetId")]
29 pub dataset_id: Option<String>,
30
31 /// Repeated form field; each entry is one node-set tag.
32 #[schema(example = json!([""]))]
33 pub node_set: Option<Vec<String>>,
34}
35
36/// Internal post-parse representation; not on the wire.
37pub struct AddRequest {
38 pub files: Vec<UploadedPart>,
39 pub dataset_name: Option<String>,
40 pub dataset_id: Option<Uuid>,
41 pub node_set: Option<Vec<String>>,
42}
43
44/// One uploaded file part (or URL-reference part) from the multipart body.
45pub struct UploadedPart {
46 pub file_name: Option<String>,
47 pub content_type: Option<String>,
48 /// Spooled temp file path (valid until the `UploadGuard` is dropped).
49 pub temp_path: std::path::PathBuf,
50 pub byte_count: u64,
51 /// Set when the part body is a URL/S3 string (< 4 KiB, valid scheme).
52 /// In that case `temp_path` has been unlinked.
53 pub url_payload: Option<String>,
54}
55
56/// `add`/`update`-specific error envelope. Keep separate from `ApiError`'s
57/// canonical `{detail: "..."}` shape for byte-for-byte Python parity.
58#[derive(Debug, Serialize, Deserialize, ToSchema)]
59#[serde(rename_all = "snake_case")]
60pub struct ErrorResponseDTO {
61 pub error: String,
62 pub detail: Option<String>,
63}