feat(client): show new file metadata fields on the client

This commit is contained in:
perf3ct 2025-07-10 21:07:35 +00:00
parent db41b15609
commit 42bdda9476
No known key found for this signature in database
GPG Key ID: 569C4EEC436F5232
6 changed files with 26 additions and 3 deletions

View File

@ -30,6 +30,7 @@ interface FileIntegrityDisplayProps {
createdAt: string; createdAt: string;
updatedAt: string; updatedAt: string;
userId?: string; userId?: string;
username?: string;
compact?: boolean; compact?: boolean;
} }
@ -41,6 +42,7 @@ const FileIntegrityDisplay: React.FC<FileIntegrityDisplayProps> = ({
createdAt, createdAt,
updatedAt, updatedAt,
userId, userId,
username,
compact = false, compact = false,
}) => { }) => {
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
@ -328,7 +330,7 @@ const FileIntegrityDisplay: React.FC<FileIntegrityDisplayProps> = ({
Uploaded By Uploaded By
</Typography> </Typography>
<Chip <Chip
label={`User: ${userId ? userId.substring(0, 8) + '...' : 'Unknown'}`} label={username || (userId ? `User: ${userId.substring(0, 8)}...` : 'Unknown')}
size="small" size="small"
sx={{ sx={{
fontSize: '0.75rem', fontSize: '0.75rem',

View File

@ -39,6 +39,7 @@ interface ProcessingTimelineProps {
createdAt: string; createdAt: string;
updatedAt: string; updatedAt: string;
userId: string; userId: string;
username?: string;
ocrStatus?: string; ocrStatus?: string;
ocrCompletedAt?: string; ocrCompletedAt?: string;
ocrRetryCount?: number; ocrRetryCount?: number;
@ -62,6 +63,7 @@ const ProcessingTimeline: React.FC<ProcessingTimelineProps> = ({
createdAt, createdAt,
updatedAt, updatedAt,
userId, userId,
username,
ocrStatus, ocrStatus,
ocrCompletedAt, ocrCompletedAt,
ocrRetryCount = 0, ocrRetryCount = 0,
@ -114,7 +116,7 @@ const ProcessingTimeline: React.FC<ProcessingTimelineProps> = ({
title: 'Document Uploaded', title: 'Document Uploaded',
description: `File "${fileName}" was uploaded successfully`, description: `File "${fileName}" was uploaded successfully`,
status: 'success', status: 'success',
metadata: { userId }, metadata: { userId, username },
}); });
// OCR processing events // OCR processing events
@ -352,7 +354,7 @@ const ProcessingTimeline: React.FC<ProcessingTimelineProps> = ({
<Box sx={{ display: 'flex', alignItems: 'center', mt: 1 }}> <Box sx={{ display: 'flex', alignItems: 'center', mt: 1 }}>
<PersonIcon sx={{ fontSize: 14, mr: 0.5, color: theme.palette.text.secondary }} /> <PersonIcon sx={{ fontSize: 14, mr: 0.5, color: theme.palette.text.secondary }} />
<Typography variant="caption" color="text.secondary"> <Typography variant="caption" color="text.secondary">
User: {event.metadata.userId.substring(0, 8)}... {event.metadata.username || `User: ${event.metadata.userId.substring(0, 8)}...`}
</Typography> </Typography>
</Box> </Box>
)} )}

View File

@ -699,6 +699,7 @@ const DocumentDetailsPage: React.FC = () => {
createdAt={document.created_at} createdAt={document.created_at}
updatedAt={document.updated_at} updatedAt={document.updated_at}
userId={document.user_id} userId={document.user_id}
username={document.username}
/> />
</Box> </Box>
</Grid> </Grid>
@ -884,6 +885,7 @@ const DocumentDetailsPage: React.FC = () => {
createdAt={document.created_at} createdAt={document.created_at}
updatedAt={document.updated_at} updatedAt={document.updated_at}
userId={document.user_id} userId={document.user_id}
username={document.username}
ocrStatus={document.has_ocr_text ? 'completed' : 'pending'} ocrStatus={document.has_ocr_text ? 'completed' : 'pending'}
ocrCompletedAt={ocrData?.ocr_completed_at} ocrCompletedAt={ocrData?.ocr_completed_at}
ocrError={ocrData?.ocr_error} ocrError={ocrData?.ocr_error}

View File

@ -21,6 +21,7 @@ export interface Document {
created_at: string created_at: string
updated_at: string updated_at: string
user_id: string user_id: string
username?: string
file_hash?: string file_hash?: string
original_created_at?: string original_created_at?: string
original_modified_at?: string original_modified_at?: string

View File

@ -51,6 +51,9 @@ pub struct DocumentResponse {
pub updated_at: DateTime<Utc>, pub updated_at: DateTime<Utc>,
/// User who uploaded/owns the document /// User who uploaded/owns the document
pub user_id: Uuid, pub user_id: Uuid,
/// Username of the user who uploaded/owns the document
#[serde(skip_serializing_if = "Option::is_none", default)]
pub username: Option<String>,
/// SHA256 hash of the file content /// SHA256 hash of the file content
#[serde(skip_serializing_if = "Option::is_none", default)] #[serde(skip_serializing_if = "Option::is_none", default)]
pub file_hash: Option<String>, pub file_hash: Option<String>,
@ -271,6 +274,7 @@ impl From<Document> for DocumentResponse {
created_at: doc.created_at, created_at: doc.created_at,
updated_at: doc.updated_at, updated_at: doc.updated_at,
user_id: doc.user_id, user_id: doc.user_id,
username: None, // Username will be populated separately where needed
file_hash: doc.file_hash, file_hash: doc.file_hash,
has_ocr_text: doc.ocr_text.is_some(), has_ocr_text: doc.ocr_text.is_some(),
ocr_confidence: doc.ocr_confidence, ocr_confidence: doc.ocr_confidence,

View File

@ -189,8 +189,20 @@ pub async fn get_document_by_id(
StatusCode::INTERNAL_SERVER_ERROR StatusCode::INTERNAL_SERVER_ERROR
})?; })?;
// Get username for the document owner
let username = state
.db
.get_user_by_id(document.user_id)
.await
.map_err(|e| {
error!("Failed to get user for document {}: {}", document_id, e);
StatusCode::INTERNAL_SERVER_ERROR
})?
.map(|user| user.username);
let mut response = DocumentResponse::from(document); let mut response = DocumentResponse::from(document);
response.labels = labels; response.labels = labels;
response.username = username;
Ok(Json(response)) Ok(Json(response))
} }