Всем привет!
В один прекрасный и немного скучный рабочий день понадобилось описать перевод по СБП по-настоящему: с лимитами, антифродом, идемпотентностью, внешним вызовом в НСПК и уведомлением.
Обычно, чтобы это сделать происходит следующее:
-
Созвон на восемь плюс человек. Платежка, антифродеры, каналы, интеграции и безопасность — каждый знает свой кусок и примерно догадывается, а иногда и первый раз слышит про соседний.
-
Miro: стикеры, прямоугольники, стрелки и подписи «тут вроде через этот сервис», «вроде этот метод».
-
Кто-то в итоге пишет sequence-диаграмму (plantUml, mermaid) на несколько десятков сообщений.
-
Диаграмма уезжает в Confluence. Её открывают, скроллят вбок и закрывают.
-
Через месяц все дружно забывают схему, а часть шагов уже не соответствует системе.
И ведь проблема не только в устаревании. Картинка плохо отвечает на вопросы. Нельзя кликнуть по antifraud-engine и проверить его контракт. Нельзя пройти только ветку BLOCK. Сложно понять, почему участник вдруг появился в середине сценария.
Sequence-диаграмма — хороший способ показать согласованный сценарий, но не лучший инструмент, чтобы этот сценарий собирать и проверять.
Поток как данные, а не как рисунок
Viaduct — редактор архитектуры на основе C4-модели: системы, контейнеры, компоненты и код. Рядом с элементами модели хранятся документация, HTTP-контракты, каналы брокеров и sequence-диаграммы.
В нем есть такой функционал, как Magic Flow, который добавляет поверх этой модели исполняемый маршрут:
Поток — это последовательность ссылок на уже существующие элементы архитектуры и их контракты.
Обычный шаг описывает отправителя, получателя, назначение хопа и связанные с ним методы (Rest, gRPC), топики и связи модели.
В менеджере слева находятся потоки проекта, по центру — их шаги, справа — свойства выбранного хопа. На демо-модели цифрового банка сейчас пять сценариев:
-
перевод по СБП;
-
оплата картой в магазине;
-
онбординг и подтверждение личности;
-
заявка на кредит и скоринг;
-
регуляторная отчётность за сутки.
Как собирается Magic Flow
Сначала задаём имя и цель сценария. Затем добавляем шаги и для каждого выбираем From и To из C4-модели. Если на хопе используется конкретный контракт, привязываем endpoint или channel.
Например, шаг «Создание перевода» связывает BFF каналов с payment-orchestrator. К нему прикреплён POST /api/v1/transfers, а в описании зафиксирована семантика повторного вызова: один Idempotency-Key не создаёт два перевода.
Сам HTTP-контракт хранится на payment-orchestrator:
Headers Idempotency-Key: string (обязателен) Authorization: Bearer jwtRequest { «amount»: 1500.00, «currency»: «RUB», «payeePhone»: «+79001234567», «payeeBankId»: «100000000111», «message»: «За обед» }Response 201 {«transferId»: «8f21c0», «status»: «PENDING»} 402 {«code»: «LIMIT_EXCEEDED», «dailyLimit»: 300000} 409 {«code»: «IDEMPOTENCY_CONFLICT»} 422 {«code»: «FRAUD_BLOCKED», «challenge»: «PUSH_CONFIRM»}
В потоке видно, на каком хопе этот контракт применяется. Полную схему запроса и ответов можно открыть на самом сервисе. Это важное разделение: flow отвечает на вопрос «где используется контракт», а карточка сервиса — «что именно в контракте».
Живой пример: перевод по СБП
В редакторе сценарий содержит 13 шагов:
1. Клиент банка → Мобильное приложение Клиент вводит сумму и телефон2. Мобильное приложение → API Gateway Запрос уходит через периметр3. API Gateway → BFF каналов Шлюз передаёт в BFF4. BFF каналов → payment-orchestrator Создание перевода POST /api/v1/transfers5. payment-orchestrator → limits-service Проверка лимитов6. payment-orchestrator → antifraud-engine Оценка риска POST /api/v1/risk/evaluate7a. antifraud-engine → payment-orchestrator ALLOW7b. antifraud-engine → push-service CHALLENGE7c. antifraud-engine → BFF каналов BLOCK8. payment-orchestrator → sbp-adapter Резерв и отправка в СБП9. sbp-adapter → API СБП Регистрация перевода POST /v1/transfer/register10. payment-orchestrator → kafka Публикация финального статуса payments.transfer.completed.v111. notification-service → push-service Уведомление клиенту
7a, 7b и 7c не выполняются последовательно. Это одна стадия с тремя альтернативными ветками.
Для антифрода условия взяты из контракта и документации сервиса:
-
ALLOW, еслиscore < 0.5; -
CHALLENGE, если0.5 ≤ score < 0.95; -
BLOCK, еслиscore ≥ 0.95или получатель находится в чёрном списке.
У вызова POST /api/v1/risk/evaluate есть бюджет 150 мс. При таймауте вызывающий применяет ALLOW и пишет TIMEOUT_BYPASS в алерты. У проверки лимитов бюджет 100 мс, у внешнего вызова в НСПК — 5 секунд. Когда хопы находятся рядом, latency budget хотя бы можно посчитать глазами.
Плеер: проходим интеграцию шаг за шагом
Поток можно запустить с элемента модели, к которому он привязан. Плеер переводит фокус между уровнями C4, подсвечивает участников и показывает описание хопа и прикреплённый контракт.
На седьмой позиции кнопка Next заблокирована, пока читатель не выберет одну из веток:
Можно пройти ALLOW, вернуться назад и отдельно посмотреть CHALLENGE или BLOCK. Поток при этом остаётся одним сценарием, а не тремя почти одинаковыми диаграммами.
Один и тот же flow может быть доступен с разных участников. Точка входа зависит от контекста: например, «Оплата картой в магазине» с карточного процессинга запускается сразу с шестой позиции, а не заставляет повторно проходить уже известную внешнюю часть.
Для повторно используемых сценариев в менеджере есть шаг Link to another flow. Так длинный процесс можно разложить на поддерживаемые части: «подтверждение личности», «оценка риска», «проведение платежа».
Sequence-диаграмма остаётся, но становится производной
Sequence-диаграммы всё ещё нужны для ADR, ревью и тикетов. Magic Flow умеет сгенерировать или перегенерировать PlantUML из маршрута. Альтернативные стадии превращаются в alt/else, участники берутся из модели, а эндпоинты и топики попадают в подписи сообщений.
В демо у payment-orchestrator хранится диаграмма «Перевод по СБП» с ветками превышения лимита, ALLOW/CHALLENGE/BLOCK, ответами НСПК и компенсацией резерва.
Для меня принципиальна не отмена диаграмм, а смена источника правды:
Сначала структурированный поток, который можно проверить и воспроизвести. Затем диаграмма для коммуникации.
В просмотрщике диаграмм можно сворачивать group/alt элементы, чтобы диаграмма читалась проще и лишние блоки можно было убирать с фокуса.
Как это ложится на работу команд
-
Архитектор или Системный аналитик собирает скелет по крупным участникам.
-
Команды уточняют свои хопы и привязывают реальные endpoints и topics.
-
На ревью сценарий проходят в плеере и проверяют ветки, таймауты и внезапно возникающих участников.
-
Общие части выносят в самостоятельные flows и связывают.
-
Для документов и тикетов генерируют sequence-диаграмму.
Вместо созвона «давайте я расскажу, как это работает» новый участник получает маршрут, который можно пройти руками.
Демо-проект находится в Viaduct. После входа откройте у системы «Цифровой банк» список Magic Flow и запустите «Перевод по СБП».
Если попробуете пройти сценарий предметно, интересно, на каком шаге вы первым делом зададите вопрос автору модели.
Ссылка на Viaduct.
ссылка на оригинал статьи https://habr.com/ru/articles/1078792/