diff --git a/backend/migrations/202511130000_rename_document_content_type/down.sql b/backend/migrations/202511130000_rename_document_content_type/down.sql new file mode 100644 index 0000000..09336bc --- /dev/null +++ b/backend/migrations/202511130000_rename_document_content_type/down.sql @@ -0,0 +1,3 @@ +-- Revert column rename. +ALTER TABLE tenant.documents + RENAME COLUMN mime_type TO content_type; diff --git a/backend/migrations/202511130000_rename_document_content_type/up.sql b/backend/migrations/202511130000_rename_document_content_type/up.sql new file mode 100644 index 0000000..7d84272 --- /dev/null +++ b/backend/migrations/202511130000_rename_document_content_type/up.sql @@ -0,0 +1,3 @@ +-- Rename document content_type column to mime_type for consistency with API. +ALTER TABLE tenant.documents + RENAME COLUMN content_type TO mime_type; diff --git a/backend/src/models.rs b/backend/src/models.rs index e2483b7..c850062 100644 --- a/backend/src/models.rs +++ b/backend/src/models.rs @@ -540,7 +540,7 @@ pub struct Document { pub id: Uuid, pub filename: String, pub original_name: String, - pub content_type: Option, + pub mime_type: Option, pub folder_id: Option, pub created_at: NaiveDateTime, pub updated_at: NaiveDateTime, @@ -558,7 +558,7 @@ pub struct NewDocument { pub id: Uuid, pub filename: String, pub original_name: String, - pub content_type: Option, + pub mime_type: Option, pub folder_id: Option, pub current_version_id: Uuid, pub metadata: serde_json::Value, diff --git a/backend/src/routes/documents.rs b/backend/src/routes/documents.rs index 1564c53..46419e9 100644 --- a/backend/src/routes/documents.rs +++ b/backend/src/routes/documents.rs @@ -200,7 +200,7 @@ pub async fn upload_document( let user_id = user_id; let mut file_bytes: Option> = None; let mut original_name: Option = None; - let mut content_type: Option = None; + let mut mime_type: Option = None; let mut folder_id: Option = None; let mut metadata: Value = Value::Object(Default::default()); let mut tag_ids: Vec = Vec::new(); @@ -219,7 +219,7 @@ pub async fn upload_document( Some("file") => { let file_name = field.file_name().map(|n| n.to_string()); original_name = file_name.clone(); - content_type = field.content_type().map(|mime| mime.to_string()); + mime_type = field.content_type().map(|mime| mime.to_string()); let data = field.bytes().await.map_err(|err| { let msg = format!("failed to read file bytes: {err}"); error!(error = %err, "failed to read file bytes"); @@ -348,7 +348,7 @@ pub async fn upload_document( let request = DocumentUploadRequest { bytes: file_bytes, original_name, - content_type, + mime_type, folder_id, metadata, title_override, @@ -689,7 +689,7 @@ pub async fn download_with_token( &version.s3_key, disposition.as_deref(), headers.get(header::RANGE).cloned(), - doc.content_type.as_deref(), + doc.mime_type.as_deref(), Some(version.id.to_string()), ) .await diff --git a/backend/src/routes/webdav/mod.rs b/backend/src/routes/webdav/mod.rs index 36b05b2..5b14b61 100644 --- a/backend/src/routes/webdav/mod.rs +++ b/backend/src/routes/webdav/mod.rs @@ -351,7 +351,7 @@ async fn stream_document( if let Some(content_type) = upstream.headers().get(header::CONTENT_TYPE) { builder = builder.header(header::CONTENT_TYPE, content_type); - } else if let Some(ref typ) = document.content_type { + } else if let Some(ref typ) = document.mime_type { builder = builder.header(header::CONTENT_TYPE, typ); } @@ -529,7 +529,7 @@ fn build_resources_for_folder( display_name, is_collection: true, content_length: None, - content_type: None, + mime_type: None, last_modified, }); @@ -545,7 +545,7 @@ fn build_resources_for_folder( display_name: subfolder.name.clone(), is_collection: true, content_length: None, - content_type: None, + mime_type: None, last_modified: Some(to_http_date(subfolder.updated_at)), }); } @@ -583,7 +583,7 @@ fn document_to_resource( display_name: document.title.clone(), is_collection: false, content_length: Some(version.size_bytes), - content_type: document.content_type.clone(), + mime_type: document.mime_type.clone(), last_modified: Some(to_http_date(document.updated_at)), } } @@ -639,7 +639,7 @@ fn render_multistatus(resources: &[DavResource]) -> Result, quick_xml::E writer.write_event(Event::End(BytesEnd::new("D:getcontentlength")))?; } - if let Some(content_type) = &resource.content_type { + if let Some(content_type) = &resource.mime_type { writer.write_event(Event::Start(BytesStart::new("D:getcontenttype")))?; writer.write_event(Event::Text(BytesText::new(content_type)))?; writer.write_event(Event::End(BytesEnd::new("D:getcontenttype")))?; @@ -681,7 +681,7 @@ struct DavResource { display_name: String, is_collection: bool, content_length: Option, - content_type: Option, + mime_type: Option, last_modified: Option, } enum ResolvedPath { diff --git a/backend/src/schema.rs b/backend/src/schema.rs index 5d86f65..c21d80e 100644 --- a/backend/src/schema.rs +++ b/backend/src/schema.rs @@ -83,7 +83,7 @@ diesel::table! { #[max_length = 255] original_name -> Varchar, #[max_length = 100] - content_type -> Nullable, + mime_type -> Nullable, folder_id -> Nullable, created_at -> Timestamptz, updated_at -> Timestamptz, diff --git a/backend/src/services/documents.rs b/backend/src/services/documents.rs index c0f4641..646beb6 100644 --- a/backend/src/services/documents.rs +++ b/backend/src/services/documents.rs @@ -133,7 +133,7 @@ pub struct DocumentResponse { pub title: String, pub original_name: String, #[schema(nullable)] - pub content_type: Option, + pub mime_type: Option, #[schema(nullable)] pub folder_id: Option, pub created_at: String, @@ -225,7 +225,7 @@ fn default_true() -> bool { pub struct DocumentUploadRequest { pub bytes: Vec, pub original_name: String, - pub content_type: Option, + pub mime_type: Option, pub folder_id: Option, pub metadata: Value, pub title_override: Option, @@ -685,7 +685,7 @@ impl<'a> DocumentsService<'a> { let DocumentUploadRequest { bytes, original_name, - content_type, + mime_type, folder_id, metadata, title_override, @@ -739,7 +739,7 @@ impl<'a> DocumentsService<'a> { .put_object( &s3_key, bytes.clone(), - content_type.clone(), + mime_type.clone(), content_disposition.clone(), ) .await @@ -756,7 +756,7 @@ impl<'a> DocumentsService<'a> { id: doc_id, filename: stored_filename.clone(), original_name: original_name.clone(), - content_type: content_type.clone(), + mime_type: mime_type.clone(), folder_id, current_version_id: version_id, metadata: metadata_value.clone(), @@ -1418,7 +1418,7 @@ impl<'a> DocumentsService<'a> { filename: doc.filename, title: doc.title, original_name: doc.original_name, - content_type: doc.content_type, + mime_type: doc.mime_type, folder_id: doc.folder_id, created_at: to_iso(doc.created_at), updated_at: to_iso(doc.updated_at), diff --git a/backend/src/workers/analyze.rs b/backend/src/workers/analyze.rs index a94c8bf..c213dc9 100644 --- a/backend/src/workers/analyze.rs +++ b/backend/src/workers/analyze.rs @@ -155,8 +155,8 @@ pub(crate) fn determine_thumbnail_support(document: &Document) -> (bool, Option< .into_iter() .collect(); - if let Some(ref content_type) = document.content_type { - if supported_mimes.contains(content_type.as_str()) { + if let Some(ref mime_type) = document.mime_type { + if supported_mimes.contains(mime_type.as_str()) { return (true, None); } } @@ -183,7 +183,7 @@ pub(crate) fn determine_thumbnail_support(document: &Document) -> (bool, Option< fn document_supports_ocr(document: &Document) -> bool { document - .content_type + .mime_type .as_deref() .map(|mime| mime.eq_ignore_ascii_case("application/pdf")) .unwrap_or_else(|| { diff --git a/backend/src/workers/ocr.rs b/backend/src/workers/ocr.rs index dddc0f6..5afc607 100644 --- a/backend/src/workers/ocr.rs +++ b/backend/src/workers/ocr.rs @@ -59,7 +59,7 @@ impl Task for GenerateOcrTask { let bytes = ctx.buffered_object().await?.to_vec(); let meta = PdfDocumentMeta { - content_type: context.document.content_type.clone(), + mime_type: context.document.mime_type.clone(), original_name: context.document.original_name.clone(), }; @@ -284,7 +284,7 @@ fn generate_ocr_text(meta: &PdfDocumentMeta, bytes: &[u8]) -> Option, + mime_type: Option, original_name: String, } @@ -395,8 +395,8 @@ fn run_ocr(bytes: &[u8]) -> Result, OcrError> { } fn document_meta_is_pdf(meta: &PdfDocumentMeta) -> bool { - if let Some(content_type) = &meta.content_type { - if content_type.eq_ignore_ascii_case("application/pdf") { + if let Some(mime_type) = &meta.mime_type { + if mime_type.eq_ignore_ascii_case("application/pdf") { return true; } } @@ -410,7 +410,7 @@ fn document_meta_is_pdf(meta: &PdfDocumentMeta) -> bool { fn document_is_pdf(document: &Document) -> bool { document - .content_type + .mime_type .as_deref() .map(|mime| mime.eq_ignore_ascii_case("application/pdf")) .unwrap_or_else(|| { diff --git a/backend/src/workers/thumbnails.rs b/backend/src/workers/thumbnails.rs index 9000d3b..5c42149 100644 --- a/backend/src/workers/thumbnails.rs +++ b/backend/src/workers/thumbnails.rs @@ -463,7 +463,7 @@ fn persist_document_page_count( fn document_is_pdf(document: &Document) -> bool { document - .content_type + .mime_type .as_deref() .map(|mime| mime.eq_ignore_ascii_case("application/pdf")) .unwrap_or_else(|| {