PandaPay - платёжная платформа для QR-оплаты

  • финтех
  • разработка бэкенда
  • QR-оплата
PandaPay

О проекте

PandaPay - финтех-платформа для бесконтактной оплаты по QR-коду, встроенная в экосистему мессенджера MAX. Покупатель открывает клиентский Mini App прямо в мессенджере, показывает QR-код кассиру - кассовая система сканирует его и инициирует списание. Средства списываются через банк-эквайер, бонусы начисляются автоматически, уведомление приходит в реальном времени. Весь сценарий от сканирования до подтверждения занимает несколько секунд.

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

Задачи

Контекст и задачи проекта

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

  • спроектировать архитектуру системы с нуля и задокументировать её до начала реализации;
  • разработать бэкенд, покрывающий три аудитории одновременно - покупателей, мерчантов, кассовые системы;
  • реализовать нетривиальные механики: оплата в offline-режиме без интернета, real-time уведомления, каскадный fallback при отказе банка, система лояльности с бонусными баллами;
  • создать API-контракт и типизированный shared-пакет так, чтобы внешняя команда, ведущая Merchant Dashboard, могла стартовать параллельно без блокеров;
  • выстроить инфраструктуру: Docker Compose, Nginx, CI/CD, деплой на Ubuntu VPS.

Описание кейса

Мы начали с проектирования по методологии C4 - структурированного подхода к документированию архитектуры программных систем на четырёх уровнях детализации.

System Context (уровень 1)

На первом уровне мы определили всех внешних акторов системы и типы взаимодействий:

  • Покупатель - работает через клиентский Mini App в WebView мессенджера MAX, подключается по HTTPS и WebSocket;
  • Мерчант - управляет бизнесом через отдельный Merchant Dashboard в браузере;
  • Кассир - работает в интерфейсе внешней кассовой системы (POS), которая взаимодействует с платформой по REST;
  • Команда платформы - мониторинг через Admin API и Bull-board;
  • MAX - мессенджер, в WebView которого живёт клиентский Mini App; интеграция через MAX Bridge API, SSO, Bot API и Channel API;
  • Банк-эквайер - двусторонняя интеграция: HTTPS REST для charge/refund и HTTPS Webhook для колбеков о результате транзакции;
  • Кассовые системы (POS) - инициируют платежи через POS API, получают результат через webhook или long polling.

Containers (уровень 2)

На втором уровне мы декомпозировали систему на развёртываемые контейнеры:

  • Backend API (NestJS) - единый модульный монолит, обслуживающий все аудитории: Client API, Merchant API, POS API, Webhook API, Admin API и WebSocket Gateway;
  • PostgreSQL 16 - основное хранилище с ACID-гарантиями для всех финансовых операций;
  • Redis 7 - кэш, очереди Bull, rate limiting, session storage, WebSocket adapter для горизонтального масштабирования;
  • Mini App (React) - клиентский SPA в WebView MAX, только для покупателей;
  • Merchant Dashboard (React) - отдельный SPA в браузере, разрабатывается внешней командой на основе нашего API-контракта.

Components (уровень 3)

Третий уровень - детальное проектирование внутренней структуры NestJS-монолита: границы модулей, их ответственности, направления зависимостей, типы взаимодействий (синхронные HTTP, асинхронные очереди, события).

Что дало проектирование

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

  • стартовать разработку Merchant Dashboard параллельно силами внешней команды без блокеров;
  • согласовать 13 спорных архитектурных решений с клиентом до написания кода;
  • зафиксировать все расхождения между исходной спецификацией и финальными архитектурными решениями в явном виде;
  • обеспечить единый язык между командами через shared-пакет @pandapay/shared с TypeScript-типами и Zod-схемами.

Выбор архитектурного стиля: модульный монолит

Для MVP мы выбрали модульный монолит вместо микросервисов. Это осознанное и обоснованное решение:

Скорость разработки. Микросервисная архитектура добавляет значительный оверхед: управление межсервисным транспортом, service discovery, распределённые транзакции, separate deployments. Для MVP эти затраты не окупаются.

