Связано с FuelBuddy

FuelBuddy Дубай: B2B-веб-портал для клиентов

Построил с нуля B2B-веб-портал для запуска FuelBuddy в ОАЭ: платежи через Stripe, регистрация по OTP, поддержка устанавливаемого PWA и CRUD-API на Hasura GraphQL.

Выход FuelBuddy на B2B-рынок ОАЭ потребовал отдельного веб-портала. Корпоративным клиентам было нужно управление автопарком, оптовые заказы и планирование доставки по нескольким точкам, а не розничные потребительские сценарии. Я построил этот портал от первого коммита в репозитории до продакшена, отвечая за архитектуру фронтенда и бэкенд-API данных.

Что я сделал

  • Архитектура фронтенда: настроил приложение с нуля, включая архитектуру компонентов, клиентскую маршрутизацию и единую систему дизайна для корпоративных сценариев.
  • B2B-сценарии: построил многошаговые формы заказа, потоки планирования оптовых поставок топлива и насыщенные данными дашборды автопарка с графиками и таблицами истории заказов и кошелька.
  • Платежи и онбординг: интегрировал Stripe для пополнения кошелька и оплаты заказов, а также регистрацию корпоративных аккаунтов через OTP по номеру телефона.
  • Функции целиком: построил CRUD-API на движке Hasura GraphQL, подключил их к состоянию UI, выпустил приложение как устанавливаемое PWA и довёл бизнес-правила валидации до продакшена.

Почему это было важно

Запуск портала дал FuelBuddy отдельную веб-платформу для корпоративных клиентов в Дубае, упростив оптовые заказы топлива и поддержав региональную экспансию компании.

Что на самом деле выкатили в продакшен

Оптовые заказы и массовое планирование смен, это настоящие, рабочие мутации к Hasura, а не формы-заглушки, наряду с дашбордом, который заменил более раннюю устаревшую версию (обе всё ещё есть в кодовой базе, но в проде работает новая). Аутентификация идёт через собственные JWT-клеймы Hasura (x-hasura-default-role считывается прямо из токена), а не через отдельный слой прав, пристроенный позже.

Платежи и онбординг, а не только CRUD

Пополнение кошелька и прямая оплата заказа идут через Stripe (@stripe/stripe-js, vue-stripe-js), с отдельными платёжными маршрутами для самостоятельных заказов и транзакций кошелька. Регистрация проходит через OTP-верификацию по телефону (vue3-otp-input, а vue-tel-input отвечает за международный формат номера), а не через обычную форму email/пароль, что соответствует порталу, построенному для корпоративных аккаунтов автопарка, а не для случайной регистрации.

Устанавливаемое, а не только адаптивное

Портал выходит как устанавливаемое прогрессивное веб-приложение через vite-plugin-pwa и Workbox, с регистрацией service worker в режиме autoUpdate, так что менеджер автопарка может добавить его на домашний экран и получать новые выкладки без ручной переустановки.

Модель данных и масштаб

  • Сгенерированный GraphQL SDK (из кодогенерации по схеме) занимает более 31 000 строк, это действительно большая типизированная API-поверхность, а не горстка запросов на скорую руку.
  • Запросы данных идут через graphql-request напрямую к Hasura, без Apollo или urql-клиента посередине.
  • Дашборды автопарка рендерятся через vue3-easy-data-table и vue-chart-3 (Chart.js), рассчитанные на таблицы и графики с реальным количеством строк, а не на горстку сводных карточек.

Стек

Vue 3, Vite, Pinia для состояния, graphql-request вместе с GraphQL Code Generator поверх Hasura, Stripe для платежей, Firebase для аутентификации, Chart.js для дашбордов, vite-plugin-pwa с Workbox для офлайн-режима и установки, Playwright для тестов.