Задача
Службе такси, которая принимает заказы через приложение, нужно гораздо больше, чем форма бронирования. Нужно найти свободного водителя поблизости, предложить ему поездку, дождаться ответа и перейти к следующему, если никто не согласился, — и всё это за секунды. В Риме есть и свои правила: фиксированные тарифы, утверждённые городом, на поездки в аэропорты и порт и обратно. Клиенту была нужна вся цепочка — от диспетчеризации до оплаты.
Что я сделал
Я создал платформу бронирования и диспетчеризации в реальном времени с единым бэкендом, тремя мобильными приложениями и веб-панелью администратора.
- Движок диспетчеризации — ищет одобренных свободных водителей, которые передали своё местоположение за последние 60 секунд, в радиусе поиска (по умолчанию 8 км). Ранжирует до 10 из них по реальному времени в пути с учётом текущих пробок по данным Google, а затем предлагает поездку водителям по одному, давая 20 секунд на принятие.
- Тарифные правила Рима — сервис расчёта цены распознаёт 9 ключевых точек, например аэропорт Фьюмичино и исторический центр. Он применяет 12 фиксированных тарифов, установленных Roma Capitale (постановление 252/2024). Остальные поездки рассчитываются по маршруту Google с надбавками за багаж и пассажиров.
- Три приложения — для пассажира, для водителя и для планшета в машине, который показывает маршрут и баннеры партнёров. Все созданы на React Native и Expo для Android и веба.
- Отслеживание в реальном времени и звонки — Socket.IO передаёт положение водителей и статус поездок. Пассажир и водитель могут позвонить друг другу прямо в приложении через WebRTC, не видя номеров телефонов друг друга.
- Платежи — Stripe с webhook-уведомлениями и проверкой подписи, а также заказы через PayPal. Платёжные ключи задаются в админ-панели и хранятся в зашифрованном виде.
- Подключение водителей — водители загружают права, документы и фото. Администратор одобряет их, прежде чем они смогут выйти на линию.
- Спонсоры и купоны — портал спонсоров с тремя тарифами и купоны с антифрод-отслеживанием, а также поездки по расписанию и отзывы.
Технологии
Бэкенд работает на Node.js 22 с TypeScript, Express и Socket.IO. Данные хранятся в MariaDB/MySQL, а схема развивалась через 24 версионированные SQL-миграции. Zod проверяет входные данные; вход — через JWT и Google. Google Maps отвечает за маршруты, время в пути и геокодирование. Приложения построены на Expo и React Native.
Почему именно так
Двум пассажирам никогда не должен достаться один и тот же водитель. Когда водитель принимает заказ, движок закрепляет его одним условным обновлением: «занят», но только если он всё ещё свободен. Если ни одна строка не изменилась, водителя только что забрали, и поездка переходит к следующему кандидату. Кандидаты ранжируются по времени в пути, а не по расстоянию по прямой, потому что в Риме ближайшая машина часто не самая быстрая. Если Google не отвечает, ранжирование переходит на расстояние.


