Хватит рисовать интеграции в Miro: я сделал архитектуру, которую можно прокликать

от автора

Всем привет!

В один прекрасный и немного скучный рабочий день понадобилось описать перевод по СБП по-настоящему: с лимитами, антифродом, идемпотентностью, внешним вызовом в НСПК и уведомлением.

Обычно, чтобы это сделать происходит следующее:

  1. Созвон на восемь плюс человек. Платежка, антифродеры, каналы, интеграции и безопасность — каждый знает свой кусок и примерно догадывается, а иногда и первый раз слышит про соседний.

  2. Miro: стикеры, прямоугольники, стрелки и подписи «тут вроде через этот сервис», «вроде этот метод».

  3. Кто-то в итоге пишет sequence-диаграмму (plantUml, mermaid) на несколько десятков сообщений.

  4. Диаграмма уезжает в Confluence. Её открывают, скроллят вбок и закрывают.

  5. Через месяц все дружно забывают схему, а часть шагов уже не соответствует системе.

И ведь проблема не только в устаревании. Картинка плохо отвечает на вопросы. Нельзя кликнуть по antifraud-engine и проверить его контракт. Нельзя пройти только ветку BLOCK. Сложно понять, почему участник вдруг появился в середине сценария.

Sequence-диаграмма — хороший способ показать согласованный сценарий, но не лучший инструмент, чтобы этот сценарий собирать и проверять.

Поток как данные, а не как рисунок

Viaduct — редактор архитектуры на основе C4-модели: системы, контейнеры, компоненты и код. Рядом с элементами модели хранятся документация, HTTP-контракты, каналы брокеров и sequence-диаграммы.

В нем есть такой функционал, как Magic Flow, который добавляет поверх этой модели исполняемый маршрут:

Поток — это последовательность ссылок на уже существующие элементы архитектуры и их контракты.

Обычный шаг описывает отправителя, получателя, назначение хопа и связанные с ним методы (Rest, gRPC), топики и связи модели.

Менеджер Magic Flow

Менеджер Magic Flow

В менеджере слева находятся потоки проекта, по центру — их шаги, справа — свойства выбранного хопа. На демо-модели цифрового банка сейчас пять сценариев:

  • перевод по СБП;

  • оплата картой в магазине;

  • онбординг и подтверждение личности;

  • заявка на кредит и скоринг;

  • регуляторная отчётность за сутки.

Как собирается Magic Flow

Сначала задаём имя и цель сценария. Затем добавляем шаги и для каждого выбираем From и To из C4-модели. Если на хопе используется конкретный контракт, привязываем endpoint или channel.

Настройка шагов Magic Flow

Настройка шагов Magic Flow

Например, шаг «Создание перевода» связывает BFF каналов с payment-orchestrator. К нему прикреплён POST /api/v1/transfers, а в описании зафиксирована семантика повторного вызова: один Idempotency-Key не создаёт два перевода.

Шаг с привязанным endpoint

Шаг с привязанным endpoint

Сам 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, участники берутся из модели, а эндпоинты и топики попадают в подписи сообщений.

PlantUML и preview перевода по СБП

PlantUML и preview перевода по СБП

В демо у payment-orchestrator хранится диаграмма «Перевод по СБП» с ветками превышения лимита, ALLOW/CHALLENGE/BLOCK, ответами НСПК и компенсацией резерва.

Для меня принципиальна не отмена диаграмм, а смена источника правды:

Сначала структурированный поток, который можно проверить и воспроизвести. Затем диаграмма для коммуникации.

В просмотрщике диаграмм можно сворачивать group/alt элементы, чтобы диаграмма читалась проще и лишние блоки можно было убирать с фокуса.

Как это ложится на работу команд

  1. Архитектор или Системный аналитик собирает скелет по крупным участникам.

  2. Команды уточняют свои хопы и привязывают реальные endpoints и topics.

  3. На ревью сценарий проходят в плеере и проверяют ветки, таймауты и внезапно возникающих участников.

  4. Общие части выносят в самостоятельные flows и связывают.

  5. Для документов и тикетов генерируют sequence-диаграмму.

Вместо созвона «давайте я расскажу, как это работает» новый участник получает маршрут, который можно пройти руками.

Демо-проект находится в Viaduct. После входа откройте у системы «Цифровой банк» список Magic Flow и запустите «Перевод по СБП».

Если попробуете пройти сценарий предметно, интересно, на каком шаге вы первым делом зададите вопрос автору модели.

Ссылка на Viaduct.

ссылка на оригинал статьи https://habr.com/ru/articles/1078792/