Чистые границы без сетевых издержек. Модульный монолит с правильно спроектированными границами даёт все преимущества изоляции бизнес-логики без накладных расходов на сетевое взаимодействие. Каждый модуль - self-contained единица с чёткой зоной ответственности.

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

Бэкенд: архитектура модулей

Auth Module

Модуль аутентификации обслуживает все четыре контекста с изолированными guards:

  • ClientAuthGuard - JWT Bearer для покупателей, полученный через SSO с MAX;
  • MerchantAuthGuard - JWT Bearer для мерчантов, выпускаемый по email/password;
  • PosApiKeyGuard - API-key аутентификация для кассовых систем (X-API-Key);
  • AdminAuthGuard - отдельный Bearer-токен из environment variables для команды платформы.

MVP использует mock-SSO для MAX для ускорения разработки. В production - WebAppData HMAC-SHA256 валидация с BOT_TOKEN, которая подтверждает, что запрос действительно пришёл из MAX. JWT access token живёт 15 минут, refresh token - 30 дней. Реализован reuse detection для refresh tokens: при повторном использовании одного refresh token вся семья токенов инвалидируется.

Авторизация мерчантов построена на классическом email/password с argon2id для хранения паролей. Новый мерчант регистрируется через публичный эндпоинт и получает статус PENDING - активацию производит команда платформы через Admin API. Это даёт контроль над онбордингом и фильтрует мусорные регистрации.

Payment Module

Ядро системы. Payment Module реализует оркестрацию всего платёжного цикла:

  1. Приём команды от POS API (POST /v1/pos/payments/init);
  2. Создание платежа в PostgreSQL и установка expires_at;
  3. Переход в состояние AWAITING_CONFIRM и push checkout-события клиенту через WebSocket;
  4. Обработка подтверждения от клиента и отправка charge в банк;
  5. Приём webhook от банка и переход в финальное состояние;
  6. Асинхронный запуск side effects: уведомление POS, начисление бонусов, уведомление в MAX.

Идемпотентность реализована на всех платёжных эндпоинтах. Для POS init используется составной уникальный ключ (pos_id, idempotency_key) - кассовая система генерирует его сама (UUID или составной ключ типа order-123-attempt-1). При повторном запросе с тем же ключом возвращается 409 с данными существующего платежа.

Каскадный fallback: если основной метод оплаты отклонён банком, и у пользователя настроен резервный метод, и пользователь явно разрешил cascade_payment_enabled - создаётся вторая попытка (PAYMENT_ATTEMPT.kind = FALLBACK). Решение о fallback принадлежит пользователю, не мерчанту.

Auto-confirm: пользователь может настроить автоматическое подтверждение платежей без интерактивного confirm до определённого лимита суммы (auto_confirm_limit, default 500 ₽). Это ускоряет оплату для малых сумм.

QR Module

Модуль управляет двумя режимами генерации QR-кодов:

Online QR (session token). Бэкенд генерирует случайный session token и сохраняет в Redis qr:session:{token} со структурой {user_id, payment_method_id} и TTL 40 секунд. Mini App обновляет QR каждые ~35 секунд. Если пользователь меняет метод оплаты - PATCH /v1/client/qr/source обновляет payment_method_id в Redis без перегенерации самого QR-кода.

Offline QR (signed token pack). Пользователь запрашивает пакет из 20 самодостаточных HMAC-подписанных токенов с TTL 15 минут. Бэкенд не хранит неиспользованные токены в Redis - они полностью самодостаточны. Redis задействован только для replay protection: атомарный SET qr:used:{token} 1 NX EX <ttl>. При валидации проверяются подпись, TTL, device binding и отсутствие токена в qr:used:*. Это чистая signed-model без гибридной stateful/stateless сложности.

Loyalty Module

