Профессиональная backend-система для проведения высоконагруженных аукционов в стиле "Battle Royale" (Top-N победителей). Система поддерживает строгую транзакционность, защиту от снайперов и гибкие финансовые настройки.
- 🎥 Видео-демонстрация: Смотреть на YouTube
- 🌐 Живое демо: http://localhost:3000
- 🛡️ Strict Top Bid: Теперь любая ставка ОБЯЗАНА перебивать текущего лидера. Никаких «скрытых» ставок в середину списка — только борьба за №1.
- ⏱️ Anti-Sniping (Seconds-based): Высокоточное управление временем. Настройка окна срабатывания и добавления времени теперь в секундах.
- 💎 Финансовая целостность: Использование ACID-транзакций MongoDB и статических моделей Mongoose для исключения ошибок при выплатах и возвратах.
По результатам анализа Telegram Gift Auctions, в систему заложены следующие продуктовые решения:
- Механика раундов (Battle Royale): Аукцион не заканчивается одним победителем. Есть фиксированное количество "мест" (Top-N). Это создает динамику, где пользователи соревнуются за право остаться в списке, а не просто за первое место.
- Экономика ставок:
- Locking: Мы блокируем средства сразу при ставке. Это гарантирует, что на момент завершения раунда у победителя точно есть деньги.
- Instant Refund: Если участника вытесняют из списка победителей более высокой ставкой, его средства разблокируются мгновенно (в той же ACID транзакции), что позволяет ему сразу сделать новую ставку.
- Anti-Sniping (Soft Close): Мы отошли от "жесткого" дедлайна. Любая активность в "окне защиты" (1-5 мин) продлевает аукцион. Это максимизирует выручку продавца и делает борьбу честной для тех, у кого медленный интернет.
- Резервная цена: Механизм защиты продавца. Если интерес к лоту ниже ожидаемого, раунд признается несостоявшимся, и система защищает актив, возвращая средства всем участникам.
По результатам анализа Telegram Gift Auctions, в систему заложены следующие продуктовые решения:
- Механика раундов (Battle Royale): Аукцион не заканчивается одним победителем. Есть фиксированное количество "мест" (Top-N). Это создает динамику, где пользователи соревнуются за право остаться в списке, а не просто за первое место.
- Экономика ставок:
- Locking: Мы блокируем средства сразу при ставке. Это гарантирует, что на момент завершения раунда у победителя точно есть деньги.
- Instant Refund: Если участника вытесняют из списка победителей более высокой ставкой, его средства разблокируются мгновенно (в той же ACID транзакции), что позволяет ему сразу сделать новую ставку.
- Anti-Sniping (Soft Close): Мы отошли от "жесткого" дедлайна. Любая активность в "окне защиты" (1-5 мин) продлевает аукцион. Это максимизирует выручку продавца и делает борьбу честной для тех, у кого медленный интернет.
- Резервная цена: Механизм защиты продавца. Если интерес к лоту ниже ожидаемого, раунд признается несостоявшимся, и система защищает актив, возвращая средства всем участникам.
jOB/
├── src/
│ ├── models/ # Mongoose модели (Auction, User, Transaction, Bid)
│ ├── services/ # Бизнес-логика
│ │ ├── AuctionService.ts # Ставки, валидация, транзакции
│ │ ├── AuctionTicker.ts # Ротация раундов, финализация, выплаты
│ │ └── BotService.ts # Симуляция активности (боты)
│ ├── routes/ # Express API эндопоинты
│ ├── infra/ # Подключение к БД
│ └── app.ts # Точка входа, Socket.io инициализация
├── public/ # Frontend (SPA на Tailwind + Socket.io)
├── tests/ # Нагрузочные и функциональные тесты
└── docker-compose.yml # Инфраструктура (MongoDB Replica Set)
- ACID Transactions: Все ставки проходят через сессии MongoDB. Списание баланса (
available -> locked) и обновление состояния аукциона атомарны. - Optimistic Concurrency: Используется версионирование документов (
__v). Если два пользователя ставят одновременно, один из них получит ошибку версии и должен будет перечитать состояние (релизовано на уровне БД). - Battle Royale Logic: При заполнении списка участников (например, 1000 мест), новая более высокая ставка вытесняет самую слабую. Вытесненный пользователь получает мгновенный возврат средств.
- Если ставка поступает в последние
Nминут (настраивается), время завершения аукциона (endsAt) автоматически продлевается. Это дает другим участникам время на реакцию.
- Locking: Средства блокируются в поле
wallet.lockedпри совершении ставки. - Settlement: При завершении раунда
AuctionTickerпроверяет Reserve Price.- Если порог пройден: Победители теряют
lockedсредства, продавец получает выплату за вычетом комиссии platform fee. - Если порог НЕ пройден: Все средства возвращаются на
availableбаланс участников.
- Если порог пройден: Победители теряют
- Audit: Все выплаты фиксируются в коллекции
Transactions.
Фоновый процесс, который:
- Переводит аукционы из
PREVIEWвACTIVE. - Обрабатывает завершение раундов.
- Автоматически создает следующий раунд, наследуя конфигурацию.
- Зависимости:
npm install - База данных:
docker-compose up -d(нужен Docker для Replica Set). - Запуск:
npm run dev - Доступ: http://localhost:3000
Для проверки всех функций предусмотрены скрипты:
npm run test(если настроен Jest)npx ts-node tests/prod-verify.ts— полный прогон проверки шага ставки и анти-снайпинга.npx ts-node tests/load-test.ts— проверка системы под нагрузкой.
Tip
При разработке фронтенда слушайте Socket.io событие notification для отображения пушей о том, что ставку пользователя перебили.