Расширению FuelBuddy в ОАЭ понадобилось отдельное приложение для франшизы, адаптированное под региональные требования к работе. Я построил приложение франшизы для Дубая с нуля, и фронтенд, и API данных под ним.
Что я сделал
- Фронтенд с нуля: построил систему компонентов и структуру приложения с нуля, обеспечив чистый и отзывчивый интерфейс для операций франшизы.
- API на Hasura GraphQL: построил бэкенд-слой данных на движке Hasura GraphQL, определив CRUD-операции и модели данных, нужные приложению.
- Карты, планирование и экспорт: интегрировал живые карты, календарное/Gantt-представление для планирования и экспорт в таблицы/PDF для отчётности франшизы.
- Аутентификация и безопасность: настроил аутентификацию на основе Firebase с ролевым доступом, обеспечиваемым через собственные JWT-клеймы Hasura.
Почему это было важно
Отдельная платформа дала операторам франшизы FuelBuddy в ОАЭ инструмент, спроектированный специально для региональных операций, на стеке, построенном для карт в реальном времени и тяжёлой отчётности.
Слой данных
Это приложение получает данные через graphql-request к типизированному SDK, сгенерированному кодогенерацией, а состояние клиента хранят Pinia-сторы, без TanStack Query где-либо в дереве зависимостей. Аутентификация работает на Firebase, а ролевой доступ берётся из собственных кастомных JWT-клеймов Hasura (x-hasura-default-role, x-hasura-user-id), а не из отдельно построенной системы прав.
Больше, чем конструктор форм
Это по-настоящему насыщенное функциями приложение там, где могло бы получиться тонкое CRUD-средство: Mapbox GL вместе с mapbox-gl-draw для рисования и редактирования зон франшизы прямо на карте, FullCalendar в паре с vue-ganttastic для планирования в стиле Gantt, Chart.js для дашбордов отчётности и полноценный конвейер экспорта (xlsx, papaparse, jszip, html2pdf.js, dom-to-image, html-to-image), так что отчёты франшизы выходят из приложения как таблицы, PDF или изображения, в зависимости от того, что нужно оператору, а не в одном фиксированном формате.
Кодогенерация, а не запросы, написанные вручную
GraphQL-операции генерируются во время сборки через vite-plugin-graphql-codegen по конфигурации codegen.yml, что даёт типизированный клиент src/sdk.ts, построенный по схеме Hasura. Каждый запрос и мутация типизированы по актуальной схеме, а не представляют собой написанные вручную строки, которые незаметно расходятся с реальностью при изменении бэкенда.
Фокус тестирования
Playwright сквозным образом покрывает два сценария: вход в систему и управление заказами, шлюз, за которым стоят все остальные экраны, и основную транзакцию, ради которой существует приложение. Всё, что находится ниже по цепочке от этих двух сценариев (планирование, экспорт, отчётность), это более новая часть функциональности, чем тесты, а не недосмотр.
Стек
Vue 3, Vite, Pinia, graphql-request с GraphQL Code Generator поверх Hasura, Firebase для аутентификации, Mapbox GL с mapbox-gl-draw, FullCalendar с vue-ganttastic, Chart.js для отчётности, Playwright для тестов.