Project detail
Service Ticket System for Hala's EV Fleet
A role-aware service ticket system that moved Hala's vehicle issues out of Excel and WhatsApp into one lifecycle across rider, technician and ops apps. Rider service complaints down ~60%.

Role: Lead Product Designer, with a senior designer reviewing. Research, IA, end-to-end UX/UI, prototyping, usability testing, engineering handoff
Team: Me, a senior design reviewer, product manager, engineering team, ops leads as partners
Product: Hala Mobility · CercleOS fleet operations platform
Surfaces: Rider app · Technician app · Ops dashboard · Hub manager view
Timeline: 2024 – 2025
TL;DR
Problem: Vehicle service issues lived in phone calls, WhatsApp groups and Excel. Nobody owned a ticket end to end, so vehicles sat idle and leadership had no reliable data.
What I did: Designed one role-aware ticket system across four surfaces: one ticket ID, one owner at every stage, one history everyone can see.
Impact: Unresolved tickets held under 5% of monthly volume · rider service complaints down ~60% · jobs closed per technician per day up ~30% · resolution time measurable for the first time (48h average).
The problem: five roles, five channels, no owner
Hala rents EVs to riders and runs fleets for business partners. As hubs multiplied, every service issue became a relay race with no baton. Riders phoned in problems. Support escalated on WhatsApp. Hub managers tracked it in Excel. Technicians closed jobs with no record of what they fixed. Every idle vehicle was lost revenue.

Goal: anyone, from rider to leadership, can log, track and resolve a service issue in one workflow, with a clear owner and a visible history.
What the hubs taught me
I didn't design this from a desk. I ran 1:1 interviews with hub (STL) managers, technicians, riders across B2B, B2C and 3PL, support agents and leadership; shadowed shifts at the hubs; audited the Excel, WhatsApp and phone trail to see exactly where it broke; and benchmarked Fleetx, Rapido Ops, Yulu and Bounce.
Three findings shaped everything that followed:

Decision 1: One ticket, many views
Options: separate tools per team, each tailored and quick to ship, or one shared ticket object with role-based surfaces on top.
I chose one ticket ID, one lifecycle and one history, with each role seeing only the actions it can take. Riders raise and track. Ops assigns and escalates. Technicians accept and close. Hub managers watch volumes and bottlenecks.
The cost: agreeing a single lifecycle across five roles before any screen was built. The payoff: no reconciling data between tools, and leadership reporting came almost for free.

Decision 2: No ticket without an owner
Options: a shared queue anyone can pick from, or mandatory assignment at every stage.
I chose mandatory ownership. Every ticket always has an assignee and a next step, hand-offs reassign it explicitly, and a stalled ticket escalates instead of silently ageing.
The cost: a little more effort for ops at creation. It's exactly the friction that ended the chasing.


Decision 3: Technicians close jobs with photos, not paragraphs
Options: a free-text closure form, or a guided close built for someone standing next to a vehicle.
I chose a guided close: accept the job, update progress and document the fix with minimal typing, so documentation actually happens in the field.
The cost: photo uploads lagged on hub connections, one of the engineering constraints we had to work through (below).


Decision 4: A quality check before a ticket can close
Options: the technician closes the ticket, or a quality checker verifies the fix first.
I chose a QC sign-off. It adds one step before closure, but a rejected fix goes straight back to the technician instead of the vehicle going back on the road unfixed.

The rider's side: report an issue without calling anyone
Riders raise a ticket in a few taps, attach what's wrong, and see its status in the app, which removes the "any update?" call to support entirely.


The hub manager's view: bottlenecks at a glance
Hub managers see ticket volumes, owners and ageing tickets for their hub, so they step in when something stalls rather than when a rider complains.

How I got there
Low-fidelity wireframes focused on four things: fewer steps to create a ticket, explicit assignment and escalation, at-a-glance views for busy ops teams, and field updates without heavy typing. I then tested realistic prototypes, with edge cases and empty, error and escalated states, with 6 hub managers, 5 technicians, 5 support agents and 3 ops heads.

One shared design system kept the rider app, technician app and dashboards consistent, and faster to build.

Shipping it with engineering
The backend had no way to track a ticket's timeline, so we stored every status change in a status log. That's what makes resolution time measurable today. Shared components were hard to change, so I prioritised lifecycle clarity over pixel perfection, and wrote clear acceptance criteria for every state so engineering could build async.
Results
Unresolved tickets: held under 5% of monthly volume, against customer support's Excel logs where a large share of issues were never formally closed
Rider service complaints: down ~60%
Technician throughput: ~30% more jobs closed per technician per day
Resolution time: 48h average, the first reliable baseline Hala has had (before: an estimated 2–4 days, with no real data)
Leadership: went from no visibility to the full ticket lifecycle across hubs
"This saved me at least 1 hour daily chasing executives. Great accountability." – Hub Manager, after launch
"I finally know who's doing their job and who's not." – Ops Head, after launch
What I'd do differently
Instrument before launch. We had no clean "before" data, so our biggest win, visibility, is also the hardest to prove.
Ship the technician app first. Field documentation was the bottleneck everything downstream depended on.
Multi-role design is systems design. Clear states, ownership and timelines cut more follow-ups than any new feature did.
Want the full walkthrough, including edge cases and the design system? I'm happy to take you through it in an interview.



