Выход 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 для тестов.