# Shipping And Launch

> Готовит запуски в продакшн. Используй при подготовке к выкатке в продакшн. Используй, когда нужен предрелизный чеклист, когда настраиваешь мониторинг, когда планируешь поэтапную выкатку или когда нужна стратегия отката.

- Skill: `aleksandr-litvinenko/shipping-and-launch` (Agent Skill)
- Install (CLI): `npx skillmds@latest add aleksandr-litvinenko/shipping-and-launch`
- Raw SKILL.md: https://api.skillmd.com/api/skills/aleksandr-litvinenko/shipping-and-launch/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: Aleksandr-Litvinenko (https://skillmd.com/u/aleksandr-litvinenko)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/aleksandr-litvinenko/shipping-and-launch

---


# Выкатка и запуск

## Обзор

Выпускай с уверенностью. Цель не просто выкатить, а выкатить безопасно: с настроенным мониторингом, готовым планом отката и ясным пониманием того, как выглядит успех. Каждый запуск должен быть обратимым, наблюдаемым и постепенным.

## Когда применять

- Впервые выкатываешь функциональность в продакшн
- Выпускаешь пользователям значимое изменение
- Мигрируешь данные или инфраструктуру
- Открываешь бету или ранний доступ
- Любая выкатка, несущая риск (то есть любая)

## Предрелизный чеклист

### Качество кода

- [ ] Все тесты проходят (юнит, интеграционные, сквозные)
- [ ] Сборка успешна и без предупреждений
- [ ] Линтер и проверка типов проходят
- [ ] Код отревьюен и одобрен
- [ ] Нет комментариев TODO, которые надо было закрыть до запуска
- [ ] Нет отладочных `console.log` в продакшн-коде
- [ ] Обработка ошибок покрывает ожидаемые режимы отказа

### Безопасность

- [ ] В коде и системе контроля версий нет секретов
- [ ] Аудит зависимостей соответствующей экосистемы (`npm audit`, `pip-audit`, `cargo audit`, …) не показывает критичных и высоких уязвимостей
- [ ] Валидация ввода на всех эндпоинтах, доступных пользователю
- [ ] Проверки аутентификации и авторизации на месте
- [ ] Настроены заголовки безопасности (CSP, HSTS и прочие)
- [ ] Ограничение частоты запросов на эндпоинтах аутентификации
- [ ] CORS настроен на конкретные источники (не на подстановочный символ)

### Производительность

- [ ] Core Web Vitals в пределах порогов «Good»
- [ ] Нет запросов N+1 на критичных путях
- [ ] Изображения оптимизированы (сжатие, адаптивные размеры, отложенная загрузка)
- [ ] Размер бандла укладывается в бюджет
- [ ] У запросов к БД есть подходящие индексы
- [ ] Настроено кеширование для статики и повторяющихся запросов

### Доступность

- [ ] Навигация с клавиатуры работает для всех интерактивных элементов
- [ ] Скринридер способен передать содержание и структуру страницы
- [ ] Контраст цветов соответствует WCAG 2.1 AA (4,5:1 для текста)
- [ ] Управление фокусом корректно для модальных окон и динамического содержимого
- [ ] Сообщения об ошибках описательны и связаны с полями формы
- [ ] Нет предупреждений о доступности в axe-core или Lighthouse

### Инфраструктура

- [ ] Переменные окружения заданы в продакшне
- [ ] Миграции БД применены (или готовы к применению)
- [ ] Настроены DNS и SSL
- [ ] Настроен CDN для статики
- [ ] Настроены логирование и отправка отчётов об ошибках
- [ ] Есть эндпоинт проверки здоровья, и он отвечает

### Документация

- [ ] README обновлён с учётом новых требований к настройке
- [ ] Документация API актуальна
- [ ] Написаны ADR по всем архитектурным решениям
- [ ] Changelog обновлён
- [ ] Пользовательская документация обновлена (если применимо)

## Стратегия фича-флагов

Выпускай под фича-флагами, чтобы отделить выкатку от релиза:

```typescript
// Проверка фича-флага
const flags = await getFeatureFlags(userId);

if (flags.taskSharing) {
  // Новая функциональность: шеринг задач
  return <TaskSharingPanel task={task} />;
}

// По умолчанию: существующее поведение
return null;
```

