Инфраструктура и тех-стек · спецификация и роадмап · быстрая обработка ситуативов · админ-таксономия событий.
Краткое резюме
Платформа из двух бизнесово раздельных продуктов, связанных глубокой интеграцией: Events («По душе» — офлайн-события) и Dating («По любви» — знакомства, существующее приложение plbvi.ru). Архитектура — 2 продуктовых бэкенда (events-backend, dating-backend; у каждого своя БД и домен, разводятся независимо) + общий слой платформенных сервисов, главный из которых — Identity/SSO (единый user_id). Это позволяет легко «развести» продукты потом, но при этом делать cross-app-интеграцию (статус «открыт для знакомств», переход между приложениями, «4 из 20 на событии открыты и подходят»).
Над бэками — 4 клиента (events/dating × mobile/web) и 1 общая админка-агрегатор. Дорогую инфраструктуру и регулируемое (identity/verification, notifications, media, analytics, moderation, payment-gateway) выносим в общие сервисы; доменную логику и данные держим в каждом продукте раздельно.
Документ покрывает: - §1 Инфраструктура и стек — дейтинг уже в проде на Python (Django+FastAPI, k8s в Yandex Cloud); наследуем стек и инфру, events строим в том же стеке; данные в РФ-облаке (152-ФЗ). - §2 Спецификация и роадмап — 2 бэка + общие сервисы + integration layer; фазы по зависимостям (P0→P8). - §3 Ситуативы — быстрое реагирование на инциденты (удаление/блокировка, сбои платежей/интеграций, модерация) через событийную шину и единый журнал; формирование решений. - §4 Админ-таксономия — единый журнал внутренних событий (от регистрации до ошибок). - §5–§6 Качество и безопасность — NFR-цели, пентест, нагрузка, масштабирование.
Дейтинг «По любви» — существующий прод (Python: Django+FastAPI, клиент Flutter, k8s в Yandex Cloud). Его бэкенд и есть dating-backend: мы его принимаем и достраиваем (общий identity, net-new фичи), а не переписываем; интеграция с events — через уже работающую Kafka.
1. ИНФРАСТРУКТУРА И ТЕХНОЛОГИЧЕСКИЙ СТЕК
Важная вводная: дейтинг «По любви» уже работает в проде на зрелом стеке (Python + k8s в Yandex Cloud). Поэтому стек мы не выбираем с нуля — наследуем существующее и достраиваем недостающее. Events — net-new; решение принято: строим его в том же стеке (Python — Django+FastAPI), чтобы переиспользовать инфраструктуру, CI и identity.
1.1 Реальная архитектура «По любви» (как есть, из репозиториев)
| Слой | Чем реализовано сейчас |
|---|---|
| Бэкенд (основной) | Django 4.2 + DRF + SimpleJWT (django-main-app): auth, профили, matching, survey/«Открывашки», cities, media. Ранжирование подбора — scikit-learn/numpy. Matching вынесен в отдельный деплой. Контент/админка — Wagtail. |
| Бэкенд (сервисы) | FastAPI: fastapi-chat-app (чат, WebSocket + aiokafka), fastapi-verification-app (фото-верификация) |
| Фоновые задачи | Dramatiq (брокер — Redis) + dramatiq-crontab |
| Данные | managed PostgreSQL (psycopg3), Redis + Redis Stack, Kafka (managed), S3 (Yandex Object Storage — медиа + бэкапы). Гео — geopy (расстояния/города, без PostGIS). |
| Контракты | контракт-фёрст: swagger (nikea-swagger, 14 доменов) → кодоген клиентов surfgen (Android/iOS/Flutter) |
| Клиент | Flutter (BLoC, dio/retrofit/fresh, drift-офлайн, in_app_purchase, geolocator, FCM-push, OTP-логин) |
| Платежи | нативные IAP (App Store / Google Play) + подписки |
| Аналитика/атрибуция | Firebase (analytics/crashlytics/messaging/remote-config) + AppMetrica + AppsFlyer (без ClickHouse) |
| DevOps | k8s (Yandex Cloud) + ArgoCD (GitOps) + Helm + Vault (секреты) + Terraform; образы — Surf Nexus (nexus.surfstudio.ru/nikea/*); бэкапы PG/Redis → S3-кронжобы; локалка — minikube |
Вывод: инфраструктура, шина (Kafka), хранилища, контракт-фёрст-пайплайн и DevOps-контур — уже есть и в РФ-облаке. Это меняет роадмап: первый шаг — не «строим инфру с нуля», а принимаем существующую (доступы, registry, CI, дампы БД).
1.2 Целевой стек — достраиваем поверх реальности
Для дейтинга стек наследуем. Для events-backend (net-new) решение принято — тот же стек (Python), чтобы переиспользовать инфру/CI/identity и не раскалывать команду. Отдельно — слои, которых сейчас нет и которые надо докупить/построить.
| Слой | Сейчас (dating) | Для events / net-new | Решение |
|---|---|---|---|
| Язык / бэкенд | Django+DRF, FastAPI | то же (Django — CRUD/админка, FastAPI — realtime) | наследуем |
| Контракты / клиент | swagger→surfgen, Flutter | то же | наследуем |
| Данные | PG + Redis + Kafka + S3 | те же managed-сервисы | наследуем |
| Шина событий | Kafka (есть) | Kafka для events↔dating | наследуем |
| Гео | geopy + lat/long | PostGIS для «события рядом» + GPS-радар (net-new для dating) | BUILD на managed PG |
| Identity / SSO | Django auth (phone OTP + JWT) | вынести в общий identity с единым user_id |
BUILD (на базе существующего) |
| Платежи | IAP + подписки | ЮKassa для events: билеты, эскроу/сплит, выплаты самозанятым, ФНС-чеки | BUY провайдер / BUILD домен |
| AI-модерация фото/чата | только фото-верификация | CV/text-модерация UGC (обязательна для сторов) | BUY + BUILD правила |
| Голосовой онбординг | — | Yandex SpeechKit (STT/TTS) + LLM на обезличенном тексте + текстовый фолбэк | BUY |
| Комплаентный скоринг | — | ЕСИА + ФССП-самопроверка + self-upload справок (без госбаз/скрейпинга) | BUY провайдеры / BUILD оркестрация |
| Реестр образов | Surf Nexus | перенести в cr.yandex заказчика |
миграция |
| Админка | Wagtail (контент) | единая админка-агрегатор над двумя бэками | BUILD |
1.3 Принципы
- РФ-локализация по умолчанию (152-ФЗ). ПДн, фото/голос (биометрия, отдельные согласия) — физически в РФ-облаке. Уже соблюдается: всё в Yandex Cloud.
- Наследуем стек, не переписываем. Единый Python-периметр (Django+FastAPI) + контракт-фёрст (swagger→surfgen) + Flutter — как у существующего дейтинга; events в том же стеке. Переписывать рабочий прод на другой язык — риск без выгоды.
- Переиспользуем существующую инфру. Kafka, PostgreSQL, Redis, S3, k8s/ArgoCD/Vault — уже в проде. Шина Kafka есть сейчас — это не «фаза V2».
- BUY для AI/инфраструктуры — BUILD для доменной логики и ПДн. Покупаем CV/text-модерацию, SpeechKit, LLM, ЕСИА/ФССП, ЮKassa; пишем сами identity, скоринг-оркестрацию, репутацию, эскроу, events-домен, integration layer.
- Net-new строим точечно — только то, чего в проде ещё нет (см. §1.2): events-домен, общий identity, GPS-радар, голосовой онбординг, скоринг, ЮKassa-эскроу, единая админка, AI-модерация.
1.4 Что покупаем (BUY) vs пишем сами (BUILD)
Уже есть — наследуем: Python-бэкенд (Django/FastAPI/Dramatiq), managed PG/Redis/Kafka/S3, k8s/ArgoCD/Helm/Vault/Terraform, swagger→surfgen, Flutter-клиент, IAP-платежи, Firebase/AppMetrica/AppsFlyer.
Покупаем (BUY) — net-new: CV/text-модерация (UGC для сторов), Yandex SpeechKit, LLM-API (обезличенный текст), ЕСИА/ФССП/KYC-провайдеры, ЮKassa + ФНС/НПД. Регулируемые внешние системы — пишем только обёртки/комплаенс вокруг.
Пишем сами (BUILD) — наш IP: общий identity/SSO (единый user_id на базе Django-auth), скоринг-оркестрация и тиры доверия, репутация, эскроу/сплит (events), events-домен (RSVP/waitlist/check-in/афиши), GPS-радар и голосовой онбординг (dating net-new), integration layer events↔dating, единая админка.
2. СПЕЦИФИКАЦИЯ + ТАЙМЛАЙН
2.1 Что строим (спецификация скоупа)
Два бизнесово раздельных продукта на общей платформе: Events («По душе» — офлайн-события) и Dating («По любви» — знакомства). У каждого — свой бэкенд со своей БД и доменом (независимый деплой, при необходимости разводятся), сверху — тонкий слой общих платформенных сервисов и integration layer для cross-app-связки. Над всем — 4 клиента и 1 общая админка-агрегатор.
Топология:
| Слой | Состав | Стек |
|---|---|---|
| Продуктовые бэки | dating-backend (существующий) + events-backend (net-new) — свои БД и домен |
Django+DRF / FastAPI, PostgreSQL, Redis, Kafka |
| Общие сервисы | identity/SSO, verification, notifications, media, moderation, payment-gateway | Python (Django/FastAPI), Kafka, S3 (Yandex Object Storage) |
| Integration layer | cross-API events↔dating + deep-link + кросс-статус на общем identity | Kafka + swagger/REST |
| Клиенты (mobile) | dating-mobile (есть), events-mobile (net-new) | Flutter (BLoC, dio/retrofit, surfgen) |
| Веб | лендинги/страницы событий для SEO (events) | Next.js (или Flutter Web) |
| Админка | 1 общая, агрегатор над двумя бэками (поверх Django/Wagtail-admin) | Django/Wagtail + кастом |
| Контракты | swagger (nikea-swagger) → surfgen-кодоген клиентов |
— |
Что шарим vs держим в продукте. Логика: общими делаем чистую инфраструктуру, регулируемое (152-ФЗ) и кросс-продуктовое; доменную логику и данные держим раздельно, чтобы продукты дёшево «развести».
| Концерн | Решение | Почему |
|---|---|---|
| Identity/SSO + Verification (ЕСИА/ФССП/селфи/KYC) | SHARED | линчпин интеграции (единый user_id); 152-ФЗ; «верифицирован в одном = в обоих» |
| Notifications (push/SMS/email) | SHARED | чистая инфра, дорого дважды |
| Media (фото/видео, РФ, биометрия) | SHARED | чистая инфра + 152-ФЗ (биометрия в РФ-контуре) |
| Analytics / атрибуция (Firebase/AppMetrica/AppsFlyer) | SHARED pipeline | кросс-продуктовая воронка; server-side события — общий стрим |
| Moderation (AI-движки + очередь) | SHARED, product-scoped | обязательна для сторов; модели дорогие — купить раз; правила per-product |
| Payment-gateway | SHARED только шлюз | dating: нативные IAP+подписки (как сейчас); events: ЮKassa (билеты, эскроу/сплит, выплаты, ФНС) — в своих бэках |
| Доменная логика, reputation | PER-PRODUCT | это и есть продукт; раздельные БД → дёшево развести |
| Growth / cross-sell | per-product; cross-sell через shared identity | кросс-промо завязан на единый профиль |
Интеграция events↔dating (сценарий)
Продукты раздельные, но внутри каждого — интеграция другого. Ключевой механизм: в Events пользователь ставит статус «открыт для знакомств», и это разворачивает расширенный функционал через cross-API к dating-backend:
- Подсветка статуса в events-профиле; на событии — «4 из 20 участников открыты для знакомств и подходят под твои критерии» (
events-backend→dating-backend: кто из этихuser_idоткрыт + matches). - Deep-link в «По любви» за полной анкетой / доп.фото / видеокружочками.
- Фильтры «показывать события/людей с таким же статусом»; рекомендации людей и событий учитывают флаг.
- Обратно:
dating-backend→events-backend— «встречал вживую» / общие посещённые события как сигнал для дейтинга.
Флаг «открыт для знакомств» и базовый кросс-профиль живут на shared identity (читают оба продукта); полная анкета — в dating-backend.
Как это ложится на реальный API «По любви»
Связь events↔dating — через общий identity + Kafka + swagger/REST (тот же контракт-фёрст, что в дейтинге). Сценарии выше опираются на уже существующие домены API «По любви»:
| Сценарий интеграции | Реальный API дейтинга | Направление |
|---|---|---|
| «Открыт для знакомств» (флаг) | хранится на shared identity, читают оба бэка | events ↔ dating |
| «4 из 20 открыты и подходят» | matching (фильтры/пересчёт) + profile/users (мини-карточка) |
events → dating |
| Переход за полной анкетой (deep-link) | profile (фото/видеокружочки) + survey («Открывашки») |
events → dating |
| Действие из контекста события | likes (лайк / супер-лайк / записка) + matching |
events → dating |
| «Встречал вживую» / общие события | сигнал в ранжирование matching |
dating → events |
| Сообщества ↔ категории событий | community (списки, вступление) |
dating ↔ events |
| Чат пост-событийных пар | chat (FastAPI WebSocket — переиспользуем, не дублируем) |
dating ↔ events |
Net-new под интеграцию (поверх существующего API): флаг «открытости» на identity, фильтр matching «по событию/участникам», пометка «met-IRL». Всё остальное — matching / likes / chat / community / profile / survey — переиспользуем как есть.
Продукт Events (events-backend). Платформа офлайн-событий: создание события, RSVP (мгновенно / по одобрению, waitlist), карта+список как главный экран, pre-event чат, geo-fenced check-in, post-event review, парсинг внешних афиш (Timepad/KudaGo) для cold-start.
- Создание события L1/L2, recurring-серии; RSVP-движок (capacity, waitlist, одобрения).
- Геопоиск (PostGIS), карта/список, geo-fenced check-in.
- Pre-event чат, post-event review, репутация явки; парсинг афиш (cold-start).
Продукт Dating (dating-backend). «По любви» (plbvi.ru) — существующее приложение знакомств для серьёзных отношений и семьи («знакомства для души»). Его бэкенд (Django+FastAPI) мы принимаем как dating-backend и достраиваем: подключаем к общему user_id, добавляем net-new фичи. Это не переписывание — перенос данных (дампы из S3 на целевой контур) + аккуратный strangler там, где выносим identity.
Текущие фичи «По любви» (переносим как есть):
- Селфи-верификация + строгая модерация — «только реальные люди», без фейков.
- «Открывашки» — ответы на вопросы-открытки для самопрезентации.
- «Видеокружочки» — короткие видео о себе.
- Лимит 8 лайков/день; «Записочки» — прямое сообщение тому, кто понравился.
- Reels от психологов об отношениях; тематические Сообщества.
Что добавляем поверх (новое):
- GPS-пересечения профилей (фоновый BLE-радар на iOS нереализуем — исключён).
- События в свайп-ленте + сигнал «пошёл бы / не интересно» (каталог из
events-backendпо API). - Голосовой онбординг — RU-каскад (Yandex SpeechKit + LLM на обезличенном тексте) + текстовый фолбэк.
- Комплаентный скоринг — ЕСИА + ФССП-самопроверка + self-upload справок (без госбаз судимостей, без скрейпинга соцсетей).
- AI-модерация фото и чата (обязательна для сторов).
2.2 Фазовый роадмап
Роадмап исходит из того, что дейтинг уже в проде: первые фазы — не «строим с нуля», а принимаем существующую систему и инфру, затем достраиваем net-new и строим events. Фазы — по зависимостям; клиент и интеграция идут внахлёст.
| Фаза | Длит. | Что шипается (результат) | Зависимости / риски |
|---|---|---|---|
| P0 — Доступы и приём проекта | 2–4 нед | Доступы: registry (Nexus→cr.yandex), CI (ветка ci-up), дампы БД (S3, выдаёт resource manager), legacy-данные. Параллельно — внешние процессы: KYC ЮKassa, аккаунты Apple/Google/RuStore, статус ИС в ЕСИА, юр.заключение по ПДн |
Доступы и внешние процессы не сжимаются — стартовать в неделю 1 |
| P1 — Принять инфру, поднять dating-backend | 2–4 нед | Существующий dating-backend (Django/FastAPI) развёрнут в целевом контуре: образы в cr.yandex, ArgoCD/Helm/Vault, прогон на стейдж-дампе, зелёный CI |
Зависит от P0; риск нестыковок секретов/конфигов Vault |
| P2 — Общий identity | 4–6 нед | Вынос Django-auth (phone OTP + JWT) в общий identity с единым user_id; cross-app SSO; контракт для events |
Затрагивает рабочий прод — strangler + обратная совместимость токенов |
| P3 — Net-new фичи dating | 6–8 нед | GPS-радар (geolocator уже в клиенте), голосовой онбординг (SpeechKit+LLM+фолбэк), скоринг (ЕСИА/ФССП/справки), AI-модерация (CV/text) | Новые внешние интеграции; голос/биометрия — отдельные согласия (152-ФЗ) |
| P4 — Events-backend (net-new) | 6–8 нед | events-backend в том же стеке: события L1/L2, RSVP/waitlist/capacity, гео (PostGIS), check-in, афиши (cold-start), эскроу/сплит на ЮKassa |
ЮKassa блокируется KYC из P0; парсинг афиш — отдельный риск |
| P5 — Events-клиент (Flutter) + веб | 5–7 нед (∥ P4) | events-mobile на Flutter (переиспользуем surfgen/компоненты), лендинги событий для SEO | Параллелится через контракт-фёрст; карты (Yandex MapKit) |
| P6 — Integration layer | 3–4 нед (∥ P5) | events↔dating через Kafka: статус «открыт для знакомств», «4 из 20», deep-link, cross-sell | Зависит от P2 (общий identity) + обоих доменов |
| P7 — Единая админка | 3–4 нед | Агрегатор над двумя бэками (поверх Django/Wagtail): модерация, пользователи, события, выплаты, жалобы, RBAC+аудит | Зависит от moderation/payments; нужна до публичного запуска events |
| P8 — Compliance / прод / сторы | 4–6 нед (∥) | Оператор ПДн в РКН, биометрия-согласия, security-hardening (OWASP), релиз events в App Store / Google Play / RuStore | Внешние блокеры ревью сторов/юр.процессов не сжимаются; 152-ФЗ |
Параллелизм. P5/P6 идут внахлёст с P4, compliance (P8) тянется процессно с P0 — реальный календарь короче суммы длительностей. Ключевое отличие от greenfield: P1–P3 опираются на готовый прод дейтинга, а не на стройку ядра с нуля. Внешние блокеры (KYC ЮKassa, ревью сторов, статус ИС в ЕСИА, доступ к дампам/legacy) ресурсами не сжимаются.
3. Обработка ситуативов: быстрое реагирование и решения
Ситуатив — любое значимое событие или инцидент в системе: от удаления/блокировки аккаунта до сбоя платежа, застрявших в эскроу денег, жалобы или падения внешней интеграции. Цель — не расписать один сценарий до винтика, а иметь единый механизм: быстро поймать → быстро отработать → сформировать решение (авто или человеком).
3.1 Единый механизм
- Каждый продукт/сервис публикует событие в шину (Kafka, уже в проде) с общим
correlation_id. - Заинтересованные сервисы реагируют идемпотентно (отмена, возврат, уведомление, скрытие, отзыв доступа).
- Всё стекается в единый журнал админки (§4) с темой / severity / тегами — оператор видит ситуатив и формирует решение в одном экране; критичное (
critical) уходит в алерт. - Принцип UX: пользователю никогда не показываем 500/битый экран — ситуатив деградирует в понятное состояние.
3.2 Каталог типовых ситуативов
| Ситуатив | Как ловим | Быстрая отработка (авто) | Где решение |
|---|---|---|---|
| Удаление / блокировка аккаунта | событие account.* от identity |
отзыв сессий, скрытие из ленты/поиска, стоп выплат, удаление медиа | админка (см. §3.3) |
| Сбой платежа / фискализации ФНС | payment.*.failed |
ретрай, статус «в обработке», сам платёж не трогаем | алерт Finance + админка |
| Деньги застряли в эскроу (бан организатора) | бан + активное платное событие | заморозка выплаты, сага возврата/переназначения | админка (ручное подтверждение) |
| Жалоба / AI-флаг модерации | moderation.* |
авто-скрытие явного, очередь для borderline | очередь модерации |
| Фейк / антифрод | antifraud.* |
шадоу-бан, капча, блок устройства | антифрод-раздел |
| Сбой внешней интеграции (афиши/ЕСИА/SpeechKit/ЮKassa) | *.integration.failed |
ретрай/деградация, фолбэк (напр. текстовый онбординг) | алерт On-call |
| Всплеск ошибок / деградация | рост error-rate / latency | автоскейл, circuit breaker | алерт On-call, инцидент-режим |
Любой ситуатив — это та же связка «событие → идемпотентная реакция → запись в журнал → решение». Новый добавляется как новая тема/правило, а не как отдельная подсистема.
3.3 Пример: удаление и блокировка аккаунта
Самый «сквозной» ситуатив — показывает механику целиком. Identity-сервис (источник истины аккаунта) публикует account.blocked / account.deleted; оба продуктовых бэка и общие сервисы реагируют идемпотентно:
- identity — мгновенный отзыв сессий/токенов; media — удаление фото/видео/биометрии; events/dating — скрытие из ленты/поиска, отмена будущих RSVP, разрыв матчей; payments — заморозка выплат, сага по эскроу; analytics — анонимизация (агрегаты сохраняем); admin/audit — след сохраняем всегда.
- Режимы: блокировка (временно, другим видно «аккаунт недоступен») vs удаление (soft-delete с окном отмены ~30 дней → purge) vs анонимизация.
- Тяжёлый кейс: деньги в эскроу при бане организатора с предстоящим платным событием — сага: вернуть гостям / переназначить хост, не «потеряв» деньги.
- Ретеншн: платёжные/ФНС/аудит-данные храним по закону даже после удаления (152-ФЗ: право на удаление vs обязательное хранение).
Все шаги каскада — обычные события в том же журнале (§4), развёрнутые по correlation_id: видно, что отработало штатно.
4. АДМИНКА: таксономия внутренних событий (теги/темы) — от новой регистрации до ошибок
4.0 Назначение и принцип
Команда оперирует двумя продуктами на общей платформе. Если каждый модуль (общие сервисы, events-backend, dating-backend) ведёт свой журнал, оператор поддержки, модератор, антифрод и дежурный инженер смотрят в разные места и не видят причинно-следственных связей. Поэтому в админке заводится единый фид внутренних системных событий — один поток, в котором появляется всё: регистрация, верификация, модерация, платежи, события/дейтинг, гео, рост, комплаенс и ошибки. Каждое событие классифицируется по теме (бизнес-домен) и severity (важность), помечается тегами (пересекающиеся срезы) и связывается с цепочкой через correlation_id.
Бизнес-смысл для CPO:
- Один экран на всю систему → поддержка/модерация/антифрод не переключаются между инструментами, время реакции на инцидент падает.
- Тема ≠ severity ≠ тег — три независимых оси фильтрации. Тема отвечает на «что за домен», severity — «насколько срочно», тег — «по какому срезу искать» (например biometric, pii, fraud, money). Это даёт точные дашборды и алерты без раздувания числа типов.
- RBAC встроен в таксономию: payload с ПДн/биометрией виден не всем (152-ФЗ), а сам факт доступа к чувствительному событию логируется как событие (compliance.audit.access).
- Переиспользование, а не новый код: фид строится поверх уже работающей шины (Kafka) и логов/аналитики — отдельная подсистема логирования не нужна.
4.1 Каталог тем (групп) событий
Severity — фиксированная шкала из 4 уровней: info (норма, для аудита/аналитики), warning (требует внимания, не блокирует), error (сбой операции/нарушение правила), critical (угроза деньгам/данным/доступности — порождает алерт).
RBAC-роли: Support-L1 (Support Specialist), Moderator (Support 1-я линия модерации/Community Manager), Antifraud, Finance (payment-focused BE/финоператор), Compliance/DPO (ответственный за ПДн, оператор РКН), Engineer/On-call (Backend/DevOps), Admin (PM/Founder — полный доступ). Принцип least-privilege: чувствительный payload (биометрия, ПДн, платёжные реквизиты) маскируется для ролей, которым он не нужен.
Темы ↦ реальные сервисы-источники.
- Auth, Profile, Matching, Likes, Survey, Community, Referral, Cities → django-main-app (Django/DRF; ранжирование подбора — scikit-learn).
- Chat → fastapi-chat-app (FastAPI/WebSocket + Kafka). Verification (селфи) → fastapi-verification-app.
- Payments: dating — нативные IAP/подписки (payment/subscription); events — ЮKassa (net-new).
- Events-домен, GPS-радар, голосовой онбординг, ЕСИА/ФССП-скоринг, AI-модерация — net-new сервисы.
- Фоновое (нотификации, обработка видео, ретеншн) → Dramatiq-воркеры.
Auth / Registration
| Тема | Примеры событий (type) |
Severity | Теги | Кто видит | Действия из админки |
|---|---|---|---|---|---|
| Auth/Registration | auth.user.registered (новая рега) |
info | auth, signup, funnel |
Support-L1, Antifraud, Admin | Открыть профиль, привязать к correlation-цепочке |
| Auth/Registration | auth.verification.selfie.passed/failed |
info / warning | auth, verification, biometric, pii |
Moderator, Compliance, Admin | Запросить переснять, эскалация на ручную проверку |
| Auth/Registration | auth.verification.document.passed/failed |
info / warning | auth, verification, pii |
Moderator, Compliance, Admin | Ручная верификация, отклонить |
| Auth/Registration | auth.verification.esia.linked/failed (net-new) |
info / error | auth, verification, esia, pii |
Compliance, Admin | Повторить привязку, пометить как «личность подтверждена» |
| Auth/Registration | auth.login.success |
info | auth, session |
Support-L1, Antifraud | Открыть сессии пользователя |
| Auth/Registration | auth.otp.requested / auth.otp.verified (вход по телефону + OTP) |
info | auth, otp, session |
Support-L1, Antifraud | Разлогинить все сессии, посмотреть попытки OTP |
| Auth/Registration | auth.login.suspicious (новый девайс/гео/невозможная поездка) |
warning | auth, security, antifraud, geo |
Antifraud, Security, Admin | Принудительный 2FA, заморозить сессию, эскалация в Security |
Profile / Media
| Тема | Примеры событий | Severity | Теги | Кто видит | Действия |
|---|---|---|---|---|---|
| Profile/Media | media.photo.uploaded |
info | media, profile |
Support-L1, Moderator | Открыть медиа (с правом просмотра) |
| Profile/Media | media.photo.autoflag (AI-модерация: 18+/насилие/чужое лицо) |
warning | media, moderation, ai, nsfw |
Moderator, Admin | Скрыть фото, отправить в очередь ручной модерации, бан |
| Profile/Media | profile.field.flagged (запрещённый текст в био) |
warning | profile, moderation, ai |
Moderator | Очистить поле, предупреждение пользователю |
Moderation
| Тема | Примеры событий | Severity | Теги | Кто видит | Действия |
|---|---|---|---|---|---|
| Moderation | moderation.complaint.created (жалоба) |
warning | moderation, report, ugc |
Moderator, Support-L1, Admin | Взять в работу, объединить дубликаты |
| Moderation | moderation.ai.flag (флаг чата/контента) |
warning | moderation, ai, chat |
Moderator | Открыть контекст, эскалировать |
| Moderation | moderation.decision.made (решение модератора) |
info | moderation, decision, audit |
Moderator, Compliance, Admin | Просмотр обоснования, апелляция |
| Moderation | moderation.user.banned (бан) |
error | moderation, ban, account, audit |
Moderator, Admin | Разбан, посмотреть каскад (см. §4.4) |
| Moderation | account.blocked / account.deleted (каскад из раздела 3) |
error / critical | moderation, compliance, account, cascade, audit |
Compliance, Admin | Просмотр каскада блокировок/удалений, выгрузка аудита |
Payments
| Тема | Примеры событий | Severity | Теги | Кто видит | Действия |
|---|---|---|---|---|---|
| Payments | payment.iap.succeeded (подписка dating — App Store/Google Play) · payment.yookassa.succeeded (events — net-new) |
info | payments, money, iap, yookassa |
Finance, Support-L1, Admin | Открыть транзакцию/подписку |
| Payments | payment.escrow.held (удержание эскроу) |
info | payments, money, escrow |
Finance, Admin | Просмотр статуса удержания |
| Payments | payment.payout.sent (выплата организатору) |
info | payments, money, payout |
Finance, Admin | Повторить выплату, открыть получателя |
| Payments | payment.refund.processed (возврат) |
info | payments, money, refund |
Finance, Support-L1 | Инициировать/подтвердить возврат |
| Payments | payment.chargeback.received (чарджбек) |
error | payments, money, chargeback, antifraud |
Finance, Antifraud, Admin | Открыть спор, заморозить выплаты по юзеру |
| Payments | payment.provider.error (ошибка ЮKassa) |
error | payments, money, integration, yookassa |
Finance, Engineer, Admin | Ретрай, ручная сверка |
| Payments | payment.fns.receipt.failed (фискализация ФНС/54-ФЗ) |
critical | payments, money, integration, fns, compliance |
Finance, Compliance, On-call | Повторить фискализацию, эскалация (риск 54-ФЗ) |
Events (events-backend)
| Тема | Примеры событий | Severity | Теги | Кто видит | Действия |
|---|---|---|---|---|---|
| Events | events.event.created |
info | events, ugc |
Support-L1, Moderator | Открыть событие, предмодерация |
| Events | events.rsvp.created |
info | events, funnel |
Support-L1 | Открыть участника |
| Events | events.checkin.done (чек-ин на месте) |
info | events, geo, attendance |
Support-L1 | Просмотр гео-подтверждения |
| Events | events.event.cancelled (отмена) |
warning | events, refund-trigger |
Support-L1, Finance | Запустить массовый возврат, уведомить участников |
| Events | events.parser.import.ok/failed (парсер-импорт афиш) |
info / error | events, integration, parser |
Engineer, Admin | Перезапустить импорт, открыть лог источника |
Dating (dating-backend)
| Тема | Примеры событий | Severity | Теги | Кто видит | Действия |
|---|---|---|---|---|---|
| Dating | dating.like.sent / superlike.sent / note.sent (записка) |
info | dating, like |
Support-L1 | Открыть пользователя (ПДн маскируются) |
| Dating | dating.match.created (матч) |
info | dating, match |
Support-L1 | Открыть пару (с маскированием ПДн) |
| Dating | dating.chat.message.sent (чат — FastAPI/Kafka) |
info | dating, chat |
Support-L1, Moderator | Открыть тред по жалобе, эскалация в модерацию |
| Dating | dating.community.joined/left (Сообщества) |
info | dating, community |
Support-L1 | Открыть сообщество и участников |
| Dating | dating.survey.prompt.answered («Открывашки») |
info | dating, survey |
Support-L1 | — |
| Dating | dating.subscription.changed (подписка/IAP) |
info | dating, payments, iap |
Finance, Support-L1 | Открыть подписку, статус IAP |
| Dating | dating.user.reported (репорт) |
warning | dating, moderation, report |
Moderator, Antifraud | Взять в модерацию, заблокировать переписку |
Geo
| Тема | Примеры событий | Severity | Теги | Кто видит | Действия |
|---|---|---|---|---|---|
| Geo | geo.crossing.detected (GPS-пересечение) |
info | geo, dating, match |
Support-L1 | Просмотр пересечения (агрегированно) |
| Geo | geo.location.fake (подмена/спуфинг локации) |
warning | geo, antifraud, security |
Antifraud, Admin | Сбросить гео-доверие, пометить юзера |
Growth / Referrals
| Тема | Примеры событий | Severity | Теги | Кто видит | Действия |
|---|---|---|---|---|---|
| Growth/Referrals | growth.invite.sent (инвайт) |
info | growth, referral |
Growth, Admin | Открыть реферальную цепочку |
| Growth/Referrals | growth.points.granted (начисление баллов) |
info | growth, referral, rewards |
Growth, Finance | Откатить начисление |
| Growth/Referrals | growth.promo.fraud (фрод промокодов) |
warning | growth, antifraud, fraud, money |
Antifraud, Finance, Admin | Деактивировать промокод, отозвать баллы |
Compliance
| Тема | Примеры событий | Severity | Теги | Кто видит | Действия |
|---|---|---|---|---|---|
| Compliance | compliance.consent.granted/revoked (согласие на ПДн/биометрию) |
info | compliance, pii, consent, audit |
Compliance, Admin | Просмотр версии согласия, история |
| Compliance | compliance.dsr.export.requested (запрос экспорта данных, 152-ФЗ) |
warning | compliance, pii, dsr, audit |
Compliance, Admin | Сформировать выгрузку, отметить срок |
| Compliance | compliance.dsr.delete.requested (запрос удаления) |
warning | compliance, pii, dsr, cascade, audit |
Compliance, Admin | Запустить каскадное удаление (см. §4.4) |
| Compliance | compliance.audit.access (доступ оператора к ПДн/биометрии) |
info | compliance, pii, audit, rbac |
Compliance, Admin | Просмотр кто/что/когда смотрел |
System / Errors
| Тема | Примеры событий | Severity | Теги | Кто видит | Действия |
|---|---|---|---|---|---|
| System/Errors | system.exception.unhandled (необработанное исключение) |
error | system, error, backend |
Engineer, On-call, Admin | Открыть стек, перейти в Grafana/Loki по correlation_id |
| System/Errors | system.integration.failed (фейл: SpeechKit/FCM/AppMetrica/ЮKassa/ЕСИА/Maps) |
error | system, integration, error |
Engineer, On-call | Ретрай, открыть статус провайдера |
| System/Errors | system.queue.backlog (переполнение очереди/ретраи шины) |
warning | system, queue, kafka |
Engineer, On-call | Открыть лаг консьюмера, масштабировать |
| System/Errors | system.service.degraded (деградация: рост latency/error-rate) |
critical | system, availability, slo |
On-call, Admin | Алерт, открыть дашборд SLO, инцидент-режим |
Security / Antifraud
| Тема | Примеры событий | Severity | Теги | Кто видит | Действия |
|---|---|---|---|---|---|
| Security/Antifraud | security.bruteforce.detected (массовые попытки входа/OTP) |
warning | security, antifraud, auth |
Antifraud, On-call | Включить rate-limit/блок IP, форс-2FA |
| Security/Antifraud | antifraud.bot.detected (поведение бота/масс-регистрация) |
warning | security, antifraud, bot, signup |
Antifraud, Admin | Шадоу-бан, капча, блок устройства |
| Security/Antifraud | security.account.banned (бан антифродом) |
error | security, antifraud, ban, account |
Antifraud, Admin | Разбан, просмотр причин и связанных аккаунтов |
| Security/Antifraud | security.data.breach.suspected (подозрение на утечку ПДн) |
critical | security, pii, breach, compliance |
Compliance, On-call, Admin | Инцидент-режим, уведомление РКН (72 ч по 152-ФЗ) |
4.2 Модель данных и источник
Единая структура события (event / audit-log)
{
"id": "evt_01J9...", // ULID, монотонный, сортируемый по времени
"ts": "2026-06-25T10:31:02.581Z",
"theme": "Payments", // тема из каталога §4.1 (enum)
"type": "payment.fns.receipt.failed", // <module>.<entity>.<action>
"severity": "critical", // info | warning | error | critical
"actor": { // кто инициировал
"kind": "user|operator|system|integration",
"id": "usr_4821", "role": null
},
"target": { // на кого/что направлено
"kind": "user|event|payment|profile|...",
"id": "pay_99213"
},
"tags": ["payments","money","integration","fns","compliance"],
"payload": { /* доменные поля; ПДн/биометрия — отдельный класс, маскируется по RBAC */ },
"correlation_id": "corr_5f1c...", // сквозной id цепочки бизнес-операции
"source": "dating.fastapi-chat", // сервис: dating.django-main | dating.fastapi-chat | dating.fastapi-verification | events-backend | shared.identity | dramatiq
"pii_class": "biometric|pii|none" // класс чувствительности → правило маскирования и хранения
}
Соглашения, чтобы таксономия оставалась управляемой:
- type = <module>.<entity>.<action> — иерархичен, новые типы добавляются без миграций, фильтр по префиксу (payment.*) работает из коробки.
- theme — закрытый enum, привязан к модулю-владельцу. Темы стабильны, типы растут.
- tags[] — открытый, но из словаря (pii, biometric, money, fraud, audit, cascade, integration, …). Один тег пересекает темы: money ловит и Payments, и Growth-фрод; pii — и Auth, и Compliance. Это даёт срезы, недоступные через тему.
- pii_class управляет двумя вещами: маскированием payload в UI (RBAC) и политикой хранения (см. ниже).
Источники и хранение
| Слой | Источник | Хранилище | Зачем |
|---|---|---|---|
| Доменные события | Событийная шина Kafka (уже в проде) — модули публикуют доменные события | Аналитическая витрина (Postgres-агрегаты + Loki для логов; ClickHouse — опционально при росте объёма) | Запросы и агрегаты по теме/тегу/времени |
| Технические события | Структурные логи приложений (JSON) → коллектор (Vector/Loki-pipeline) → нормализация в ту же схему | Та же витрина (Postgres/Loki) | Единый формат с доменными событиями, общий фид |
| Критичный аудит | Те же события с severity=critical и/или тегом audit/compliance/money/pii |
Durable-хранилище: PostgreSQL (append-only, WORM-семантика) + бэкап | Юридически значимый аудит (152-ФЗ, 54-ФЗ): неизменяемость, длительное хранение, доказуемость |
Принцип: витрина — для объёма и аналитики, durable-стор — для доказуемости. Критичные события пишутся в оба (dual-write через шину). Хранение по классам: none/pii info-события — короткий TTL в аналитической витрине; audit/compliance/money — длительное durable-хранение по требованиям регуляторов; биометрические payload не дублируются в фид — событие хранит только факт и ссылку, сами биоданные лежат в защищённом хранилище с отдельным согласием.
correlation_id присваивается в точке входа (регистрация, открытие платежа, создание события) и протягивается через шину по всей цепочке. Именно он связывает «рега → верификация → платёж → ошибка» в один трейс и соединяет фид с логами/метриками в Grafana/Loki (уже в инфре; distributed tracing OTel/Tempo — по мере внедрения).
4.3 UX админки
Лента (основной экран). Реверс-хронологический поток событий. Каждая строка: время · цветной бейдж severity · тема · type · actor → target · теги-чипы · кнопка drill-down. Цветовой код severity: info — нейтральный, warning — янтарный, error — красный, critical — красный с пульсацией + значок алерта.
Фильтры (комбинируются, сохраняются в URL).
| Фильтр | Значения | Сценарий |
|---|---|---|
| Тема | мультиселект из каталога §4.1 | «покажи только Payments + Moderation» |
| Severity | info / warning / error / critical | дежурный смотрит только error+critical |
| Пользователь | actor.id / target.id / телефон / email |
поддержка разбирает жалобу на конкретного юзера |
| Время | пресеты + произвольный диапазон | «последний час», «во время инцидента 03:00–03:40» |
| Тег | мультиселект из словаря | антифрод: всё с fraud; DPO: всё с pii |
correlation_id |
точный ввод/из drill-down | развернуть цепочку одной операции |
| Источник/модуль | общие сервисы, events-backend, dating-backend |
изоляция продукта |
Drill-down в событие. Полная карточка: вся структура §4.2, развёрнутый payload (с маскированием по RBAC), кнопки действий из §4.1 (контекстно по теме), ссылки на профиль/транзакцию/событие и переход в Grafana/Loki по correlation_id.
Drill-down в цепочку (по correlation_id). Таймлайн-вид: все события одной бизнес-операции в хронологии, с переходами между темами и подсветкой, где цепочка «сломалась» (первый error/critical). Это ключевой инструмент разбора инцидентов — видно весь путь от регистрации до сбоя.
Сохранённые фильтры (saved views). Преднастроенные ленты под роли, чтобы не собирать фильтр заново:
- Дежурный инженер: severity ≥ error, темы System/Errors + Payments-integration.
- Антифрод: тег fraud/antifraud/bot + Security/Antifraud + Geo-fake.
- DPO/Compliance: тег pii/consent/dsr/audit + темы Compliance/Moderation-каскад.
- Финансы: тема Payments + тег money.
- Модерация: Moderation + Profile-autoflag + Dating-report.
Алерты на critical. Любое severity=critical (фискализация ФНС, деградация сервиса, подозрение на утечку, чарджбек-шторм) → мгновенный алерт в Telegram (дежурный чат) и на почту ответственной роли, с дедупликацией и группировкой, чтобы один инцидент не породил сотню сообщений. Алерты конфигурируются по комбинации тема+severity+тег.
Дашборды по темам. Поверх аналитической витрины: динамика событий по темам, доля error/critical, воронка Auth/Registration (рега → селфи → документ → ЕСИА), здоровье платежей (success-rate ЮKassa, фейлы ФНС), очередь модерации, лаги консьюмеров шины. Дашборды и лента используют одни и те же оси (тема/severity/тег) — то, что видно агрегатом, разворачивается в конкретные события одним кликом.
4.4 Связь с разделом 3 (каскад блокировки/удаления)
События жизненного цикла аккаунта из раздела 3 — не отдельный механизм, а часть этого же фида. Когда срабатывает account.blocked или account.deleted и запускается каскад (отмена будущих RSVP/событий, разрыв матчей, остановка выплат, удаление медиа, отзыв согласий), каждый шаг каскада публикуется в шину как обычное событие с общим correlation_id блокировки/удаления:
| Событие каскада | Тема | Severity | Ключевые теги |
|---|---|---|---|
account.blocked |
Moderation | error | account, cascade, audit |
account.deleted |
Compliance | critical | account, pii, cascade, dsr, audit |
events.rsvp.cancelled (каскад) |
Events | info | cascade, refund-trigger |
dating.match.broken (каскад) |
Dating | info | cascade |
payment.payout.frozen (каскад) |
Payments | warning | cascade, money |
media.purged (каскад) |
Profile/Media | info | cascade, pii |
compliance.consent.revoked (каскад) |
Compliance | info | cascade, pii, consent, audit |
В админке оператор открывает событие account.deleted, разворачивает по correlation_id — и видит весь каскад: что именно было удалено/отменено, в каком порядке, без ошибок ли. Для DPO это готовое доказательство исполнения требования по удалению ПДн (152-ФЗ): единый журнал = единый источник правды, не нужно собирать подтверждения из разных модулей.
4.5 Сквозной пример: жизненный цикл в ленте
Один пользователь, одна цепочка correlation_id=corr_5f1c. Как это выглядит в фиде (новый → старый порядок показан сверху вниз по времени):
| # | ts | Тема | type |
Severity | Теги | actor → target | Что произошло |
|---|---|---|---|---|---|---|---|
| 1 | 10:00:01 | Auth/Registration | auth.user.registered |
info | auth, signup, funnel |
usr_4821 → usr_4821 | Новая регистрация |
| 2 | 10:01:14 | Compliance | compliance.consent.granted |
info | compliance, pii, biometric, consent, audit |
usr_4821 | Согласие на ПДн + биометрию (селфи) |
| 3 | 10:01:40 | Auth/Registration | auth.verification.selfie.passed |
info | auth, verification, biometric, pii |
system → usr_4821 | Селфи-верификация пройдена |
| 4 | 10:02:55 | Auth/Registration | auth.verification.esia.linked |
info | auth, verification, esia, pii |
usr_4821 | Личность подтверждена через ЕСИА |
| 5 | 10:20:33 | Payments | payment.succeeded |
info | payments, money, yookassa |
usr_4821 → pay_99213 | Первый платёж (билет на событие) через ЮKassa |
| 6 | 11:42:09 | Moderation | moderation.complaint.created |
warning | moderation, report, ugc |
usr_7777 → usr_4821 | На пользователя поступила жалоба |
| 7 | 12:05:50 | Moderation | moderation.decision.made |
info | moderation, decision, audit |
op_mod_3 → usr_4821 | Модератор: предупреждение (бана нет) |
| 8 | 12:06:02 | System/Errors | payment.fns.receipt.failed |
critical | payments, money, integration, fns, compliance |
integration → pay_99213 | (опц.) Ошибка фискализации чека ФНС по платежу из шага 5 → алерт в Telegram + Finance/Compliance |
Как это читается командой:
- Поддержка фильтрует по target.id=usr_4821 и видит всю историю человека в одной ленте — от реги до жалобы.
- DPO по тегу pii/consent и шагам 2–4 доказывает, что биометрия собрана с согласием (152-ФЗ).
- Модератор по теме Moderation (шаги 6–7) разбирает жалобу с полным контекстом.
- Финансы/дежурный получают алерт по шагу 8 (critical), открывают цепочку по corr_5f1c и сразу видят, что упала именно фискализация уже успешного платежа — ретраят чек, не трогая сам платёж.
- Всё это — одна цепочка corr_5f1c, развёрнутая в drill-down как таймлайн: видно, что система отработала штатно, а сбой — только на последней внешней интеграции.
Источник истины по реальному стеку дейтинга — репозитории nikea-backend, nikea-swagger, nikea-backend-infra (Django/FastAPI, swagger→surfgen, k8s/ArgoCD/Vault).
5. Нефункциональные требования и качество (NFR)
5.1 Целевые показатели качества
| Метрика | Цель MVP | Цель stable | Как меряем / обеспечиваем |
|---|---|---|---|
| Crash-free sessions (мобайл) | > 98% | ≥ 99% | Firebase Crashlytics + AppMetrica (уже в приложении); релиз-гейт — не катим при регрессе |
| API latency p95 / p99 | < 800 мс / < 1.5 с | < 500 мс / < 1 с | Prometheus + Grafana (уже в инфре), алерт на деградацию (§4); tracing (OTel/Tempo) — добавить |
| Холодный старт приложения | < 2.5 с | < 2 с | RUM, perf-профайлинг релиза |
| Веб (LCP / TTI) | LCP < 2.5 с | < 2 с | Lighthouse CI + RUM; SSR Next.js |
| Uptime | 99.5% | 99.9% | health/ready-пробы, managed-БД; мульти-AZ — апгрейд под 99.9% (сейчас PG/Redis/Kafka single-AZ) |
| RPO / RTO | 1 ч / 4 ч | ниже | бэкапы уже есть (PG/Redis → S3 cronjobs), managed-БД (PITR), отработка восстановления |
Crash-free и latency — релиз-гейты: сборка не уходит в прод/стор, если показатели хуже порога.
5.2 Покрытие устройств и версий (цель ≥ 80%)
- iOS: три последних мажорных версии (ориентир iOS 16–18), минимум iOS 15 (deployment target в проекте 12–15) → ~95%+ активных устройств.
- Android: minSdk 28 (Android 9.0) — как в приложении сейчас (compileSdk 36 / targetSdk 35) → ≥ 80% активных устройств РФ. Пуш сейчас — FCM + AppMetrica; RuStore (дистрибуция) и Huawei/HMS — отдельно учесть/добавить (в коде их пока нет), иначе теряем долю РФ-рынка.
- Матрица версий фиксируется и пересматривается ежеквартально по статистике установок.
5.3 Клиент: Flutter (как сейчас) → нативные модули точечно
- База: Flutter — как у существующего «По любви»; один стек на обе апки (events/dating) и переиспользование наработок дейтинга; перф-чувствительные куски (карты/гео, камера/верификация) — точечно нативными модулями (platform channels).
- Триггер перехода на натив: после релиза stable MVP и подтверждения PMF, если упираемся в производительность/нативные возможности (плавность свайп-ленты, карта/гео, анимации, фоновые сценарии).
- Подход — постепенный (brownfield), не big-bang: сначала самые перф-чувствительные экраны (лента, карта, чат), при необходимости — полная нативная переписка одной из апок. Снижает риск против «переписать всё сразу».
- Только по метрикам: полная нативная переписка — заметные доп.затраты и время → делаем лишь при доказанной необходимости по §5.1, а не по умолчанию.
6. Безопасность и DevOps-гейты
6.1 Тестирование безопасности
- Пентест: внешний — обязательный gate перед публичным релизом, далее раз в 6–12 мес и после крупных изменений. Охват: мобайл (OWASP MASVS), API, инфра, флоу ПДн/платежей.
- В CI постоянно: SAST (код), SCA (зависимости/CVE), DAST (по стейджу), секрет-сканер — добавляем в существующий пайплайн (сейчас CI — Jenkins PR/TAG-джобы + ruff-линт).
- Bug-bounty — опционально после релиза.
6.2 Нагрузочное и стресс-тестирование
- Нагрузочные тесты (k6 / Locust / Gatling) — net-new, добавляем (сейчас в проде их нет): перед релизом и пиками, целевой RPS с запасом, проверка автоскейла, soak-тесты на утечки/деградацию.
- Часть CI/CD-гейтов перед прод-деплоем; результаты питают capacity planning.
6.3 Динамическое (полуавто) масштабирование
- K8s HPA (CPU/RPS/кастомные метрики) + Cluster Autoscaler (ноды). Managed-кластер в Yandex есть, но cluster-autoscaler сейчас выключен, а HPA — настроить. «Полуавто» = включаем автоскейл по метрикам + ручной контроль порогов и capacity planning по §6.2.
6.4 ТГ-боты (верификация и аналитика/алерты)
- Бот верификации: быстрый low-friction канал подтверждения личности/ускоренной верификации (Telegram/MAX-bot link в онбординге), интеграция с identity/verification.
- Бот аналитики/алертов: дежурные алерты
critical(§4), быстрые метрики/отчёты для команды. - 152-ФЗ: в ботов не уходят ПДн — только id-ссылки, метрики, severity, correlation_id (согласовано с §4.3).
6.5 Предиктивные белые списки + «рубильник» сертификатов
Единый контур безопасности, оба аспекта:
- Антифрод-allowlist'ы (юзеры/устройства): предиктивные списки доверенных (поведение, репутация, верификация) — снижают трение для «хороших» и фокусируют антифрод/модерацию на рисковых; риск-скоринг устройств/аккаунтов отдаёт сигнал в moderation/growth.
- Инфра/доступы: IP-allowlist на админку и служебные эндпоинты; отзыв клиентских сертификатов / ключей / токенов API.
- Cert kill-switch (мобайл): certificate pinning (net-new в Flutter-клиенте) с удалённым отзывом/ротацией пина через remote-config (Firebase Remote Config — уже в приложении, §1) — при компрометации/плановой смене сертификата апки не «кирпичатся» и не ждут релиза в сторе. Закладываем remote pin-set + аварийный bypass.
- Все срабатывания — события темы Security в админ-фиде (§4); механика kill-switch — поверх Firebase Remote Config (§1).