Система лояльности работает как side effect успешного платежа:

  • cashback_percent - процент от суммы транзакции, настраивается мерчантом (например, 5.00% или 12.50%);
  • welcome_bonus - приветственный бонус при первой покупке у конкретного мерчанта;
  • балансы по мерчантам - бонусы у каждого мерчанта учитываются отдельно;
  • списание перед деньгами - при оплате сначала списываются бонусы, затем денежные средства;
  • отмена при возврате - при успешном refund начисленные бонусы сторнируются, ранее списанные - возвращаются.

Начисление бонусов выполняется асинхронно через Bull-очередь loyalty-accrual, не блокируя основной платёжный flow.

Merchant Module

Полный цикл работы мерчанта:

  • Онбординг - регистрация с юридическими данными (ИНН, расчётный счёт, БИК, наименование);
  • Управление точками продаж - CRUD POS с уникальными API-ключами для каждой кассы;
  • POS API-ключи - один активный ключ на POS, plaintext выдаётся один раз, в базе хранится только bcrypt-хэш; при выпуске нового ключа предыдущий автоматически отзывается;
  • Настройки лояльности - cashback_percent, welcome_bonus, опциональный MAX-канал;
  • Статические QR для печати - генерация PDF с QR-кодами для размещения в точках продаж.

В MVP реализована только роль OWNER. Схема данных и RBAC (OWNER/MANAGER/ACCOUNTANT/CASHIER) заложены в Prisma-модель заранее, чтобы при post-MVP расширении не делать breaking migration.

Transaction Module

Read-модель для истории операций:

  • для покупателей - лента покупок с фильтрацией по периоду (today/7d/30d/1y/all), агрегаты по сумме и количеству;
  • для мерчантов - реестр транзакций с фильтрацией, пагинацией, поиском;
  • детализация чека, ссылка на ОФД;
  • инициирование возврата с передачей управления в Payment Module.

Bank Adapter

Абстракция над API конкретного банка-эквайера. Три метода: charge(token, amount), refund(tx_id), tokenize(redirect_url). Такая абстракция изолирует бизнес-логику от деталей конкретного эквайера - смена банка или подключение второго не требует изменений в Payment Module.

Входящие webhooks от банка проходят через inbox-таблицу BANK_WEBHOOK_EVENT с дедупликацией по provider_event_id. Подпись каждого webhook проверяется HMAC-SHA256 с использованием BANK_API_WEBHOOK_SECRET. Если подпись невалидна - событие сохраняется в inbox с signature_valid=false и не обрабатывается.

MAX Adapter

Интеграция с мессенджером MAX:

  • MVP: mock-SSO для ускорения разработки и ранней интеграции с командой Mini App;
  • Production: валидация initData (WebAppData) через HMAC-SHA256 с BOT_TOKEN, извлечение user_id, имени и языка пользователя;
  • Bot API: отправка чека от имени бота мерчанта в чат покупателя после успешной оплаты;
  • Channel API: подписка пользователя на канал мерчанта.

POS Adapter

Интерфейс для кассовых систем:

  • POST /v1/pos/payments/init - инициация платежа с суммой и idempotency_key;
  • GET /v1/pos/payments/{id}/status - long polling для получения результата;
  • Webhook: push-уведомление на зарегистрированный URL кассы при изменении статуса.

Кассовая система сама выбирает режим получения результата: long polling подходит для простых интеграций, webhook - для production-систем с обработкой событий.

Admin Module

Инструменты для команды платформы:

  • Bull-board UI (/admin/queues) - визуальная панель управления очередями: просмотр pending/active/failed задач, ручной retry зависших jobs;
  • Health-check - статус PostgreSQL, Redis и Bull-очередей;
  • Мониторинг платежей - активные платежи, зависшие (>5 мин в PROCESSING), агрегаты по суммам и конверсии;
  • Управление мерчантами - активация (PENDING → ACTIVE), приостановка (ACTIVE → SUSPENDED), отклонение заявок (PENDING → REJECTED);
  • Метрики - Redis keys по паттернам, количество WebSocket-соединений, rate limit counters.

Admin-контур полностью изолирован от client/merchant auth: отдельный AdminAuthGuard с Bearer-токеном из env.

Конечный автомат платежа

