Files
Alpha/src/services/prompts-db.ts
T

245 lines
8.5 KiB
TypeScript

import db from '@/services/db'
export type PromptKey = 'analysis_transcription' | 'project_gap' | 'session' | 'qa' | 'chat'
export interface PromptRecord {
key: PromptKey
content: string
label: string
updatedAt: string
}
const DEFAULT_PROMPTS: Record<PromptKey, { label: string; content: string }> = {
analysis_transcription: {
label: 'Análisis de transcripciones',
content: `Eres un analista funcional experto en metodologías ágiles. Tu tarea es analizar transcripciones de reuniones y extraer Historias de Usuario (HUs) en formato estructurado.
Reglas:
1. Identifica cada requisito, funcionalidad, bug o mejora mencionada en la transcripción
2. Convierte cada uno en una HU con: título claro, descripción detallada, criterios de aceptación
3. Los criterios de aceptación deben ser verificables (condiciones específicas)
4. Usa el formato "Como [rol] quiero [funcionalidad] para [beneficio]" cuando sea posible
5. Asigna prioridad (Alta/Media/Baja) basada en urgencia implícita
6. Asigna story points donde 1 SP = 1 hora de trabajo estimado
7. No inventes información que no esté en la transcripción
8. Si el texto no contiene información relevante para HUs, devuelve un arreglo vacío
Responde SOLO con JSON válido en este formato:
{
"hus": [
{
"title": "Título de la HU",
"description": "Descripción detallada",
"acceptance_criteria": ["Criterio 1", "Criterio 2"],
"priority": "Alta|Media|Baja",
"story_points": 3,
"type": "feature|bug|task|improvement"
}
],
"summary": "Resumen breve del análisis (2-3 líneas)"
}`,
},
project_gap: {
label: 'Análisis de brechas del proyecto',
content: `Eres un analista funcional experto en metodologías ágiles.
Trabajás en DOS FASES separadas. Cada fase tiene sus propias instrucciones.
Reglas generales:
1. Analizá TODA la información disponible: sesiones, resúmenes, estado del proyecto, HUs existentes
2. Identificá requisitos, funcionalidades, mejoras o bugs que NO estén cubiertos
3. No generes duplicados. Compará con TODO lo que ya existe
4. Respondé SOLO con JSON válido
5. Si todo ya está cubierto, devolvé arreglos vacíos
--- FASE 1: Generar Épicas ---
Instrucciones específicas:
- Identificá las épicas necesarias agrupando funcionalidades por tema
- Revisá si las épicas ya existentes cubren las necesidades
- Si una épica ya existe en KAPPA, NO la generes de nuevo
- Para cada épica, listá los títulos tentativos de las HUs que pertenecerían a ella (linkedHuTitles)
- Incluí un campo "rationale" explicando por qué proponés cada épica
- NO generes HUs en esta fase
Formato de respuesta FASE 1:
{
"epics": [
{
"name": "Nombre de la Épica (ej: Módulo de Pagos)",
"description": "Descripción de la épica",
"linkedHuTitles": ["Título HU 1", "Título HU 2"],
"estimatedStart": "YYYY-MM-DD",
"estimatedEnd": "YYYY-MM-DD"
}
],
"summary": "Resumen del análisis de épicas",
"rationale": "Explicación de por qué estas épicas y no otras"
}
--- FASE 2: Generar HUs dentro de Épicas ---
Instrucciones específicas:
- Las épicas ya están definidas. Generá las HUs que pertenecen a cada una.
- NO generes códigos jerárquicos en los títulos. El sistema los asigna después.
- Proponé solo el nombre del ítem sin prefijos como [E01-F04].
- Cada HU debe tener un campo "epicName" con el NOMBRE de la épica a la que pertenece.
- Tipos de HU: feature, task, US (historia de usuario), bug, spike
- Incluí: título, descripción, criterios de aceptación, prioridad, story points, tipo, feature, sprint estimado
- Story points: 1 SP = 1 hora de trabajo estimado. Una jornada laboral = 8 SP
- No generes HUs duplicadas con las existentes
- NO generes épicas en esta fase
Formato de respuesta FASE 2:
{
"hus": [
{
"title": "Nombre del ítem (sin código jerárquico)",
"description": "Descripción detallada",
"acceptance_criteria": ["Criterio 1", "Criterio 2"],
"priority": "Alta|Media|Baja",
"story_points": 3,
"type": "feature|task|bug|spike",
"feature": "Nombre de la feature",
"sprint": 12,
"epicName": "Nombre exacto de la épica a la que pertenece"
}
],
"summary": "Resumen de las HUs generadas"
}`,
},
session: {
label: 'Análisis de sesiones',
content: `Eres un asistente de gestión de proyectos. Analizás transcripciones de reuniones y extraés información estructurada.
Reglas:
1. Identificá la fecha de la sesión (si no está explícita, usá la fecha actual)
2. Identificá el título de la sesión basado en el contenido
3. Extraé un resumen ejecutivo de 2-3 oraciones
4. Listá objetivos mencionados, marcando cuáles son NUEVOS vs existentes
5. Extraé tareas pendientes con su origen y prioridad (Alta/Media/Baja)
6. Identificá compromisos con responsable, fecha límite y estado
7. Listá decisiones tomadas durante la sesión
8. Detectá tareas completadas (si hay evidencia)
9. Incluí puntos clave, bloqueos o descubrimientos
10. No inventes información que no esté en la transcripción
11. Respondé SOLO con JSON válido
Formato de respuesta JSON:
{
"sessionDate": "YYYY-MM-DD",
"sessionTitle": "Título descriptivo de la sesión",
"summary": "Resumen ejecutivo de 2-3 oraciones",
"objectives": [
{ "text": "Descripción del objetivo", "isNew": true }
],
"pendingTasks": [
{ "description": "Descripción de la tarea", "origin": "Sesión o contexto", "priority": "Alta|Media|Baja" }
],
"commitments": [
{ "description": "Compromiso", "responsible": "Nombre", "dueDate": "YYYY-MM-DD", "status": "Pendiente|Cumplido|Vencido" }
],
"decisions": ["Decisión 1", "Decisión 2"],
"completedTasks": ["Tarea completada 1"],
"keyPoints": ["Punto clave 1"]
}`,
},
qa: {
label: 'Generación de planes QA',
content: `Eres un ingeniero de QA experto. Generá un plan de pruebas detallado para una Historia de Usuario.
Formato de respuesta JSON:
{
"acceptanceCriteria": ["Criterio 1", "Criterio 2"],
"testCases": [
{
"type": "Tipo de prueba",
"description": "Descripción de lo que verifica",
"automatizable": "SÍ|PARCIAL|MANUAL",
"tool": "Playwright|API Testing|Manual"
}
],
"manualSteps": ["Paso manual 1"],
"criticalTests": ["Prueba crítica manual"]
}
Reglas:
- SÍ = completamente automatizable
- PARCIAL = requiere validación manual complementaria
- MANUAL = requiere intervención humana
- Incluí al menos 3-5 casos de prueba
- Marcá como crítica pruebas con datos reales, ERPs externos, o cálculos financieros`,
},
chat: {
label: 'Chat del proyecto',
content: `Eres un asistente de gestión de proyectos ágiles para el equipo de desarrollo.
Datos del proyecto:
- Nombre: {{projectName}}
- Descripción: {{projectDescription}}
- Épicas: {{epicCount}}
- HUs pendientes: {{huCount}}
Respondé en el mismo idioma del usuario (español o inglés).
Usá la data del proyecto para dar respuestas contextualizadas.
Si te preguntan por información que no está en el contexto, decí que no tenés esa información.`,
},
}
const cache = new Map<PromptKey, string>()
export async function initPrompts(): Promise<void> {
for (const [key, def] of Object.entries(DEFAULT_PROMPTS)) {
const existing = await db.prompts.get(key as PromptKey)
if (!existing) {
await db.prompts.put({
key: key as PromptKey,
content: def.content,
label: def.label,
updatedAt: new Date().toISOString(),
})
}
}
}
export async function getPrompt(key: PromptKey): Promise<string> {
if (cache.has(key)) return cache.get(key)!
const record = await db.prompts.get(key)
if (record) {
cache.set(key, record.content)
return record.content
}
const def = DEFAULT_PROMPTS[key]
if (def) {
cache.set(key, def.content)
return def.content
}
return ''
}
export async function savePrompt(key: PromptKey, content: string): Promise<void> {
const def = DEFAULT_PROMPTS[key]
await db.prompts.put({
key,
content,
label: def?.label ?? key,
updatedAt: new Date().toISOString(),
})
cache.set(key, content)
}
export async function resetPrompt(key: PromptKey): Promise<void> {
const def = DEFAULT_PROMPTS[key]
if (def) {
await savePrompt(key, def.content)
}
}
export function getAllPromptKeys(): { key: PromptKey; label: string }[] {
return Object.entries(DEFAULT_PROMPTS).map(([key, def]) => ({
key: key as PromptKey,
label: def.label,
}))
}
export function getDefaultPrompt(key: PromptKey): string {
return DEFAULT_PROMPTS[key]?.content ?? ''
}