Files
Alpha/src/services/qa-analyzer.ts
T
ricardo 4e90f6f7b2 users: AG Grid reemplazado por tabla nativa paginada + QA indicators
- UsersView: tabla nativa con busqueda, paginacion (15/page), iniciales
- UsersView: eliminada dependencia ag-grid (mantenida en bundle por otros modulos)
- DashboardView: QA metrics con desglose auto/parcial/manual
- DashboardView: seccion expandible con planes QA detallados
- qa-analyzer: fix field name automatizable
- ToDo: K-09 eliminada
2026-05-28 23:49:41 -05:00

89 lines
2.9 KiB
TypeScript

import { callAI } from '@/services/ai'
import db from '@/services/db'
export interface QATestCase {
type: string
description: string
automatizable: string
tool: string
}
export interface HUQAPlan {
huTitle: string
huId: string
acceptanceCriteria: string[]
testCases: QATestCase[]
manualSteps: string[]
criticalTests: string[]
}
const QA_PROMPT = `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`
export async function generateQAPlan(huTitle: string, huDescription: string, acceptanceCriteria: string): Promise<HUQAPlan> {
const userContent = `HU: ${huTitle}\nDescripción: ${huDescription}\nCriterios: ${acceptanceCriteria}`
const content = await callAI(
[{ role: 'system', content: QA_PROMPT }, { role: 'user', content: userContent }],
0.3, 4096,
)
try {
const jsonStr = extractJSON(content)
const result: Omit<HUQAPlan, 'huTitle' | 'huId'> = JSON.parse(jsonStr)
return { huTitle, huId: '', ...result }
} catch (e) {
console.error('[Alpha] Failed to parse QA plan. Raw:', content)
throw new Error(`Error generando plan QA para: ${huTitle}`)
}
}
export async function saveQAPlan(projectId: number, huId: string, huTitle: string, plan: HUQAPlan) {
await db.table('qa_plans').put({
id: `${projectId}-${huId}`, projectId, huId, huTitle,
plan: JSON.stringify(plan),
createdAt: new Date().toISOString(),
})
}
export async function getQAPlans(projectId: number) {
return db.table('qa_plans').where('projectId').equals(projectId).toArray()
}
export async function generateAndSavePlan(projectId: number, huId: string, huTitle: string, huDescription: string, acceptanceCriteria: string): Promise<HUQAPlan> {
const plan = await generateQAPlan(huTitle, huDescription, acceptanceCriteria)
plan.huId = huId
await saveQAPlan(projectId, huId, huTitle, plan)
return plan
}
function extractJSON(text: string): string {
try { JSON.parse(text); return text } catch {}
const block = text.match(/```(?:json)?\s*([\s\S]*?)```/)
if (block) { try { JSON.parse(block[1].trim()); return block[1].trim() } catch {} }
const first = text.indexOf('{')
const last = text.lastIndexOf('}')
if (first !== -1 && last > first) { const c = text.slice(first, last + 1); try { JSON.parse(c); return c } catch {} }
return text
}