Одним из центральных архитектурных артефактов стала формальная машина состояний платежа. PAYMENT.status в PostgreSQL - единственный источник истины.

Состояния

СостояниеСмысл
CREATEDПлатёж создан кассой, checkout ещё не открыт клиенту
AWAITING_CONFIRMПокупатель видит экран подтверждения
PROCESSINGCharge отправлен в банк, ожидаем webhook
SUCCESSСписание успешно, возможен refund
FAILEDПопытка отклонена, оценивается fallback
FAILED_FINALПлатёж окончательно отклонён
CANCELLEDПокупатель отменил до отправки в банк
EXPIREDИстёк TTL без подтверждения
REFUND_PENDINGВозврат отправлен в банк
REFUNDEDВозврат успешно завершён
REFUND_FAILEDБанк отклонил возврат

FAILED - не финальный статус, а развилка: если разрешён fallback и есть активный резервный метод, создаётся вторая PAYMENT_ATTEMPT(kind=FALLBACK) и платёж уходит обратно в PROCESSING. В MVP максимум два PAYMENT_ATTEMPT на один платёж.

Финальный исход charge и refund определяется bank webhook, а не синхронным HTTP-ответом банка. Это принципиально: синхронный ответ может быть timeout или недостоверным в случае сетевых проблем - webhook приходит, когда банк реально завершил операцию.

Все переходы состояний записываются в append-only таблицу PAYMENT_EVENT с информацией о триггере, акторе и контексте. Это полный audit trail для каждого платежа.

Recovery flow

Ключевой UX-проблемой в платёжных системах является разрыв соединения в момент оплаты. Если покупатель свернул Mini App или потерял интернет во время AWAITING_CONFIRM, платёж не должен зависнуть.

Решение: при создании checkout бэкенд записывает payment:pending:{user_id} в Redis (TTL 300 сек). При повторном открытии Mini App клиент всегда проверяет GET /v1/client/payments/pending и восстанавливает активный экран. Redis хранит только read-модель для UX - источником истины остаётся PostgreSQL.

WebSocket - основной канал доставки checkout-события. GET /v1/client/payments/pending - канонический fallback при потере соединения или переоткрытии Mini App.

Модель данных

Ключевые сущности

USER - покупатель Mini App. Хранит настройки: show_qr_on_open (показывать QR при открытии), cascade_payment_enabled (разрешить fallback на резервный метод), auto_confirm_enabled и auto_confirm_limit (автоподтверждение платежей до лимита).

PAYMENT_METHOD - привязанный способ оплаты: СБП или карта. PAN/CVC не хранятся никогда - только token_ref как ссылка на токен у банка/провайдера. Soft delete для отвязки методов.

MERCHANT - мерчант с юридическими данными (inn, settlement_account, bik), настройками лояльности (cashback_percent, welcome_bonus) и статусом (PENDING/ACTIVE/SUSPENDED/REJECTED). Пароль хранится как argon2id hash.

POS / POS_API_KEY - точка продаж и её API-ключи. В базе хранится только bcrypt-хэш ключа; история отозванных ключей сохраняется для audit.

PAYMENT - главный агрегат с status, суммой, ссылками на payment_method_id и fallback_payment_method_id, idempotency_key, временными метками и bank_tx_id.

PAYMENT_ATTEMPT - отдельная попытка списания (kind: PRIMARY/FALLBACK) с provider_tx_id, decline_code и временными метками.

PAYMENT_EVENT - append-only журнал всех переходов состояний. Каждая запись фиксирует from_status, to_status, тип события, актора и payload.

LOYALTY_ACCOUNT / LOYALTY_TRANSACTION - ledger-модель для бонусных балансов в разрезе по мерчантам.

BANK_WEBHOOK_EVENT - inbox для входящих событий банка с provider_event_id для дедупликации.

