mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-01-16 11:12:11 +01:00
feat: update session metrics and processing to use enums for sentiment and streamline status tracking
This commit is contained in:
@ -453,41 +453,25 @@ export function sessionMetrics(
|
||||
if (session.escalated) escalatedCount++;
|
||||
if (session.forwardedHr) forwardedHrCount++;
|
||||
|
||||
// Sentiment
|
||||
// Sentiment (now using enum values)
|
||||
if (session.sentiment !== undefined && session.sentiment !== null) {
|
||||
// Example thresholds, adjust as needed
|
||||
if (session.sentiment > 0.3) sentimentPositiveCount++;
|
||||
else if (session.sentiment < -0.3) sentimentNegativeCount++;
|
||||
else sentimentNeutralCount++;
|
||||
if (session.sentiment === "POSITIVE") sentimentPositiveCount++;
|
||||
else if (session.sentiment === "NEGATIVE") sentimentNegativeCount++;
|
||||
else if (session.sentiment === "NEUTRAL") sentimentNeutralCount++;
|
||||
}
|
||||
|
||||
// Sentiment Alert Check
|
||||
// Sentiment Alert Check (simplified for enum)
|
||||
if (
|
||||
companyConfig.sentimentAlert !== undefined &&
|
||||
session.sentiment !== undefined &&
|
||||
session.sentiment !== null &&
|
||||
session.sentiment < companyConfig.sentimentAlert
|
||||
session.sentiment === "NEGATIVE"
|
||||
) {
|
||||
alerts++;
|
||||
}
|
||||
|
||||
// Tokens
|
||||
if (session.tokens !== undefined && session.tokens !== null) {
|
||||
totalTokens += session.tokens;
|
||||
}
|
||||
if (session.tokensEur !== undefined && session.tokensEur !== null) {
|
||||
totalTokensEur += session.tokensEur;
|
||||
}
|
||||
|
||||
// Daily metrics
|
||||
const day = new Date(session.startTime).toISOString().split("T")[0];
|
||||
byDay[day] = (byDay[day] || 0) + 1; // Sessions per day
|
||||
if (session.tokens !== undefined && session.tokens !== null) {
|
||||
tokensByDay[day] = (tokensByDay[day] || 0) + session.tokens;
|
||||
}
|
||||
if (session.tokensEur !== undefined && session.tokensEur !== null) {
|
||||
tokensCostByDay[day] = (tokensCostByDay[day] || 0) + session.tokensEur;
|
||||
}
|
||||
// Note: tokens and tokensEur are not available in the new schema
|
||||
|
||||
// Category metrics
|
||||
if (session.category) {
|
||||
@ -506,24 +490,7 @@ export function sessionMetrics(
|
||||
|
||||
// Extract questions from session
|
||||
const extractQuestions = () => {
|
||||
// 1. Extract from questions JSON field
|
||||
if (session.questions) {
|
||||
try {
|
||||
const questionsArray = JSON.parse(session.questions);
|
||||
if (Array.isArray(questionsArray)) {
|
||||
questionsArray.forEach((question: string) => {
|
||||
if (question && question.trim().length > 0) {
|
||||
const cleanQuestion = question.trim();
|
||||
questionCounts[cleanQuestion] = (questionCounts[cleanQuestion] || 0) + 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`[metrics] Failed to parse questions JSON for session ${session.id}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Extract questions from user messages (if available)
|
||||
// 1. Extract questions from user messages (if available)
|
||||
if (session.messages) {
|
||||
session.messages
|
||||
.filter(msg => msg.role === 'User')
|
||||
|
||||
@ -52,7 +52,7 @@ export function startCsvImportScheduler() {
|
||||
tokensEur: rawSession.tokensEur,
|
||||
category: rawSession.category,
|
||||
initialMessage: rawSession.initialMessage,
|
||||
status: "QUEUED", // Reset status for reprocessing if needed
|
||||
// Status tracking now handled by ProcessingStatusManager
|
||||
},
|
||||
create: {
|
||||
companyId: company.id,
|
||||
@ -72,7 +72,7 @@ export function startCsvImportScheduler() {
|
||||
tokensEur: rawSession.tokensEur,
|
||||
category: rawSession.category,
|
||||
initialMessage: rawSession.initialMessage,
|
||||
status: "QUEUED",
|
||||
// Status tracking now handled by ProcessingStatusManager
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
// Combined scheduler initialization
|
||||
import { startScheduler } from "./scheduler";
|
||||
import { startCsvImportScheduler } from "./scheduler";
|
||||
import { startProcessingScheduler } from "./processingScheduler";
|
||||
|
||||
/**
|
||||
* Initialize all schedulers
|
||||
* - Session refresh scheduler (runs every 15 minutes)
|
||||
* - CSV import scheduler (runs every 15 minutes)
|
||||
* - Session processing scheduler (runs every hour)
|
||||
*/
|
||||
export function initializeSchedulers() {
|
||||
// Start the session refresh scheduler
|
||||
startScheduler();
|
||||
// Start the CSV import scheduler
|
||||
startCsvImportScheduler();
|
||||
|
||||
// Start the session processing scheduler
|
||||
startProcessingScheduler();
|
||||
|
||||
@ -54,8 +54,7 @@ export interface ChatSession {
|
||||
language?: string | null;
|
||||
country?: string | null;
|
||||
ipAddress?: string | null;
|
||||
sentiment?: number | null;
|
||||
sentimentCategory?: string | null; // "positive", "neutral", "negative" from OpenAPI
|
||||
sentiment?: string | null; // Now a SentimentCategory enum: "POSITIVE", "NEUTRAL", "NEGATIVE"
|
||||
messagesSent?: number;
|
||||
startTime: Date;
|
||||
endTime?: Date | null;
|
||||
@ -66,14 +65,11 @@ export interface ChatSession {
|
||||
avgResponseTime?: number | null;
|
||||
escalated?: boolean;
|
||||
forwardedHr?: boolean;
|
||||
tokens?: number;
|
||||
tokensEur?: number;
|
||||
initialMsg?: string;
|
||||
fullTranscriptUrl?: string | null;
|
||||
processed?: boolean | null; // Flag for post-processing status
|
||||
questions?: string | null; // JSON array of questions asked by user
|
||||
summary?: string | null; // Brief summary of the conversation
|
||||
messages?: Message[]; // Parsed messages from transcript
|
||||
transcriptContent?: string | null; // Full transcript content
|
||||
}
|
||||
|
||||
export interface SessionQuery {
|
||||
|
||||
Reference in New Issue
Block a user