Skip to main content
Skip to main content

Кейс

LocalFood: P2P‑платформа доставки домашней еды от соседей (iOS + бэкенд)

Полноценная мобильная платформа, связывающая домашних поваров с любителями еды по соседству: нативное iOS‑приложение (Swift/SwiftUI) с двухролевой архитектурой (Повар и Пользователь), отслеживание заказов в реальном времени с интеграцией карт, многошаговая регистрация с OTP‑верификацией, гео‑фильтрованная лента блюд с рекомендациями, корзина и чекаут с опциями самовывоза/доставки, обработка платежей картами МИР, верификация качества кухни через фото/видео, push‑уведомления и Node.js/PostgreSQL бэкенд с геопространственными запросами, WebSocket‑обновлениями заказов и S3 медиа‑пайплайном.

40+Экранов UI
2 (Chef + Customer)Ролей пользователей
4Шагов регистрации
6Статусов заказа
Год: 2024Индустрия: FoodTech / Маркетплейс / ДоставкаСроки: 14 недель

Задача

Заказчик из Москвы хотел запустить P2P‑маркетплейс еды — платформу, где домашние повара могут продавать блюда соседям с отслеживанием доставки в реальном времени, верификацией качества и обработкой платежей. Существующие приложения доставки (Яндекс.Еда, Delivery Club) обслуживают рестораны, а не частных лиц. Клиенту требовался двусторонний маркетплейс с раздельным опытом для поваров (управление меню, обработка заказов, верификация кухни) и покупателей (гео‑поиск, корзина, чекаут с самовывозом/доставкой, трекинг на карте). Платформа должна обрабатывать геопространственный поиск (повара в радиусе 50–1000 м), двойную OTP‑верификацию (телефон + email), приём карт МИР, обновления статуса заказа через WebSocket, фото/видео‑верификацию кухни для контроля санитарных условий и маршрутизацию доставки на карте с расчётом ETA. По договорённости с заказчиком, название и логотип приложения на скриншотах изменены.

Ограничения

  • Нативный iOS (Swift 5 + SwiftUI) — без кросс‑платформенных компромиссов ради премиального ощущения
  • Двухролевая архитектура: одно приложение, разный опыт для Повара и Пользователя
  • 4‑шаговая регистрация с двойной OTP‑верификацией (SMS + email)
  • Геопространственная лента: PostGIS‑запросы по радиусу (50 м – 1000 м) с чипами расстояния
  • Отслеживание заказов в реальном времени: WebSocket + рендеринг маршрута MapKit с ETA
  • Приём платежей картами МИР (интеграция с российской платёжной системой)
  • Верификация кухни: фото + видеотрансляция для контроля санитарных условий
  • Push‑уведомления по жизненному циклу заказа (готов, в пути, ошибка оплаты)
  • Название и логотип приложения изменены по договорённости с заказчиком (NDA)

Решение

Спроектировали и построили full‑stack двусторонний маркетплейс еды для iOS и бэкенда.

iOS‑ПРИЛОЖЕНИЕ (Swift 5 + SwiftUI)

двухролевой онбординг — на Шаге 1 регистрации пользователь выбирает Повар или Пользователь, определяя всё дерево навигации; 4‑шаговый flow регистрации (выбор роли → личные данные с био/датой рождения/полом → контакты с телефоном/email/адресом с геолокацией → двойная OTP‑верификация телефона и email); персонализированная гео‑фильтрованная лента с каруселью рекомендаций (фитчер‑блюдо с аватаром повара, рейтингом, ценой, добавлением в корзину одним нажатием), поиск с расширенными фильтрами (чипы радиуса 50–1000 м, слайдер цены, сортировка, теги типа блюда — Мясное, Салат, Закуска, Выпечка, Гарнир, Суп, Напитки, Гриль); детальный экран блюда с full‑bleed фото, бейджем повара, рейтингом с количеством отзывов, описанием, составом, тегами категорий и секцией «Ещё блюда от этого повара»; корзина с управлением (количество +/−, избранное, удаление), разбивкой по позициям и итогом; чекаут с сегментированным контролом Самовывоз/Доставка (самовывоз показывает адрес повара + ссылку на карту, доставка — адрес пользователя + расчёт стоимости доставки), сохранённые карты МИР с добавлением/удалением, сводка заказа с разбивкой сервисного сбора; 6‑стадийный трекинг заказа на живой карте (Ожидание → Принят → Готовка → В пути → Доставлен → Завершён) с позицией курьера в реальном времени через WebSocket, рендеринг маршрута с ETA (например, «32 мин, 27.6 км»), оверлей деталей заказа; экран ошибки оплаты с retry и контактом поддержки; центр push‑уведомлений со статусами заказов и алертами ошибок оплаты.

ОПЫТ ПОВАРА

