Системный анализ · E-commerce · Telegram
NNNplace Commerce Platform
Production-платформа магазина: единый заказ из Telegram Mini App и браузера, ручное подтверждение криптооплаты, RBAC, аудит и две изолированные инсталляции.
Исходная ситуация
Продажи велись через Telegram и веб-канал, а оформление заказа, подтверждение оплаты и коммуникация с покупателем требовали единого управляемого процесса. Нужно было исключить доверие к данным браузера, разграничить полномочия сотрудников и сохранить независимость двух магазинов на общей кодовой базе.
Что спроектировано
Спроектирована платформа с единой витриной для Telegram Mini App и браузера, серверным пересчётом заказа, ручным подтверждением криптооплаты, защищёнными пользовательскими сессиями, ролевой админ-панелью, аудитом действий и изолированными production-контурами.
Артефакты
Решение изнутри
architecture
Контекст системы
Граница решения отделяет магазин от Telegram, сервиса курсов и криптовалютной сети. Платформа формирует платёжные реквизиты, но поступление средств подтверждает сотрудник.
architecture
Контейнерная архитектура
Статический React-интерфейс работает через reverse proxy. Fastify API, Telegram-бот и бизнес-правила выполняются в одном Node.js-процессе, а операционные данные хранятся в SQLite.
process
Авторизация покупателя
Mini App подтверждает пользователя подписанным Telegram initData. В обычном браузере используется одноразовый код из бота; идентификатор покупателя никогда не принимается как доверенный параметр клиента.
process
Создание и подтверждение заказа
Сервер повторно читает цены, доступность, оплату и промокод из БД. После отметки покупателя решение об оплате принимает сотрудник через Telegram или админ-панель.
process
Жизненный цикл заказа
Статусная модель блокирует повторные и произвольные переходы. Инструкция получения раскрывается покупателю только после подтверждения оплаты.
architecture
Ролевая модель админ-панели
Три уровня доступа отделяют операционные действия от изменения конфигурации и управления командой. Права проверяются на сервере для каждого защищённого маршрута.
data
Логическая модель данных
Заказ хранит snapshots товаров, оплаты и кошелька, поэтому последующее изменение каталога не искажает историю. Сессии и аудит отделены от бизнес-сущностей.
api
Фрагмент API-контракта
Клиент передаёт только идентификаторы и количество. Итоговая сумма, скидка, кошелёк и принадлежность заказа определяются сервером.
POST /api/orders
Content-Type: application/json
Cookie: customer_session=<HttpOnly>
{
"items": [{ "id": 12, "qty": 2 }],
"fulfillment": "pickup",
"paymentMethodId": 3,
"promoCode": "WELCOME"
}
201 Created
{
"orderId": 1042,
"status": "awaiting_payment",
"total": 48.50,
"paymentCode": "NNN-1042",
"payment": { "ticker": "XMR", "amount": 0.312, "approx": true }
}
401 invalid_customer_auth
409 wrong_status
422 invalid_items | invalid_promo | payment_unavailabletesting
Трассировка требований и проверок
Критические требования связаны с наблюдаемым результатом и автоматической либо операционной проверкой.
ID Требование Проверка Результат FR-01 Заказ создаёт авторизованный клиент API без сессии 401 FR-02 Сервер сам пересчитывает стоимость Подмена total в запросе Игнорируется FR-03 Чужой заказ не раскрывается Запрос другого tg_user_id 404 FR-04 Повторная отметка оплаты запрещена paid после смены статуса 409 SEC-01 Токены не хранятся открыто Проверка SQLite SHA-256 SEC-02 Пароли сотрудников защищены Проверка записи admin scrypt hash SEC-03 Права проверяются на сервере operator меняет settings 403 SEC-04 Изменения администратора фиксируются Смена статуса заказа audit event NFR-01 Чувствительные ответы не кэшируются Проверка response headers no-store NFR-02 Сервис сообщает готовность бота GET /api/ready без Telegram non-200
architecture
Две независимые production-инсталляции
Одна версия кода разворачивается в двух изолированных контурах. Конфигурации, базы, файлы, токены и пользовательские сессии не разделяются.