Принципы проектирования схемы

  • Все денежные суммы - DECIMAL(12,2), а не FLOAT. Floating point неприемлем для финансов.
  • Cascade payment и прочие настройки пользователя - поля USER, а не MERCHANT: это выбор пользователя, не бизнес-конфигурация мерчанта.
  • Mutable fields с updated_at, immutable events в PAYMENT_EVENT - чёткое разделение мутабельного состояния и неизменяемого журнала.
  • Soft delete везде, где нужна история: методы оплаты, сотрудники, API-ключи.

Безопасность: модель токенов и ключей

Система работает с несколькими классами криптографических материалов:

QR Session Token - случайная строка в Redis, TTL 40 сек. Не содержит ничего секретного, но однозначно идентифицирует пользователя и его метод оплаты в момент сканирования.

Offline HMAC Token - самодостаточный подписанный токен для бесинтернетной оплаты. Содержит user_id, payment_method_id, device_id, exp, нунс. Подписывается HMAC-SHA256 на серверном секрете. Бэкенд не хранит токен - только проверяет подпись и наличие в replay protection set Redis.

JWT Access/Refresh - стандартная JWT-пара, access TTL 15 мин / refresh TTL 30 дней. Refresh token rotation с reuse detection: повторное использование одного refresh token приводит к инвалидации всей семьи.

POS API Key - секрет для кассовых систем. plaintext выдаётся один раз при создании, в базе хранится bcrypt(cost=10). При выпуске нового ключа предыдущий отзывается атомарно.

Bank Webhook Signature - HMAC-SHA256 подпись от тела webhook с использованием BANK_API_WEBHOOK_SECRET. Позволяет убедиться, что webhook пришёл от реального банка.

MAX WebAppData HMAC - production-валидация initData от MAX через HMAC-SHA256 с BOT_TOKEN. Подтверждает, что запрос действительно инициирован из мессенджера пользователем с конкретным user_id.

API-дизайн: пять контекстов в одном монолите

Все публичные маршруты работают под префиксом /v1 с разбивкой по аудитории:

Client API (/v1/client/*)

Покрывает полный клиентский сценарий: SSO с MAX, управление профилем и методами оплаты, QR-сессии (online и offline), подтверждение платежа, recovery pending checkout, история транзакций с агрегатами.

Реализован механизм смены метода оплаты без перегенерации QR: PATCH /v1/client/qr/source обновляет payment_method_id в Redis-сессии. Пользователь может переключиться с карты на СБП прямо на экране QR.

Merchant API (/v1/merchant/*)

Регистрация и авторизация мерчанта, управление профилем и настройками лояльности, CRUD точек продаж, управление API-ключами касс, история транзакций с реестром и фильтрацией, инициирование возвратов.

Все merchant-эндпоинты защищены MerchantAuthGuard, который проверяет merchant-JWT и извлекает employee_id + role из payload.

POS API (/v1/pos/*)

Инициация платежа с idempotency_key, получение статуса через long polling или webhook. API-key аутентификация. Минималистичный контракт, ориентированный на интеграцию с кассовым ПО.

Webhook API (/v1/webhooks/*)

Получение событий от банка-эквайера. Каждый входящий запрос: проверка HMAC-подписи, запись в inbox (BANK_WEBHOOK_EVENT), постановка в Bull-очередь bank-webhooks для асинхронной обработки.

Admin API (/v1/admin/*)

Мониторинг системы, управление мерчантами (активация/блокировка), просмотр активных и зависших платежей, агрегаты. Отдельный AdminAuthGuard, изолированный от client/merchant auth.

Стандарт ошибок

Все ошибки возвращаются в единой структуре:

{
  "error": {
    "code": "PAYMENT_METHOD_DECLINED",
    "message": "Недостаточно средств на счёте",
    "details": {}
  }
}

Машинно-читаемые code позволяют клиентским приложениям обрабатывать ошибки точечно, не парсируя текстовые сообщения.

Real-time: WebSocket Gateway

Для real-time уведомлений реализован Socket.IO Gateway на NestJS. Клиент (Mini App) и касса (POS) подключаются по WebSocket и получают события без polling.

Ключевые события:

  • payment:confirm - кассе нужно подтвердить оплату; клиент видит экран checkout;
  • payment:success / payment:failed - финальный результат платежа обеим сторонам;
  • payment:cancelled / payment:expired - статусные уведомления.

WebSocket-сессии аутентифицируются JWT на handshake. Redis используется как adapter для Socket.IO: при горизонтальном масштабировании несколько инстансов API синхронизируют события через Redis pub/sub. Это позволяет масштабировать WebSocket-контур без sticky sessions.

Очереди: асинхронная обработка событий

Bull на Redis обеспечивает три ключевые очереди:

bank-webhooks - обработка входящих событий банка. Очередь гарантирует, что webhook не потеряется, даже если в момент поступления система перегружена. Retry с backoff при транзиентных ошибках.

loyalty-accrual - начисление бонусов после успешного платежа. Асинхронное выполнение не задерживает основной платёжный flow.

max-notifications - отправка чека в MAX через Bot API. Failure в этой очереди не влияет на статус платежа.

Bull-board UI (/admin/queues) даёт команде платформы визуальный интерфейс для мониторинга состояния очередей, просмотра зависших задач и ручного retry.

Инфраструктура и деплой

Монорепо

Проект организован как pnpm-монорепо с Turborepo:

  • apps/api - NestJS-монолит;
  • apps/mini-app - клиентский SPA в MAX;
  • packages/shared - @pandapay/shared с TypeScript-типами и Zod-схемами.

Shared-пакет - связующее звено между нашей командой и командой Merchant Dashboard. Внешняя команда подключает пакет и получает актуальные типы и схемы без ручной синхронизации контрактов.

Turborepo управляет кэшированием артефактов сборки и параллельным запуском задач. pnpm workspaces обеспечивает изоляцию зависимостей между пакетами.

Docker Compose

Для MVP выбран Docker Compose - достаточный инструмент для одного VPS без оверхеда Kubernetes. Стек:

  • api - NestJS-приложение (expose: 3000), не публикуется напрямую в интернет;
  • postgres - PostgreSQL 16 Alpine с persistent volume;
  • redis - Redis 7 Alpine с appendonly yes и persistent volume;
  • nginx - reverse proxy, единственный контейнер с публичными портами 80/443.

Nginx маршрутизирует по доменам: api.pandapay.ru/v1/* → NestJS API, /admin/queues → Bull-board. Mini App и Merchant Dashboard живут на внешних серверах других команд и обращаются к API через CORS.

CI/CD

Релизный процесс: push в Git → CI lint/test/build → Docker image → push в registry → docker compose pull && docker compose up -d на VPS. Сервер не является рабочей git-копией - доставка только через CI. Rollback по тегу image.

Домены и маршрутизация

api.pandapay.ru/v1/*         → Backend API (NestJS :3000)
api.pandapay.ru/admin/queues → Bull-board UI
api.pandapay.ru/health       → Health check
max.pandapay.ru              → Mini App (внешний сервер)
merc.pandapay.ru             → Merchant Dashboard (внешний сервер)

Планируемые этапы развития

Self-Ordering (Stage 6)

После релиза MVP запланирован сценарий самостоятельного заказа. Покупатель сканирует статический QR на столике или витрине заведения, Mini App открывается в контексте конкретного мерчанта и конкретной точки (или стола). Покупатель видит меню, формирует заказ и оплачивает через уже существующий C2B-механизм.

Это потребует новых модулей на бэкенде: catalog (товары/услуги мерчанта по категориям с ценами) и order (управление заказом, связь с Payment после оформления). Существующий платёжный flow меняться не будет.

Масштабирование

Архитектура готова к горизонтальному масштабированию без рефакторинга бизнес-логики:

  • несколько инстансов api за Nginx load balancer;
  • Redis adapter для Socket.IO синхронизирует WebSocket события между инстансами;
  • Bull-воркеры выносятся в отдельный процесс (тот же Docker-образ, другая команда запуска);
  • при необходимости - выделение отдельного worker-сервиса в compose.

Технологический стек

СлойТехнологии
BackendNestJS 10, TypeScript, Prisma ORM
База данныхPostgreSQL 16
Кэш и очередиRedis 7, Bull
Real-timeSocket.IO (NestJS Gateway)
АутентификацияJWT (access 15 мин / refresh 30 дней), HMAC-SHA256, argon2id, bcrypt
APIREST, WebSocket, Long Polling, Webhook
Монорепоpnpm workspaces, Turborepo
ИнфраструктураDocker Compose, Nginx, Ubuntu 24 LTS
Shared@pandapay/shared (TypeScript types + Zod schemas)

Итог

Мы спроектировали и разработали бэкенд платёжной платформы с нуля: от архитектурных артефактов C4 до работающего NestJS-монолита с PostgreSQL, Redis, Bull-очередями и WebSocket.

Система покрывает полный платёжный цикл: инициация с POS → QR на экране покупателя → подтверждение → списание через банк → real-time уведомления → начисление бонусов. Реализована offline-оплата без интернета на HMAC-подписанных токенах, каскадный fallback при отказе банка, recovery flow при разрыве соединения, полный refund-процесс.

Архитектурная документация позволила параллельно запустить разработку Merchant Dashboard внешней командой с первого дня - без блокеров и ручной синхронизации контрактов. Все ключевые решения согласованы с клиентом до написания кода и зафиксированы в явном виде.

Стек: NestJS · TypeScript · Prisma · PostgreSQL · Redis · Bull · Socket.IO · Docker · Nginx · pnpm · Turborepo

Роль: Архитектурное проектирование (C4) · Разработка бэкенда · API-дизайн · Безопасность · Инфраструктура · Shared-пакет

Технологии

NestJS
PostgreSQL
Redis

Другие кейсы

Лига Диванов
Разработка и сопровождения проекта
1С-Битрикс 3500 человеко-часов
Лига Диванов Разработка и поддержка магазина мягкой мебели на Битрикс
Максимус
поддержка и обслуживание сайта
платформа Битрикс
более 3500 человеко-часов с 2014 года
Максимус Разработка и поддержка интернет-магазина электроники
Интернет-магазин мебели в стиле Баухаус
Разработка и сопровождение с 2014 года
Более 6 000 человеко-часов
Интернет-магазин мебели в стиле Баухаус Разработка и поддержка магазина и CRM системы
redan.ru
Техподдержка и обслуживание сайта
платформа 1С-Битрикс
Мото-техника и запчасти
redan.ru Поддержка интернет-магазина мото-запчастей
Горные вершины
Редизайн интернет-магазина
Поддержка сайта
Горные вершины Редизайн интернет-магазина на 1С-Битрикс
hi-tech-media.ru
Редизайн интернет-магазина
Поддержка сайта
hi-tech-media.ru Редизайн интернет-магазина на 1С-Битрикс
Техническая поддержка сайта tdtorus.ru
Техническая поддержка сайта
Разработка дополнительного функционала
Поддержка DevOps
Техническая поддержка сайта tdtorus.ru Обслуживание сайта и серверов
ATENPRO
Поддержка Битрикс24
Поддержка серверной части
Разработка Дашборда
ATENPRO Поддержка корпоративного портала на Битрикс24
bipG
18000 часов разработки
Разработка EPR на базе Б24
bipG Разработка системы управления персоналом компании
CONZEPTplus OHG
20 лет непрерывной работы с проектом
Больше 10 000 человеко-часов
CONZEPTplus OHG Система бронирования краткосрочной аренды в Германии
AGUTEENS
система бронирования билетов
внедрение Битрикс24
AGUTEENS Редизайн проекта, разработка системы бронирования билетов
SPBGaz.com
Перевод с Drupal на 1C-Битрикс
SPBGaz.com Поддержка проекта
perfekta.ru
Поддержка
Сопровождение
perfekta.ru

Оставьте заявку

close

Предпочтительный способ связи

Телефон
Email
Telegram
attachment Добавить файлы
delete Удалить
checkmark
Я согласен на обработку персональных данных
close
checkmark-circle

Cпасибо! Данные успешно отправлены.