Демка · 8 сентября 2026
Fullstack Test Shop
Тестовое задание реализовано как полный контур цифрового магазина: Angular-витрина, NestJS API, PostgreSQL через Prisma, webhook оплаты, два поставщика ключей и фоновый worker выдачи. В интерфейсе можно пройти покупку, повторить событие оплаты и проверить восстановление заказа после нехватки товара или сбоя поставщика.
Каталог товаров. Внешние сервисы замоканы.
01 / Задача
Магазин цифровых товаров
В рамках тестового задания требовалось собрать магазин цифровых товаров с каталогом, оформлением заказа и оплатой. Я расширил исходный сценарий до эксплуатационного: добавил идемпотентный inbox webhook, конкурентно безопасную выдачу ключей, повтор этапов и наблюдаемые состояния ошибок.
Сценарий: Покупка цифровых товаров. Здесь учебный вариант с моками поставщиков.
Что делал
- Витрина, карточка заказа и история статусов на Angular.
- API на NestJS, схема БД, воркер и HTTP-моки двух поставщиков.
- Обработка дублей и сбоев, проверки конкурентных запросов, деплой.
- Для демки добавил сессии, TTL, сброс своих данных и управляемый сбой заказа.
02 / Реализация
Что отличает реализацию
Выдача выполняется однократно даже при повторных и параллельных webhook. Стабильный provider request ID переживает неоднозначный timeout; out_of_stock и delivery_failed восстанавливаются повторным worker-проходом. Ограничения БД и выборка FOR UPDATE SKIP LOCKED удерживают инварианты на уровне хранилища, а не только контроллера.
Скриншоты
Экраны, формы, ошибкиСкриншоты, схемы и исходные материалы сохранены на языке оригинала; подписи и описание переведены.
03 / Технологии
Что использовано
Доли по размеру прикладных файлов Git в закреплённой версии. Каждый файл отнесён к одной подсистеме по правилам scripts/generate-stack-share.mjs; тесты, ассеты, зависимости и generated-файлы исключены. Округление — до 0,1%. Это состав кода, а не уровень владения технологиями.
Angular / TypeScript
Витрина, сигналы состояния, HTTP-клиент и polling заказа.
NestJS
Контракты, валидация, webhook, операции восстановления и границы демо.
PostgreSQL / Prisma
Снимки денег, inbox, очередь с lease, уникальные индексы и транзакции.
Node.js worker
HTTP-вызовы поставщиков вне короткой транзакции, retry и финальная выдача.
04 / Решения
Как устроен проект
- Цена и скидка вычисляются на сервере и фиксируются в заказе.
- Idempotency-Key защищён уникальным индексом; входные данные повтора сверяются с исходным намерением.
- Webhook сначала сохраняется в durable inbox. Отдельный worker обрабатывает платёж и очередь выдачи.
- Стабильный requestId поставщика сохраняется при повторе. Неоднозначный timeout не разрешает немедленно выдать второй код.
05 / Проверка
Сценарии демки
- Выберите товар и выполните успешную тестовую оплату. Дождитесь кода и просмотрите историю.
- Повторите то же платёжное событие: код и выдача должны остаться единственными.
- Создайте заказ через сценарий сбоя, оплатите и нажмите «Восстановить мой заказ».
- Проверьте отказ оплаты, чужой UUID в другой сессии и сброс своего примера.
Результаты проверок
- Сохранено 14 содержательных кадров фактического интерфейса.
- Дата, сценарий и версия указаны у каждого кадра.
- Максимум RAM контейнеров в коротком тесте: 218.56 MiB. Общие службы учитываются отдельно; магазин включает свою БД.
- Измерено 6 повторений сценария; медиана 129.0 мс, максимум 1939 мс. Время включает браузер и HTTPS; методика и ограничения приложены.
Ограничения
- Оплата и поставщики — явные моки; деньги не списываются, коды учебные.
- До 20 заказов на сессию и 1000 новых демонстрационных заказов суммарно. TTL один час, очистка каждые пять минут.
- Пример восстановления намеренно завершает первую попытку одного заказа ошибкой. Он не меняет глобальные режимы поставщиков.
Технические заметки
Модули, API, схема данных, запуск и результаты проверок.
Документация →Материалы ↓