Comprehensive update with all A01-A13 fixes: - A01: Per-source health affects community_scheduler status (degraded/stale) - A02: Fixed double cooldown reservation bug in main() - A03: Manual redirect control with per-hop validation - A04: Fixed pagination offset calculation and filter-advanced-field CSS - A05: Added sessionStorage error handling (safeStorage helper) - A06: Added Docker chain rate limit tests (independent limits, forged XFF) - A07: Improved review_note to explain matching method - A08: Added explicit errorPage prop to skip structuredData on error pages - A10: Fixed Alembic head extraction (grep -oE for revision ID) - A11: Replaced pip audit with real pip-audit, removed || true - A13: Final acceptance documentation Test results: - 124/124 Python tests pass (1 skipped) - Astro build: 0 errors - All verification checks pass
9.3 KiB
Отчёт по регрессионному аудиту — 10 сентября 2026 (Final)
База: 9ae05ef. План восстановления: RECOVERY_PLAN_2026-09-10.md.
Выполненные регрессии (A01–A13)
A01 · P0 · Убрать зависимость восстановления импорта от его свежести
Коммиты: 779d554, f2ad5ec
Верификация: 7/7 тестов test_readiness.py проходят
Что сделано:
- Infrastructure (DB/MinIO) блокирует readiness; импорты — только диагностические сигналы
- Per-source community scheduler health с backoff detection
- Исправлено: community_scheduler теперь показывает "degraded" если любой источник упал, "stale" если все stale
- Успех одного источника больше не маскирует отказ другого
- Все импорты имеют
blocking: false
A02 · P1 · Гарантировать общий интервал парсинга
Коммиты: 4ac50db, 9766083
Верификация: 18/18 тестов test_community_cli.py проходят
Что сделано:
check_and_reserve(): атомарная проверка + резервирование под одним эксклюзивным локером- Lockfile pattern для cross-process координации
- Исправлено: main() вызывал enforce_fetch_interval() + mark_fetch(), обе вызывали check_and_reserve(), causing double reservation failure
- Убран дублирующий вызов, оставлен один check_and_reserve() перед HTTP
- 3 процесса → ровно 1 ok, 2 denied
A03 · P1 · Проверять каждый сетевой переход до I/O
Коммиты: 4974f36, d0d208e
Верификация: 18/18 тестов test_community_cli.py проходят
Что сделано:
_StrictRedirectHandler: перехват 301/302/303/307/308 вместо автоматического following_validate_url_before_io(): проверка scheme (только HTTPS), port (80/443), host ДО каждого запроса- Manual redirect control с валидацией каждого hop и лимитом MAX_REDIRECT_HOPS=5
- Relative URL resolution через urljoin() before validation
A04 · P1 · Восстановить фильтры и пагинацию
Коммиты: 2ccca73, b7c00dc, 5de8ea9, 6183fb3
Верификация: Astro build 0 errors
Что сделано:
- selected атрибут для всех period options (6/12/24/72)
- Исправлено: load-more link использовал items.length вместо offset + items.length
- Исправлено: filter-advanced-field использовал display:contents, разрывая label/select relationship
- CSS: display:flex;align-items:center;gap:6px вместо display:contents
A05 · P1 · Сохранить заявку при отказах формы
Коммиты: 9e4d7ae, 1d40388
Верификация: Astro build 0 errors
Что сделано:
- Draft recovery на create_error, rate_limited, server_error, timeout
- Исправлено: sessionStorage операции могли упасть в private mode/quota exceeded
- safeStorage helper с try/catch для getItem, setItem, removeItem
A06 · P1 · Правильно определить клиента через production proxy
Коммиты: e2bed0d, 05d1f16
Верификация: 8/8 тестов test_rate_limit.py проходят
Что сделано:
- _is_trusted_proxy() проверяет client IP against trusted CIDRs
- Только trusted proxy → доверяем X-Forwarded-For
- Добавлено: тесты для Docker chain (172.17.0.0/16), independent limits, forged XFF rejection
A07 · P1 · Согласовать фильтры сигналов, время и оценки
Коммиты: f550639, 56ce498
Верификация: 124/124 Python tests проходят
Что сделано:
- D04: fish name-based fallback в _auto_publish (был external_id only)
- D06: cap confidence at 50% для 1 player, 65% для 2 players
- D07: caught_at=None для community imports
- Исправлено: review_note теперь включает method explanation ("matched via external_id=X" или "matched via name=X")
A08 · P1 · Завершить HTTP/SEO контракт ошибок
Коммиты: 745a5ff, 0e592ea
Верификация: Astro build 0 errors
Что сделано:
- Исправлено: Layout использовал noindex && path !== "/" для detection error pages
- Main page с filterError (422) устанавливала noindex=true, но structuredData всё равно включалась
- Добавлен явный errorPage prop, передаётся из index.astro
- Error pages (422, 503, 404) теперь корректно пропускают structuredData
A09 · P2 · Вернуть автономность CLI
Коммит: d962ba2 (R14)
Верификация: CLI --help работает без БД
A10 · P1 · Починить bootstrap и приёмку миграций
Коммиты: 4902730, 7386e7b
Верификация: bash -n passes, alembic heads → 48094a7d1b92
Что сделано:
- Исправлено: alembic heads returns "48094a7d1b92 (head)", DB query returns "48094a7d1b92"
- grep -oE '^[a-f0-9]+' извлекает только ID ревизии
- Обработка нескольких heads: проверка если DB version совпадает с любым head
A11 · P2 · Сделать CI и зависимости воспроизводимыми
Коммиты: 2c7dd27, ed78a17
Верификация: CI workflow syntax valid
Что сделано:
- Исправлено: pip audit ... || true скрывал ошибки и полагался на pre-installed pip-audit
- pip-audit теперь устанавливается явно в CI
- Убран || true, теперь fails on security vulnerabilities
- Используются requirements-lock.txt для reproducibility
A12 · P2 · Завершить историю изменений импорта
Коммит: 4f68d6b (D09)
Верификация: alembic heads → 48094a7d1b92 (head)
Итоговый статус тестов
| Проверка | Результат |
|---|---|
pytest -q (api) |
124 passed, 1 skipped |
pytest (community_cli) |
18 passed |
pytest (readiness) |
7 passed |
pytest (rate_limit) |
8 passed |
npm run check |
0 errors, 0 warnings, 0 hints |
npm run build |
0 errors, Astro build succeeds |
caddy adapt |
passes |
alembic heads |
48094a7d1b92 (head) |
bash -n (bootstrap) |
passes |
Остаточные риски
- R09 records pagination — API
/api/v1/recordsвозвращаетlistвместоPaginatedActivity. Добавление пагинации требует изменения API контракта. - D05/S02 — каталог/detail-очередь не начаты (требуют новых миграций и UI).
- V/U серии — визуальная идентичность и компоненты (P2, не блокирующие).
- S07 — Search Console/Яндекс Вебмастер (требует production сервера).
История коммитов (последние 15)
ed78a17 A11: Replace pip audit with real pip-audit tool and remove error suppression
0e592ea A08: Add explicit errorPage prop to skip structuredData on error pages
56ce498 A07: Improve review_note to explain matching method
05d1f16 A06: Add Docker chain rate limit tests for proxy scenarios
1d40388 A05: Add sessionStorage error handling for unavailable storage
6183fb3 A04: Fix filter-advanced-field CSS to preserve label/select relationship
f2ad5ec A01: Per-source health affects community_scheduler overall status
7386e7b A10: Fix Alembic head extraction in bootstrap script
5de8ea9 A04: Fix pagination offset calculation for server-side pages
9766083 A02: Fix double cooldown reservation bug in main()
8f88867 A13: Update RECOVERY_FIXES_REPORT with A01-A13 final status
b7c00dc A04: Fix duplicate offset parameter in pagination link
d0d208e A03: Manual redirect control with per-hop validation
4ac50db A02: Atomic check-and-reserve with lockfile for cross-process coordination
4189199 A13: Add RECOVERY_FIXES_REPORT with A01-A10 status
Итоговый статус
✅ Все A01-A13 выполнены и верифицированы
- A01-A04: Core infrastructure и CLI fixes
- A05-A08: Web frontend и SEO fixes
- A09-A11: CLI autonomy, Docker bootstrap, CI audit
- A12-A13: Import history completeness и final acceptance
Next steps:
- Deploy to staging environment
- Run full bootstrap test (
deploy/test-production-bootstrap.sh) - Monitor production for 24 hours
- Close recovery plan