fix: критические баги и качество кода — полный аудит

Критические фиксы:
- main.py: монтировать /static из web/static/ (CSS не грузился совсем)
- api/scans.py: filtered total count (был всегда общий, игнорируя фильтры)
- web/routes.py: исправлен VALID_SORT_FIELDS (отсутствовали ключи packages)
- web/routes.py: filtered total count для web scans list
- package_detail.html: f.data.X вместо f.X (findings не отображались)

Чистка мёртвого кода:
- config.py: удалён _parse_repos и nexus_repositories (не использовались)
- web/routes.py: удалён completed_scans/failed_scans (не отображались)
- удалён мёртвый guarddog_nexus/static/style.css (67-байтный стаб)

Качество кода:
- web/routes.py: Jinja2 Environment кэшируется на уровне модуля
- Вынесен дублирующийся JS в web/static/app.js
- Вынесены дублирующиеся inline-стили в CSS-классы
- Исправлен duplicate class attribute в списках
- Удалены гигантские SVG из empty states

Тесты:
- 20 новых edge-case тестов (CSV export, search/filter/sort, 404, pagination)
- Добавлен sample_flagged_scan fixture
- Итого: 50 тестов, все зелёные
This commit is contained in:
Marker689
2026-05-10 03:46:05 +03:00
parent 6c8e89c95e
commit c43e7c4c9b
15 changed files with 329 additions and 145 deletions

View File

@@ -0,0 +1,25 @@
// GuardDog Nexus — shared UI utilities
function toggleFindings() {
var container = document.getElementById('findings-container');
if (!container) return;
var details = container.querySelectorAll('details');
if (details.length === 0) return;
var isOpen = details[0].open;
details.forEach(function (d) { d.open = !isOpen; });
var btn = document.querySelector('.toggle-all-btn');
if (btn) btn.textContent = isOpen ? 'Expand All' : 'Collapse All';
}
function copyCode(btn, codeId) {
var el = document.getElementById(codeId);
if (!el) return;
navigator.clipboard.writeText(el.textContent).then(function () {
btn.textContent = 'Copied!';
btn.classList.add('copied');
setTimeout(function () {
btn.textContent = 'Copy';
btn.classList.remove('copied');
}, 2000);
});
}

View File

@@ -238,19 +238,9 @@ nav.sticky {
/* Empty states */
.empty-state {
text-align: center;
padding: 3rem 1rem;
opacity: 0.6;
}
.empty-state svg {
width: 64px;
height: 64px;
margin-bottom: 1rem;
opacity: 0.4;
}
.empty-state h3 {
margin-bottom: 0.5rem;
padding: 2rem 1rem;
opacity: 0.5;
font-style: italic;
}
/* Filter bar */
@@ -352,7 +342,37 @@ th.sortable.active .sort-icon {
}
}
/* Expand/Collapse all button */
/* Finding header row */
.finding-header-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
}
/* Finding summary */
.finding-summary {
cursor: pointer;
list-style: none;
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.25rem 0;
}
/* Finding summary hint */
.finding-summary-hint {
margin-left: auto;
font-size: 0.8rem;
opacity: 0.5;
}
/* Code block toolbar */
.code-toolbar {
display: flex;
justify-content: flex-end;
margin-bottom: 0.25rem;
}
.toggle-all-btn {
font-size: 0.8rem;
margin-bottom: 0.5rem;