8.5 KiB
Sprint 28 — docs sync + test coverage gap-fill (overnight)
Цель: воспользоваться overnight-окном для накопления реального soak- теста (4 часа), параллельно — мелкие реальные улучшения: точность auto-generated api-reference, новые integration-тесты, CI-integration.
Старт: 2026-06-09 03:15. Исполнитель: Claude Opus 4.7 (autonomous). Продолжение sprint27_done.
Что сделано
1. api-reference.md теперь имеет 240 endpoint'ов (было 195)
ApiReferenceDocsJob regex для return-type'a слишком строгий — матчил
только 1-level generic. Не ловил Task<ActionResult<PagedResult<EmployeeDto>>>
(double-nested), поэтому пропускал ~45 endpoint'ов.
Фикс: новый regex [^(=;{}\n]+? для return-type (любой identifier
с любой глубиной генериков) в:
src/food-market.api/Background/ApiReferenceDocsJob.cs(runtime job для weekly auto-gen в /content-root/api-reference-generated.md)scripts/gen-api-reference.py(Python-эквивалент для коммита в репо)
Результат: 240 endpoints, 58 controllers (было 195/57). Пример
пропуска: EmployeesController имел 4 из 5 endpoint'ов; теперь все 5
(GET /api/organization/employees был пропущен — это list endpoint с
return типом Task<ActionResult<PagedResult<EmployeeDto>>>).
2. observability.md дополнен (Sprint 20+ + Sprint 26)
- Добавлен ряд про
food_market_disk_free_bytes(Sprint 20DiskMonitoringJob). - Новый раздел «quality-watchdog метрики» — 5 метрик textfile exporter'a
(
quality_watchdog_run_total,step_failure_total,endpoint_p95_ms,last_run_status,incidents_total). - Раздел «Готовые dashboards» теперь упоминает оба JSON (food-market.json
- quality-watchdog.json) с UID/назначением.
3. Integration spec #7: 1C-CSV import + GDPR org-export
tests/integration/07-import-export-flows.spec.ts:
- POST
/api/catalog/products/import/1c-csvс 1С-форматом (Наименование;Штрихкод;Цена;Единица;Группа в semicolon-CSV) → возвращает{created, skipped, errors[], ids[]}. - POST
/api/org/export(НЕ/api/admin/org-export, как я было предположил — был баг в моих оригинальных предположениях) → возвращает{id, status, ...}. - orgB не видит export orgA — multi-tenant clean.
Прогон 8.2s. Pass.
4. PruneQualityTestOrgsAsync unit test
tests/food-market.IntegrationTests/PruneQualityTestOrgsTests.cs — два
[Fact]'a:
Deletes_only_quality_orgs_older_than_threshold— 4 org'и (старая quality, свежая quality, реальная org, edge-старше-threshold). Threshold 24h. Удаляет 2 (старую quality + edge). Свежая quality и реальная остаются.Returns_zero_when_no_candidates_match— только свежая quality → deleted=0, org остаётся.
Тест требует Testcontainers (PostgreSQL для information_schema +
DO блоков) — не SQLite. Прогоняется в CI на dev-vm; локально нет
.NET 8.0.417 SDK (global.json pin).
5. Forgejo CI workflow: integration suite
.forgejo/workflows/regression.yml добавлен шаг "Run integration
cross-feature suite" после regression flows+visual. На failure артефакты
из tests/integration/reports/ тоже загружаются. Telegram-уведомление
обновлено: 35 flows + 60 visual + 8 integration.
6. 4-часовой soak test запущен в фоне
setsid nohup k6 run ... & — детачнутая сессия. Параметры:
- DURATION=4h, RPS=50
- E2E_ADMIN_URL=stage
- Output:
/tmp/soak-real/k6.log,/tmp/soak-real/summary.json - Monitor: 5-минутный snapshot в
/tmp/soak-real/metrics.csv
ETA финиша: ~07:15. Финальные числа добавлю в этот файл после завершения.
Soak: интерим-результаты (на момент 03:46, 31 мин run)
| Метрика | Значение | Замечание |
|---|---|---|
| iterations | 91371 | 0 interrupted |
| iter/sec | 49.2 | target 50 (constant-arrival-rate) |
| api_mem_mb (range) | 250-465 | spike 465 — это redeploy для HSTS, нормальное |
| api_cpu_pct (steady) | 54-83% | под нагрузкой |
| pg_connections | 19-56 | spike 56 во время restart, обратно к 19 |
| disk_free_gb | 30 | без изменений |
| products p95 | 32-256ms | 256ms был во время старта (warmup) |
Зафиксированы 0 failures (http_req_failed.rate=0.0). Memory не растёт
линейно — bounces around 250-300 MiB после warmup.
Soak продолжается до ~07:15. Финальные числа в этом разделе после завершения.
Дополнительная работа (overnight)
После основных 6 пунктов чек-листа также сделано:
7. fix: ApiReferenceDocsJob handle ~/path ASP.NET convention
HttpPost("~/connect/token") — ASP.NET Core конвенция «absolute from
root, ignore class [Route]». До фикса генератор клеил с base-route'ом →
/~/connect/token (невалидный). Теперь tilde корректно срезается.
Виден /connect/token в api-reference.md.
8. fix(security): HSTS header on stage
Найдено: stage отдавал security-headers (CSP, X-Frame-Options, etc.) но
БЕЗ Strict-Transport-Security. Причина: UseHsts() в ASP.NET Core не
срабатывает за nginx-прокси (api видит HTTP, не HTTPS — нет
ForwardedHeaders middleware'a).
Фикс: добавлен add_header Strict-Transport-Security в
deploy/nginx.conf. max-age=2592000 (30 дней), без includeSubDomains
и без preload — pre-emptive consent, можно безопасно убрать.
Verified: curl -I https://test.admin.food-market.kz/ → strict-transport-security: max-age=2592000.
Integration test tests/integration/08-security-headers.spec.ts (2
[Fact]) проверяет 7 security-заголовков на главной + на 404.
9. test: ApiReferenceDocsJob regex lock-down
tests/food-market.UnitTests/ApiReferenceDocsJobTests.cs — создаёт
временный controller-файл с double-nested generic
(Task<ActionResult<PagedResult<Dto>>>), прогоняет GenerateAsync,
проверяет count=3 и наличие всех routes в output.
Защищает от регрессии Sprint 28 fix'a.
10. perf: integration suite workers=2 (46% speedup)
Раньше tests/integration/playwright.config.ts имел workers: 1
из-за signup rate-limit. После Sprint 26 повышения stage до
5000/min — больше не упирается. Включил workers: 2 → прогон 66s → 36s.
11. README + ONBOARDING update до Sprint 28
Sprint history дополнен 25-28. Endpoint count обновлён до 240. Sprint counter unified.
Метрики
| До Sprint 28 | После | Δ | |
|---|---|---|---|
| API endpoints в docs/api-reference.md | 195 (из 240) | 240 | +45 |
| Controllers в reference | 57 | 58 | +1 |
| Integration specs | 6 | 7 | +1 |
| CI integration step | (нет) | Sprint 27/28 step | new |
| PruneQualityTestOrgs unit test | (нет) | 2 [Fact]'a | new |
| Observability metrics doc | 6 кастомных | 11 кастомных (+ disk + 5 watchdog) | +5 |
Артефакты этой ночи
scripts/gen-api-reference.py— Python-генератор (соответствует обновлённомуApiReferenceDocsJob.cs)docs/api-reference.md— пересгенерирован, 240 endpointsdocs/observability.md— дополненtests/integration/07-import-export-flows.spec.ts— новый spectests/food-market.IntegrationTests/PruneQualityTestOrgsTests.cs— новый C# test.forgejo/workflows/regression.yml— added integration step/tmp/soak-real/k6.log,/tmp/soak-real/metrics.csv— soak в процессе