Техническое руководство по архитектуре avanX

v1.0 (Стадия: Ранняя Разработка) Бэкенд: NestJS Фронтенд: Next.js

Важное примечание: На текущий момент проект находится в состоянии активной ранней разработки: выполнено порядка 50 процентов работы до стадии минимального жизнеспособного продукта (MVP). Данный документ описывает как локальную конфигурацию разработки (As-Is), так и целевую архитектуру MVP (To-Be в Yandex Cloud) с контейнеризацией через Docker.

1. Концепция C4 Model в проекте

Архитектура avanX документируется с использованием методологии C4. Это позволяет структурировать техническое описание на различных уровнях абстракции, избегая хаотичного смешения деталей реализации и общего контекста.

2. Виртуализация, контейнеризация и оркестрация

При развертывании avanX применяются различные подходы к изоляции вычислений. Это разделение важно для понимания логики работы тестовых и промышленных сред.

2.1 Виртуализация

Создание изолированных виртуальных серверов с собственной операционной системой на базе одного физического оборудования. В Yandex Cloud это виртуальные машины Compute Cloud (VM), на которых разворачивается тестовая среда.

2.2 Контейнеризация

Упаковка приложений и их зависимостей в легкие Docker-образы. В отличие от тяжелых виртуальных машин, контейнеры делят ядро хост-системы, запускаются мгновенно и требуют минимум ресурсов. Dockerfile в проекте используется для сборки NestJS API.

2.3 Оркестрация в Kubernetes (K8s)

Автоматизированное управление жизненным циклом контейнеров в распределенном кластере. Kubernetes обеспечивает автоматическое горизонтальное масштабирование (HPA), проверку работоспособности подов (Liveness/Readiness Probes), самовосстановление и внутреннюю балансировку трафика.

3. Логические компоненты системы (System Landscape)

Платформа состоит из гибридной сети компонентов, распределенных по разным облачным инфраструктурам для оптимизации стоимости и отказоустойчивости:

4. Тестовый и промышленный деплой

Развертывание платформы разделено на две конфигурации:

4.1 Локальная среда разработки (Local Dev)

Контур предназначен для высокоскоростной параллельной разработки фронтенда и бэкенда силами одного инженера. Приложения запускаются локально в режиме горячей перезагрузки (Hot-reload) напрямую в операционной системе, что гарантирует максимальную отзывчивость и скорость отладки. В контейнерах Docker Compose (файл docker-compose.dev.yml) поднимаются исключительно хранилища данных (PostgreSQL, Redis, MinIO S3), что освобождает от избыточной виртуализации самих сервисов при постоянном написании кода. Данная конфигурация является основной вплоть до создания первых пред-MVP и MVP сборок. Одновременно с этим на локальном этапе осуществляются все необходимые приготовления к оркестрации (написание Dockerfile, конфигурации переменных и сред) для последующего бесшовного деплоя в Kubernetes (k8s).

4.2 Целевая архитектура MVP (Target MVP: To-Be в Yandex Cloud)

Для продуктива Next.js деплоится на платформу Vercel с автоматическим кэшированием статики. Для обхода потенциальных блокировок Vercel в РФ на виртуальной машине Yandex Compute Cloud (или через CDN) разворачивается защитный прокси-сервер Nginx, который проксирует запросы с домена avanx.com на Vercel. Бэкенд NestJS API упаковывается в Docker и деплоится в Yandex Managed Kubernetes (или на виртуальную машину через Docker Compose). Базы данных разворачиваются как Managed Services с высокой доступностью: Managed PostgreSQL с pgBouncer (порт 6432) и Managed Redis Cluster (порт 6380 c TLS).

5. База данных и оптимизация индексов

База данных PostgreSQL спроектирована под высокие нагрузки. Для исключения медленного сканирования таблиц (Full Table Scan) в схему Prisma заложены критичные индексы:

// Поиск лотов по игре, типу и статусу
@@index([gameId, type, status])

// Оптимизация динамических характеристик товаров
@@unique([listingId, attributeId])
@@index([attributeId, value])

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

6. Интерактивная схема и связи таблиц СУБД (ERD)

Для предотвращения избыточного дублирования со Swagger и обеспечения максимальной наглядности, вся детальная схема структуры хранения данных PostgreSQL, её связи, индексы и типы полей перенесены в интерактивном формате на дашборд.

Интерактивный ERD-дашборд включает:

Открыть интерактивную схему БД (ERD)

