# Runbook Этот runbook задаёт основной сценарий проверки по критериям `B1..B10` и выбранным `FX`. ## 1. Что проверяем Сквозной поток: - `decide` -> `events` -> `report`; - lifecycle/review/guardrails; - observability (`/health`, `/ready`, `/metrics`); - инженерная дисциплина (tests, lint, format); - выбранные FX: notifications, learnings, conflicts. Артефакты: - `compliance-matrix.md` - `ADR/*` - `MAP.md` - `assets/plantuml/raw/c4-context.puml` - `assets/plantuml/raw/c4-container.puml` - `assets/plantuml/raw/c4-component-critical-path.puml` ## 2. Предусловия ### 2.1 Основной сценарий (по умолчанию): Docker Compose Нужно: - Docker - Docker Compose Файлы: - `compose.yaml` - базовый стек - `compose.prod.yaml` - базовый стек + observability - Детали по compose-конфигурации: `README.md` -> `Setup with docker compose`. Порты по умолчанию (см. `.env.template`): - reverse proxy: `80` ### 2.2 Дополнительный локальный сценарий (для тестов/линтинга) Нужно: - Python `>=3.13,<3.15` - `uv` - `just` Рабочая директория: - `cd src/backend` ## 3. Основной сценарий запуска (Docker Compose) ### 3.1 Выбор стека Базовый стек: ```bash docker compose -f compose.yaml up -d ``` Полный стек (с observability): ```bash docker compose -f compose.prod.yaml --profile observability up -d ``` ### 3.2 Проверка, что сервисы поднялись ```bash docker compose -f compose.yaml ps # или docker compose -f compose.prod.yaml --profile observability ps ``` Ожидаем `running/healthy` для `postgresql`, `valkey`, `backend`, `backend-celery-worker`, `backend-celery-beat`. ### 3.3 Runtime sanity-check Через reverse proxy (`80`): ```bash curl -i http://127.0.0.1/health curl -i http://127.0.0.1/ready curl -s http://127.0.0.1/metrics | head -n 40 ``` Альтернатива напрямую в backend (`14609`): ```bash curl -i http://127.0.0.1:14609/health curl -i http://127.0.0.1:14609/ready curl -s http://127.0.0.1:14609/metrics | head -n 40 ``` ### 3.4 Просмотр логов ```bash docker compose -f compose.yaml logs -f backend backend-celery-worker backend-celery-beat # или docker compose -f compose.prod.yaml --profile observability logs -f backend backend-celery-worker backend-celery-beat ``` ### 3.5 Seed демо-данных через HTTP API Скрипт создаёт следующие сущности: - test flags; - experiments + variants + lifecycle до `running`; - event types (`exposure`, `click`); - metrics (`ctr`, `exposure_count`, `click_count`) и привязку к эксперименту; - telegram notification channel + rules; - smtp notification channel + rules (опционально); - conflict domain с включёнными экспериментами; - два learning (для color/copy), чтобы проверить похожие; - guardrail (`pause`) c порогом, который не срабатывает сразу; - subjects + decide + события (`show+click`, `show-only`, `click-only`, out-of-order). Команда: ```bash BACKEND_BASE_URL='http://127.0.0.1' \ TG_BOT_TOKEN='6196898691:AAGbCxOf7-iXWKkKeOr9GrgHKcw6G7Ou1zU' \ TG_CHAT_ID='826812483' \ ./infrastructure/http/seed-demo-data.sh ``` Команда c SMTP: ```bash BACKEND_BASE_URL='http://127.0.0.1' \ TG_BOT_TOKEN='6196898691:AAGbCxOf7-iXWKkKeOr9GrgHKcw6G7Ou1zU' \ TG_CHAT_ID='826812483' \ SMTP_ENABLED=true \ SMTP_RECIPIENT='itq.dev@ya.ru' \ SMTP_FROM_EMAIL='mikrotik@itqdev.xyz' \ SMTP_HOST='smtp.office365.com' \ SMTP_PORT=587 \ SMTP_USERNAME='mikrotik@itqdev.xyz' \ SMTP_PASSWORD='5x9NqfIO4tVMg0B' \ SMTP_USE_TLS=true \ SMTP_USE_SSL=false \ SMTP_TIMEOUT=15 \ ./infrastructure/http/seed-demo-data.sh ``` Что получаем: - скрипт печатает ключевые ID прямо в stdout; - артефакты в `artifacts/http-seed//`; - сводка в `artifacts/http-seed//summary.json`. ### 3.6 Что проверяем в Swagger ([localhost/api/v1/docs](http://localhost:80/api/v1/docs)) 1. Открыть `http://127.0.0.1/api/v1/docs`. 2. Получить токен через `POST /api/v1/auth/login` (admin/experimenter/approver). 3. Нажать `Authorize` и вставить `Bearer `. 4. Проверить `GET /api/v1/reports/{experiment_id}` для `experiment_color_id` из seed-вывода: - по вариантам есть `exposures`, `click_count`, `exposure_count`, `ctr`. 5. Проверить `POST /api/v1/experiments/{experiment_id}/guardrails/check`: - `triggered=0`. 6. Проверить `GET /api/v1/conflicts/domains/{domain_id}/experiments`: - видно оба running эксперимента в домене. 7. Проверить `POST /api/v1/decide` для `color_flag_key`: - `reason=experiment_assigned`. 8. Проверить `POST /api/v1/decide` для `copy_flag_key` тем же subject: - `reason=domain_conflict`. 9. Проверить `GET /api/v1/notification-channels`, `GET /api/v1/notification-rules`, `GET /api/v1/notification-logs`: - есть telegram channel/rules и, если `SMTP_ENABLED=true`, smtp channel/rules. 10. Проверить `GET /api/v1/learnings`: - есть как минимум 2 seeded learning. 11. Проверить `GET /api/v1/experiments/{experiment_id}/similar-learnings` для `experiment_color_id`: - ответ непустой; - в выдаче есть `learning_copy_id` и `similarity_score`. ## 4. Проверка критериев B1..B10 ### B1. Запуск и воспроизводимость Compose runtime-подтверждение: ```bash docker compose -f compose.yaml up -d docker compose -f compose.yaml ps curl -i http://127.0.0.1/health curl -i http://127.0.0.1/ready ``` Показываем: - сервисы запускаются без ручных скрытых шагов; - backend жив и готов после зависимостей. ### B2-B6, B8, B10. Функциональность, отчёты, тестирование и дисциплина Эти проверки выполняются локально из `src/backend` (dev-зависимости): ```bash cd src/backend just --list just test just test-coverage just show-coverage just lint just format ``` Точечные наборы: ```bash cd src/backend uv run python manage.py test apps.decision.tests.test_decide uv run python manage.py test apps.events.tests.test_services tests.integration.test_events uv run python manage.py test apps.reports.tests.test_reports apps.guardrails.tests.test_guardrails uv run python manage.py test apps.reviews.tests.test_reviews_policy apps.experiments.tests.test_services uv run python manage.py test tests.integration.test_negative tests.integration.test_happy_path tests.integration.test_api_contract ``` ### B7. Архитектурные артефакты Проверяем: - `compliance-matrix.md` - `ADR/README.md` - `ADR/04-decisions.md` - `MAP.md` - `assets/plantuml/raw/c4-context.puml` - `assets/plantuml/raw/c4-container.puml` - `assets/plantuml/raw/c4-component-critical-path.puml` ### B9. Эксплуатационная готовность и наблюдаемость Runtime через compose: ```bash curl -i http://127.0.0.1/health curl -i http://127.0.0.1/ready curl -s http://127.0.0.1/metrics | head -n 40 ``` ## 5. Проверка выбранных допфич (FX) Локально из `src/backend`: FX: Notifications ```bash uv run python manage.py test apps.notifications.tests.test_notifications api.v1.notifications.tests.test_notifications_api ``` FX: Learnings ```bash uv run python manage.py test apps.learnings.tests.test_learnings api.v1.learnings.tests.test_learnings_api ``` FX: Conflicts ```bash uv run python manage.py test apps.conflicts.tests.test_conflicts api.v1.conflicts.tests.test_conflicts_api ``` Объединённый прогон: ```bash uv run python manage.py test \ apps.notifications.tests.test_notifications \ apps.learnings.tests.test_learnings \ apps.conflicts.tests.test_conflicts \ api.v1.notifications.tests.test_notifications_api \ api.v1.learnings.tests.test_learnings_api \ api.v1.conflicts.tests.test_conflicts_api ``` ## 6. Остановка и очистка Базовый стек: ```bash docker compose -f compose.yaml down ``` Полный стек: ```bash docker compose -f compose.prod.yaml --profile observability down ``` С удалением томов: ```bash docker compose -f compose.yaml down -v # или docker compose -f compose.prod.yaml --profile observability down -v ```