профиль с рейтингом, био, управление меню, форма «Добавить блюдо» (загрузка фото, название, описание, состав, теги, цена), управление заказами (входящие с Принять/Отклонить, детали заказа с позициями и действием «Готовить»), верификация качества кухни (фото кухни/продуктов для санитарной проверки + видеотрансляция с камеры), медиа‑галерея (загруженные фото + видео для прозрачности).

БЭКЕНД (Node.js + Express + PostgreSQL + PostGIS)

геопространственные запросы через PostGIS (ST_DWithin для поиска по радиусу, ST_Distance для расчёта расстояния, пространственный индекс на локациях поваров — менее 50 мс на 100K+ записей), WebSocket‑сервер (Socket.IO) для push статуса заказа и позиции курьера, S3 медиа‑пайплайн (фото блюд, аватары поваров, фото/видео верификации кухни — загрузка через pre‑signed URL, ресайзинг через Sharp в 3 брейкпоинта, CDN через CloudFront), интеграция платёжного шлюза МИР (токенизированное хранение карт, 3‑D Secure, идемпотентные charge‑запросы), OTP‑сервис (SMS через SMS.RU + email через Nodemailer/SES, 6‑значные коды с TTL 90 секунд и rate limiting), state machine заказов (Pending → Accepted → Cooking → Ready → InTransit → Delivered, с компенсирующими переходами для отмены/возврата), рекомендательный движок (коллаборативная фильтрация по истории заказов + скоринг по гео‑близости), структурированное логирование через Pino с трейсингом запросов.

Результаты

  • Нативное iOS‑приложение (Swift 5 + SwiftUI, две роли: Повар и Пользователь)
  • 4‑шаговая регистрация с двойным OTP (SMS + email‑верификация)
  • Гео‑фильтрованная лента с каруселью рекомендаций и расширенными фильтрами
  • Детали блюда, профиль повара, раздел «Ещё блюда от повара»
  • Корзина с управлением количеством, избранным и итогами
  • Чекаут с Самовывоз/Доставка, управление картами МИР, разбивка сборов
  • 6‑стадийный трекинг заказа на живой карте (WebSocket + MapKit + ETA)
  • Обработка ошибок оплаты с retry
  • Центр push‑уведомлений (заказ готов, в пути, ошибка оплаты)
  • Повар: CRUD меню (фото, описание, состав, теги, цена)
  • Повар: управление заказами (принять/отклонить, детали, «готовить»)
  • Повар: верификация кухни (фото + видеотрансляция для санитарного контроля)
  • Node.js + Express REST API с PostGIS геопространственными запросами
  • WebSocket‑сервер (Socket.IO) для обновлений заказа/курьера
  • S3 медиа‑пайплайн (pre‑signed upload, Sharp ресайзинг, CloudFront CDN)
  • Платёжный шлюз МИР (токенизация карт, 3‑D Secure, идемпотентные charge)
  • OTP‑сервис (SMS.RU + SES, rate limiting, TTL 90 с)

Скриншоты / UX‑поток

Пошаговый обзор интерфейса продукта

01

Онбординг — приветственный экран «Заказывайте вкусную еду от соседей» с брендингом LocalFood

02

Вход — аутентификация email/телефон + пароль со ссылкой «Зарегистрируйтесь»

03

OTP — верификация номера телефона, ввод 6‑значного кода с таймером повторной отправки 1:27

04

OTP — верификация email, 6‑значный код отправлен на example@mail.ru

05

Регистрация Шаг 1 — выбор роли: Повар (иконка поварского колпака) или Пользователь (иконка приборов)

06

Регистрация Шаг 2 — личные данные: имя, фамилия, «расскажите о себе», дата рождения, пол

07

Регистрация Шаг 3 — контактные данные: телефон или почта, адрес с геолокацией, пароль

08

Регистрация Шаг 4 — OTP‑верификация email в потоке регистрации

09

Регистрация Шаг 4 — OTP‑верификация телефона в потоке регистрации

10

Главная лента — адрес доставки, карусель рекомендаций (Салат Цезарь 249₽), поиск, карточки поваров с рейтингами

11

Лента с бейджем корзины — плавающая кнопка корзины 2184₽ / 2 позиции

12

Лента с баннером активного заказа — Заказ №160924 «Ожидает получения» с кнопкой «На карте»

13

Фильтры — чипы расстояния (50–1000 м), слайдер цены (120–1100₽), сортировка по цене, теги типов блюд

14

Детали блюда — полное фото, бейдж повара (4.8★), 141 оценка, описание, состав, теги, «Ещё от повара»

15

Детали блюда (альтернативный) — тот же макет с другим блюдом, кнопка добавления 249₽

16

Профиль повара — аватар, юзернейм, рейтинг 4.8★, «Обо мне», список меню с ценами и кнопками добавления

17

