import { pool } from "../../shared/db/pool.js"; // ───────────────────────────────────────────────────────────── // Prompt Templates - CRUD con versionado // ───────────────────────────────────────────────────────────── // Prompt keys válidos export const PROMPT_KEYS = ["router", "greeting", "orders", "shipping", "payment", "browse"]; // Modelos por defecto para cada prompt export const DEFAULT_MODELS = { router: "gpt-4o-mini", greeting: "gpt-4-turbo", orders: "gpt-4-turbo", shipping: "gpt-4o-mini", payment: "gpt-4o-mini", browse: "gpt-4-turbo", }; /** * Obtiene el prompt activo para un tenant y key * @returns {Object|null} { id, prompt_key, content, model, version, is_active, created_at, created_by } */ export async function getActivePrompt({ tenantId, promptKey }) { const sql = ` SELECT id, prompt_key, content, model, version, is_active, created_at, created_by FROM prompt_templates WHERE tenant_id = $1 AND prompt_key = $2 AND is_active = true LIMIT 1 `; const { rows } = await pool.query(sql, [tenantId, promptKey]); return rows[0] || null; } /** * Lista todos los prompts activos de un tenant */ export async function listActivePrompts({ tenantId }) { const sql = ` SELECT id, prompt_key, content, model, version, is_active, created_at, created_by FROM prompt_templates WHERE tenant_id = $1 AND is_active = true ORDER BY prompt_key `; const { rows } = await pool.query(sql, [tenantId]); return rows; } /** * Obtiene todas las versiones de un prompt */ export async function getPromptVersions({ tenantId, promptKey, limit = 20 }) { const sql = ` SELECT id, prompt_key, content, model, version, is_active, created_at, created_by FROM prompt_templates WHERE tenant_id = $1 AND prompt_key = $2 ORDER BY version DESC LIMIT $3 `; const { rows } = await pool.query(sql, [tenantId, promptKey, limit]); return rows; } /** * Obtiene una versión específica de un prompt */ export async function getPromptVersion({ tenantId, promptKey, version }) { const sql = ` SELECT id, prompt_key, content, model, version, is_active, created_at, created_by FROM prompt_templates WHERE tenant_id = $1 AND prompt_key = $2 AND version = $3 LIMIT 1 `; const { rows } = await pool.query(sql, [tenantId, promptKey, version]); return rows[0] || null; } /** * Desactiva el prompt activo actual (para crear nueva versión) */ export async function deactivatePrompt({ tenantId, promptKey }) { const sql = ` UPDATE prompt_templates SET is_active = false WHERE tenant_id = $1 AND prompt_key = $2 AND is_active = true `; await pool.query(sql, [tenantId, promptKey]); } /** * Crea una nueva versión del prompt (automáticamente desactiva la anterior) * @returns {Object} El prompt creado con su versión */ export async function createPrompt({ tenantId, promptKey, content, model, createdBy = null }) { // Validar prompt_key if (!PROMPT_KEYS.includes(promptKey)) { throw new Error(`Invalid prompt_key: ${promptKey}. Valid keys: ${PROMPT_KEYS.join(", ")}`); } // Desactivar versión anterior await deactivatePrompt({ tenantId, promptKey }); // Insertar nueva versión (el trigger calcula la versión automáticamente) const sql = ` INSERT INTO prompt_templates (tenant_id, prompt_key, content, model, is_active, created_by) VALUES ($1, $2, $3, $4, true, $5) RETURNING id, prompt_key, content, model, version, is_active, created_at, created_by `; const { rows } = await pool.query(sql, [ tenantId, promptKey, content, model || DEFAULT_MODELS[promptKey] || "gpt-4-turbo", createdBy, ]); return rows[0]; } /** * Restaura una versión anterior del prompt (crea nueva versión con el contenido antiguo) */ export async function rollbackPrompt({ tenantId, promptKey, toVersion, createdBy = null }) { // Obtener la versión a restaurar const oldVersion = await getPromptVersion({ tenantId, promptKey, version: toVersion }); if (!oldVersion) { throw new Error(`Version ${toVersion} not found for prompt ${promptKey}`); } // Crear nueva versión con el contenido antiguo return createPrompt({ tenantId, promptKey, content: oldVersion.content, model: oldVersion.model, createdBy, }); } /** * Resetea un prompt a su default (desactiva todas las versiones custom) */ export async function resetPromptToDefault({ tenantId, promptKey }) { const sql = ` UPDATE prompt_templates SET is_active = false WHERE tenant_id = $1 AND prompt_key = $2 `; await pool.query(sql, [tenantId, promptKey]); return { success: true, message: `Prompt ${promptKey} reset to default` }; } /** * Elimina todas las versiones de un prompt (usar con cuidado) */ export async function deleteAllPromptVersions({ tenantId, promptKey }) { const sql = ` DELETE FROM prompt_templates WHERE tenant_id = $1 AND prompt_key = $2 RETURNING id `; const { rows } = await pool.query(sql, [tenantId, promptKey]); return { deleted: rows.length }; } /** * Obtiene estadísticas de prompts de un tenant */ export async function getPromptStats({ tenantId }) { const sql = ` SELECT prompt_key, COUNT(*) as total_versions, MAX(version) as latest_version, MAX(CASE WHEN is_active THEN version END) as active_version, MAX(created_at) as last_updated FROM prompt_templates WHERE tenant_id = $1 GROUP BY prompt_key ORDER BY prompt_key `; const { rows } = await pool.query(sql, [tenantId]); return rows; }