**Жизненный цикл фича-флага:**

```
1. ВЫКАТКА с флагом ВЫКЛ        → Код в продакшне, но неактивен
2. ВКЛЮЧИТЬ для команды/беты    → Внутреннее тестирование в продакшн-среде
3. ПОСТЕПЕННАЯ ВЫКАТКА          → 5% → 25% → 50% → 100% пользователей
4. НАБЛЮДАТЬ на каждом этапе    → Следить за долей ошибок, производительностью, откликом пользователей
5. ПРИБРАТЬСЯ                   → Удалить флаг и мёртвую ветку после полной выкатки
```

**Правила:**
- У каждого фича-флага есть владелец и дата истечения
- Убирай флаги в течение 2 недель после полной выкатки
- Не вкладывай фича-флаги друг в друга (порождает экспоненциальное число комбинаций)
- Проверяй в CI оба состояния флага (вкл и выкл)

## Поэтапная выкатка

### Последовательность выкатки

```
1. ВЫКАТИТЬ на стенд
   └── Полный прогон тестов в среде стенда
   └── Ручная дымовая проверка критичных сценариев

2. ВЫКАТИТЬ в продакшн (фича-флаг ВЫКЛ)
   └── Убедиться, что выкатка удалась (проверка здоровья)
   └── Проверить мониторинг ошибок (новых ошибок нет)

3. ВКЛЮЧИТЬ для команды (флаг ВКЛ для внутренних пользователей)
   └── Команда пользуется функциональностью в продакшне
   └── Окно наблюдения 24 часа

4. КАНАРЕЕЧНАЯ выкатка (флаг ВКЛ для 5% пользователей)
   └── Следить за долей ошибок, задержками, поведением пользователей
   └── Сравнить метрики: канарейка против базовой линии
   └── Окно наблюдения 24–48 часов
   └── Двигаться дальше, только если все пороги пройдены (см. таблицу ниже)

5. ПОСТЕПЕННОЕ увеличение (25% → 50% → 100%)
   └── То же наблюдение на каждом шаге
   └── Возможность откатиться к предыдущему проценту в любой момент

6. ПОЛНАЯ выкатка (флаг ВКЛ для всех)
   └── Наблюдать неделю
   └── Убрать фича-флаг
```

### Пороги принятия решения при выкатке

Используй эти пороги, чтобы решить, двигаться дальше, задержаться или откатиться на каждом этапе:

| Метрика | Двигаться дальше (зелёный) | Задержаться и разобраться (жёлтый) | Откатиться (красный) |
|--------|-----------------|-------------------------------|-----------------|
| Доля ошибок | В пределах 10% от базовой | На 10–100% выше базовой | >2× базовой |
| P95 задержки | В пределах 20% от базовой | На 20–50% выше базовой | Более чем на 50% выше базовой |
| Ошибки JS на клиенте | Новых типов ошибок нет | Новые ошибки в <0,1% сессий | Новые ошибки в >0,1% сессий |
| Бизнес-метрики | Нейтрально или лучше | Падение <5% (может быть шумом) | Падение >5% |

### Когда откатываться

Откатывайся немедленно, если:
- Доля ошибок выросла более чем в 2 раза от базовой
- P95 задержки выросла более чем на 50%
- Резко выросло число жалоб пользователей
- Обнаружены проблемы с целостностью данных
- Обнаружена уязвимость

## Мониторинг и наблюдаемость

### За чем следить

```
Метрики приложения:
├── Доля ошибок (общая и по эндпоинтам)
├── Время ответа (p50, p95, p99)
├── Объём запросов
├── Активные пользователи
└── Ключевые бизнес-метрики (конверсия, вовлечённость)

Метрики инфраструктуры:
├── Загрузка CPU и памяти
├── Использование пула соединений с БД
├── Место на диске
├── Сетевые задержки
└── Глубина очереди (если применимо)

Клиентские метрики:
├── Core Web Vitals (LCP, INP, CLS)
├── Ошибки JavaScript
├── Доля ошибок API с точки зрения клиента
└── Время загрузки страницы
```

### Отправка отчётов об ошибках

