feat: análisis extendido (10 campos nuevos) + generador de guiones con GPT-4o
Análisis extendido: - Nuevos campos: apertura_exacta, cierre_exacto, tecnica_retencion, momento_pico_seg - Copywriting: nivel_consciencia (Schwartz), objecion_principal, avatar_descripcion - Replicabilidad: ingredientes_clave, replicabilidad, ratio_emocion_logica - analizador.js: prompt extendido con metodología Schwartz + retención - validador.js: schema Zod actualizado con 6 nuevos enums - Migración SQL 05: ALTER TABLE + nuevos ENUMs + índices Generador de guiones: - generador.js: lib GPT-4o con temperatura 0.7 y contexto de patrones - server.js: endpoints POST /api/generar, GET /api/generados, GET /api/generados/:id - backend/api/generar.js + api/generar.js + api/generados.js: Vercel handlers - Migración SQL 06: tabla guiones_generados con score_estimado, variantes, notas - GenerateView.vue: formulario completo + preview del guion con copy al portapapeles - SideNavBar: nueva entrada "Generar" con ícono auto_fix_high - Router: ruta /generate → GenerateView - api.js: api.generar() + api.generados.listar/obtener() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@ -5,25 +5,31 @@
|
||||
// ============================================================
|
||||
import { z } from 'zod'
|
||||
|
||||
const EstructuraEnum = z.enum(['AIDA','PAS','hero_journey','storybrand','antes_despues','otra'])
|
||||
const GanchoTipoEnum = z.enum(['pregunta','declaracion_shock','dato_estadistica','historia','controversia','promesa_directa'])
|
||||
const DesarrolloEnum = z.enum(['problema_solucion','lista','demostracion','testimonio','tutorial','storytelling_puro'])
|
||||
const CtaTipoEnum = z.enum(['seguir','comentar','compartir','comprar','visitar_link','guardar','ninguno'])
|
||||
const PacingEnum = z.enum(['lento','medio','rapido','variable'])
|
||||
const TriggerEnum = z.enum(['miedo','esperanza','curiosidad','ira','orgullo','tristeza','sorpresa','humor'])
|
||||
const AtencionVisualEnum= z.enum(['zoom_agresivo','corte_rapido','texto_pantalla','cara_camara','broll_dinamico','ninguno'])
|
||||
const DolorPlacerEnum = z.enum(['apela_dolor','apela_placer','ambos'])
|
||||
const CargaEnum = z.enum(['baja','media','alta'])
|
||||
const VelocidadEnum = z.enum(['lenta','normal','rapida','muy_rapida'])
|
||||
const TonoEnum = z.enum(['educativo','entretenimiento','inspiracional','controversial','informativo','humoristico'])
|
||||
const PersonaEnum = z.enum(['primera_persona','segunda_persona','tercera_persona','mixta'])
|
||||
const EspecificidadEnum = z.enum(['generico','especifico','ultra_especifico'])
|
||||
const EstructuraEnum = z.enum(['AIDA','PAS','hero_journey','storybrand','antes_despues','otra'])
|
||||
const GanchoTipoEnum = z.enum(['pregunta','declaracion_shock','dato_estadistica','historia','controversia','promesa_directa'])
|
||||
const DesarrolloEnum = z.enum(['problema_solucion','lista','demostracion','testimonio','tutorial','storytelling_puro'])
|
||||
const CtaTipoEnum = z.enum(['seguir','comentar','compartir','comprar','visitar_link','guardar','ninguno'])
|
||||
const PacingEnum = z.enum(['lento','medio','rapido','variable'])
|
||||
const TriggerEnum = z.enum(['miedo','esperanza','curiosidad','ira','orgullo','tristeza','sorpresa','humor'])
|
||||
const AtencionVisualEnum = z.enum(['zoom_agresivo','corte_rapido','texto_pantalla','cara_camara','broll_dinamico','ninguno'])
|
||||
const DolorPlacerEnum = z.enum(['apela_dolor','apela_placer','ambos'])
|
||||
const CargaEnum = z.enum(['baja','media','alta'])
|
||||
const VelocidadEnum = z.enum(['lenta','normal','rapida','muy_rapida'])
|
||||
const TonoEnum = z.enum(['educativo','entretenimiento','inspiracional','controversial','informativo','humoristico'])
|
||||
const PersonaEnum = z.enum(['primera_persona','segunda_persona','tercera_persona','mixta'])
|
||||
const EspecificidadEnum = z.enum(['generico','especifico','ultra_especifico'])
|
||||
const TecnicaRetencionEnum= z.enum(['open_loop','cliffhanger','curiosity_gap','countdown','pregunta_abierta','ninguna'])
|
||||
const RatioEmocionEnum = z.enum(['emocional','logico','equilibrado'])
|
||||
const NivelConcienciaEnum = z.enum(['inconsciente','problema_consciente','solucion_consciente','producto_consciente','mas_consciente'])
|
||||
const ReplicabilidadEnum = z.enum(['alta','media','baja'])
|
||||
|
||||
export const AnalisisSchema = z.object({
|
||||
// Storytelling
|
||||
estructura_narrativa: EstructuraEnum,
|
||||
gancho_tipo: GanchoTipoEnum,
|
||||
gancho_texto: z.string().min(1).max(200),
|
||||
apertura_exacta: z.string().min(1).max(300),
|
||||
cierre_exacto: z.string().min(1).max(200),
|
||||
gancho_duracion_seg: z.number().int().min(0).max(30),
|
||||
desarrollo_tipo: DesarrolloEnum,
|
||||
cta_tipo: CtaTipoEnum,
|
||||
@ -33,6 +39,8 @@ export const AnalisisSchema = z.object({
|
||||
resolucion: z.string().min(1).max(500),
|
||||
pacing_ritmo: PacingEnum,
|
||||
numero_actos: z.number().int().min(1).max(4),
|
||||
tecnica_retencion: TecnicaRetencionEnum,
|
||||
momento_pico_seg: z.number().int().min(0).max(600),
|
||||
|
||||
// Cialdini
|
||||
cialdini_reciprocidad: z.boolean(),
|
||||
@ -57,8 +65,9 @@ export const AnalisisSchema = z.object({
|
||||
velocidad_locucion: VelocidadEnum,
|
||||
uso_musica: z.boolean(),
|
||||
micro_compromisos: z.boolean(),
|
||||
ratio_emocion_logica: RatioEmocionEnum,
|
||||
|
||||
// Contenido
|
||||
// Contenido + Copywriting
|
||||
tema_principal: z.string().min(1).max(100),
|
||||
angulo_unico: z.string().min(1).max(500),
|
||||
palabras_clave: z.array(z.string()).min(1).max(10),
|
||||
@ -66,10 +75,15 @@ export const AnalisisSchema = z.object({
|
||||
persona_narradora: PersonaEnum,
|
||||
promesa_explicita: z.string().min(1).max(500),
|
||||
nivel_especificidad: EspecificidadEnum,
|
||||
nivel_consciencia: NivelConcienciaEnum,
|
||||
objecion_principal: z.string().max(500).nullable(),
|
||||
avatar_descripcion: z.string().min(1).max(500),
|
||||
ingredientes_clave: z.array(z.string()).min(1).max(7),
|
||||
replicabilidad: ReplicabilidadEnum,
|
||||
|
||||
// Métricas calculadas por GPT-4o
|
||||
// Métricas
|
||||
score_virabilidad: z.number().int().min(1).max(100),
|
||||
resumen_patron: z.string().min(10).max(1000),
|
||||
resumen_patron: z.string().min(10).max(1500),
|
||||
})
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user