Hasta ahora el render solo se condicionaba con tipo/m²/calidad + notas de texto
libre por zona; lo que el cliente decía hablando con Luisa o en la llamada
(estilo, colores, materiales) se guardaba en estilo/tasteText pero NO viajaba al
generador de imagen, así que el render no lo representaba.
- b2c (perfil.ts): el payload de PERFIL_WEBHOOK_URL incluye ahora
preferencias:{estilo, gustos} (gustos = tasteText). Claves vacías se omiten.
- worker (webhook.dto): nuevo PreferenciasDto opcional.
- worker (prompt-builder): construirUserContent (función pura) inyecta el estilo
y los gustos del cliente como bloque dedicado y omite el "modern" por defecto
cuando hay preferencias; el system prompt prioriza colores/materiales del
cliente sobre un estilo genérico.
- worker (pipeline): enhebra preferencias hasta generarPrompt.
- worker (sandbox): acepta estilo/gustos para poder probarlos.
- docs/arquitectura-integracion: documenta el campo preferencias.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
113 lines
1.7 KiB
TypeScript
113 lines
1.7 KiB
TypeScript
import { IsString, IsOptional, IsNumber, IsBoolean, IsArray, ValidateNested, IsIn, IsUUID } from 'class-validator';
|
|
import { Type } from 'class-transformer';
|
|
|
|
class ClienteDto {
|
|
@IsString()
|
|
nombre: string;
|
|
|
|
@IsString()
|
|
telefono: string;
|
|
|
|
@IsString()
|
|
email: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
provincia?: string;
|
|
}
|
|
|
|
class ReformaDto {
|
|
@IsString()
|
|
@IsIn(['cocina', 'bano', 'salon', 'comedor', 'integral', 'otro'])
|
|
tipo: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
m2Suelo?: number;
|
|
|
|
@IsString()
|
|
@IsIn(['basica', 'media', 'premium'])
|
|
calidad: string;
|
|
|
|
@IsOptional()
|
|
@IsBoolean()
|
|
estructural?: boolean;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
@IsIn(['alta', 'media', 'baja'])
|
|
urgencia?: string;
|
|
|
|
@IsOptional()
|
|
@IsNumber()
|
|
presupuestoTarget?: number;
|
|
}
|
|
|
|
class PreferenciasDto {
|
|
@IsOptional()
|
|
@IsString()
|
|
estilo?: string;
|
|
|
|
@IsOptional()
|
|
@IsString()
|
|
gustos?: string;
|
|
}
|
|
|
|
class EmpresaDto {
|
|
@IsUUID()
|
|
tenantId: string;
|
|
|
|
@IsString()
|
|
nombre: string;
|
|
}
|
|
|
|
class FotosDto {
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
antes: string[];
|
|
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
despues: string[];
|
|
}
|
|
|
|
class ZonaDto {
|
|
@IsString()
|
|
zona: string;
|
|
|
|
@IsArray()
|
|
@IsString({ each: true })
|
|
notas: string[];
|
|
|
|
@ValidateNested()
|
|
@Type(() => FotosDto)
|
|
fotos: FotosDto;
|
|
}
|
|
|
|
export class PerfilCompletoDto {
|
|
@IsUUID()
|
|
leadId: string;
|
|
|
|
@ValidateNested()
|
|
@Type(() => ClienteDto)
|
|
cliente: ClienteDto;
|
|
|
|
@ValidateNested()
|
|
@Type(() => ReformaDto)
|
|
reforma: ReformaDto;
|
|
|
|
@IsOptional()
|
|
@ValidateNested()
|
|
@Type(() => PreferenciasDto)
|
|
preferencias?: PreferenciasDto;
|
|
|
|
@ValidateNested()
|
|
@Type(() => EmpresaDto)
|
|
empresa: EmpresaDto;
|
|
|
|
@IsArray()
|
|
@ValidateNested({ each: true })
|
|
@Type(() => ZonaDto)
|
|
zonas: ZonaDto[];
|
|
}
|