```typescript
// Граница ошибок с отправкой отчётов
class ErrorBoundary extends React.Component {
  componentDidCatch(error: Error, info: React.ErrorInfo) {
    // Отправить в сервис отслеживания ошибок
    reportError(error, {
      componentStack: info.componentStack,
      userId: getCurrentUser()?.id,
      page: window.location.pathname,
    });
  }

  render() {
    if (this.state.hasError) {
      return <ErrorFallback onRetry={() => this.setState({ hasError: false })} />;
    }
    return this.props.children;
  }
}

// Отправка отчётов об ошибках на сервере
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
  reportError(err, {
    method: req.method,
    url: req.url,
    userId: req.user?.id,
  });

  // Не раскрывать внутренние детали пользователям
  res.status(500).json({
    error: { code: 'INTERNAL_ERROR', message: 'Something went wrong' },
  });
});
```

### Проверка после запуска

В первый час после запуска:

```
1. Проверить, что эндпоинт здоровья отдаёт 200
2. Проверить дашборд мониторинга ошибок (новых типов ошибок нет)
3. Проверить дашборд задержек (регрессии нет)
4. Вручную пройти критичный пользовательский сценарий
5. Убедиться, что логи идут и читаемы
6. Убедиться, что механизм отката работает (по возможности прогнать вхолостую)
```

## Стратегия отката

У каждой выкатки должен быть план отката ещё до её начала:

```markdown
## План отката для [фичи/релиза]

### Условия срабатывания
- Доля ошибок > 2× базовой
- P95 задержки > [X] мс
- Сообщения пользователей о [конкретной проблеме]

### Шаги отката
1. Выключить фича-флаг (если применимо)
   ЛИБО
1. Выкатить предыдущую версию: `git revert <commit> && git push`
2. Проверить откат: проверка здоровья, мониторинг ошибок
3. Сообщить: уведомить команду об откате

### Что учесть по базе данных
- У миграции [X] есть откат: `npx prisma migrate rollback`
- Данные, вставленные новой функциональностью: [сохраняются / удаляются]

### Время отката
- Фича-флаг: < 1 минуты
- Повторная выкатка предыдущей версии: < 5 минут
- Откат базы данных: < 15 минут
```
## См. также

- Общий для проекта Definition of Done, который любое изменение проходит до этого чеклиста, — см. `../../references/definition-of-done.md`
- Предрелизные проверки безопасности — см. `../../references/security-checklist.md`
- Предрелизный чеклист производительности — см. `../../references/performance-checklist.md`
- Проверка доступности перед запуском — см. `../../references/accessibility-checklist.md`

## Типовые самооправдания

| Самооправдание | Как на самом деле |
|---|---|
| «На стенде работает, значит и в продакшне заработает» | В продакшне другие данные, другие профили нагрузки и другие краевые случаи. Наблюдай после выкатки. |
| «Для этого фича-флаги не нужны» | Любой функциональности полезен аварийный выключатель. Даже «простые» изменения ломают вещи. |
| «Мониторинг — лишние расходы» | Отсутствие мониторинга означает, что о проблемах ты узнаёшь из жалоб пользователей, а не с дашбордов. |
| «Мониторинг добавим потом» | Добавь до запуска. Нельзя отлаживать то, чего не видишь. |
| «Откат — это признание провала» | Откат — это ответственная инженерия. Провал — это выпустить сломанную функциональность. |

## Тревожные признаки

- Выкатка без плана отката
- В продакшне нет мониторинга и отчётов об ошибках
- Релизы «одним взрывом» (всё сразу, без промежуточных этапов)
- Фича-флаги без срока истечения и владельца
- Никто не следит за выкаткой в первый час
- Конфигурация продакшн-среды сделана по памяти, а не кодом
- «Пятница, вечер — давай выкатим»

## Проверка

Перед выкаткой:

- [ ] Предрелизный чеклист пройден (все разделы зелёные)
- [ ] Фича-флаг настроен (если применимо)
- [ ] План отката задокументирован
- [ ] Дашборды мониторинга настроены
- [ ] Команда уведомлена о выкатке

После выкатки:

- [ ] Проверка здоровья возвращает 200
- [ ] Доля ошибок в норме
- [ ] Задержки в норме
- [ ] Критичный пользовательский сценарий работает
- [ ] Логи идут
- [ ] Откат протестирован или подтверждена его готовность

