FuelBuddy 拓展阿联酋业务需要一个专门为区域运营需求定制的加盟商应用。我从零构建了这个迪拜加盟商应用,涵盖前端和数据 API 两方面。
我做了什么
- 全新前端: 从零构建组件体系和应用结构,为加盟商运营交付了一个简洁、响应式的界面。
- Hasura GraphQL API: 在 Hasura GraphQL 引擎上构建后端数据层,定义了应用所需的 CRUD 操作和数据模型。
- 地图、排期与导出: 集成了实时地图、日历/甘特图排期视图,以及用于加盟商报表的电子表格/PDF 导出功能。
- 身份验证与安全: 配置了基于 Firebase 的身份验证,并通过 Hasura 自身的 JWT claims 强制执行基于角色的访问控制。
为什么它有意义
交付这个专属平台,为 FuelBuddy 阿联酋的加盟商运营者提供了一个专为区域运营打造的工具,其技术栈也是为实时地图数据和繁重报表而设计的。
数据层
这个应用通过 graphql-request 访问一个带类型、由 codegen 生成的 SDK,客户端状态由 Pinia store 持有,整个依赖树里没有 TanStack Query。身份验证跑在 Firebase 上,基于角色的访问控制来自 Hasura 自己的 JWT 自定义 claims(x-hasura-default-role、x-hasura-user-id),而不是另外搭建的一套权限系统。
不只是一个表单构建器
对于一个本可以只是薄薄一层 CRUD 工具的应用来说,这里的功能密度相当高:用 Mapbox GL 加 mapbox-gl-draw 直接在地图上绘制和编辑加盟商区域;FullCalendar 搭配 vue-ganttastic 实现甘特图式排期;Chart.js 用于报表仪表盘;还有一整套导出流水线(xlsx、papaparse、jszip、html2pdf.js、dom-to-image、html-to-image),让加盟商报表可以按运营者的需要,以电子表格、PDF 或图片的形式导出,而不是固定为一种格式。
用代码生成,而不是手写查询
GraphQL 操作在构建时通过 vite-plugin-graphql-codegen 依据 codegen.yml 生成,从 Hasura schema 产出一个带类型的 src/sdk.ts 客户端。每一个查询和 mutation 都针对实时 schema 带有类型,而不是手写字符串,那种写法在后端变更时会悄悄地跑偏而不被察觉。
测试重点
Playwright 端到端覆盖了两个流程:登录和订单管理,前者是其他所有页面的前置关卡,后者是这个应用存在的核心交易场景。排期、导出、报表这些属于这两个流程下游的功能,都是比测试覆盖更新的功能面,而不是被遗漏了。
技术栈
Vue 3、Vite、Pinia、graphql-request 配合 GraphQL Code Generator 对接 Hasura、Firebase 用于身份验证、Mapbox GL 配合 mapbox-gl-draw、FullCalendar 配合 vue-ganttastic、Chart.js 用于报表、Playwright 用于测试。