FuelBuddy에서 나는 프랜차이즈 애플리케이션의 핵심 엔지니어였다. 프랜차이즈 운영자들이 지역 허브, 재고, 배송 차량을 관리하는 데 사용하는 앱이다.
내가 만든 것
- 실시간 트럭 추적: 폴링 간격으로 차량 위치를 표시하는 대화형 Google Maps 모듈을 구축해, 운영자에게 트럭 이동과 배차 상태에 대한 지속적인 가시성을 제공했다.
- GraphQL API와 캐싱: urql을 통해 Hasura GraphQL 엔진을 사용하는 데이터 API를 구축했으며, 정규화된 클라이언트 사이드 캐시와 만료 시 자동 토큰 갱신을 포함한다.
- 워크플로우 단순화: 재고 조정과 기사 배정을 포함한 여러 단계의 운영 작업을 간소화된 인터페이스로 재설계해 운영 오류를 줄였다.
왜 중요했는가
차량 추적으로 배차 물류가 더 예측 가능해졌고 트럭 유휴 시간이 줄었다. 간소화된 배정 및 재고 워크플로우는 프랜차이즈 허브 전반에서 운영 오류를 줄였다.
"실시간"이 여기서 실제로 의미하는 것
트럭 지도는 GraphQL 구독이 아니라 폴링 간격으로 업데이트되는데, 같은 클라이언트가 앱의 다른 곳에서는 구독용으로 연결되어 있는데도 그렇다(graphql-ws는 주문 상태 업데이트에 구성되고 사용되지만, 이 특정 지도에는 아니다). 이것은 간과가 아니라 의도적인 서버 비용 트레이드오프였다: 구독은 클라이언트가 그것을 열어둔 시간만큼 서버에 지속적인 연결을 유지하는데, 배차 담당자의 근무 시간 내내 몇 시간 동안 열려 있는 지도 화면은 일회성 주문 상태 업데이트보다 훨씬 더 무겁고 오래 지속되는 연결 부하다. 폴링은 그 연결을 아예 열어두지 않는 대신, 주기적인 요청/응답 사이클로 그것을 대체한다.
배정과 재고, 더 자세히
기사 배정은 단일한 "배정" 동작 하나가 아니라 단일, 대량, 재배정, 배정 취소 흐름을 다룬다. 재고 추적은 일반적인 부품 재고가 아니라 연료 보저(탱커 트럭)에 특화된 재고 잔량을 전용 재고 잔량 쿼리와 로그 테이블과 함께 추적하는, 실제 운영 데이터 모델이다.
데이터 모델과 규모
- urql의 정규화된 캐시와 401/만료된 토큰 응답에서 자동으로 갱신되는 Firebase 토큰 인증 계층이 있어서, 만료된 세션이 배차 담당자의 작업 도중을 방해하지 않는다.
- Playwright는 로그인과 주문 관리를 엔드투엔드로 커버하는데, 이는 앱의 다른 모든 화면이 의존하는 두 흐름이다.
Stack
Vue 3, Vite, Pinia, Hasura를 상대하는 urql, Firebase 인증, Google Maps, 테스트를 위한 Playwright.