Запустить за 5 минут
Минимальный путь от пустого браузера до первого алерта на staging-стенде staging.antifraud.slim-shaggy.com (Hetzner).
0. Что нужно
- SSH-доступ к
root@178.104.214.209(ключ~/.ssh/id_rsa) — стек уже поднят, нужны только команды внутри. - Python 3.12 на ноуте (для
scripts/dry_run.pyи synthetic generator — стримит на staging API через HTTPS). - Браузер для дашборда.
1. Проверить, что стек жив
curl https://staging.antifraud.slim-shaggy.com/healthz # → 200
curl https://staging.antifraud.slim-shaggy.com/readyz # → 200 (CH+Kafka+Redis+PG все ОК)
Если 200 — деплой здоров. Если нет — раздел Если сломалось.
Опционально посмотреть статус всех контейнеров:
ssh root@178.104.214.209 'cd /root/antifraud/infra && docker compose ps'
Все должны быть Up (healthy). Перманентно unhealthy образы (mlflow, alertmanager, blackbox-exporter, promtail) — норма, deploy-workflow их игнорирует.
2. Засеять dev-данные (один раз, если ещё не делал)
ssh root@178.104.214.209
cd /root/antifraud/infra
docker compose exec dashboard python manage.py bootstrap_dev
В выводе:
============================================================
Operator: Casino Alpha
Admin user: admin@antifraud.dev / devpassword123
API key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
============================================================
--rotate.Альтернативно — отдельный суперюзер на твою почту:
docker compose exec dashboard python manage.py createsuperuser
# email: твоя@почта
# password: что-то длинное
3. Зайти в админку
https://staging.antifraud.slim-shaggy.com/admin/ → логин admin@antifraud.dev / devpassword123 (или твой суперюзер).
4. Послать поток событий с ноута
cd ~/PycharmProjects/iGamingAntiFraudSaaS
python -m tools.synthetic_events \
--count 500 --mode stream --rps 50 \
--api-url https://staging.antifraud.slim-shaggy.com \
--api-key sk_live_xxxxxxxx \
--fraud-rate 0.15
5. Посмотреть алерты
https://staging.antifraud.slim-shaggy.com/dashboard/alerts/ — там сработавшие правила.
Логин и регистрация
Auth построен на django-allauth. Поддержано: email+пароль, magic-link, Google OAuth. Роли operator_admin и risk_lead также проходят TOTP MFA (Sprint 24 — подробнее в UI v2).
Все точки входа на staging
| URL | Что там |
|---|---|
/accounts/login/ | Логин (email + пароль или magic-link или Google) |
/accounts/2fa/authenticate/ | Ввод TOTP-кода (шаг 2 для привилегированных ролей) |
/accounts/signup/ | Самостоятельная регистрация (на free-плане) |
/accounts/logout/ | Выход |
/accounts/password/reset/ | Сброс пароля |
/accounts/email/ | Управление email-ами учётки |
/accounts/social/connections/ | Привязанные OAuth-провайдеры (Google) |
Какие учётки есть сейчас на staging
admin@antifraud.dev / devpassword123 — суперюзер, есть доступ ко всему (и в админку, и в дашборд).
Создать свою учётку
Способ 1 — самостоятельно через signup:
- Открыть /accounts/signup/.
- Подтвердить email (на staging email уходит на console — смотри лог dashboard-контейнера).
- Зайти. Без оператора попадёшь на
/dashboard/access-pending/— суперюзер должен в админке привязать тебя к Operator-у через User → operator_membership.
Способ 2 — суперюзер из консоли:
ssh root@178.104.214.209
cd /root/antifraud/infra
docker compose exec dashboard python manage.py createsuperuser
# email: твоя@почта
# password: длинный
Способ 3 — приглашение в существующего оператора (Module 09 invite flow):
- В админке Operators → твой оператор → "Invite user".
- Ввести email + role.
- На указанный email приходит ссылка
/operators/<id>/accept-invite/<url_key>/. - Получатель кликает, ставит пароль, заходит в дашборд оператора.
Роли
| Role | Что может | MFA обязательна |
|---|---|---|
operator_admin | Всё в дашборде своего оператора + биллинг + приглашать юзеров + управлять API-ключами | Да (TOTP) |
risk_lead | Алерты, кейсы, разметка, граф, audit log. Без биллинга и инвайтов. | Да (TOTP) |
operator_viewer | Только чтение: алерты, кейсы, статистика | Нет |
platform_admin (только мы) | Админка + все операторы | Нет (bypass для staff) |
UI v2 — design system + новые экраны (Sprint 24)
Sprint 24 обновил визуальный слой дашборда с нуля: появилась дизайн-система на CSS-переменных, все 9 операторских экранов переработаны, добавлено 5 новых URL, введён MFA-флоу для привилегированных ролей.
Design system
Файл токенов: apps/dashboard/static/css/tokens.css. Содержит CSS-переменные для цветов, типографики, отступов, радиусов, теней — единый источник правды для всего UI. Брендовые SVG-ассеты лежат в apps/dashboard/static/img/: logo-mark.svg, logo-mark-solid.svg, wordmark.svg.
Переработанные экраны (9 поверхностей)
Все экраны перешли на токены из tokens.css. Визуальный ревамп не менял маршруты — URL-ы остались прежними.
| Экран | URL (prefix /dashboard/) | Что изменилось |
|---|---|---|
| Биллинг | billing/ | Карточки плана + usage-gauge в новом стиле |
| ML labels (разметка) | active-learning/ | Queue-UI с compact-карточками |
| Кейсы | cases/ | Список с табами статусов (см. новые URL ниже) |
| Профили игроков | players/<id>/ | Header-карточка + новые HTMX-табы wallet/ip |
| Аффилейты | affiliate/ | Cohort-dashboard с sparkline-метриками |
| Вебхуки | webhooks/ | Endpoint-карточки с inline-статусом доставок |
| API-ключи | settings/api-keys/ | Self-service CRUD (новый URL, см. ниже) |
| Audit log | audit/ | Таблица с CSV-экспортом (новый URL, см. ниже) |
| Уведомления | notifications/ | Preferences-форма (новый URL, см. ниже) |
Кастомный Unfold Admin Index (/admin/) тоже переработан: stat-карточки на главной странице.
Новые URL Sprint 24 (не существовавшие раньше)
| URL | Что | Было раньше |
|---|---|---|
/dashboard/cases/ |
Список всех кейсов с фильтрацией по статусу (open / under_review / closed_clean / closed_fraud). Детальная страница — /dashboard/cases/<uuid>/. |
Список был только в /admin/cases/case/. Детальная страница создавалась только как форма на профиле игрока. |
/dashboard/settings/api-keys/ |
Self-service CRUD: оператор сам создаёт ключ, видит список, отзывает. Секрет показывается один раз (как в Admin). | Только через /admin/apikeys/ — платформенный администратор. |
/dashboard/audit/ |
Audit log оператора: что кто и когда менял в рамках своего тенанта. Кнопка CSV-экспорт (/dashboard/audit/export.csv). |
Только /admin/audit/ — не было доступа для самого оператора. |
/dashboard/notifications/ |
Preferences уведомлений: Email / Slack / Telegram, матрица событий (alert.created / case.closed_fraud / decision.updated / network.report_published), тихие часы. | Не существовало. |
/dashboard/players/<id>/wallet/ |
HTMX-таб wallet intel на профиле игрока: wallet_address, chain-age, OFAC-статус, mixer-хопы. | Данные считались в hot-path, но в UI не выводились. |
/dashboard/players/<id>/ip/ |
HTMX-таб IP intel: provider chain resolution, VPN/Tor/proxy-флаги, geo, ASN. | Данные считались в hot-path, но в UI не выводились. |
MFA enforcement (новый flow)
Роли operator_admin и risk_lead обязаны пройти TOTP-регистрацию после первого логина. Реализовано в apps/dashboard/apps/accounts/mfa_middleware.py (EnforceMfaForPrivilegedMiddleware).
Флоу:
/accounts/login/— ввод email + пароля (или Google OAuth)./accounts/2fa/authenticate/— ввод TOTP-кода (если уже зарегистрирован) или редирект на setup если ещё нет./dashboard/— вход в дашборд.
Platform admins (Django staff/superusers) MFA не требуют — чтобы не заблокировать recovery. Остальные роли (operator_viewer и т.д.) MFA не требуют.
admin@antifraud.dev — суперюзер (staff=True), поэтому MFA bypass активен. Для тестирования MFA-флоу создай отдельную учётку с ролью operator_admin.Дашборд оператора (UI)
Это то, что видит риск-менеджер казино после логина. Не путать с Django Admin — это разные интерфейсы под разные задачи.
admin@antifraud.dev / devpassword123).Различие админка vs дашборд
Django Admin (/admin/) | Operator Dashboard (/dashboard/) | |
|---|---|---|
| Для кого | Платформенные админы (мы, поддержка) | Риск-менеджер казино-оператора |
| Стиль | CRUD-таблицы Django Admin (Unfold theme) | HTMX + Alpine + Tailwind, оптимизирован под workflow |
| Видит | Всех операторов, всех юзеров, любой объект | Только своего оператора (multi-tenant scope) |
| Действия | Создать оператора, изменить лимит, посмотреть audit всей платформы | Расследовать алерт, открыть/закрыть кейс, разметить случай, настроить вебхук, управлять своими API-ключами и уведомлениями |
Карта страниц
Главная и поиск
| URL | Что там |
|---|---|
/dashboard/ | Лендинг оператора: сводка событий за сутки, top reasons, последние алерты, лента активности |
/dashboard/search/ | Глобальный HTMX-поиск по player_id / email / wallet / fingerprint_hash |
/dashboard/stats/ | Расширенная статистика: графики decisions по часам/дням, conversion воронка |
Алерты (Module 04)
| URL | Что там |
|---|---|
/dashboard/alerts/ | Лента: rule_code, severity, player, reason, timestamp. Фильтры: rule, severity, period, status. Сортировка по любой колонке. |
/dashboard/alerts/rows/ | HTMX-эндпоинт: подгружает строки бесконечного скролла |
/dashboard/alerts/<uuid>/resolve/ | Resolve-action — пометить алерт как обработанный с комментарием |
Профиль игрока (Module 05 + 09 + 12 + 13)
| URL | Что там |
|---|---|
/dashboard/players/<player_id>/ | Профиль с 6 табами (HTMX): Events, Alerts, Links, Graph, Wallet, IP |
/dashboard/players/<id>/tabs/events/ | Таб событий — таймлайн всех signup/login/deposit/withdraw/bet/bonus |
/dashboard/players/<id>/tabs/alerts/ | Таб алертов — все срабатывания на этом игроке |
/dashboard/players/<id>/tabs/links/ | Таб связей — таблица shared identifiers (карты, IP /24, fingerprint, кошельки) |
/dashboard/players/<id>/wallet/ | HTMX-таб wallet intel: адрес, chain-age, OFAC-статус, mixer-хопы. Добавлен в Sprint 24. |
/dashboard/players/<id>/ip/ | HTMX-таб IP intel: VPN/Tor/proxy-флаги, geo, ASN, provider chain. Добавлен в Sprint 24. |
/dashboard/players/<id>/graph.json/ | vis-network JSON для графа связей (1-2 hops). Render через Alpine.js. |
Кейсы (Module 09)
| URL | Что там |
|---|---|
/dashboard/cases/ | Список всех кейсов с табами статусов: open / under_review / closed_clean / closed_fraud. Добавлен в Sprint 24. |
/dashboard/cases/<uuid>/ | Детальная страница кейса. |
/dashboard/cases/players/<player_id>/label/ | Создать case-event на игроке: статус + комментарий. closed_fraud триггерит Module 16. |
Аффилейты (Module 17)
| URL | Что там |
|---|---|
/dashboard/affiliate/ | Список аффилейт-кейсов (cohort-level, не per-player) |
/dashboard/affiliate/<uuid>/ | Детали кейса: какие правила сработали, какие игроки в когорте |
/dashboard/affiliate/cohort/<affiliate_id>/ | Drilldown по конкретному аффилейту: метрики когорты (LTV, retention, IP concentration, ML-скор) |
/dashboard/affiliate/manage/ | Управление: блокировка/одобрение аффилейтов |
/dashboard/affiliate/manage/<uuid>/ | Профиль конкретного аффилейта |
Вебхуки (Module 15)
| URL | Что там |
|---|---|
/dashboard/webhooks/ | Endpoint-ы оператора: добавить, отключить, ротировать секрет, удалить |
/dashboard/webhooks/<uuid>/rotate/ | Сгенерировать новый секрет — старый перестаёт работать сразу |
/dashboard/webhooks/<uuid>/toggle/ | Вкл/выкл endpoint без удаления |
/dashboard/webhooks/<uuid>/deliveries/ | Журнал доставок: успехи, ретраи, DLQ. Фильтр по статусу. |
Active learning (Module 09 + 08)
| URL | Что там |
|---|---|
/dashboard/active-learning/ | Очередь кейсов на разметку: показывает наиболее uncertain (по ML score) + случайные. Risk manager помечает «фрод подтверждён» / «ложное» / «не уверен» — корпус для обучения. |
/dashboard/active-learning/rows/ | HTMX-подгрузка следующих |
/dashboard/active-learning/<case_id>/label/ | Action: записать лейбл |
Биллинг и тарифы
| URL | Что там |
|---|---|
/dashboard/billing/ | Текущий план, потребление за месяц (events, RPS-пики), ближайший биллинг-цикл |
/dashboard/billing/usage/ | HTMX-эндпоинт: график использования |
/dashboard/billing/change-plan/ | Сменить тариф (free / starter / pro) |
/pricing/ | Публичная страница с тарифами — без логина |
API-ключи (самообслуживание)
| URL | Что там |
|---|---|
/dashboard/settings/api-keys/ | Список ключей оператора, создание нового, отзыв. Секрет показывается один раз. Добавлен в Sprint 24 — больше не нужно обращаться в поддержку. |
/dashboard/settings/api-keys/create/ | Форма создания ключа (POST) |
/dashboard/settings/api-keys/<uuid>/revoke/ | Отозвать конкретный ключ |
Audit log (для оператора)
| URL | Что там |
|---|---|
/dashboard/audit/ | Журнал изменений в рамках тенанта оператора. Добавлен в Sprint 24. |
/dashboard/audit/export.csv | CSV-экспорт для периодических проверок |
Уведомления
| URL | Что там |
|---|---|
/dashboard/notifications/ | Preferences: Email/Slack/Telegram, матрица событий, тихие часы. Добавлен в Sprint 24. |
Инвайты (Module 09)
| URL | Что там |
|---|---|
/operators/<operator_id>/invite-user/ | Форма приглашения нового юзера в оператора (для owner-а). Email + role. |
/operators/<operator_id>/accept-invite/<url_key>/ | Ссылка из письма-инвайта. Кликаешь → форма установки пароля. |
Стек UI
- Django 5 + DRF (API endpoints) + django-allauth (auth + MFA)
- HTMX — частичные обновления страниц без JS-фреймворков (alert feed, инфинит-скролл, табы)
- Alpine.js — реактивность для сложных компонентов (граф, фильтры)
- Tailwind CSS — стили, бандлятся через whitenoise (не CDN — Sprint 23 #393)
- Design system —
apps/dashboard/static/css/tokens.css(CSS-переменные), SVG-ассеты вapps/dashboard/static/img/ - Unfold — современная тема для Django Admin (кастомный index — Sprint 24)
- vis-network — рендер графа связей в профиле игрока
Multi-tenant scoping
Каждый запрос к дашборду фильтруется по request.user.operator. Юзер из casino-A физически не может видеть события casino-B — middleware OperatorScopedMiddleware подсаживает фильтр в каждый ORM-запрос (apps.accounts.middleware). Тесты на изоляцию: apps/dashboard/tests/test_scoping.py.
Если впервые открываешь дашборд
Если событий ноль — все страницы покажут пустые состояния. Чтобы увидеть систему «в действии»:
- Залогинься
admin@antifraud.dev. - С ноута запусти synthetic generator (→ раздел Первое событие):
python -m tools.synthetic_events --count 500 --mode stream --rps 50 \ --api-url https://staging.antifraud.slim-shaggy.com \ --api-key <твой-API-ключ из bootstrap_dev> \ --fraud-rate 0.20 - Через 30-60 секунд обнови /dashboard/alerts/ — должны появиться сработавшие правила.
- Кликни в любого игрока в алерте — увидишь профиль с табами + графом.
Django Admin (для платформы)
Django Admin на staging — главная панель управления оператором, юзерами, ключами, кейсами.
URL
https://staging.antifraud.slim-shaggy.com/admin/
Креды
- Дев-учётка (после
bootstrap_dev):admin@antifraud.dev/devpassword123. - Свой суперюзер (рекомендую сделать сразу для прода):
После — войти под своим email + паролем.ssh root@178.104.214.209 cd /root/antifraud/infra docker compose exec dashboard python manage.py createsuperuser
Сменить пароль дев-учётке
ssh root@178.104.214.209
cd /root/antifraud/infra
docker compose exec dashboard python manage.py changepassword admin@antifraud.dev
Что есть в админке
Accounts → Users
Платформенные юзеры. Роли: admin, risk_manager, operator_owner, operator_viewer.
Operators → Operators
Клиенты (казино). Поля: имя, plan (free/starter/pro), network_optin, лимиты.
Apikeys → API keys
API-ключи всех операторов. Секрет показывается один раз. В БД хранится PBKDF2-хеш. Оператор управляет своими ключами самостоятельно через /dashboard/settings/api-keys/ (Sprint 24).
Players → Players
Все игроки, по которым прошли события. Заполняется автоматически из ingest-а.
Alerts → Alerts
Сработавшие правила: rule_code, severity, player, context.
Cases → Cases
Кейсы расследований. Status: open / under_review / closed_clean / closed_fraud. closed_fraud триггерит Module 16.
Webhooks → Endpoints
HTTPS endpoint оператора + HMAC-секрет + список подписанных событий.
Pricing → Plans
Тарифы: events/month, RPS, retention, цена.
Audit → AuditLog
Что кто и когда менял. Только чтение. PII в before/after-значениях санитизирован.
ML labels
UI разметки риск-менеджером (правда/ложь по алерту) — корпус для будущей supervised-модели.
Первое событие
Три способа отправить trafic: curl (одно событие), synthetic generator (поток), dry-run (полный smoke).
1. curl — одно событие на staging API
curl -X POST https://staging.antifraud.slim-shaggy.com/v1/events \
-H "Authorization: Bearer sk_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"event_type": "signup",
"player_id": "player_001",
"timestamp": "2026-05-07T10:00:00Z",
"ip": "1.2.3.4",
"email": "test@example.com",
"fingerprint": {"fingerprint_hash": "abc123", "signals": {}}
}'
Ответ:
{"risk_score": 12, "decision": "allow", "reasons": []}
2. Синтетический генератор
Лежит в tools/synthetic_events/ на ноуте. Запускается локально, стримит в staging API через HTTPS.
--mode parquet— пишет в файл (для офлайн-обучения / тестов).--mode stream— стримит в API с указанной RPS.
# 10000 событий на диск (локально)
python -m tools.synthetic_events --count 10000 --mode parquet --out events.parquet
# Поток в staging API
python -m tools.synthetic_events --count 500 --mode stream --rps 50 \
--api-url https://staging.antifraud.slim-shaggy.com \
--api-key sk_live_xxx \
--fraud-rate 0.15
Параметры:
| Флаг | Что делает | Default |
|---|---|---|
--count | Сколько событий сгенерить | 1000 |
--fraud-rate | Доля игроков с фрод-паттернами | 0.15 |
--seed | Random seed для воспроизводимости | 42 |
--rps | RPS для stream-режима | 10 |
--operator | operator_id, который штампуется на события | demo_operator |
3. Полный operator dry-run против staging
Шипнули в Sprint 23 (sid #397). Делает прогон по 9 поверхностям и печатает PASS/FAIL/SKIP.
python scripts/dry_run.py \
--api-base https://staging.antifraud.slim-shaggy.com \
--api-key sk_live_xxx \
--dashboard-base https://staging.antifraud.slim-shaggy.com # для проб alert-feed/graph
# --webhook-receiver-url https://your-receiver # опционально
Что проверяет:
- Ingest
/healthz→ 200 - Ingest
/readyz→ подключения к CH+Redis+Kafka+PG - Decision quality — >0 решений block/review
- ATO baseline — срабатывание правил new_device/new_country
- Wallet intel — проверка OFAC/mixer (SKIP на синтетике)
- Alert feed — лента в дашборде (SKIP без сессии)
- Graph — построение графа связей
- Webhook delivery — отправка на receiver (SKIP без флага)
- Network blocklist — Module 16 round-trip
- Affiliate cohort — ML-скор
Полный runbook: docs/integration/dry-run.md.
Архитектура целиком
Два приложения, четыре хранилища, несколько consumers, observability-стек. Всё в Docker Compose.
Hot path vs async path
Hot path — что мы успеваем сделать за <100мс перед ответом оператору:
- Распаковать payload, проверить API-ключ, idempotency.
- Применить «дешёвые» правила (geo, IP, fingerprint, OFAC лукап по wallet, network blocklist hit).
- Агрегировать score, вернуть
{risk_score, decision, reasons}.
Async path — что считается в фоне через Kafka и попадает в дашборд позже:
- Тяжёлые графовые правила (shared_card_with_many_accounts, communities).
- ML-скор аффилиат-когорт (LightGBM).
- ATO-baseline пересчёт.
- Webhook-доставка.
- Module 16 — публикация в network_blocklist.
Принцип: синхронный ответ всегда быстрый, точность дотачивается асинхронно. Если async-правила улучшили решение — летит вебхук decision.updated.
Сервисы (контейнеры)
Все 21 контейнера крутятся на staging-хосте 178.104.214.209. Compose project name = infra, поэтому имена контейнеров infra-*. Порты внутренних сервисов забинды на 127.0.0.1 (наружу торчат только :80 и :443 через Caddy).
Заглянуть в любой:
ssh root@178.104.214.209
cd /root/antifraud/infra
docker compose ps # все 21 контейнера
docker compose logs <name> # лог конкретного
Приложения
infra-api-1
Ingest endpoint /v1/events. Auth, rate-limit, idempotency, hot-path rules, scoring, sync response. Снаружи доступен через Caddy на https://staging.antifraud.slim-shaggy.com/v1/events. См. apps/api/.
infra-dashboard-1
Веб-UI + админка. Снаружи: https://staging.antifraud.slim-shaggy.com/admin/, /dashboard/. HTMX, Alpine.js, Tailwind через whitenoise.
infra-caddy-1
Reverse-proxy + auto-HTTPS (Let's Encrypt) + JA3/JA4 plugin. Сертификат для staging.antifraud.slim-shaggy.com.
Хранилища
infra-clickhouse-1
Аналитика. Таблицы: events, players, links, network_blocklist, behavioral_signals.
infra-postgres-1
Метаданные Django: операторы, юзеры, ключи, кейсы, вебхуки, биллинг, audit.
infra-redis-1
Idempotency keys, rate-limit counters, session cache.
infra-redpanda-1
Kafka-совместимая очередь. Топики: events.raw, alerts.created, webhooks.outbound, network.auto_report_requests, *.dlq.
Consumers
alert-consumer
Читает alerts.created, пишет в Postgres + триггерит UI-уведомление.
webhook-consumer
Читает webhooks.outbound, делает HMAC-подпись, ретраит с экспоненциальным backoff, в DLQ если 5xx>5.
auto-report-consumer
Читает network.auto_report_requests, лукапит opt-in, пишет хешированные идентификаторы в network_blocklist. Шипнули Sprint 22 (sid #382 — был BLOCKER).
erasure-consumer
Читает erasure.requests, удаляет персональные данные игрока из CH + PG.
async-rules-consumer
Тяжёлые правила (графовые, ATO baseline, ML scorers). Пишет апдейт-события и triggerит decision.updated webhook.
ML и observability
infra-mlflow-1
Tracking + model registry. Эксперименты, метрики, артефакты моделей.
infra-prometheus-1
Метрики со всех сервисов. Скрейпит api, dashboard, consumers, redpanda, postgres-exporter, blackbox.
infra-grafana-1
Дашборды поверх Prometheus + Loki. admin/admin при первом входе.
infra-loki-1
Лог-агрегация. Promtail кормит из Docker.
infra-alertmanager-1
Маршрутизация прометеевских алертов в Slack/email/PagerDuty.
Жизненный цикл одного события
Что происходит с момента POST /v1/events до возврата ответа — и что ещё догоняется в фоне.
Идемпотентность
Каждый запрос несёт Idempotency-Key header. Redis хранит первый ответ 24 часа. Повторы возвращают тот же ответ без выполнения правил — оператор может безопасно ретраить.
Rate limit
Sliding-window counter в Redis по ключу operator_id. Лимит читается из плана (Plan.rps_limit). При превышении — 429 + Retry-After.
Hot path budget
p99 цель: <100мс. Поэтому в hot-path только всё, что можно посчитать за O(1) лукапы:
- OFAC list (in-memory set).
- Network blocklist (Redis SET по хешу).
- IP intel (Redis cache + provider chain).
- Fingerprint dedup (CH dictionary).
- Geo по IP (MaxMind в памяти).
Типы событий
Шесть базовых типов. Discriminated union в Pydantic — каждый со своей схемой и набором обязательных полей.
| Тип | Когда оператор шлёт | Ключевые поля | Что чекаем |
|---|---|---|---|
signup | При регистрации игрока | email, ip, fingerprint, affiliate_id, utm_* | Disposable email, geo, IP-интел, аффилиат-фрод |
login | Каждый логин | player_id, ip, fingerprint, ua, ja3 | ATO (новый device/country), биометрика |
deposit | Депозит (фиат или крипта) | amount, currency, payment_method, wallet_address | Wallet intel (OFAC/mixer/age), shared_card |
withdraw | Вывод | amount, currency, wallet_address | withdraw_without_play, round_trip, recovery_then_withdraw |
bet | Ставка / спин | game_id, stake, rtp, outcome | high_rtp_slots_only_pattern, bot timing |
bonus_claim | Активация бонуса | bonus_id, amount | bonus_to_withdraw_velocity, multi-account-by-fingerprint |
Общие поля
На каждом событии:
{
"event_type": "",
"player_id": "operator-side ID",
"timestamp": "ISO 8601 UTC",
"ip": "x.x.x.x",
"fingerprint": {
"fingerprint_hash": "...",
"signals": { "canvas": "...", "webgl": "...", "audio": "...", "fonts": [...], "screen": "...", "tz": "...", "ua_ch": {...} }
},
"behavioral": {
"mouse_path": [...],
"keystroke_intervals": [...],
"form_fill_ms": 4200
}
}
Полные схемы: packages/shared/schemas/events.py. Документация для оператора: docs/integration/events.md.
Как мы ловим фрод
Стек защиты — четыре слоя: правила, граф, сигналы fingerprint/biometric, кросс-операторная сеть.
Слой 1 — Rules engine
Каждое правило — Python класс, drop-in в apps/api/app/rules/plugins/. Авто-discovery, регистр не редактируется. Сейчас 51 правило.
Интерфейс правила:
class Rule:
code: str
severity: int # 0..100
hot: bool # True → синхронно; False → async-rules-consumer
def applies_to(self, event_type: str) -> bool: ...
async def evaluate(self, event, context) -> RuleHit | None: ...
Новое правило = новый файл + декоратор. Никогда не правится центральный if/else.
Слой 2 — Graph module
Узлы: player, card_hash, IP /24, email_domain, fingerprint_hash, wallet_address. Рёбра: «использовал». Nawcomers: → полный раздел.
Слой 3 — Fingerprint + biometrics
Серверные сигналы (TLS JA3/JA4, HTTP header order) + клиентские (ThumbmarkJS canvas/webgl/audio/fonts) + behavioral (мышь, клавиатура, время заполнения формы) → 11 правил, в т.ч. biometrics_no_human_input, device_emulator_detected.
Слой 4 — Cross-operator network (Module 16)
Opt-in voluntary blocklist между операторами. Идентификаторы хешированы (SHA-256 от card_hash / email_domain / fingerprint_hash) — никаких сырых PII между операторами. Полный раздел: → Module 16.
51 правило
Все правила группированы по категориям. Файлы в apps/api/app/rules/plugins/.
Аффилиат-фрод (12)
| Код | Описание |
|---|---|
affiliate_self_referral | Аффилиат сам себя зарегистрировал |
affiliate_cohort_velocity_burst | Аномальный всплеск регистраций по аффилиату |
affiliate_cohort_ip_concentration | Все игроки аффилиата с одного /24 |
affiliate_cohort_low_ltv | Когорта с подозрительно низким LTV (бонус-абьюз) |
affiliate_low_diversity | Однородные fingerprint/UA в когорте |
affiliate_device_diversity | Слишком мало уникальных устройств |
affiliate_ip_quality | Доля прокси/VPN/Tor выше треshhold |
affiliate_zero_retention | Все игроки покинули после первого депо |
affiliate_bonus_abuse | Когорта оптимизирует только бонус-флоу |
affiliate_timing | Регистрации идут в подозрительные интервалы |
affiliate_utm_consistency | UTM не бьются с трафик-источником |
affiliate_network_blocklist_hit_rate | Игроки аффилиата часто матчатся в Module 16 |
Биометрика и поведение (7)
biometrics_no_human_input | Нулевая активность мыши/клавы |
biometrics_no_mouse_movement | Только клики, без траектории |
biometrics_robotic_typing | Идеально равные интервалы клавиш |
keystroke_too_uniform | Разброс латентности нажатий ≈0 |
mouse_no_jitter | Прямая линия без дрожи |
form_filled_too_fast | Регистрация <1с |
paste_in_sensitive_field | Пароль/email вставлен через clipboard |
Fingerprint / device (4)
device_emulator_detected | BlueStacks/NoxPlayer/Multilogin сигнатуры |
http2_fingerprint_anomaly | HTTP/2 setting frame не бьётся с UA |
ja3_user_agent_mismatch | JA3 не соответствует заявленному UA |
shared_fingerprint_with_many_accounts | Один fingerprint у N+ аккаунтов |
ATO / identity change (5)
new_device_login | Логин с устройства, которого не было в baseline |
new_country_login | Логин из новой страны |
password_reset_then_large_withdraw | Reset → крупный вывод в окне 1-24ч |
email_change_then_withdraw_window | Смена email → вывод |
phone_change_then_withdraw_window | Смена телефона → вывод |
recovery_then_withdraw | Recovery flow → вывод |
behavior_change_post_login | Биометрика после логина не похожа на baseline |
Wallet intel (4)
wallet_in_ofac_sanctions | Адрес в OFAC SDN list |
wallet_interacted_with_mixer | ≥1 hop через Tornado/ChipMixer/etc. |
wallet_in_scam_list | Chainabuse/CryptoScamDB hit |
wallet_age_too_young | Кошелёк создан <7 дней до депо |
fresh_wallet_funded_only_for_deposit | Кошелёк фондировался единственным переводом |
Граф / shared identifiers (4)
shared_card_with_many_accounts | Одна карта у N+ аккаунтов |
shared_ip_24_with_many_accounts | Один /24 у N+ аккаунтов |
shared_wallet_with_many_accounts | Один кошелёк у N+ аккаунтов |
network_blocklist_hit | Module 16 — match по хешу с другого оператора |
Бонус / play patterns (4)
bonus_to_withdraw_velocity | Активировал бонус → быстрый вывод |
withdraw_without_play | Депо → вывод без ставок |
round_trip_deposit_withdraw | Депо и вывод почти равны и близко по времени |
high_rtp_slots_only_pattern | Играет только в high-RTP слоты |
Geo / IP / identity (8)
country_mismatch_signup_vs_deposit | Страна signup ≠ страна deposit |
geo_impossible | Перемещение быстрее, чем самолётом |
ip_proxy_or_tor | IP — известный прокси/Tor exit |
residential_proxy_signup | Резидентный прокси на signup |
disposable_email_domain | 10minutemail/mailinator/etc. |
rapid_signup_burst | N signup-ов за секунды с одного fingerprint |
deposit_anomaly_first_time | Первый депо в N раз больше типичного |
timing_pattern_bot | Интервалы между событиями строго периодичны |
Scoring и decision
Как из набора сработавших правил рождается одно решение.
Aggregator
Каждое сработавшее правило возвращает RuleHit{code, severity ∈ [0,100], reason_string}. Aggregator делает:
risk_score = min(100, sum(hit.severity for hit in hits) * decay)
где decay — фактор насыщения (чтобы 10 слабых правил не перевесили 1 сильное). Конфигурируется per-operator в operators.scoring_config.
Decision
Пороги — per-operator config. Дефолты:
| Score | Decision | Что оператор должен сделать |
|---|---|---|
| 0–39 | allow | Пропустить без вмешательства |
| 40–69 | review | Step-up auth / ручная модерация |
| 70–100 | block | Отказать |
Reasons
Список snake_case строк — машинно-читаемый, дашборд маппит на UI-копи. Пример:
{
"risk_score": 78,
"decision": "block",
"reasons": [
"wallet_in_ofac_sanctions",
"shared_fingerprint_with_many_accounts",
"ip_proxy_or_tor"
]
}
Объяснимость
В дашборде на странице игрока для каждого решения показывается:
- Список сработавших правил с severity-вкладом.
- Для async ML-скоров — SHAP top-N features (через
apps/api/app/ml/audit.py). - Граф связей: вершины и рёбра, контрибьютировавшие в shared_*-правила.
Графовый модуль
Module 05. Сейчас на networkx + ClickHouse, в будущем — Neo4j (за тем же интерфейсом).
Что в графе
Узлы: player, card_hash, IP /24, email_domain, fingerprint_hash, wallet_address. Рёбра: «использовал» с весом и timestamp. Хранятся в ClickHouse links.
Так формируется community вокруг общих идентификаторов. Если узлов в community > threshold — каждый player в community получает алерт shared_*_with_many_accounts.
Алгоритмы
- Connected components — базовый детектор колец.
- PageRank — выявить «хабовых» игроков (мул-аккаунты).
- Louvain communities — кластеризация плотных сообществ.
- Fingerprint similarity (cosine) — связки по похожим, но не идентичным fingerprint-ам.
Когда считается
Не на hot path (слишком дорого). async-rules-consumer подгружает subgraph радиуса 2 вокруг игрока на каждое событие, считает за <500мс, при ringe-detection пишет алерт + триггерит decision.updated.
Кеш
Считанные subgraph и community-IDs кешируются в Redis по хешу содержимого. TTL 5 минут. Инвалидация при новых рёбрах в links.
Известный баг: cache invalidation не покрывает PageRank/community ключи (intake #356 — low).
Module 16 — кросс-операторная сеть
Стратегический моат, который конкуренты не повторят. Voluntary opt-in blocklist между операторами с privacy by hash.
Зачем
Регуляторные регистры самоисключения (GamStop, Spelpaus и т.д.) недоступны крипто-казино с лицензиями Curaçao/Anjouan. Module 16 — наша замена: операторы добровольно складывают хеши идентификаторов известных фродеров в общий пул, на ингесте каждый opt-in оператор лукапит входящие хеши.
Как работает
Что хешируется
- SHA-256(card_hash) — карты.
- SHA-256(email_domain) — НЕ полный email, только домен.
- SHA-256(fingerprint_hash) — устройства.
- SHA-256(wallet_address) — крипто-кошельки.
Сырых PII в blocklist нет. Соответствие восстановить по хешу нереально — только посмотреть «знакомо ли».
Проверка end-to-end
Sprint 23 (sid #391) шипнул staging smoke: scripts/smoke/module16_e2e.py + tests/staging/test_smoke.py @smoke. Прогоняется при каждом деплое.
Включить для оператора
В админке: Operators → выбрать оператора → галочка network_optin = True. После включения — кейсы с лейблом closed_fraud начинают публиковаться.
ML-пайплайн
Module 08. Сейчас в проде одна модель — affiliate cohort baseline (LightGBM). Inference ML scorer-ов реализован за Scorer protocol — модели свапаются конфигом.
Этапы
- Feature engineering —
apps/api/app/ml/features/. Рассчитывает признаки изevents+links: aggregations за 1ч/24ч/7д, графовые (degree, PR-rank), behavioral (mouse_entropy_x — TODO #350). - Feature store — Feast. Online (для инференса) + offline (для обучения). Time-travel lookups (важно: PaySim leakage был intake #358 — нужен time-travel, не обычный join).
- Training — Jupyter ноутбуки в
notebooks/. Сейчас работают с public datasets (IEEE-CIS, PaySim) для смоук-проверки плумбинга. - Tracking — MLflow на
:15000. Каждый run пишет params/metrics/artifacts. - Registry — модели регистрируются в MLflow Model Registry с тегом
artifact_sha256(для верификации в проде — intake #378). - Deployment —
Scorerпротокол:
Реализации: rules-only (baseline), LightGBM affiliate cohort, GNN (DGL — пока не в проде), ensemble.class Scorer(Protocol): def score(self, features: dict) -> tuple[float, list[str]]: ... - Drift —
apps/api/app/ml/drift.py. Считает PSI/JS-divergence между training distribution и live, шлёт прометеевские алерты при дрифте. - Explainability — SHAP top-N features логируется на каждом async-инференсе для дашборда.
Откуда данные для модели
Три источника, по приоритету: (1) operator labels, (2) public datasets, (3) synthetic.
1. Размеченные данные оператора
Канонический спек: DATA_REQUIREMENTS.md в корне репо. Что просим:
- events за 6+ месяцев (шесть типов).
- player labels —
fraud_category ∈ {clean, multi_account, bonus_abuse, ato, mule, chargeback, fake_kyc}. - cases history — что закрыто как фрод/чисто.
- chargeback ledger.
Импорт: scripts/import_operator_dataset.py. Когда первый партнёр-казино пришлёт данные — за ~3-4 недели поднимем baseline LightGBM (multi-class fraud).
2. Public datasets (для plumbing-проверки)
- IEEE-CIS Fraud Detection (Kaggle) — 590k строк e-commerce фрода. Используется в смоук-ноутбуках, чтобы убедиться что MLflow + Feast + LightGBM едут.
- PaySim — синтетический mobile-money dataset. Был leak в dest_fan_in feature → intake #358 предписывает Feast time-travel.
3. Synthetic events (для dev / demo / load test)
tools/synthetic_events/generator.py — SyntheticEventGenerator класс. Генерит:
- Реалистичные распределения (Pareto на amount, lognormal на time-between-events).
fraud-rate%-доля игроков с fraud-патернами (multi-account по shared fingerprint, bonus → withdraw, OFAC wallet, mixer hop).- Output: parquet (для офлайн) или stream в API.
Используется в:
- Локальный smoke (
scripts/dry_run.py). - CI integration tests.
- Demo/sales-демонстрации.
Active learning loop
В дашборде есть /dashboard/active-learning/ — UI разметки. Risk manager помечает алерт как «фрод подтверждён» / «ложное срабатывание» / «не уверен». Эти лейблы накапливаются в apps/dashboard/apps/ml_labels/ и кормят следующий цикл обучения. Это и есть наш «корпус» для supervised fine-tuning, когда оператор-данные приедут.
Деплой моделей
Модели свапаются конфигом, не кодом. Принцип «конфигурация над кодом» из CLAUDE.md.
Текущее состояние
| Модель | Файл | Использует |
|---|---|---|
| affiliate_cohort_baseline | apps/api/app/ml/models/affiliate_cohort_baseline.lgb | affiliate_cohort_scorer.py в async path |
Как добавить новую модель
- Натренировать → залогировать в MLflow с тегом артефакта.
- Положить артефакт в
apps/api/app/ml/models/(или подгрузить из MLflow registry на старте). - Реализовать
Scorerprotocol вapps/api/app/ml/scorers/your_model.py. - Зарегистрировать в
scoring_configу оператора в админке (через JSON-поле).
Перезапуск api НЕ нужен — конфиг читается из БД на каждом scoring call.
Roll-out / Roll-back
В scoring_config есть shadow_mode: True — модель считает скор, но в decision не учитывается. Логи пишутся параллельно с baseline для сравнения. Через 1-2 недели shadow → flip в active. Roll-back = снять флаг.
Drift и мониторинг
Прометеевские метрики (Module 08):
ml_inference_latency_seconds— p99 на скоринг.ml_feature_psi— PSI между train и live на каждый feature.ml_score_distribution_jsd— JS-divergence распределения скоров.
Alertmanager шлёт алерт в Slack при PSI > 0.2 на любом критичном feature — сигнал что пора переобучать.
JS SDK + fingerprint
Module 06. Оператор embed-ит SDK в страницы signup/login/deposit. SDK собирает fingerprint и behavioral signals, кладёт в request на ingest API.
Что внутри
- База: ThumbmarkJS — canvas, webgl, audio, fonts, screen, timezone.
- UA Client Hints (новый стандарт).
- Behavioral capture (Module 11): mouse path, keystroke timing, form-fill duration, paste detection.
- GDPR / DNT compliance — если выставлен
navigator.doNotTrackили флагantifraud_consent=false, behavioral capture отключается.
Дистрибуция
- npm:
@antifraud/sdk(планируется). - CDN bundle (для прямого embed):
https://cdn.antifraud.example/sdk-0.2.0.min.js. - Build:
tsup+viteвapps/sdk/.
Версии
Sprint 22 (sid #379) шипнул transition window 0.1.x → 0.2.0. Дашборд лукапит правила по обоим хешам в течение 30-90 дней. Полный гайд: docs/integration/sdk-fingerprint-migration.md.
Использование
<script src="https://cdn.antifraud.example/sdk-0.2.0.min.js"></script>
<script>
const fp = await window.AntifraudSDK.collect();
// fp = { fingerprint_hash, signals, behavioral }
await fetch('/api/casino/signup', {
method: 'POST',
body: JSON.stringify({...formData, antifraud: fp})
});
</script>
Дальше backend оператора прокидывает antifraud субобъект в ingest API в поле fingerprint.
Webhook-и
Module 15. Async-доставка событий оператору: alert.created, decision.updated, case.closed, network.report_published.
Настройка
- Админка → Webhooks → Endpoints → Add.
- Поля:
operator,url(только https),events_subscribed(CSV),secret(генерится). - Секрет показывается один раз — записать.
Доставка
- POST на
urlс body JSON и заголовкамиX-Antifraud-Signature(HMAC-SHA256) +X-Antifraud-Event. - Retry: экспоненциальный backoff 1s, 5s, 30s, 5m, 30m. Всего 5 попыток.
- После 5 неудач — в DLQ
webhooks.dlq. В дашборде/dashboard/webhooks/deliveries/— фильтр failed.
Verify пример (Python)
import hmac, hashlib
def verify(body: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature, expected)
Полные примеры (Node, PHP, Java): docs/integration/webhooks.md.
API-ключи и лимиты
Формат ключа
sk_live_ + 32 символа base62. Префикс позволяет grep-нуть в логах. В Postgres хранится pbkdf2(secret, salt, 100k iterations).
Создание
Оператор сам: /dashboard/settings/api-keys/ → Create. Платформенный admin: Apikeys → API keys → Add в /admin/. После сохранения секрет показывается один раз в обоих случаях.
Программно: apps.apikeys.services.create_api_key(operator, label).
Rotation
Создать новый ключ → раздать оператору → подождать <TTL → пометить старый revoked=True. Старый перестаёт авторизовать запросы (401), новый продолжает.
Лимиты per-plan
| Plan | Events/мес | RPS | Retention |
|---|---|---|---|
| free | 50k | 20 | 30 дней |
| starter | 500k | 100 | 90 дней |
| pro | 5M | 500 | 365 дней |
| enterprise | custom | custom | 365+ дней |
Конфигурятся в apps/dashboard/apps/pricing/. При превышении — 429 + Retry-After.
Деплой и rollback
Auto-deploy
Push в main → GitHub Actions .github/workflows/deploy.yml → SSH на Hetzner → git pull → migrations → docker compose up -d --build → smoke. Время цикла ~1 мин.
CI/e2e/SLO workflows отключены с автотриггеров (Sprint 23, commit b921503) чтобы не палить Actions-бюджет. Запуск вручную: Actions tab → "CI" → Run workflow.
Ручной деплой конкретного SHA
gh workflow run deploy.yml -f sha=<commit-sha>
Rollback
gh workflow run deploy.yml -f sha=<previous-green-sha>
Workflow идемпотентный — деплой того же SHA повторно безопасен.
Hotfix
Не редактировать прод по SSH. Патч → коммит → push → дождаться auto-deploy. Если очень срочно — workflow_dispatch с конкретным SHA.
ClickHouse миграции
SQL-файлы в apps/api/migrations/clickhouse/NNN_*.sql. Применяются deploy-workflow-ом по порядку. Идемпотентные (CREATE ... IF NOT EXISTS, ALTER ... ADD COLUMN IF NOT EXISTS).
Логи и метрики
Логи через SSH
ssh root@178.104.214.209
cd /root/antifraud/infra
docker compose logs -f api --tail=200
docker compose logs -f dashboard --tail=200
docker compose logs -f auto-report-consumer alert-consumer webhook-consumer --tail=100
Логи через Loki (Grafana)
Grafana запущена на хосте на :13000 (только 127.0.0.1). Чтобы открыть в браузере — туннель:
ssh -L 3000:127.0.0.1:13000 root@178.104.214.209
# открыть http://localhost:3000 → Explore → Loki
Полезные запросы:
{container="infra-api-1"} |= "ERROR"
{container=~"infra-(alert|webhook|auto-report)-consumer-1"} |~ "exception"
{container="infra-dashboard-1"} | json | level="error"
Метрики (Prometheus, через туннель)
ssh -L 9090:127.0.0.1:19090 root@178.104.214.209
# открыть http://localhost:9090/targets — все scrape targets
- API:
infra-api-1:8000/metrics - Dashboard:
infra-dashboard-1:8001/metrics - Auto-report consumer:
infra-auto-report-consumer-1:9400/metrics - Redpanda:
infra-redpanda-1:9644/metrics - Postgres / CH / Redis — через соответствующие exporter-ы
Дашборды Grafana
Готовые дашборды в infra/grafana/provisioning/:
- Ingest API — RPS, p50/p95/p99 latency, error rate.
- Decisions — распределение allow/review/block, top reasons.
- Consumers lag — Kafka lag по каждому consumer.
- Database — CH inserts/sec, PG connections, Redis ops/sec.
- ML — inference latency, PSI, score distribution.
Health-checks (с ноута через HTTPS)
curl https://staging.antifraud.slim-shaggy.com/healthz # 200 — стек жив
curl https://staging.antifraud.slim-shaggy.com/readyz # 200 — все подключения ОК
Если /healthz = 200, а /readyz ≠ 200 — какой-то из бэкендов отвалился. Тело ответа покажет какой (ClickHouse/Kafka/Redis/Postgres).
Если сломалось
Все диагностические команды — через ssh root@178.104.214.209 с переходом в /root/antifraud/infra.
HTTPS не отвечает
Сначала с ноута:
curl -v https://staging.antifraud.slim-shaggy.com/healthz
Если timeout / TLS error — Caddy лежит. SSH на хост:
docker compose ps caddy
docker compose logs caddy --tail=200
docker compose restart caddy
Контейнер не поднимается
docker compose ps # увидеть статус всех 21
docker compose logs <service> --tail=200
docker compose restart <service>
API возвращает 500
Проверь подключения изнутри хоста:
docker compose exec clickhouse clickhouse-client --query 'SELECT 1'
docker compose exec postgres pg_isready -U antifraud
docker compose exec redis redis-cli ping
docker compose exec redpanda rpk cluster health
Алерты не появляются
docker compose logs alert-consumer --tail=50— есть ли exceptions?docker compose exec redpanda rpk topic consume events.raw --num 5— события вообще пишутся?- Если consumer стоит →
docker compose restart alert-consumer.
Module 16 не пишет в blocklist
- В админке проверь у оператора галочку
network_optin = True. docker compose logs auto-report-consumer --tail=100.- Запусти staging smoke (с ноута):
cd ~/PycharmProjects/iGamingAntiFraudSaaS python scripts/smoke/module16_e2e.py --full-pipeline \ --api-base https://staging.antifraud.slim-shaggy.com \ --api-key sk_live_xxx
Деплой упал
С ноута:
gh run list --branch main --limit 5 # последний run
gh run view <run-id> --log-failed # лог упавшего шага
Откат на предыдущий зелёный SHA:
gh workflow run deploy.yml -f sha=<previous-green-sha>
Где смотреть «что сработало» в правилах
Поставь LOG_LEVEL=DEBUG на хосте в /root/antifraud/.env, потом docker compose restart api. Каждое решение пишется со списком hits.
Полный perf-debug
Через SSH-туннель открой Grafana (ssh -L 3000:127.0.0.1:13000 root@178.104.214.209) → дашборд "Ingest API" покажет p99-spike. В Loki фильтр {container="infra-api-1"} |~ "slow query" найдёт медленные правила. Если правило конкретное — смотри apps/api/app/rules/plugins/<rule_code>.py.
Куда копать дальше
| Хочешь | Куда смотреть |
|---|---|
| Полный план + архитектура (RU+EN) | Plan.md, Implementation.md |
| CLAUDE.md (агентам) | CLAUDE.md |
| Dev-обзор на русском | docs/обзор.md |
| Дока для оператора-клиента | docs/integration/README.md |
| Operator dry-run runbook | docs/integration/dry-run.md |
| Onboarding оператора | docs/onboarding/ |
| Runbook-и для прода | docs/runbooks/ |
| Бенчмарки | docs/benchmarks/ |
| DATA_REQUIREMENTS | DATA_REQUIREMENTS.md |
| Postman / Bruno | docs/integration/postman/, bruno/ |
| Code samples (Python/Node/PHP/Java) | docs/integration/code-samples/ |
| Plane (задачник) | Backlog |
| Спринт-история | memory/sprint_*_plan.md |
| Staging credentials | memory/staging_server.md |
| Plane API reference | memory/plane_api_works.md |
Кого спрашивать
Каждый area:* в Plane имеет свой sub-agent в .claude/agents/. При работе с задачей label определяет агента:
area:backend→backend-engineer(FastAPI, rules, async pipelines)area:frontend→django-engineer(Django, HTMX, Alpine, Tailwind)area:infra→infra-engineer(Docker, Caddy, observability)area:deploy→deploy-engineer(CD, hetzner, rollback)area:ml→ml-engineer(LightGBM, GNN, Feast, MLflow, SHAP)area:sdk→sdk-engineer(TS SDK, Thumbmark, biometrics)area:graph→graph-engineer(networkx, communities)area:crypto→crypto-engineer(wallet APIs, OFAC, mixer)area:docs→docs-writer(integration guides, samples)- cross-cutting →
security-engineer(auth, secrets, hashing, multi-tenant isolation)
Статус проекта
На 2026-05-07: 24 спринта закрыты, MVP + UI v2 отгружены, все 17 модулей реализованы (~1450 тестов), все production launch gates closed. Sprint 24 добавил design system, 9 переработанных экранов, 5 новых URL и MFA-флоу. Следующий шаг — живой operator dry-run через scripts/dry_run.py с реальным opt-in оператором, потом подписать первый контракт.