В FuelBuddy я был ключевым инженером приложения франшизы, которым операторы франшизы пользуются, чтобы управлять региональными хабами, запасами и автопарками доставки.
Что я сделал
- Отслеживание грузовиков в реальном времени: построил интерактивный модуль на Google Maps, показывающий местоположение автопарка с опросом через заданный интервал, дав операторам постоянную видимость перемещений грузовиков и статусов диспетчеризации.
- API на GraphQL и кэширование: построил API данных на движке Hasura GraphQL через urql, с нормализованным клиентским кэшем и автоматическим обновлением токена по истечении срока.
- Упрощение сценариев: переработал многошаговые операционные задачи, включая сверку запасов и назначение водителей, в упрощённые интерфейсы, которые сократили операционные ошибки.
Почему это было важно
Отслеживание автопарка сделало логистику диспетчеризации предсказуемее и сократило простой машин. Упрощённые сценарии назначения и учёта запасов сократили операционные ошибки во всех хабах франшизы.
Что здесь на самом деле значит «в реальном времени»
Карта грузовиков обновляется по опросу через интервал, а не через GraphQL-подписку, хотя тот же клиент настроен на подписки в других местах приложения (graphql-ws сконфигурирован и используется для обновлений статуса заказа, просто не для этой конкретной карты). Это осознанный компромисс ради стоимости сервера, а не недосмотр: подписка держит открытым постоянное соединение на сервере столько, сколько клиент держит её открытой, а экран карты, оставленный открытым на протяжении всей смены диспетчера часами напролёт, создаёт куда более тяжёлую и долгоживущую нагрузку на соединения, чем разовое обновление статуса заказа. Опрос вообще не держит соединение открытым, обменивая его на периодические циклы запрос/ответ.
Назначения и запасы подробнее
Назначение водителей охватывает сценарии одиночного, массового назначения, переназначения и снятия назначения, а не одно-единственное действие «назначить». Учёт запасов отслеживает остатки конкретно для топливных цистерн (bowsers), с отдельными запросами остатков и таблицами журналов, это настоящая операционная модель данных, а не общий учёт запчастей.
Модель данных и масштаб
- Нормализованный кэш urql плюс слой аутентификации на токенах Firebase, который автоматически обновляется при ответах 401/истёкший токен, так что истёкшая сессия не прерывает диспетчера посреди задачи.
- Playwright сквозным образом покрывает вход в систему и управление заказами, два сценария, от которых зависят все остальные экраны приложения.
Стек
Vue 3, Vite, Pinia, urql поверх Hasura, аутентификация Firebase, Google Maps, Playwright для тестов.