Корзина — позиции с фото, ценами, управление количеством (−/+), избранное, удаление, 2 позиции 596₽

18

Чекаут (Самовывоз) — переключатель самовывоз/доставка, адрес повара на карте, карты МИР, 596₽ + сбор 49₽ = 645₽

19

Чекаут (Доставка) — доставка выбрана, адрес пользователя, карты МИР, 596₽ + сбор 49₽ + доставка 120₽ = 765₽

20

Ошибка оплаты — красный экран «Заказ №52120120 не удалось оплатить» с кнопкой Повторить и контактом поддержки

21

Трекинг заказа — карта с маршрутом, статус «Ожидает получения», ETA 32 мин, 27.6 км, оверлей деталей

22

Трекинг заказа — статус «В пути» с позицией курьера на маршруте карты

23

Трекинг заказа — вид повара: инструкция «Доставьте блюда заказчику» с картой

24

Заказ доставлен — статус «Доставлен», список позиций с кнопкой «Повторить заказ»

25

Меню аккаунта — Профиль, Адреса, Уведомления, Настройки + CTA «Стать поваром», Выйти/Поддержка

26

Платёжные данные — сохранённые карты МИР (····7289, ····3212) с удалением/подтверждением, кнопка «Добавить карту»

27

Добавление платёжного метода — номер карты, имя и фамилия, ММ/ГГ, CVV с кнопкой «Добавить»

28

Уведомления — «Ваш заказ готов» (×2), «Не удалось оплатить» с номерами заказов и временем

29

Список адресов — сохранённый адрес (Москва, пл. Ленина 11) с иконкой редактирования, кнопка «Новый адрес»

30

Карта адреса — полная карта с маршрутом (32 мин / 27.6 км), ввод адреса доставки, квартира/этаж, «Определить местоположение»

31

Редактирование профиля — загрузка аватара, имя, фамилия, юзернейм, «обо мне», дата рождения, пол, контакты, пароль

32

Профиль повара (свой) — аватар, имя, рейтинг 4.8★, кнопка «Изменить», бейдж «Мои заказы», био, меню с «Добавить блюдо»

33

Заказы повара — входящий заказ №160924 (1265₽, «Доставлен») с превью блюд, кнопки Принять/Отклонить

34

Детали заказа повара — Заказ №160924 «Принят», список позиций (Цезарь ×2, шашлык, крабовый салат) с кнопкой «Готовить»

35

Верификация кухни — «Сфотографируйте кухню и продукты для определения качества и санитарных условий» с кнопками фото/загрузки

36

Видеотрансляция — «Подготовьте камеру, продукты и включите трансляцию» с окном камеры

37

Медиа‑галерея — сетка загруженных фото + секция видео с кнопкой воспроизведения, действие «Заказ готов»

38

Блюдо (вид повара) — тот же экран, но с иконкой удаления и кнопкой «Редактировать» вместо добавления в корзину

39

Редактирование блюда — область загрузки фото, название, описание, состав, теги, цена, кнопка «Сохранить»

40

Создание блюда — пустая форма с плейсхолдером фото, название, описание, состав, кнопка «Сохранить»

Артефакты

Документы и результаты проекта

iOS‑приложение + трекинг + гео‑лента

Артефакт

Отчёт верификации

Гейт релиза

Верификация / гейты качества

8-фазный чеклист перед релизом

01Сборка (Xcode + бэкенд)
Пройден
02Производительность PostGIS‑запросов (<50 мс)
Пройден
03E2E‑тестирование WebSocket‑трекинга
Пройден
04Тесты интеграции платежей МИР
Пройден
05Верификация доставки OTP (SMS + email)
Пройден
06Аудит двухролевой навигации
Пройден
07Медиа‑пайплайн (загрузка → ресайз → CDN)
Пройден
08UAT с тестовой группой в Москве
Пройден
Все гейты пройдены
8/8

Стек технологий

Swift 5SwiftUIMapKitCoreLocationNode.jsExpressPostgreSQLPostGISSocket.IORedisAWS S3CloudFrontSharpMIR Payment GatewaySMS.RUPinoDockerNginx

Результат

Поставили production‑ready двусторонний маркетплейс еды: 40+ iOS‑экранов, покрывающих полный путь пользователя от онбординга до доставки, двухролевая архитектура (Повар управляет меню/заказами/верификацией, Пользователь ищет/заказывает/отслеживает), трекинг на карте в реальном времени с WebSocket‑обновлениями и ETA, PostGIS‑поиск по геолокации (менее 50 мс на 100K+ записей поваров), приём карт МИР с 3‑D Secure, верификация качества кухни через фото и видеотрансляцию. Платформа обрабатывает полный жизненный цикл заказа с 6 отслеживаемыми статусами, push‑уведомлениями на каждом переходе и обработкой ошибок с retry. По договорённости с заказчиком, приложение поставлено под псевдонимом (LocalFood) с нейтральным логотипом — реальный продукт работает под брендом клиента в Москве.

