d3731e78df
- added images of notification feature working - added seed data script - race condition fix for notifications worker - small improvements
271 lines
8.8 KiB
Markdown
271 lines
8.8 KiB
Markdown
# 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/<RUN_ID>/`;
|
||
- сводка в `artifacts/http-seed/<RUN_ID>/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 <access_token>`.
|
||
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
|
||
```
|