frontend
This commit is contained in:
+35
-6
@@ -57,7 +57,8 @@ use uuid::Uuid;
|
||||
schemas::LoginResponseVariants,
|
||||
schemas::DocumentResponse,
|
||||
schemas::DocumentDetailResponse,
|
||||
schemas::DocumentVersion,
|
||||
schemas::DocumentVersionResponse,
|
||||
schemas::DocumentVersionDetailResponse,
|
||||
schemas::DocumentAssetSummary,
|
||||
schemas::DocumentAssetDetail,
|
||||
schemas::DocumentAssetObject,
|
||||
@@ -238,6 +239,27 @@ mod doc {
|
||||
)]
|
||||
pub(super) fn delete_document() {}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/documents/{id}/versions",
|
||||
params(("id" = Uuid, Path, description = "Document ID")),
|
||||
responses((status = 200, description = "Document versions", body = [DocumentVersionResponse])),
|
||||
tag = "Documents"
|
||||
)]
|
||||
pub(super) fn list_document_versions() {}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/documents/{id}/versions/{version_id}",
|
||||
params(
|
||||
("id" = Uuid, Path, description = "Document ID"),
|
||||
("version_id" = Uuid, Path, description = "Version ID"),
|
||||
),
|
||||
responses((status = 200, description = "Document version detail", body = DocumentVersionDetailResponse)),
|
||||
tag = "Documents"
|
||||
)]
|
||||
pub(super) fn get_document_version() {}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/api/documents/{id}/restore",
|
||||
@@ -650,15 +672,22 @@ pub mod schemas {
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct DocumentVersion {
|
||||
pub struct DocumentVersionResponse {
|
||||
pub id: Uuid,
|
||||
pub version_number: i32,
|
||||
pub checksum: String,
|
||||
pub s3_key: String,
|
||||
pub size_bytes: i64,
|
||||
pub checksum: String,
|
||||
pub created_at: String,
|
||||
pub metadata: Value,
|
||||
#[schema(nullable)]
|
||||
pub assets: Option<Vec<DocumentAssetSummary>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
pub struct DocumentVersionDetailResponse {
|
||||
#[serde(flatten)]
|
||||
pub version: DocumentVersionResponse,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub assets: Vec<DocumentAssetSummary>,
|
||||
pub download_path: String,
|
||||
}
|
||||
|
||||
@@ -692,7 +721,7 @@ pub mod schemas {
|
||||
#[schema(nullable)]
|
||||
pub correspondents: Option<Vec<DocumentCorrespondent>>,
|
||||
#[schema(nullable)]
|
||||
pub current_version: Option<DocumentVersion>,
|
||||
pub current_version: Option<DocumentVersionDetailResponse>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, ToSchema)]
|
||||
|
||||
@@ -133,7 +133,6 @@ impl From<Tag> for TagResponse {
|
||||
pub struct DocumentVersionResponse {
|
||||
pub id: Uuid,
|
||||
pub version_number: i32,
|
||||
pub s3_key: String,
|
||||
pub size_bytes: i64,
|
||||
pub checksum: String,
|
||||
pub created_at: String,
|
||||
@@ -175,7 +174,7 @@ pub struct DocumentAssetDetailResponse {
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, ToSchema)]
|
||||
pub struct DocumentCurrentVersionResponse {
|
||||
pub struct DocumentVersionDetailResponse {
|
||||
#[serde(flatten)]
|
||||
pub version: DocumentVersionResponse,
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
@@ -209,7 +208,7 @@ pub struct DocumentResponse {
|
||||
#[serde(default, skip_serializing_if = "Vec::is_empty")]
|
||||
pub correspondents: Vec<DocumentCorrespondentResponse>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub current_version: Option<DocumentCurrentVersionResponse>,
|
||||
pub current_version: Option<DocumentVersionDetailResponse>,
|
||||
}
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct DocumentDetailResponse {
|
||||
@@ -1145,6 +1144,73 @@ pub async fn get_document_asset(
|
||||
Ok(Json(to_asset_detail_response(asset, object_responses)))
|
||||
}
|
||||
|
||||
pub async fn list_document_versions(
|
||||
Path(document_id): Path<Uuid>,
|
||||
TenantScopedConn {
|
||||
mut conn,
|
||||
tenant_id,
|
||||
..
|
||||
}: TenantScopedConn,
|
||||
) -> AppResult<Json<Vec<DocumentVersionResponse>>> {
|
||||
let document: Document = documents::table
|
||||
.find(document_id)
|
||||
.filter(documents::tenant_id.eq(tenant_id))
|
||||
.first(&mut conn)?;
|
||||
|
||||
if document.deleted_at.is_some() {
|
||||
return Err(AppError::not_found());
|
||||
}
|
||||
|
||||
let versions: Vec<DocumentVersion> = document_versions::table
|
||||
.filter(document_versions::document_id.eq(document_id))
|
||||
.filter(document_versions::tenant_id.eq(tenant_id))
|
||||
.order(document_versions::version_number.asc())
|
||||
.load(&mut conn)?;
|
||||
|
||||
let versions: Vec<DocumentVersionResponse> =
|
||||
versions.into_iter().map(to_version_response).collect();
|
||||
|
||||
Ok(Json(versions))
|
||||
}
|
||||
|
||||
pub async fn get_document_version(
|
||||
State(state): State<AppState>,
|
||||
Path((document_id, version_id)): Path<(Uuid, Uuid)>,
|
||||
TenantScopedConn {
|
||||
mut conn,
|
||||
tenant_id,
|
||||
user_id,
|
||||
..
|
||||
}: TenantScopedConn,
|
||||
) -> AppResult<Json<DocumentVersionDetailResponse>> {
|
||||
let document: Document = documents::table
|
||||
.find(document_id)
|
||||
.filter(documents::tenant_id.eq(tenant_id))
|
||||
.first(&mut conn)?;
|
||||
|
||||
if document.deleted_at.is_some() {
|
||||
return Err(AppError::not_found());
|
||||
}
|
||||
|
||||
let version: DocumentVersion = document_versions::table
|
||||
.find(version_id)
|
||||
.filter(document_versions::document_id.eq(document_id))
|
||||
.filter(document_versions::tenant_id.eq(tenant_id))
|
||||
.first(&mut conn)?;
|
||||
|
||||
drop(conn);
|
||||
|
||||
let assets = load_asset_responses(&state, tenant_id, version.id).await?;
|
||||
let download_path = build_download_path(&state, &document, user_id)?;
|
||||
let version_core = to_version_response(version);
|
||||
|
||||
Ok(Json(DocumentVersionDetailResponse {
|
||||
version: version_core,
|
||||
assets,
|
||||
download_path,
|
||||
}))
|
||||
}
|
||||
|
||||
pub async fn download_document(
|
||||
State(state): State<AppState>,
|
||||
Path(document_id): Path<Uuid>,
|
||||
@@ -2574,7 +2640,7 @@ pub(crate) fn to_document_response(
|
||||
) -> AppResult<DocumentResponse> {
|
||||
let current_version = if let Some((version, assets)) = current_version {
|
||||
let download_path = build_download_path(state, &doc, user_id)?;
|
||||
Some(DocumentCurrentVersionResponse {
|
||||
Some(DocumentVersionDetailResponse {
|
||||
version,
|
||||
assets,
|
||||
download_path,
|
||||
|
||||
@@ -28,7 +28,6 @@ pub fn to_version_response(version: DocumentVersion) -> DocumentVersionResponse
|
||||
DocumentVersionResponse {
|
||||
id: version.id,
|
||||
version_number: version.version_number,
|
||||
s3_key: version.s3_key,
|
||||
size_bytes: version.size_bytes,
|
||||
checksum: version.checksum,
|
||||
created_at: to_iso(version.created_at),
|
||||
|
||||
@@ -85,6 +85,11 @@ pub fn create_router(state: AppState) -> Router<()> {
|
||||
get(documents::list_document_assets).post(documents::request_document_assets),
|
||||
)
|
||||
.route("/:id/folder", patch(documents::move_document))
|
||||
.route("/:id/versions", get(documents::list_document_versions))
|
||||
.route(
|
||||
"/:id/versions/:version_id",
|
||||
get(documents::get_document_version),
|
||||
)
|
||||
.route("/:id/restore", post(documents::restore_document))
|
||||
.route("/:id/tags", post(documents::assign_tags))
|
||||
.route("/:id/tags/:tag_id", delete(documents::remove_tag))
|
||||
|
||||
Reference in New Issue
Block a user