Files
site/docs/release.md
T
влад 12c983c0fc Шхуна не тонет: security, infra и доки на русском.
Безопасность довёл до ума — Cursor-генерацию переписал руками.
IDOR закрыл, CSRF задушил, refresh rotation теперь как надо.
HSTS на staging, ENABLE_DOCS=false, install.env recovery протестил.

Backend:
- jwt_denylist + auth_epoch: мгновенный revoke access JWT (logout/block/reset)
- auth/admin/users: bump epoch, logout с Bearer, forgot_password skip для blocked
- install_secrets: путь всегда apps/api/data/secrets/ (bootstrap из корня не ломает Docker)
- seed: SEED_DEMO_USERS=false на prod/staging
- тесты: jwt revoke, integration, coverage gate 90%

Frontend:
- logout шлёт Bearer, обработка TOKEN_REVOKED
- guards TypeScript fix
- E2E: blocked user → 401 сразу после block

Infra:
- staging/prod compose, TLS nginx, deploy-скрипты
- k6 §17.2, backup/health/smoke scripts

Docs:
- docs/ на русском: project, security, deploy, release (старые md слили)
- README короткий + план ТЗ + стандартные логины dev

Код готов к плаванию. Капитан может идти писать фронт.
2026-07-15 00:06:13 +03:00

3.0 KiB

Релиз и QA gates

Перед production не «авось прокатит», а чеклист из ТЗ §17. Если что-то красное — сначала staging, потом prod. Живёт один раз.

Pipeline

flowchart TD
  CI[CI green] --> ST[Staging + TLS]
  ST --> E2E[E2E 11/11]
  ST --> K6[k6 pass]
  ST --> ZAP[ZAP 0 High/Crit]
  ST --> LH[Lighthouse ≥ 85]
  E2E --> PROD[Production deploy]
  K6 --> PROD
  ZAP --> PROD
  LH --> PROD
  PROD --> SM[smoke-prod.sh]
  SM --> DNS[DNS cutover]
  DNS --> MON[24h мониторинг]

Регрессия E2E

Последний локальный прогон: 2026-07-14 — backend 137 / 90.43% cov, frontend 46.

Staging

E2E_BASE_URL=https://staging.example.com E2E_START_API=false pnpm --filter web e2e
# Сценарий Local Staging
1 Landing hero, reduced-motion
2 Register → verify → login → profile → logout
3 Forgot → reset → login
4 Admin publish → public slug
5 Block user → login denied
6 Pending → нет /profile
7 Refresh rotation
8 IDOR user A ≠ user B
9 Admin не блокирует себя / last admin
10 Avatar: bad MIME / size / SVG
11 Block → access JWT 401 TOKEN_REVOKED

Локально

pnpm --filter web e2e    # API :8001, Vite :5175

k6 (§17.2)

k6 run infra/k6/mvp-load-test.js -e BASE_URL=https://staging.example.com
Параметр Порог
VU / ramp 50 / 5 min
Mix 35% list, 25% login, 20% me, 10% refresh, 10% slug
p95 < 300 ms
Errors < 1%

OWASP ZAP

docker run --rm -v "$(pwd):/zap/wrk:rw" -t ghcr.io/zap/zaproxy:stable \
  zap-baseline.py -t https://staging.example.com -r zap-report.html
Severity Pass
High, Critical 0

Medium/Low — review руками. zap-report.html — в архив релиза.

Lighthouse

npx lighthouse https://staging.example.com \
  --preset=mobile --only-categories=performance \
  --output=json --output-path=./lighthouse-report.json
Метрика
Performance (mobile, /) 85

Не прошло — hero video preload="none", font swap, меньше JS на лендинге.

Release gates (сводка)

  • CI green на main
  • E2E 11/11 на staging
  • k6 pass
  • ZAP 0 High/Critical
  • Lighthouse ≥ 85
  • security.md staging-пункты
  • ./infra/scripts/smoke-prod.sh на prod
  • DNS cutover + rollback plan (previous tag)

CI локально

pnpm lint && pnpm typecheck
cd apps/api && python -m mypy app
pnpm --filter web test:ci
cd apps/api && python -m pytest --cov=app --cov-fail-under=90

Полный pipeline: .github/workflows/ci.yml.