Parannettu staattinen analyysi + docker-compose template
Staattinen analyysi: tarkistaa 15 yleistä symbolia (Boolean, Text, Depends, HTTPException jne.) puuttuvista importeista. Models-esimerkki: lisätty Boolean ja Text importteihin. docker-compose.yml: template ilman LLM:ää — ei enää version tai turhaa PostgreSQL-containeria SQLite-projektissa. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1514,7 +1514,7 @@ IMPORTANT: Use uv for package management (uv sync, uv run)` },
|
|||||||
data: { label: 'Data', prompt: `SQLAlchemy models and database setup.
|
data: { label: 'Data', prompt: `SQLAlchemy models and database setup.
|
||||||
|
|
||||||
EXAMPLE:
|
EXAMPLE:
|
||||||
from sqlalchemy import create_engine, Column, Integer, String
|
from sqlalchemy import create_engine, Column, Integer, String, Boolean, Text
|
||||||
from sqlalchemy.orm import sessionmaker, DeclarativeBase
|
from sqlalchemy.orm import sessionmaker, DeclarativeBase
|
||||||
|
|
||||||
engine = create_engine("sqlite:///app.db")
|
engine = create_engine("sqlite:///app.db")
|
||||||
@@ -2463,7 +2463,7 @@ def create_user(name: str, db: Session = Depends(get_db)):
|
|||||||
return {"id": user.id, "name": user.name}`
|
return {"id": user.id, "name": user.name}`
|
||||||
: file.name.includes('model')
|
: file.name.includes('model')
|
||||||
? `\nEXAMPLE output for a models.py:
|
? `\nEXAMPLE output for a models.py:
|
||||||
from sqlalchemy import create_engine, Column, Integer, String
|
from sqlalchemy import create_engine, Column, Integer, String, Boolean, Text
|
||||||
from sqlalchemy.orm import sessionmaker, DeclarativeBase
|
from sqlalchemy.orm import sessionmaker, DeclarativeBase
|
||||||
|
|
||||||
engine = create_engine("sqlite:///app.db")
|
engine = create_engine("sqlite:///app.db")
|
||||||
@@ -2523,11 +2523,20 @@ IMPORTANT: Keep the code SHORT. Max ~50 lines. No comments, no docstrings. Write
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Tarkista puuttuvat importit
|
// Tarkista puuttuvat importit
|
||||||
if (code.includes('FastAPI') && !imports.some(i => i.includes('FastAPI'))) {
|
const importText = imports.join(' ');
|
||||||
staticIssues.push(`${name}: käyttää FastAPI mutta ei importtaa sitä`);
|
const needsImport = [
|
||||||
|
['FastAPI', 'FastAPI'], ['Session', 'Session'], ['Depends', 'Depends'],
|
||||||
|
['HTTPException', 'HTTPException'], ['TestClient', 'TestClient'],
|
||||||
|
['Boolean', 'Boolean'], ['Text', 'Text'], ['Float', 'Float'], ['DateTime', 'DateTime'],
|
||||||
|
['Column', 'Column'], ['create_engine', 'create_engine'],
|
||||||
|
['DeclarativeBase', 'DeclarativeBase'], ['sessionmaker', 'sessionmaker'],
|
||||||
|
];
|
||||||
|
for (const [symbol, name_] of needsImport) {
|
||||||
|
// Tarkista käytetäänkö symbolia koodissa (ei import-riveillä)
|
||||||
|
const codeWithoutImports = lines.filter(l => !l.match(/^(from|import)\s/)).join('\n');
|
||||||
|
if (codeWithoutImports.includes(symbol) && !importText.includes(symbol)) {
|
||||||
|
staticIssues.push(`${name}: käyttää '${symbol}' 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
|
// Tarkista tyhjät funktiot
|
||||||
const emptyFuncs = code.match(/def \w+\([^)]*\):\s*\n\s*(pass|\.\.\.)/g);
|
const emptyFuncs = code.match(/def \w+\([^)]*\):\s*\n\s*(pass|\.\.\.)/g);
|
||||||
@@ -2642,16 +2651,21 @@ CMD ["uv", "run", "uvicorn", "${mainFile.replace('.py','')}:app", "--host", "0.0
|
|||||||
const step7 = step6 + 1;
|
const step7 = step6 + 1;
|
||||||
termLog(`\n<span style="color:#d29922;font-weight:bold">[${step7}] DevOps</span> — docker-compose.yml`);
|
termLog(`\n<span style="color:#d29922;font-weight:bold">[${step7}] DevOps</span> — docker-compose.yml`);
|
||||||
pipelineStep('tester', 'Compose', 'active', 'docker-compose.yml');
|
pipelineStep('tester', 'Compose', 'active', 'docker-compose.yml');
|
||||||
const composePrompt = `Write a docker-compose.yml for this project. Include:
|
// docker-compose.yml templatesta (ei LLM:llä — vältetään version/postgres ongelmat)
|
||||||
- app service (build from Dockerfile, port mapping, restart: unless-stopped)
|
const composeContent = `services:
|
||||||
- db service if SQLite/PostgreSQL is used (volume for data persistence)
|
app:
|
||||||
- Named volumes for persistent data
|
build: .
|
||||||
Only output the YAML content, nothing else.
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
volumes:
|
||||||
|
- app-data:/app/data
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
Files: ${Object.keys(generatedFiles).join(', ')}`;
|
volumes:
|
||||||
const compose = await kpnRun(agentPrompts.tester.model, composePrompt, false, 256);
|
app-data:`;
|
||||||
if (compose) generatedFiles['docker-compose.yml'] = compose;
|
generatedFiles['docker-compose.yml'] = composeContent;
|
||||||
pipelineStep('tester', 'Compose', 'done', 'docker-compose.yml', compose);
|
termLog(` <span style="color:#3fb950">✓</span> docker-compose.yml generoitu (template)`);
|
||||||
|
pipelineStep('tester', 'Compose', 'done', composeContent, composeContent);
|
||||||
|
|
||||||
// Vaihe 8: DevOps — README
|
// Vaihe 8: DevOps — README
|
||||||
const step8 = step7 + 1;
|
const step8 = step7 + 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user