Testaaja: staattinen analyysi + strukturoitu LLM-arviointi

Staattinen analyysi selaimessa (ennen LLM:ää):
- Käyttämättömät importit
- Puuttuvat importit (FastAPI, Session)
- Tyhjät funktiot

LLM-arviointi 5 kohdalla (esimerkkivastauksineen):
1. Imports, 2. Database, 3. Endpoints, 4. Error handling, 5. Security

Korjausluuppi käynnistyy jos ✗ löytyy tai staattinen analyysi huomauttaa.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 10:13:15 +03:00
parent 21a8015ea3
commit cea1961183

View File

@@ -2499,17 +2499,70 @@ IMPORTANT: Keep the code SHORT. Max ~50 lines. No comments, no docstrings. Write
.map(([name, code]) => `--- ${name} ---\n${code}`)
.join('\n\n');
termLog(`\n<span style="color:#58a6ff;font-weight:bold">[${fileList.length + 2}] Testaaja</span> — arviointi`);
// Staattinen analyysi ennen LLM-arviointia
termLog(`\n<span style="color:#58a6ff;font-weight:bold">[${fileList.length + 2}] Testaaja</span> — staattinen analyysi + arviointi`);
pipelineStep('tester', 'Review', 'active', `${Object.keys(generatedFiles).length} tiedostoa`);
const reviewPrompt = `Review this project. List bugs or issues. Be brief.
If the code is correct, say "LGTM".
// Yksinkertainen staattinen tarkistus selaimessa
const staticIssues = [];
for (const [name, code] of Object.entries(generatedFiles)) {
if (!name.endsWith('.py')) continue;
const lines = (code || '').split('\n');
// Tarkista importit
const imports = lines.filter(l => l.match(/^(from|import)\s/));
const usedNames = code.replace(/^(from|import)\s.*/gm, '');
for (const imp of imports) {
const match = imp.match(/import\s+(\w+)|from\s+\S+\s+import\s+(.+)/);
if (match) {
const names = (match[1] || match[2]).split(',').map(n => n.trim().split(' as ').pop().trim());
for (const n of names) {
if (n && !usedNames.includes(n) && n !== '*') {
staticIssues.push(`${name}: käyttämätön import '${n}'`);
}
}
}
}
// Tarkista puuttuvat importit
if (code.includes('FastAPI') && !imports.some(i => i.includes('FastAPI'))) {
staticIssues.push(`${name}: käyttää FastAPI mutta ei importtaa sitä`);
}
if (code.includes('Session') && !imports.some(i => i.includes('Session'))) {
staticIssues.push(`${name}: käyttää Session mutta ei importtaa sitä`);
}
// Tarkista tyhjät funktiot
const emptyFuncs = code.match(/def \w+\([^)]*\):\s*\n\s*(pass|\.\.\.)/g);
if (emptyFuncs) staticIssues.push(`${name}: ${emptyFuncs.length} tyhjää funktiota`);
}
if (staticIssues.length > 0) {
termLog(` <span style="color:#d29922">Staattinen analyysi (${staticIssues.length} huomautusta):</span>`);
for (const issue of staticIssues) {
termLog(` <span style="color:#d29922">⚠</span> ${esc(issue)}`);
}
} else {
termLog(' <span style="color:#3fb950">Staattinen analyysi: ei huomautuksia</span>');
}
const reviewPrompt = `Review this project code. Check EVERY item and report result:
1. Imports: ✓/✗ — are all imports valid and available?
2. Database: ✓/✗ — is the DB setup correct (engine, session, models)?
3. Endpoints: ✓/✗ — do all routes have correct parameters and return types?
4. Error handling: ✓/✗ — are edge cases handled (404, validation)?
5. Security: ✓/✗ — any SQL injection, missing auth, or data exposure?
EXAMPLE output:
1. Imports: ✓ — all imports are valid
2. Database: ✗ — missing Base.metadata.create_all(engine) call
3. Endpoints: ✓ — GET/POST/DELETE routes are correct
4. Error handling: ✗ — no 404 when todo not found
5. Security: ✓ — using ORM, no raw SQL
${allCode}`;
const review = await kpnRun(agentPrompts.tester.model, reviewPrompt, false, 200);
const review = await kpnRun(agentPrompts.tester.model, reviewPrompt, false, 300);
pipelineStep('tester', 'Review', 'done', `${Object.keys(generatedFiles).length} tiedostoa`, review);
// Vaihe 4: Korjausluuppi — jos testaaja löysi ongelmia
if (review && !review.toLowerCase().includes('lgtm') && !review.toLowerCase().includes('looks good')) {
const hasIssues = review && (review.includes('') || staticIssues.length > 0);
if (hasIssues) {
termLog(`\n<span style="color:#d29922;font-weight:bold">[${fileList.length + 3}] Koodari</span> — korjaukset`);
pipelineStep('coder', 'Korjaukset', 'active', review);
const fixPrompt = `Fix the issues found in the review.