7. Транзакционная логика Escrow (Сценарий покупки)

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

  1. Покупатель нажимает кнопку Купить лот на Next.js фронтенде.
  2. Next.js отправляет POST запрос на бэкенд NestJS API через Nginx Ingress.
  3. NestJS открывает базу данных и проверяет статус лота: он должен быть ACTIVE.
  4. Создается запись Order со статусом PENDING и признаком escrowHeld: false. Лот переходит в статус PAUSED, блокируя повторную покупку другими пользователями.
  5. API бэкенда делает запрос к шлюзу Cryptomus/ЮKassa для генерации инвойса, получает ссылку на оплату payUrl и возвращает ее клиенту.
  6. Пользователь переходит по ссылке и производит оплату.
  7. Шлюз оплат обрабатывает транзакцию и присылает зашифрованный асинхронный Webhook на Ingress, который форвардит его в API бэкенда.
  8. NestJS бэкенд выполняет атомарную транзакцию СУБД: обновляет статус заказа на PAID, устанавливает признак escrowHeld: true и логирует финансовую проводку типа ESCROW_HOLD.
  9. NestJS публикует событие OrderPaid в шину Redis.
  10. Подписчики в Redis реагируют на событие: NotificationHandler шлет Telegram Push продавцу с призывом передать товар, а ChatHandler создает системный защищенный чат сделки.
  11. Продавец передает товар (или автодоставка отправляет логин/пароль из deliveryData) и нажимает кнопку Я передал товар. Заказ переходит в статус DELIVERED.
  12. Покупатель проверяет товар и нажимает кнопку Подтвердить получение.
  13. NestJS запускает финальную атомарную Prisma-транзакцию распределения средств:
    • Обновляет статус заказа на COMPLETED, сбрасывает флаг escrowHeld.
    • Начисляет 95 процентов от суммы заказа на баланс продавца.
    • Начисляет 5 процентов комиссии на баланс платформы.
    • Создает запись финансовой проводки типа ESCROW_RELEASE.
  14. Продавец получает Telegram Push о зачислении средств. Сделка считается успешно завершенной.

8. Паттерн Saga и компенсирующие действия споров

Для обработки сбоев и сетевых задержек в распределенном окружении применяется паттерн Saga. Ниже приведено детальное пошаговое описание компенсирующих действий при сбое или открытии спора:

8.1 Таймаут ожидания оплаты (Сбой на этапе шлюза)

Если покупатель не оплатил инвойс в течение 15 минут, планировщик Bull Queue в Redis автоматически вызывает задачу отмены. NestJS переводит заказ в статус CANCELLED, а заблокированный лот возвращает обратно в статус ACTIVE для продажи.

8.2 Спор и Арбитраж (Refund Saga)

Если продавец не передал товар или передал неверные данные, покупатель открывает спор, переводя заказ в статус DISPUTED. Процесс арбитража и возврата выглядит следующим образом:

  1. Покупатель нажимает Открыть Спор. NestJS API создает запись Dispute в статусе OPEN.
  2. Система делает иммутабельный снимок (Snapshot) описания лота и всей переписки в чате сделки на данный момент, защищая данные от удаления.
  3. Если за 24 часа стороны не договорились, спор переходит в статус ESCALATED, и за его разбор берется Арбитр (SUPPORT).
  4. Арбитр проверяет чеклист, прикрепленные медиа-доказательства DisputeEvidence и выносит вердикт в пользу покупателя.
  5. Арбитр нажимает кнопку Resolve as Refund. Бэкенд NestJS API мгновенно запускает компенсирующую ACID-транзакцию в PostgreSQL:
    • Обновляет статус спора на RESOLVED, а тип решения на REFUND.
    • Снимает признак удержания средств escrowHeld: false и меняет статус заказа на REFUNDED.
    • Возвращает заблокированную сумму заказа в полном объеме на баланс покупателя.
    • Начисляет продавцу предупреждение (warningCount увеличивается на 1).
    • Создает финансовую лог-транзакцию типа REFUND.
  6. NestJS отправляет событие в Redis EventBus.
  7. Bull-воркеры рассылают Telegram-уведомления обеим сторонам. Покупатель видит возврат средств на баланс, продавец получает уведомление о штрафе.
  8. Бэкенд проверяет счетчик предупреждений продавца. Если warningCount >= 5, NestJS атомарно блокирует его учетную запись (устанавливает isBanned: true) и удаляет все связанные сессии авторизации из базы данных.

9. Консистентность данных (Transactional Outbox)

Для исключения потери событий в распределенной среде при падении серверов или недоступности шины Redis в бэкенд внедрен паттерн Transactional Outbox. Все критичные действия фиксируются в базе данных в рамках той же ACID-транзакции:

10. Архитектура мультикасс (Payment Provider Strategy)

Для гибкого подключения различных способов оплаты (банковские карты, СБП, зарубежные переводы, криптовалюта) спроектирована расширяемая архитектура на основе паттернов Стратегия (Strategy) и Фабрика (Factory):

11. Многоразовые объявления и контроль остатков

Для поддержки продажи товаров разного типа (одноразовые аккаунты, многоразовая игровая валюта, многоразовые услуги) в платформу внедрена гибкая логика контроля количества лотов:

12. Диаграммы критических флоу и интерактивный симулятор

Для обеспечения максимальной наглядности и полного погружения в транзакционную логику платформы avanX все ключевые Sequence-диаграммы перенесены на наш **Интерактивный дашборд архитектуры**.

Вместо статичных схем вы можете запустить интерактивный симулятор потоков трафика непосредственно в браузере и пошагово наблюдать за прохождением данных, активацией контейнеров бэкенда NestJS API, ACID-транзакциями базы данных PostgreSQL и обменом через шину Redis.

Доступные интерактивные сценарии на дашборде:


Открыть Интерактивный Дашборд Архитектуры