Configuracion de prompt Luisa

This commit is contained in:
unknown
2026-06-02 22:48:59 -04:00
parent 9a8f84ff37
commit 9c5e6bc7fa
8 changed files with 841 additions and 196 deletions

View File

@@ -3,6 +3,31 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository, LessThan } from 'typeorm';
import { Lead, EstadoLead } from './lead.entity';
const SECUENCIA_ESTADOS = [
'nuevo',
'apertura',
'espacio',
'tamano',
'estilo',
'urgencia',
'presupuesto',
] as const;
const VALORES_POR_ESTADO: Record<string, string[]> = {
espacio: ['cocina', 'bano', 'salon', 'integral', 'otro'],
tamano: ['menos10', '10a20', '20a40', 'mas40'],
estilo: ['funcional', 'cuidado', 'exclusivo'],
urgencia: ['urgente', 'medio_plazo', 'frio'],
};
const CAMPO_POR_ESTADO: Record<string, keyof Lead> = {
espacio: 'espacio',
tamano: 'rango_m2',
estilo: 'estilo',
urgencia: 'urgencia',
presupuesto: 'presupuesto_declarado',
};
@Injectable()
export class LeadsService {
private readonly logger = new Logger(LeadsService.name);
@@ -12,6 +37,58 @@ export class LeadsService {
private readonly leadRepo: Repository<Lead>,
) {}
/**
* Normaliza estados legacy del scheduler/DB al flujo de cualificacion.
*/
normalizarEstadoFlujo(estado: string): string {
if (estado === 'en_proceso' || estado === 'recopilando_datos') {
return 'apertura';
}
return estado;
}
getSiguienteEstado(estadoActual: string, viable?: boolean): string {
const estado = this.normalizarEstadoFlujo(estadoActual);
if (estado === 'presupuesto') {
return viable === false ? 'fin_no_viable' : 'fin_viable';
}
const idx = SECUENCIA_ESTADOS.indexOf(
estado as (typeof SECUENCIA_ESTADOS)[number],
);
if (idx === -1 || idx >= SECUENCIA_ESTADOS.length - 1) {
return estado;
}
return SECUENCIA_ESTADOS[idx + 1];
}
getValoresPermitidos(estado: string): string[] {
const estadoNorm = this.normalizarEstadoFlujo(estado);
return VALORES_POR_ESTADO[estadoNorm] ?? [];
}
getCampoParaEstado(estado: string): keyof Lead | null {
const estadoNorm = this.normalizarEstadoFlujo(estado);
return CAMPO_POR_ESTADO[estadoNorm] ?? null;
}
esPresupuestoValido(valor: string): boolean {
const normalizado = valor.trim().toLowerCase();
if (!normalizado) return false;
return /\d/.test(normalizado);
}
evaluarViabilidad(presupuesto: string): boolean {
const numeros = presupuesto.match(/\d[\d.]*/g);
if (!numeros?.length) return true;
const valor = parseInt(numeros[0].replace(/\./g, ''), 10);
if (Number.isNaN(valor)) return true;
return valor >= 5000;
}
/**
* Busca un lead por número de teléfono.
* Si no existe, lo crea con estado 'nuevo'.
@@ -38,8 +115,8 @@ export class LeadsService {
return this.leadRepo.find({ where: { estado_actual: estado } });
}
async updateEstado(lead: Lead, estado: EstadoLead): Promise<Lead> {
lead.estado_actual = estado;
async updateEstado(lead: Lead, estado: EstadoLead | string): Promise<Lead> {
lead.estado_actual = estado as EstadoLead;
return this.leadRepo.save(lead);
}