import { CATEGORIES } from "./categories"; export type PromptAnswers = Record; type PromptSection = { id: string; title: string; render: (answers: PromptAnswers) => string; }; export type PromptTemplate = { name: string; intro?: string; sections: PromptSection[]; }; const safeValue = (value?: string) => { const cleaned = value?.trim(); return cleaned ? cleaned : "Não informado."; }; const renderContextItem = (label: string, value?: string) => `- ${label}: ${safeValue(value)}`; const buildExampleHeadline = (answers: PromptAnswers) => { const perfil = answers.perfil?.trim(); const local = answers.localizacao?.trim(); if (perfil && local) { return `Experimente ${perfil} em ${local}.`; } if (perfil) { return `Descubra ${perfil} feito para surpreender.`; } if (local) { return `Sua próxima estadia em ${local} começa aqui.`; } return "Uma experiência de hotelaria pensada para encantar."; }; const buildExampleCTA = (answers: PromptAnswers) => { const cta = answers.cta?.trim(); return cta ? cta : "Reserve agora e viva essa experiência."; }; export const DEFAULT_PROMPT_TEMPLATE: PromptTemplate = { name: "hotelaria-core", intro: "Você é um redator sênior em hotelaria. Use as informações abaixo para criar uma peça de comunicação clara, persuasiva e fiel ao briefing.", sections: [ { id: "objetivo", title: "Objetivo", render: (answers) => safeValue(answers.objetivo) }, { id: "contexto", title: "Contexto", render: (answers) => { const lines = [ renderContextItem("Perfil do hotel", answers.perfil), renderContextItem("Localização", answers.localizacao), renderContextItem("Diferenciais", answers.diferenciais), renderContextItem("Serviços e amenidades", answers.servicos), renderContextItem("Experiência desejada", answers.experiencia), renderContextItem("Gastronomia", answers.gastronomia), renderContextItem("Bem-estar", answers["bem-estar"]), renderContextItem("Sustentabilidade", answers.sustentabilidade), renderContextItem("Sazonalidade", answers.sazonalidade) ]; return lines.join("\n"); } }, { id: "publico", title: "Público", render: (answers) => safeValue(answers["publico-alvo"]) }, { id: "tom", title: "Tom", render: (answers) => safeValue(answers["tom-de-voz"]) }, { id: "formato", title: "Formato", render: (answers) => [ "Idioma: português (pt-BR).", "Estrutura: 1 headline, 1 parágrafo curto, 1 lista de até 3 diferenciais, CTA final.", "Extensão sugerida: 90 a 130 palavras.", `CTA preferencial: ${safeValue(answers.cta)}` ].join("\n") }, { id: "restricoes", title: "Restrições", render: (answers) => safeValue(answers.restricoes) }, { id: "exemplos", title: "Exemplos", render: (answers) => [ `Headline: ${buildExampleHeadline(answers)}`, `CTA: ${buildExampleCTA(answers)}` ].join("\n") } ] }; export const montarPromptFinal = ( answers: PromptAnswers, template: PromptTemplate = DEFAULT_PROMPT_TEMPLATE ) => { const intro = template.intro ? `${template.intro}\n\n` : ""; const body = template.sections .map((section) => { const content = section.render(answers); return `### ${section.title}\n${content}`; }) .join("\n\n"); const missing = CATEGORIES.filter( (category) => !answers[category.id]?.trim() ).map((category) => category.title); const missingLine = missing.length ? `\n\nAtenção: faltam respostas em ${missing.join(", ")}.` : ""; return `${intro}${body}${missingLine}`.trim(); };