feat(server/client): make sure that the documents endpoint isn't broken
This commit is contained in:
parent
da4f770292
commit
96c47af2c0
|
|
@ -153,6 +153,7 @@ const DocumentsPage: React.FC = () => {
|
|||
pagination.offset,
|
||||
ocrFilter || undefined
|
||||
);
|
||||
// Backend returns wrapped object with documents and pagination
|
||||
setDocuments(response.data.documents || []);
|
||||
setPagination(response.data.pagination || { total: 0, limit: 20, offset: 0, has_more: false });
|
||||
} catch (err) {
|
||||
|
|
|
|||
|
|
@ -271,4 +271,31 @@ impl Database {
|
|||
row.get("failed"),
|
||||
))
|
||||
}
|
||||
|
||||
/// Counts total documents for a user with role-based access control
|
||||
pub async fn count_documents_by_user_with_role(&self, user_id: Uuid, user_role: UserRole) -> Result<i64> {
|
||||
let mut query = QueryBuilder::<Postgres>::new("SELECT COUNT(*) as total FROM documents WHERE 1=1");
|
||||
apply_role_based_filter(&mut query, user_id, user_role);
|
||||
let row = query.build().fetch_one(&self.pool).await?;
|
||||
Ok(row.get("total"))
|
||||
}
|
||||
|
||||
/// Counts documents for a user with role-based access control and OCR status filtering
|
||||
pub async fn count_documents_by_user_with_role_and_filter(
|
||||
&self,
|
||||
user_id: Uuid,
|
||||
user_role: UserRole,
|
||||
ocr_status: Option<&str>
|
||||
) -> Result<i64> {
|
||||
let mut query = QueryBuilder::<Postgres>::new("SELECT COUNT(*) as total FROM documents WHERE 1=1");
|
||||
apply_role_based_filter(&mut query, user_id, user_role);
|
||||
|
||||
if let Some(status) = ocr_status {
|
||||
query.push(" AND ocr_status = ");
|
||||
query.push_bind(status);
|
||||
}
|
||||
|
||||
let row = query.build().fetch_one(&self.pool).await?;
|
||||
Ok(row.get("total"))
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ use crate::{
|
|||
models::DocumentResponse,
|
||||
AppState,
|
||||
};
|
||||
use super::types::{PaginationQuery, DocumentUploadResponse};
|
||||
use super::types::{PaginationQuery, DocumentUploadResponse, PaginatedDocumentsResponse, DocumentPaginationInfo};
|
||||
|
||||
/// Upload a new document
|
||||
#[utoipa::path(
|
||||
|
|
@ -201,7 +201,7 @@ pub async fn get_document_by_id(
|
|||
),
|
||||
params(PaginationQuery),
|
||||
responses(
|
||||
(status = 200, description = "List of documents", body = Vec<DocumentResponse>),
|
||||
(status = 200, description = "Paginated list of documents", body = PaginatedDocumentsResponse),
|
||||
(status = 401, description = "Unauthorized"),
|
||||
(status = 500, description = "Internal server error")
|
||||
)
|
||||
|
|
@ -210,10 +210,34 @@ pub async fn list_documents(
|
|||
State(state): State<Arc<AppState>>,
|
||||
auth_user: AuthUser,
|
||||
Query(query): Query<PaginationQuery>,
|
||||
) -> Result<Json<Vec<DocumentResponse>>, StatusCode> {
|
||||
) -> Result<Json<PaginatedDocumentsResponse>, StatusCode> {
|
||||
let limit = query.limit.unwrap_or(25);
|
||||
let offset = query.offset.unwrap_or(0);
|
||||
|
||||
// Get total count for pagination
|
||||
let total_count = if let Some(ocr_status) = query.ocr_status.as_deref() {
|
||||
state
|
||||
.db
|
||||
.count_documents_by_user_with_role_and_filter(
|
||||
auth_user.user.id,
|
||||
auth_user.user.role,
|
||||
Some(ocr_status),
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
state
|
||||
.db
|
||||
.count_documents_by_user_with_role(
|
||||
auth_user.user.id,
|
||||
auth_user.user.role,
|
||||
)
|
||||
.await
|
||||
}
|
||||
.map_err(|e| {
|
||||
error!("Database error counting documents: {}", e);
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
})?;
|
||||
|
||||
let documents = if let Some(ocr_status) = query.ocr_status.as_deref() {
|
||||
state
|
||||
.db
|
||||
|
|
@ -272,7 +296,18 @@ pub async fn list_documents(
|
|||
})
|
||||
.collect();
|
||||
|
||||
Ok(Json(responses))
|
||||
// Create pagination info
|
||||
let pagination = DocumentPaginationInfo {
|
||||
total: total_count,
|
||||
limit,
|
||||
offset,
|
||||
has_more: offset + limit < total_count,
|
||||
};
|
||||
|
||||
Ok(Json(PaginatedDocumentsResponse {
|
||||
documents: responses,
|
||||
pagination,
|
||||
}))
|
||||
}
|
||||
|
||||
/// Delete a specific document
|
||||
|
|
|
|||
|
|
@ -64,6 +64,20 @@ pub struct DocumentDebugInfo {
|
|||
pub permissions: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct DocumentPaginationInfo {
|
||||
pub total: i64,
|
||||
pub limit: i64,
|
||||
pub offset: i64,
|
||||
pub has_more: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize, ToSchema)]
|
||||
pub struct PaginatedDocumentsResponse {
|
||||
pub documents: Vec<crate::models::DocumentResponse>,
|
||||
pub pagination: DocumentPaginationInfo,
|
||||
}
|
||||
|
||||
impl Default for PaginationQuery {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
|
|
|||
Loading…
Reference in New Issue