131 lines
3.8 KiB
TypeScript
131 lines
3.8 KiB
TypeScript
import { CATEGORIES } from "./categories";
|
|
|
|
export type PromptAnswers = Record<string, string>;
|
|
|
|
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();
|
|
};
|