This commit is contained in:
2025-10-27 22:25:43 +01:00
parent 50125f4659
commit 2d80515ad5
5 changed files with 279 additions and 12 deletions
+79 -5
View File
@@ -62,12 +62,24 @@ const QUICKWIT_MAX_HITS: usize = 200;
pub struct DocumentListQuery {
pub folder_id: Option<Uuid>,
#[serde(default)]
pub include_deleted: bool,
#[serde(default)]
pub include_descendants: Option<bool>,
pub query: Option<String>,
pub tags: Option<String>,
pub correspondents: Option<String>,
#[serde(default = "default_document_status_filter")]
pub status: DocumentStatusFilter,
}
fn default_document_status_filter() -> DocumentStatusFilter {
DocumentStatusFilter::Active
}
#[derive(Clone, Copy, Deserialize, Serialize, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum DocumentStatusFilter {
Active,
Deleted,
All,
}
#[derive(Deserialize, IntoParams, ToSchema)]
@@ -380,6 +392,12 @@ pub struct MoveDocumentRequest {
pub folder_id: Option<Uuid>,
}
#[derive(Deserialize, ToSchema)]
pub struct RestoreDocumentRequest {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub folder_id: Option<Uuid>,
}
#[derive(Deserialize, ToSchema)]
pub struct AssignTagsRequest {
pub tag_ids: Vec<Uuid>,
@@ -406,19 +424,25 @@ pub async fn list_documents(
) -> AppResult<Json<Vec<DocumentResponse>>> {
let DocumentListQuery {
folder_id,
include_deleted,
include_descendants,
query,
tags,
correspondents,
status,
} = params;
let mut docs_query = documents::table
.filter(documents::tenant_id.eq(tenant_id))
.into_boxed();
if !include_deleted {
docs_query = docs_query.filter(documents::deleted_at.is_null());
match status {
DocumentStatusFilter::Active => {
docs_query = docs_query.filter(documents::deleted_at.is_null());
}
DocumentStatusFilter::Deleted => {
docs_query = docs_query.filter(documents::deleted_at.is_not_null());
}
DocumentStatusFilter::All => {}
}
let search_text = query
@@ -1387,6 +1411,56 @@ pub async fn update_document(
}))
}
pub async fn restore_document(
Path(document_id): Path<Uuid>,
TenantScopedConn {
mut conn,
tenant_id,
..
}: TenantScopedConn,
Json(payload): Json<RestoreDocumentRequest>,
) -> AppResult<StatusCode> {
let mut document: Document = documents::table
.find(document_id)
.filter(documents::tenant_id.eq(tenant_id))
.first(&mut conn)?;
if document.deleted_at.is_none() {
return Ok(StatusCode::NO_CONTENT);
}
if let Some(folder_id) = payload.folder_id {
ensure_folder_exists_on_conn(&mut conn, tenant_id, folder_id)?;
document.folder_id = Some(folder_id);
} else if let Some(folder_id) = document.folder_id {
let exists: bool = diesel::select(exists(
folders::table
.filter(folders::id.eq(folder_id))
.filter(folders::tenant_id.eq(tenant_id)),
))
.get_result(&mut conn)?;
if !exists {
document.folder_id = None;
}
}
let now = Utc::now().naive_utc();
diesel::update(
documents::table
.find(document_id)
.filter(documents::tenant_id.eq(tenant_id)),
)
.set((
documents::deleted_at.eq::<Option<NaiveDateTime>>(None),
documents::folder_id.eq(document.folder_id),
documents::updated_at.eq(now),
))
.execute(&mut conn)?;
Ok(StatusCode::NO_CONTENT)
}
fn merge_document_metadata(existing: Value, updates: Value) -> AppResult<Value> {
let mut base = match existing {
Value::Object(map) => map,