reduce to 1 object per asset
This commit is contained in:
@@ -16,17 +16,16 @@ use uuid::Uuid;
|
||||
|
||||
use crate::auth::{ensure_active_tenant_with_conn, jwt::DownloadSubject, TenantScopedConn};
|
||||
use crate::documents::asset::{
|
||||
asset_object_disposition, DocumentAssetDetailResponse, DocumentAssetResponse,
|
||||
asset_disposition, DocumentAssetDetailResponse, DocumentAssetResponse,
|
||||
DocumentVersionDetailResponse, DocumentVersionResponse,
|
||||
};
|
||||
#[allow(unused_imports)]
|
||||
use crate::error::ApiErrorResponse;
|
||||
use crate::error::{AppError, AppResult};
|
||||
use crate::http::responders::{accepted_json, created_json, no_content, ok_json, JsonResponse};
|
||||
use crate::models::{Document, DocumentAsset, DocumentAssetObject, DocumentVersion};
|
||||
use crate::models::{Document, DocumentAsset, DocumentVersion};
|
||||
use crate::schema::{
|
||||
document_asset_objects, document_assets, document_versions, documents,
|
||||
user_sessions::dsl as session_dsl,
|
||||
document_assets, document_versions, documents, user_sessions::dsl as session_dsl,
|
||||
};
|
||||
use crate::services::correspondents::{
|
||||
AssignCorrespondentsRequest, BulkCorrespondentAction, BulkCorrespondentResponse,
|
||||
@@ -91,15 +90,6 @@ pub struct RestoreDocumentRequest {
|
||||
pub folder_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Default, IntoParams, ToSchema)]
|
||||
#[into_params(parameter_in = Query)]
|
||||
pub struct AssetObjectsQuery {
|
||||
#[serde(default)]
|
||||
pub start: Option<i32>,
|
||||
#[serde(default)]
|
||||
pub limit: Option<i32>,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/documents",
|
||||
@@ -467,12 +457,13 @@ pub async fn list_document_assets(
|
||||
TenantScopedConn {
|
||||
mut conn,
|
||||
tenant_id,
|
||||
user_id,
|
||||
..
|
||||
}: TenantScopedConn,
|
||||
) -> AppResult<JsonResponse<Vec<DocumentAssetResponse>>> {
|
||||
let service = DocumentsService::new(&state);
|
||||
let assets = service
|
||||
.list_document_assets(&mut conn, tenant_id, document_id)
|
||||
.list_document_assets(&mut conn, tenant_id, user_id, document_id)
|
||||
.await?;
|
||||
ok_json(assets)
|
||||
}
|
||||
@@ -480,14 +471,13 @@ pub async fn list_document_assets(
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/assets/{asset_id}",
|
||||
params(("asset_id" = Uuid, Path, description = "Asset ID"), AssetObjectsQuery),
|
||||
params(("asset_id" = Uuid, Path, description = "Asset ID")),
|
||||
responses((status = 200, description = "Asset detail", body = DocumentAssetDetailResponse)),
|
||||
tag = "Assets"
|
||||
)]
|
||||
pub async fn get_document_asset(
|
||||
State(state): State<AppState>,
|
||||
Path(asset_id): Path<Uuid>,
|
||||
Query(query): Query<AssetObjectsQuery>,
|
||||
TenantScopedConn {
|
||||
conn,
|
||||
tenant_id,
|
||||
@@ -495,17 +485,9 @@ pub async fn get_document_asset(
|
||||
..
|
||||
}: TenantScopedConn,
|
||||
) -> AppResult<JsonResponse<DocumentAssetDetailResponse>> {
|
||||
let start = query.start.unwrap_or(1);
|
||||
let limit = query.limit.unwrap_or(1);
|
||||
if start < 1 {
|
||||
return Err(AppError::bad_request("start must be at least 1"));
|
||||
}
|
||||
if limit < 1 {
|
||||
return Err(AppError::bad_request("limit must be at least 1"));
|
||||
}
|
||||
let service = DocumentsService::new(&state);
|
||||
let detail = service
|
||||
.get_document_asset(conn, tenant_id, user_id, asset_id, start, limit)
|
||||
.get_document_asset(conn, tenant_id, user_id, asset_id)
|
||||
.await?;
|
||||
ok_json(detail)
|
||||
}
|
||||
@@ -637,20 +619,7 @@ pub async fn download_with_token(
|
||||
)
|
||||
.await
|
||||
}
|
||||
DownloadSubject::AssetObject {
|
||||
asset_id,
|
||||
object_id,
|
||||
} => {
|
||||
if !state.config.proxy_downloads {
|
||||
return Err(AppError::not_found());
|
||||
}
|
||||
|
||||
let object: DocumentAssetObject = document_asset_objects::table
|
||||
.find(*object_id)
|
||||
.filter(document_asset_objects::asset_id.eq(*asset_id))
|
||||
.filter(document_asset_objects::tenant_id.eq(claims.tenant_id))
|
||||
.first(&mut conn)?;
|
||||
|
||||
DownloadSubject::Asset { asset_id } => {
|
||||
let asset: DocumentAsset = document_assets::table
|
||||
.find(*asset_id)
|
||||
.filter(document_assets::tenant_id.eq(claims.tenant_id))
|
||||
@@ -659,14 +628,28 @@ pub async fn download_with_token(
|
||||
drop(conn);
|
||||
|
||||
let storage = state.storage_for_tenant(claims.tenant_id)?;
|
||||
let disposition = asset_object_disposition(&asset, &object);
|
||||
let disposition = asset_disposition(&asset);
|
||||
|
||||
if !state.config.proxy_downloads {
|
||||
let presigned_url = storage
|
||||
.presign_get_object(
|
||||
&asset.s3_key,
|
||||
Duration::from_secs(PRESIGNED_URL_EXPIRY_SECONDS),
|
||||
disposition.as_deref(),
|
||||
)
|
||||
.await
|
||||
.storage_context("failed to generate download URL")?;
|
||||
|
||||
return Ok(axum::response::Redirect::temporary(&presigned_url).into_response());
|
||||
}
|
||||
|
||||
proxy_storage_object(
|
||||
storage,
|
||||
&object.s3_key,
|
||||
&asset.s3_key,
|
||||
disposition.as_deref(),
|
||||
headers.get(header::RANGE).cloned(),
|
||||
Some(asset.mime_type.as_str()),
|
||||
Some(object.id.to_string()),
|
||||
Some(asset.id.to_string()),
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -1078,13 +1061,11 @@ pub async fn remove_tag(
|
||||
crate::routes::documents::MoveDocumentRequest,
|
||||
crate::routes::documents::BulkReanalyzeSelectionRequest,
|
||||
crate::routes::documents::BulkReanalyzeResponse,
|
||||
crate::routes::documents::AssetObjectsQuery,
|
||||
crate::routes::documents::UploadDocumentForm,
|
||||
crate::documents::asset::DocumentVersionResponse,
|
||||
crate::documents::asset::DocumentVersionDetailResponse,
|
||||
crate::documents::asset::DocumentAssetResponse,
|
||||
crate::documents::asset::DocumentAssetDetailResponse,
|
||||
crate::documents::asset::DocumentAssetObjectResponse,
|
||||
crate::documents::correspondents::DocumentCorrespondentResponse,
|
||||
crate::error::ApiErrorResponse,
|
||||
))
|
||||
|
||||
Reference in New Issue
Block a user