Translate Phase 2 medium-priority files (frontend utils + backend dimensions)

Phase 2 of Spanish-to-English translation for medium-priority files:

Frontend utils (2 files):
- dataTransformation.ts: Translated ~72 occurrences (comments, docs, console logs)
- segmentClassifier.ts: Translated ~20 occurrences (JSDoc, inline comments, UI strings)

Backend dimensions (3 files):
- OperationalPerformance.py: Translated ~117 lines (docstrings, comments)
- SatisfactionExperience.py: Translated ~33 lines (docstrings, comments)
- EconomyCost.py: Translated ~79 lines (docstrings, comments)

All function names and variable names preserved for API compatibility.
Frontend and backend compilation tested and verified successful.

Related to TRANSLATION_STATUS.md Phase 2 objectives.

https://claude.ai/code/session_01GNbnkFoESkRcnPr3bLCYDg
This commit is contained in:
Claude
2026-02-07 11:03:00 +00:00
parent 94178eaaae
commit 8c7f5fa827
5 changed files with 325 additions and 335 deletions

View File

@@ -1,5 +1,5 @@
// utils/segmentClassifier.ts
// Utilidad para clasificar colas/skills en segmentos de cliente
// Utility to classify queues/skills into customer segments
import type { CustomerSegment, RawInteraction, StaticConfig } from '../types';
@@ -10,8 +10,8 @@ export interface SegmentMapping {
}
/**
* Parsea string de colas separadas por comas
* Ejemplo: "VIP, Premium, Enterprise" → ["VIP", "Premium", "Enterprise"]
* Parses queue string separated by commas
* Example: "VIP, Premium, Enterprise" → ["VIP", "Premium", "Enterprise"]
*/
export function parseQueueList(input: string): string[] {
if (!input || input.trim().length === 0) {
@@ -25,13 +25,13 @@ export function parseQueueList(input: string): string[] {
}
/**
* Clasifica una cola según el mapeo proporcionado
* Usa matching parcial y case-insensitive
* Classifies a queue according to the provided mapping
* Uses partial and case-insensitive matching
*
* Ejemplo:
* Example:
* - queue: "VIP_Support" + mapping.high: ["VIP"] → "high"
* - queue: "Soporte_General_N1" + mapping.medium: ["Soporte_General"] → "medium"
* - queue: "Retencion" (no match) → "medium" (default)
* - queue: "General_Support_L1" + mapping.medium: ["General_Support"] → "medium"
* - queue: "Retention" (no match) → "medium" (default)
*/
export function classifyQueue(
queue: string,
@@ -39,7 +39,7 @@ export function classifyQueue(
): CustomerSegment {
const normalizedQueue = queue.toLowerCase().trim();
// Buscar en high value
// Search in high value
for (const highQueue of mapping.high_value_queues) {
const normalizedHigh = highQueue.toLowerCase().trim();
if (normalizedQueue.includes(normalizedHigh) || normalizedHigh.includes(normalizedQueue)) {
@@ -47,7 +47,7 @@ export function classifyQueue(
}
}
// Buscar en low value
// Search in low value
for (const lowQueue of mapping.low_value_queues) {
const normalizedLow = lowQueue.toLowerCase().trim();
if (normalizedQueue.includes(normalizedLow) || normalizedLow.includes(normalizedQueue)) {
@@ -55,7 +55,7 @@ export function classifyQueue(
}
}
// Buscar en medium value (explícito)
// Search in medium value (explicit)
for (const mediumQueue of mapping.medium_value_queues) {
const normalizedMedium = mediumQueue.toLowerCase().trim();
if (normalizedQueue.includes(normalizedMedium) || normalizedMedium.includes(normalizedQueue)) {
@@ -63,13 +63,13 @@ export function classifyQueue(
}
}
// Default: medium (para colas no mapeadas)
// Default: medium (for unmapped queues)
return 'medium';
}
/**
* Clasifica todas las colas únicas de un conjunto de interacciones
* Retorna un mapa de cola → segmento
* Classifies all unique queues from a set of interactions
* Returns a map of queue → segment
*/
export function classifyAllQueues(
interactions: RawInteraction[],
@@ -77,10 +77,10 @@ export function classifyAllQueues(
): Map<string, CustomerSegment> {
const queueSegments = new Map<string, CustomerSegment>();
// Obtener colas únicas
// Get unique queues
const uniqueQueues = [...new Set(interactions.map(i => i.queue_skill))];
// Clasificar cada cola
// Classify each queue
uniqueQueues.forEach(queue => {
queueSegments.set(queue, classifyQueue(queue, mapping));
});
@@ -89,8 +89,8 @@ export function classifyAllQueues(
}
/**
* Genera estadísticas de segmentación
* Retorna conteo, porcentaje y lista de colas por segmento
* Generates segmentation statistics
* Returns count, percentage and list of queues by segment
*/
export function getSegmentationStats(
interactions: RawInteraction[],
@@ -108,13 +108,13 @@ export function getSegmentationStats(
total: interactions.length
};
// Contar interacciones por segmento
// Count interactions by segment
interactions.forEach(interaction => {
const segment = queueSegments.get(interaction.queue_skill) || 'medium';
stats[segment].count++;
});
// Calcular porcentajes
// Calculate percentages
const total = interactions.length;
if (total > 0) {
stats.high.percentage = Math.round((stats.high.count / total) * 100);
@@ -122,7 +122,7 @@ export function getSegmentationStats(
stats.low.percentage = Math.round((stats.low.count / total) * 100);
}
// Obtener colas por segmento (únicas)
// Get queues by segment (unique)
queueSegments.forEach((segment, queue) => {
if (!stats[segment].queues.includes(queue)) {
stats[segment].queues.push(queue);
@@ -133,7 +133,7 @@ export function getSegmentationStats(
}
/**
* Valida que el mapeo tenga al menos una cola en algún segmento
* Validates that the mapping has at least one queue in some segment
*/
export function isValidMapping(mapping: SegmentMapping): boolean {
return (
@@ -144,8 +144,8 @@ export function isValidMapping(mapping: SegmentMapping): boolean {
}
/**
* Crea un mapeo desde StaticConfig
* Si no hay segment_mapping, retorna mapeo vacío
* Creates a mapping from StaticConfig
* If there is no segment_mapping, returns empty mapping
*/
export function getMappingFromConfig(config: StaticConfig): SegmentMapping | null {
if (!config.segment_mapping) {
@@ -160,8 +160,8 @@ export function getMappingFromConfig(config: StaticConfig): SegmentMapping | nul
}
/**
* Obtiene el segmento para una cola específica desde el config
* Si no hay mapeo, retorna 'medium' por defecto
* Gets the segment for a specific queue from the config
* If there is no mapping, returns 'medium' by default
*/
export function getSegmentForQueue(
queue: string,
@@ -177,7 +177,7 @@ export function getSegmentForQueue(
}
/**
* Formatea estasticas para mostrar en UI
* Formats statistics for display in UI
*/
export function formatSegmentationSummary(
stats: ReturnType<typeof getSegmentationStats>
@@ -185,15 +185,15 @@ export function formatSegmentationSummary(
const parts: string[] = [];
if (stats.high.count > 0) {
parts.push(`${stats.high.percentage}% High Value (${stats.high.count} interacciones)`);
parts.push(`${stats.high.percentage}% High Value (${stats.high.count} interactions)`);
}
if (stats.medium.count > 0) {
parts.push(`${stats.medium.percentage}% Medium Value (${stats.medium.count} interacciones)`);
parts.push(`${stats.medium.percentage}% Medium Value (${stats.medium.count} interactions)`);
}
if (stats.low.count > 0) {
parts.push(`${stats.low.percentage}% Low Value (${stats.low.count} interacciones)`);
parts.push(`${stats.low.percentage}% Low Value (${stats.low.count} interactions)`);
}
return parts.join(' | ');