fix: query documents table for analytics instead of empty events table
The document_processing_events table was never populated. Analytics endpoints now query the documents table directly using status and timestamp columns. Also updated upload page labels to remove outdated "Agentic RAG" references. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -170,8 +170,9 @@ export interface SessionAnalytics {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns per-day session statistics from document_processing_events.
|
||||
* Groups upload_started events by date, then joins completed/failed counts.
|
||||
* Returns per-day session statistics from the documents table.
|
||||
* Groups documents by creation date, counts by status, and derives processing time
|
||||
* from (updated_at - created_at) for completed documents.
|
||||
*/
|
||||
export async function getSessionAnalytics(days: number): Promise<SessionAnalytics> {
|
||||
const pool = getPostgresPool();
|
||||
@@ -186,11 +187,14 @@ export async function getSessionAnalytics(days: number): Promise<SessionAnalytic
|
||||
}>(`
|
||||
SELECT
|
||||
DATE(created_at) AS date,
|
||||
COUNT(*) FILTER (WHERE event_type = 'upload_started') AS total_sessions,
|
||||
COUNT(*) FILTER (WHERE event_type = 'completed') AS successful_sessions,
|
||||
COUNT(*) FILTER (WHERE event_type = 'failed') AS failed_sessions,
|
||||
COALESCE(AVG(duration_ms) FILTER (WHERE event_type = 'completed'), 0) AS avg_processing_time
|
||||
FROM document_processing_events
|
||||
COUNT(*) AS total_sessions,
|
||||
COUNT(*) FILTER (WHERE status = 'completed') AS successful_sessions,
|
||||
COUNT(*) FILTER (WHERE status = 'failed') AS failed_sessions,
|
||||
COALESCE(
|
||||
AVG(EXTRACT(EPOCH FROM (updated_at - created_at)) * 1000)
|
||||
FILTER (WHERE status = 'completed'), 0
|
||||
) AS avg_processing_time
|
||||
FROM documents
|
||||
WHERE created_at >= NOW() - $1::interval
|
||||
GROUP BY DATE(created_at)
|
||||
ORDER BY date DESC
|
||||
@@ -230,7 +234,7 @@ export interface ProcessingStatsFromEvents {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns processing pipeline statistics from document_processing_events.
|
||||
* Returns processing pipeline statistics from the documents table.
|
||||
*/
|
||||
export async function getProcessingStatsFromEvents(): Promise<ProcessingStatsFromEvents> {
|
||||
const pool = getPostgresPool();
|
||||
@@ -241,10 +245,11 @@ export async function getProcessingStatsFromEvents(): Promise<ProcessingStatsFro
|
||||
avg_processing_ms: string | null;
|
||||
}>(`
|
||||
SELECT
|
||||
COUNT(DISTINCT document_id) AS total_documents,
|
||||
COUNT(*) FILTER (WHERE event_type = 'completed') AS succeeded,
|
||||
AVG(duration_ms) FILTER (WHERE event_type = 'completed') AS avg_processing_ms
|
||||
FROM document_processing_events
|
||||
COUNT(*) AS total_documents,
|
||||
COUNT(*) FILTER (WHERE status = 'completed') AS succeeded,
|
||||
AVG(EXTRACT(EPOCH FROM (updated_at - created_at)) * 1000)
|
||||
FILTER (WHERE status = 'completed') AS avg_processing_ms
|
||||
FROM documents
|
||||
`);
|
||||
|
||||
const row = rows[0]!;
|
||||
@@ -256,7 +261,7 @@ export async function getProcessingStatsFromEvents(): Promise<ProcessingStatsFro
|
||||
documentAiAgenticRag: row.avg_processing_ms ? parseFloat(row.avg_processing_ms) : 0,
|
||||
},
|
||||
averageApiCalls: {
|
||||
documentAiAgenticRag: 0, // API call counting not tracked in events table
|
||||
documentAiAgenticRag: 0,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -278,7 +283,7 @@ export interface HealthFromEvents {
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives system health status from recent document_processing_events.
|
||||
* Derives system health status from recent documents.
|
||||
* Looks at the last 24 hours to determine health.
|
||||
*/
|
||||
export async function getHealthFromEvents(): Promise<HealthFromEvents> {
|
||||
@@ -293,18 +298,14 @@ export async function getHealthFromEvents(): Promise<HealthFromEvents> {
|
||||
}>(`
|
||||
SELECT
|
||||
COUNT(*) AS total,
|
||||
COUNT(*) FILTER (WHERE event_type = 'completed') AS succeeded,
|
||||
COUNT(*) FILTER (WHERE event_type = 'failed') AS failed,
|
||||
AVG(duration_ms) FILTER (WHERE event_type = 'completed') AS avg_processing_ms,
|
||||
COUNT(*) FILTER (WHERE status = 'completed') AS succeeded,
|
||||
COUNT(*) FILTER (WHERE status = 'failed') AS failed,
|
||||
AVG(EXTRACT(EPOCH FROM (updated_at - created_at)) * 1000)
|
||||
FILTER (WHERE status = 'completed') AS avg_processing_ms,
|
||||
COUNT(*) FILTER (
|
||||
WHERE event_type = 'processing_started'
|
||||
AND document_id NOT IN (
|
||||
SELECT document_id FROM document_processing_events
|
||||
WHERE event_type IN ('completed', 'failed')
|
||||
AND created_at >= NOW() - INTERVAL '24 hours'
|
||||
)
|
||||
WHERE status NOT IN ('completed', 'failed')
|
||||
) AS active
|
||||
FROM document_processing_events
|
||||
FROM documents
|
||||
WHERE created_at >= NOW() - INTERVAL '24 hours'
|
||||
`);
|
||||
|
||||
|
||||
@@ -226,7 +226,7 @@ const Analytics: React.FC = () => {
|
||||
<h3 className="text-md font-medium text-gray-700">Average Processing Time</h3>
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-gray-600">Document AI + Agentic RAG</span>
|
||||
<span className="text-sm text-gray-600">Single-Pass + Quality Check</span>
|
||||
<span className="text-sm font-medium">{formatTime(processingStats.averageProcessingTime?.documentAiAgenticRag ?? 0)}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -236,7 +236,7 @@ const Analytics: React.FC = () => {
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-sm text-gray-600">Processing Method</span>
|
||||
<span className="text-sm font-medium">Document AI + Agentic RAG</span>
|
||||
<span className="text-sm font-medium">Single-Pass + Quality Check</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -325,7 +325,7 @@ const DocumentUpload: React.FC<DocumentUploadProps> = ({
|
||||
case 'uploaded':
|
||||
return 'Uploaded to Cloud Storage ✓';
|
||||
case 'processing':
|
||||
return 'Processing with Document AI + Optimized Agentic RAG...';
|
||||
return 'Processing with AI-Powered CIM Analysis...';
|
||||
case 'completed':
|
||||
return 'Completed ✓ (PDF automatically deleted)';
|
||||
case 'error':
|
||||
@@ -344,10 +344,9 @@ const DocumentUpload: React.FC<DocumentUploadProps> = ({
|
||||
<div className="flex items-center">
|
||||
<CheckCircle className="h-5 w-5 text-blue-600 mr-2" />
|
||||
<div>
|
||||
<h3 className="text-sm font-medium text-blue-800">Document AI + Optimized Agentic RAG Processing</h3>
|
||||
<h3 className="text-sm font-medium text-blue-800">AI-Powered CIM Analysis Processing</h3>
|
||||
<p className="text-sm text-blue-700 mt-1">
|
||||
All documents are automatically processed using Google Document AI for extraction and our advanced optimized agentic RAG system for analysis,
|
||||
including intelligent chunking, vectorization, and multi-agent CIM review. PDFs are automatically deleted after processing.
|
||||
All documents are automatically processed using AI-powered extraction and structured CIM review analysis. PDFs are automatically deleted after processing.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -372,7 +371,7 @@ const DocumentUpload: React.FC<DocumentUploadProps> = ({
|
||||
Drag and drop PDF files here, or click to browse
|
||||
</p>
|
||||
<p className="text-xs text-gray-500">
|
||||
Maximum file size: 50MB • Supported format: PDF • Stored securely in Cloud Storage • Automatic Document AI + Optimized Agentic RAG Processing • PDFs deleted after processing
|
||||
Maximum file size: 50MB • Supported format: PDF • Stored securely in Cloud Storage • Automatic AI-Powered CIM Analysis Processing • PDFs deleted after processing
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -401,7 +400,7 @@ const DocumentUpload: React.FC<DocumentUploadProps> = ({
|
||||
<h4 className="text-sm font-medium text-success-800">Upload Complete</h4>
|
||||
<p className="text-sm text-success-700 mt-1">
|
||||
Files have been uploaded successfully! You can now navigate away from this page.
|
||||
Processing will continue in the background using Document AI + Optimized Agentic RAG. This can take several minutes. PDFs will be automatically deleted after processing to save costs.
|
||||
Processing will continue in the background using AI-Powered CIM Analysis. This can take several minutes. PDFs will be automatically deleted after processing to save costs.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user