Сложные задачи, которые мы решили

Двухролевая архитектура в одном приложении

Повар и Пользователь разделяют аутентификацию и базовую инфраструктуру, но имеют полностью разные деревья навигации, экраны и потоки данных. Роль выбирается на Шаге 1 регистрации и определяет поведение приложения: Пользователи видят гео‑ленту, корзину, чекаут и трекинг; Повара — управление меню, очередь заказов, верификацию кухни и профиль повара. Реализовано через NavigationView SwiftUI с role‑conditional корневыми экранами, @EnvironmentObject для пропагации состояния роли и общим слоем данных (CoreData для офлайн‑кэша + URLSession API sync). Выбор SwiftUI вместо UIKit в 2021 году был осознанным forward‑thinking решением — фреймворк был достаточно зрелым на iOS 14+ для этого скоупа, при этом давал декларативную композицию UI и значительно более быстрые итерации.

PostGIS геопространственный поиск с производительностью менее 50 мс

Поиск еды основан на близости — пользователи видят блюда от поваров в настраиваемом радиусе (50 м – 1000 м). Реализовано через PostGIS: локации поваров хранятся как geography(POINT, 4326), пространственный GIST‑индекс, ST_DWithin для фильтрации по радиусу. Чипы расстояния в UI фильтра напрямую маппятся в SQL‑параметры. На 100K+ записей поваров запросы возвращаются менее чем за 50 мс. Совмещено с коллаборативной фильтрацией (история заказов + скоринг по близости) для карусели рекомендаций.

Трекинг заказов в реальном времени с 6‑стадийным state machine

Жизненный цикл заказа: Ожидание → Принят → Готовка → Готов/В пути → Доставлен → Завершён. Каждый переход триггерит WebSocket‑событие (через Socket.IO), обновляющее карту клиента в реальном времени: пин курьера анимируется по маршруту, ETA пересчитывается, статусный баннер меняется. MapKit рендерит полилинию маршрута с оверлеем расстояния и времени («32 мин, 27.6 км»). Компенсирующие переходы обрабатывают отмену (возврат через шлюз МИР) и ошибку оплаты (экран retry с контактом поддержки). Повар получает push на новый заказ и может Принять/Отклонить из уведомления или экрана заказов.

Верификация кухни для санитарного соответствия

Прежде чем повар начнёт принимать заказы, он должен пройти верификацию кухни: загрузить фото кухни и продуктов (проверяются модерацией платформы) и опционально запустить видеотрансляцию с камеры для инспекции в реальном времени. Flow верификации использует камеру устройства (AVFoundation) для фото и HLS для стриминга на дашборд модерации. Медиа загружается в S3 через pre‑signed URL, ресайзится через Sharp и раздаётся через CloudFront. Эта функция была регуляторным требованием клиента для демонстрации ответственности за безопасность еды.

Похожий проект? Получите оценку или запишитесь на звонок.

Похожие кейсы

Продукт

TRM Oferta: онлайн‑регистрация и акцепт публичной оферты (end‑to‑end)

Полный продуктовый поток: регистрация, акцепт публичной оферты с аудит‑трейлом, PDF‑подтверждение с печатью/подписью, админка. Юридически корректно, mobile‑first.

Продукт

Система учёта заказов и ингредиентов для ресторана (end‑to‑end)

Полноценная система управления рестораном: ролевой доступ (Шеф, Сотрудник, Бухгалтер, Владелец), учёт ингредиентов с себестоимостью, рецепты роллов с авторасчётом себестоимости/маржи, состав сетов с ценами, управление заказами, логирование поставок/списаний, бухгалтерия с выгрузкой в Excel, аналитические дашборды и полная история изменений.

Продукт

KutWallet: мультиактивный криптокошелёк со встроенной биржей (iOS, end‑to‑end)

Полноценный мобильный криптокошелёк для iOS: некастодиальное управление ключами с AES‑256‑GCM‑шифрованием, 4‑значный PIN + биометрия Face ID, 3‑шаговый онбординг с ценностным сторителлингом, мультиактивный дашборд портфеля с ценами в реальном времени (BTC, ETH, LTC, XRP), встроенная биржа с интерактивными свечными графиками и потоком Buy/Sell, аналитика расходов с сегментированной donut‑диаграммой, QR‑сканер для мгновенных P2P‑переводов, мультивалютные фиатные настройки (6+ валют), OAuth‑вход (Google, Apple ID), OTP‑верификация email и Node.js/PostgreSQL бэкенд с WebSocket‑стримингом цен и агрегацией CoinGecko.

Похожий проект?

20 минут — обсудим вашу задачу, дадим честную оценку. Без обязательств.