MK / ENGINEERING NOTES

Красиво снаружи.
Продумано внутри.

Разбираю инженерные решения на примере самого MK • DΞV: границы доверия, состояния заказа и восстановление после ошибок.

В интерфейсе — одна кнопка. За ней — проверка условий, серверная цена, отдельный платёжный запрос и выдача только после подтверждения.

01 / STATE MACHINE

А если событие придёт дважды?

Интерактивная схема

Упрощённая локальная модель. Никаких реальных платежей, запросов к провайдерам или выдачи файлов.

  1. Заказ создан
  2. 02Платёж проверен
  3. 03Покупка выдана
Сначала нужно подтверждение платежа. Нажмите «Выдать», чтобы проверить защиту.Попыток выдачи: 0 · Успешных выдач: 0

Браузер не назначает цену

Сервер читает товар и стоимость из каталога. Значение, переданное клиентом, не определяет сумму заказа.

server/commerce.ts · createOrder

Состояние и задача — вместе

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

server/commerce.ts · confirm

Ошибка — тоже сценарий

Неудачную выдачу можно повторить без повторной оплаты. Поздние и неоднозначные переводы требуют отдельной проверки.

server/jobs.ts · server/commerce.ts

Проверять поведение, не обещания

Автотесты проверяют повторы событий, доступ к заказу, неподтверждённые платежи и отсутствие товара. Это проверки логики, а не доказательство боевой нагрузки.

tests/payment.test.mjs

02 / THE BUILD

Один продукт. Несколько слоёв.

InterfaceReact · TypeScript
ApplicationVinext · Worker
StorageD1 · R2
VerificationSQLite fixtures · mock APIs

Эта схема описывает текущую реализацию MK • DΞV. Архитектура сторонних кейсов не раскрывается без подтверждения.

03 / DECISIONS, NOT BUZZWORDS

Почему так, а не иначе.

Решение: общая проверка брифа

Контекст

Форма должна сразу объяснять ошибку. Но запрос можно отправить в обход формы, поэтому сервер не доверяет проверке браузера.

Выбор

Один модуль правил используется в двух местах: перед отправкой и перед записью заявки. Доступ, согласие и ограничение частоты проверяются на сервере.

// server/api.ts
const errors = validateBrief(details);
if (Object.keys(errors).length) {
  return json({
    error: 'Invalid brief',
    fields: Object.keys(errors)
  }, 400);
}

Компромисс

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

Что проверять на ревью
  • Доверяет ли код входящим данным без проверки?
  • Что произойдёт при повторе или тайм-ауте?
  • Можно ли восстановиться без потери введённых данных?
  • Доступен ли сценарий с клавиатуры и без анимации?
  • Есть ли тест на отрицательный сценарий?
Что должно остаться после передачи проекта
  • Инструкция запуска и список настроек без секретов.
  • Схема данных, интеграций и фоновых задач.
  • Проверки основных сценариев и известные ограничения.
  • Порядок резервного копирования и восстановления.
  • Согласованные границы поддержки и следующий этап.

Нужна не просто функция,
а связанное решение?

Разобрать задачу