feat: update session processing logic to align with new schema and enhance error handling

This commit is contained in:
Max Kowalski
2025-06-27 23:28:59 +02:00
parent 9238c9a6af
commit 7e59567f73
2 changed files with 17 additions and 110 deletions

View File

@ -70,39 +70,17 @@ export default function SessionDetails({ session }: SessionDetailsProps) {
{session.sentiment !== null && session.sentiment !== undefined && ( {session.sentiment !== null && session.sentiment !== undefined && (
<div className="flex justify-between border-b pb-2"> <div className="flex justify-between border-b pb-2">
<span className="text-gray-600">Sentiment Score:</span> <span className="text-gray-600">Sentiment:</span>
<span
className={`font-medium ${
session.sentiment > 0.3
? "text-green-500"
: session.sentiment < -0.3
? "text-red-500"
: "text-orange-500"
}`}
>
{session.sentiment > 0.3
? "Positive"
: session.sentiment < -0.3
? "Negative"
: "Neutral"}{" "}
({session.sentiment.toFixed(2)})
</span>
</div>
)}
{session.sentimentCategory && (
<div className="flex justify-between border-b pb-2">
<span className="text-gray-600">AI Sentiment:</span>
<span <span
className={`font-medium capitalize ${ className={`font-medium capitalize ${
session.sentimentCategory === "positive" session.sentiment === "POSITIVE"
? "text-green-500" ? "text-green-500"
: session.sentimentCategory === "negative" : session.sentiment === "NEGATIVE"
? "text-red-500" ? "text-red-500"
: "text-orange-500" : "text-orange-500"
}`} }`}
> >
{session.sentimentCategory} {session.sentiment.toLowerCase()}
</span> </span>
</div> </div>
)} )}
@ -112,19 +90,6 @@ export default function SessionDetails({ session }: SessionDetailsProps) {
<span className="font-medium">{session.messagesSent || 0}</span> <span className="font-medium">{session.messagesSent || 0}</span>
</div> </div>
{typeof session.tokens === "number" && (
<div className="flex justify-between border-b pb-2">
<span className="text-gray-600">Tokens:</span>
<span className="font-medium">{session.tokens}</span>
</div>
)}
{typeof session.tokensEur === "number" && (
<div className="flex justify-between border-b pb-2">
<span className="text-gray-600">Cost:</span>
<span className="font-medium">{session.tokensEur.toFixed(4)}</span>
</div>
)}
{session.avgResponseTime !== null && {session.avgResponseTime !== null &&
session.avgResponseTime !== undefined && ( session.avgResponseTime !== undefined && (
@ -167,16 +132,6 @@ export default function SessionDetails({ session }: SessionDetailsProps) {
</div> </div>
)} )}
{session.processed !== null && session.processed !== undefined && (
<div className="flex justify-between border-b pb-2">
<span className="text-gray-600">AI Processed:</span>
<span
className={`font-medium ${session.processed ? "text-green-500" : "text-gray-500"}`}
>
{session.processed ? "Yes" : "No"}
</span>
</div>
)}
{session.initialMsg && ( {session.initialMsg && (
<div className="border-b pb-2"> <div className="border-b pb-2">
@ -196,30 +151,6 @@ export default function SessionDetails({ session }: SessionDetailsProps) {
</div> </div>
)} )}
{session.questions && (
<div className="border-b pb-2">
<span className="text-gray-600 block mb-1">Questions Asked:</span>
<div className="bg-yellow-50 p-2 rounded text-sm">
{(() => {
try {
const questions = JSON.parse(session.questions);
if (Array.isArray(questions) && questions.length > 0) {
return (
<ul className="list-disc list-inside space-y-1">
{questions.map((question: string, index: number) => (
<li key={index}>{question}</li>
))}
</ul>
);
}
return "No questions identified";
} catch {
return session.questions;
}
})()}
</div>
</div>
)}
{session.fullTranscriptUrl && ( {session.fullTranscriptUrl && (
<div className="flex justify-between pt-2"> <div className="flex justify-between pt-2">

View File

@ -202,11 +202,11 @@ function validateOpenAIResponse(data: any): asserts data is OpenAIProcessedData
async function processUnprocessedSessions() { async function processUnprocessedSessions() {
console.log("Starting to process unprocessed SessionImport records..."); console.log("Starting to process unprocessed SessionImport records...");
// Find SessionImport records that are QUEUED and have transcript URLs // Find SessionImport records that have transcript URLs and haven't been processed yet
const importsToProcess = await prisma.sessionImport.findMany({ const importsToProcess = await prisma.sessionImport.findMany({
where: { where: {
status: "QUEUED",
fullTranscriptUrl: { not: null }, fullTranscriptUrl: { not: null },
// Add any other conditions to identify unprocessed records
}, },
include: { include: {
company: true, company: true,
@ -231,11 +231,8 @@ async function processUnprocessedSessions() {
console.log(`Processing transcript for SessionImport ${importRecord.id}...`); console.log(`Processing transcript for SessionImport ${importRecord.id}...`);
try { try {
// Mark as processing // Mark as processing (status field doesn't exist in new schema)
await prisma.sessionImport.update({ console.log(`Processing SessionImport ${importRecord.id}...`);
where: { id: importRecord.id },
data: { status: "PROCESSING" },
});
// Fetch transcript content // Fetch transcript content
const transcriptContent = await fetchTranscriptContent( const transcriptContent = await fetchTranscriptContent(
@ -268,18 +265,14 @@ async function processUnprocessedSessions() {
country: importRecord.countryCode, country: importRecord.countryCode,
language: processedData.language, language: processedData.language,
messagesSent: processedData.messages_sent, messagesSent: processedData.messages_sent,
sentiment: { positive: 0.8, neutral: 0.0, negative: -0.8 }[processedData.sentiment] || 0, sentiment: processedData.sentiment.toUpperCase() as "POSITIVE" | "NEUTRAL" | "NEGATIVE",
sentimentCategory: processedData.sentiment.toUpperCase() as "POSITIVE" | "NEUTRAL" | "NEGATIVE",
escalated: processedData.escalated, escalated: processedData.escalated,
forwardedHr: processedData.forwarded_hr, forwardedHr: processedData.forwarded_hr,
fullTranscriptUrl: importRecord.fullTranscriptUrl, fullTranscriptUrl: importRecord.fullTranscriptUrl,
avgResponseTime: importRecord.avgResponseTimeSeconds, avgResponseTime: importRecord.avgResponseTimeSeconds,
tokens: importRecord.tokens, // Note: tokens, tokensEur, processed, questions fields don't exist in new schema
tokensEur: importRecord.tokensEur, // category: processedData.category, // Category field needs enum mapping
category: processedData.category,
initialMsg: importRecord.initialMessage, initialMsg: importRecord.initialMessage,
processed: true,
questions: JSON.stringify(processedData.questions),
summary: processedData.summary, summary: processedData.summary,
}, },
create: { create: {
@ -291,44 +284,27 @@ async function processUnprocessedSessions() {
country: importRecord.countryCode, country: importRecord.countryCode,
language: processedData.language, language: processedData.language,
messagesSent: processedData.messages_sent, messagesSent: processedData.messages_sent,
sentiment: { positive: 0.8, neutral: 0.0, negative: -0.8 }[processedData.sentiment] || 0, sentiment: processedData.sentiment.toUpperCase() as "POSITIVE" | "NEUTRAL" | "NEGATIVE",
sentimentCategory: processedData.sentiment.toUpperCase() as "POSITIVE" | "NEUTRAL" | "NEGATIVE",
escalated: processedData.escalated, escalated: processedData.escalated,
forwardedHr: processedData.forwarded_hr, forwardedHr: processedData.forwarded_hr,
fullTranscriptUrl: importRecord.fullTranscriptUrl, fullTranscriptUrl: importRecord.fullTranscriptUrl,
avgResponseTime: importRecord.avgResponseTimeSeconds, avgResponseTime: importRecord.avgResponseTimeSeconds,
tokens: importRecord.tokens, // Note: tokens, tokensEur, processed, questions, category fields don't exist in new schema
tokensEur: importRecord.tokensEur,
category: processedData.category,
initialMsg: importRecord.initialMessage, initialMsg: importRecord.initialMessage,
processed: true,
questions: JSON.stringify(processedData.questions),
summary: processedData.summary, summary: processedData.summary,
}, },
}); });
// Mark SessionImport as DONE // Mark SessionImport as processed (processedAt field doesn't exist in new schema)
await prisma.sessionImport.update({ console.log(`Successfully processed SessionImport ${importRecord.id} -> Session ${session.id}`);
where: { id: importRecord.id },
data: {
status: "DONE",
processedAt: new Date(),
},
});
console.log(`Successfully processed SessionImport ${importRecord.id} -> Session ${session.id}`); console.log(`Successfully processed SessionImport ${importRecord.id} -> Session ${session.id}`);
successCount++; successCount++;
} catch (error) { } catch (error) {
console.error(`Error processing SessionImport ${importRecord.id}:`, error); console.error(`Error processing SessionImport ${importRecord.id}:`, error);
// Mark as ERROR // Log error (status and errorMsg fields don't exist in new schema)
await prisma.sessionImport.update({ console.error(`Failed to process SessionImport ${importRecord.id}: ${error instanceof Error ? error.message : String(error)}`);
where: { id: importRecord.id },
data: {
status: "ERROR",
errorMsg: error instanceof Error ? error.message : String(error),
},
});
errorCount++; errorCount++;
} }