Technical Paper

Этап 0 — Загрузка

2.3 Этап 0 — Загрузка и предобработка

Сторона клиента

Клиент отправляет сфотографированное изображение или PDF напрямую на конечную точку загрузки приложения как multipart POST. Предобработка — обязанность сервера: тонкий клиент означает, что каждая поверхность съёмки получает одну и ту же нормализацию без доставки кода обработки изображений на каждую платформу.

Сторона сервера

Маршрут загрузки проверяет запрос до какой-либо работы с хранилищем:

  • Ограничение размера — размер загрузки сверяется с ограничением, определённым в продакшене.
  • Проверка сигнатуры файла (magic bytes) — сервер анализирует ведущие байты буфера, чтобы подтвердить, что полезная нагрузка действительно является растровым изображением (JPEG, PNG, WEBP, HEIC и другие поддерживаемые форматы) или PDF, независимо от Content-Type, переданного клиентом. Это блокирует скрипты или разметку, протащенные под типом image/*.

Принятые загрузки затем проходят серверную предобработку с помощью sharp:

  • Ориентация — автоповорот на основе EXIF, чтобы чек был выпрямлен перед этапом чтения.
  • Сжатие — изображение перекодируется в профиль размера и качества, настроенный для этапа зрения (vision).
  • Хранение — обработанное изображение записывается в объектное хранилище Vercel Blob с резервным путём в базе данных на случай недоступности Blob-хранилища. Сохранённые изображения планируются к удалению согласно политике хранения.

Ответ возвращает receipt_id и ссылку на сохранённое изображение. Затем клиент вызывает POST /api/receipt/analyze для перехода на Этап 1.

Дедупликация

Точная проверка по хэшу файла выполняется до начала любой ресурсоёмкой работы: SHA-256 загруженных байтов сравнивается с ранее сохранёнными чеками. Проверка перцептивного сходства сознательно отложена до момента после извлечения содержимого, где её можно сверить с хэшем содержимого; ранний запуск визуального сравнения потратил бы эту работу на загрузки, которые точная проверка уже разрешает.

Оба случая дублирования отклоняют загрузку с ошибкой дубликата:

  1. Дубль того же пользователя — пользователю сообщается, что он уже загружал этот чек. Это предотвращает случайные повторные загрузки и попытки повторного получения вознаграждения.
  2. Межпользовательское столкновение — пользователю сообщается, что чек был загружен другим аккаунтом. Это часть защиты от фарминга.

Точные сигналы сходства настраиваются в продакшене и управляются внутренним операционным слоем.