feat: LLM-анализ — индикатор прогресса, кнопка рескана, статистика на дашборде

- Добавлен статус {"status": "analyzing"} в finding.report на время LLM-анализа
- Кнопка рескана (Retry) под LLM-отчётом в ручном режиме
- LLM-статистика на дашборде: analysed / pending
- Защита от двойного анализа через per-finding asyncio.Lock
- _llm_spinner.html — фрагмент спиннера для состояния analysing
- Удалён мёртвый код: constants, i18n, CSS, queries
- Фиксы: _env_int, индексы БД, UnicodeDecodeError, time.mktime и др.
- Шаблоны: shared includes (_status_badge, _pagination)
- AGENTS.md: workflow (lint, test, commit, rebuild)
This commit is contained in:
Marker689
2026-05-10 09:54:04 +03:00
parent c99a7bf67c
commit 6984844161
26 changed files with 261 additions and 266 deletions

View File

@@ -68,8 +68,25 @@ async def init_db():
async with _engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
await _migrate()
await _ensure_indexes()
async def get_session() -> AsyncSession:
async with _async_session() as session:
yield session
async def _ensure_indexes():
"""Create indexes that are not covered by ORM model definitions."""
indexes = [
"CREATE INDEX IF NOT EXISTS idx_scans_status ON scans(status)",
"CREATE INDEX IF NOT EXISTS idx_scans_sha256 ON scans(sha256)",
"CREATE INDEX IF NOT EXISTS idx_scans_package_name ON scans(package_name)",
"CREATE INDEX IF NOT EXISTS idx_scans_package_version ON scans(package_version)",
"CREATE INDEX IF NOT EXISTS idx_scans_flagged ON scans(flagged)",
"CREATE INDEX IF NOT EXISTS idx_scans_nexus_asset_url ON scans(nexus_asset_url)",
"CREATE INDEX IF NOT EXISTS idx_findings_scan_id ON findings(scan_id)",
]
async with _engine.begin() as conn:
for sql in indexes:
await conn.execute(text(sql))